// player.cpp: Beispielspieler für Asteroids
// Harald Bögeholz / c't
// modifiziert von Gerd Meier 91287 Plech Bernheck 13
// 2008 April für den Programmierwettbewerb

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <math.h>

#if defined(WINDOWS)
#include <winsock2.h>
#else
// 2 Includes für socket()
#include <sys/types.h>
#include <sys/socket.h>
// 2 Includes für inet_addr()
#include <netinet/in.h>
#include <arpa/inet.h>
// 2 Includes für fcntl()
#include <unistd.h>
#include <fcntl.h>
// für memset()
#define INVALID_SOCKET -1
#define WSAGetLastError() errno
#endif

#include "player.h"

struct winkelbyte{
	int dx;
	int dy;
};
struct winkelbyte wb[256];

void init_wb(void)
{
wb[0].dx=1536, wb[0].dy=0;
wb[3].dx=1536, wb[3].dy=0;
wb[6].dx=1528, wb[6].dy=152;
wb[9].dx=1504, wb[9].dy=296;
wb[12].dx=1472, wb[12].dy=440;
wb[15].dx=1472, wb[15].dy=440;
wb[18].dx=1416, wb[18].dy=584;
wb[21].dx=1360, wb[21].dy=720;
wb[24].dx=1280, wb[24].dy=856;
wb[27].dx=1280, wb[27].dy=856;
wb[30].dx=1192, wb[30].dy=976;
wb[33].dx=1088, wb[33].dy=1088;
wb[36].dx=976, wb[36].dy=1192;
wb[39].dx=976, wb[39].dy=1192;
wb[42].dx=856, wb[42].dy=1280;
wb[45].dx=720, wb[45].dy=1360;
wb[48].dx=584, wb[48].dy=1416;
wb[51].dx=584, wb[51].dy=1416;
wb[54].dx=440, wb[54].dy=1472;
wb[57].dx=296, wb[57].dy=1504;
wb[60].dx=152, wb[60].dy=1528;
wb[63].dx=152, wb[63].dy=1528;
wb[66].dx=-152, wb[66].dy=1528;
wb[69].dx=-296, wb[69].dy=1504;
wb[72].dx=-296, wb[72].dy=1504;
wb[75].dx=-440, wb[75].dy=1472;
wb[78].dx=-584, wb[78].dy=1416;
wb[81].dx=-720, wb[81].dy=1360;
wb[84].dx=-720, wb[84].dy=1360;
wb[87].dx=-856, wb[87].dy=1280;
wb[90].dx=-976, wb[90].dy=1192;
wb[93].dx=-1088, wb[93].dy=1088;
wb[96].dx=-1088, wb[96].dy=1088;
wb[99].dx=-1192, wb[99].dy=976;
wb[102].dx=-1280, wb[102].dy=856;
wb[105].dx=-1360, wb[105].dy=720;
wb[108].dx=-1360, wb[108].dy=720;
wb[111].dx=-1416, wb[111].dy=584;
wb[114].dx=-1472, wb[114].dy=440;
wb[117].dx=-1504, wb[117].dy=296;
wb[120].dx=-1504, wb[120].dy=296;
wb[123].dx=-1528, wb[123].dy=152;
wb[126].dx=-1536, wb[126].dy=0;
wb[129].dx=-1536, wb[129].dy=0;
wb[132].dx=-1528, wb[132].dy=-152;
wb[135].dx=-1528, wb[135].dy=-152;
wb[138].dx=-1504, wb[138].dy=-296;
wb[141].dx=-1472, wb[141].dy=-440;
wb[144].dx=-1416, wb[144].dy=-584;
wb[147].dx=-1416, wb[147].dy=-584;
wb[150].dx=-1360, wb[150].dy=-720;
wb[153].dx=-1280, wb[153].dy=-856;
wb[156].dx=-1192, wb[156].dy=-976;
wb[159].dx=-1192, wb[159].dy=-976;
wb[162].dx=-1088, wb[162].dy=-1088;
wb[165].dx=-976, wb[165].dy=-1192;
wb[168].dx=-856, wb[168].dy=-1280;
wb[171].dx=-856, wb[171].dy=-1280;
wb[174].dx=-720, wb[174].dy=-1360;
wb[177].dx=-584, wb[177].dy=-1416;
wb[180].dx=-440, wb[180].dy=-1472;
wb[183].dx=-440, wb[183].dy=-1472;
wb[186].dx=-296, wb[186].dy=-1504;
wb[189].dx=-152, wb[189].dy=-1528;
wb[192].dx=0, wb[192].dy=-1536;
wb[195].dx=152, wb[195].dy=-1528;
wb[198].dx=296, wb[198].dy=-1504;
wb[201].dx=440, wb[201].dy=-1472;
wb[204].dx=440, wb[204].dy=-1472;
wb[207].dx=584, wb[207].dy=-1416;
wb[210].dx=720, wb[210].dy=-1360;
wb[213].dx=856, wb[213].dy=-1280;
wb[216].dx=856, wb[216].dy=-1280;
wb[219].dx=976, wb[219].dy=-1192;
wb[222].dx=1088, wb[222].dy=-1088;
wb[225].dx=1192, wb[225].dy=-976;
wb[228].dx=1192, wb[228].dy=-976;
wb[231].dx=1280, wb[231].dy=-856;
wb[234].dx=1360, wb[234].dy=-720;
wb[237].dx=1416, wb[237].dy=-584;
wb[240].dx=1416, wb[240].dy=-584;
wb[243].dx=1472, wb[243].dy=-440;
wb[246].dx=1504, wb[246].dy=-296;
wb[249].dx=1528, wb[249].dy=-152;
wb[252].dx=1528, wb[252].dy=-152;
wb[255].dx=1536, wb[255].dy=0;
wb[2].dx=1536, wb[2].dy=0;
wb[5].dx=1528, wb[5].dy=152;
wb[8].dx=1504, wb[8].dy=296;
wb[11].dx=1504, wb[11].dy=296;
wb[14].dx=1472, wb[14].dy=440;
wb[17].dx=1416, wb[17].dy=584;
wb[20].dx=1360, wb[20].dy=720;
wb[23].dx=1360, wb[23].dy=720;
wb[26].dx=1280, wb[26].dy=856;
wb[29].dx=1192, wb[29].dy=976;
wb[32].dx=1088, wb[32].dy=1088;
wb[35].dx=1088, wb[35].dy=1088;
wb[38].dx=976, wb[38].dy=1192;
wb[41].dx=856, wb[41].dy=1280;
wb[44].dx=720, wb[44].dy=1360;
wb[47].dx=720, wb[47].dy=1360;
wb[50].dx=584, wb[50].dy=1416;
wb[53].dx=440, wb[53].dy=1472;
wb[56].dx=296, wb[56].dy=1504;
wb[59].dx=296, wb[59].dy=1504;
wb[62].dx=152, wb[62].dy=1528;
wb[65].dx=-152, wb[65].dy=1528;
wb[68].dx=-152, wb[68].dy=1528;
wb[71].dx=-296, wb[71].dy=1504;
wb[74].dx=-440, wb[74].dy=1472;
wb[77].dx=-584, wb[77].dy=1416;
wb[80].dx=-584, wb[80].dy=1416;
wb[83].dx=-720, wb[83].dy=1360;
wb[86].dx=-856, wb[86].dy=1280;
wb[89].dx=-976, wb[89].dy=1192;
wb[92].dx=-976, wb[92].dy=1192;
wb[95].dx=-1088, wb[95].dy=1088;
wb[98].dx=-1192, wb[98].dy=976;
wb[101].dx=-1280, wb[101].dy=856;
wb[104].dx=-1280, wb[104].dy=856;
wb[107].dx=-1360, wb[107].dy=720;
wb[110].dx=-1416, wb[110].dy=584;
wb[113].dx=-1472, wb[113].dy=440;
wb[116].dx=-1472, wb[116].dy=440;
wb[119].dx=-1504, wb[119].dy=296;
wb[122].dx=-1528, wb[122].dy=152;
wb[125].dx=-1536, wb[125].dy=0;
wb[128].dx=-1536, wb[128].dy=0;
wb[131].dx=-1536, wb[131].dy=0;
wb[134].dx=-1528, wb[134].dy=-152;
wb[137].dx=-1504, wb[137].dy=-296;
wb[140].dx=-1472, wb[140].dy=-440;
wb[143].dx=-1472, wb[143].dy=-440;
wb[146].dx=-1416, wb[146].dy=-584;
wb[149].dx=-1360, wb[149].dy=-720;
wb[152].dx=-1280, wb[152].dy=-856;
wb[155].dx=-1280, wb[155].dy=-856;
wb[158].dx=-1192, wb[158].dy=-976;
wb[161].dx=-1088, wb[161].dy=-1088;
wb[164].dx=-976, wb[164].dy=-1192;
wb[167].dx=-976, wb[167].dy=-1192;
wb[170].dx=-856, wb[170].dy=-1280;
wb[173].dx=-720, wb[173].dy=-1360;
wb[176].dx=-584, wb[176].dy=-1416;
wb[179].dx=-584, wb[179].dy=-1416;
wb[182].dx=-440, wb[182].dy=-1472;
wb[185].dx=-296, wb[185].dy=-1504;
wb[188].dx=-152, wb[188].dy=-1528;
wb[191].dx=-152, wb[191].dy=-1528;
wb[194].dx=152, wb[194].dy=-1528;
wb[197].dx=296, wb[197].dy=-1504;
wb[200].dx=296, wb[200].dy=-1504;
wb[203].dx=440, wb[203].dy=-1472;
wb[206].dx=584, wb[206].dy=-1416;
wb[209].dx=720, wb[209].dy=-1360;
wb[212].dx=720, wb[212].dy=-1360;
wb[215].dx=856, wb[215].dy=-1280;
wb[218].dx=976, wb[218].dy=-1192;
wb[221].dx=1088, wb[221].dy=-1088;
wb[224].dx=1088, wb[224].dy=-1088;
wb[227].dx=1192, wb[227].dy=-976;
wb[230].dx=1280, wb[230].dy=-856;
wb[233].dx=1360, wb[233].dy=-720;
wb[236].dx=1360, wb[236].dy=-720;
wb[239].dx=1416, wb[239].dy=-584;
wb[242].dx=1472, wb[242].dy=-440;
wb[245].dx=1504, wb[245].dy=-296;
wb[248].dx=1504, wb[248].dy=-296;
wb[251].dx=1528, wb[251].dy=-152;
wb[254].dx=1536, wb[254].dy=0;
wb[1].dx=1536, wb[1].dy=0;
wb[4].dx=1528, wb[4].dy=152;
wb[7].dx=1528, wb[7].dy=152;
wb[10].dx=1504, wb[10].dy=296;
wb[13].dx=1472, wb[13].dy=440;
wb[16].dx=1416, wb[16].dy=584;
wb[19].dx=1416, wb[19].dy=584;
wb[22].dx=1360, wb[22].dy=720;
wb[25].dx=1280, wb[25].dy=856;
wb[28].dx=1192, wb[28].dy=976;
wb[31].dx=1192, wb[31].dy=976;
wb[34].dx=1088, wb[34].dy=1088;
wb[37].dx=976, wb[37].dy=1192;
wb[40].dx=856, wb[40].dy=1280;
wb[43].dx=856, wb[43].dy=1280;
wb[46].dx=720, wb[46].dy=1360;
wb[49].dx=584, wb[49].dy=1416;
wb[52].dx=440, wb[52].dy=1472;
wb[55].dx=440, wb[55].dy=1472;
wb[58].dx=296, wb[58].dy=1504;
wb[61].dx=152, wb[61].dy=1528;
wb[64].dx=0, wb[64].dy=1536;  // senkrecht nach oben
wb[67].dx=-152, wb[67].dy=1528;
wb[70].dx=-296, wb[70].dy=1504;
wb[73].dx=-440, wb[73].dy=1472;
wb[76].dx=-440, wb[76].dy=1472;
wb[79].dx=-584, wb[79].dy=1416;
wb[82].dx=-720, wb[82].dy=1360;
wb[85].dx=-856, wb[85].dy=1280;
wb[88].dx=-856, wb[88].dy=1280;
wb[91].dx=-976, wb[91].dy=1192;
wb[94].dx=-1088, wb[94].dy=1088;
wb[97].dx=-1192, wb[97].dy=976;
wb[100].dx=-1192, wb[100].dy=976;
wb[103].dx=-1280, wb[103].dy=856;
wb[106].dx=-1360, wb[106].dy=720;
wb[109].dx=-1416, wb[109].dy=584;
wb[112].dx=-1416, wb[112].dy=584;
wb[115].dx=-1472, wb[115].dy=440;
wb[118].dx=-1504, wb[118].dy=296;
wb[121].dx=-1528, wb[121].dy=152;
wb[124].dx=-1528, wb[124].dy=152;
wb[127].dx=-1536, wb[127].dy=0;
wb[130].dx=-1536, wb[130].dy=0;
wb[133].dx=-1528, wb[133].dy=-152;
wb[136].dx=-1504, wb[136].dy=-296;
wb[139].dx=-1504, wb[139].dy=-296;
wb[142].dx=-1472, wb[142].dy=-440;
wb[145].dx=-1416, wb[145].dy=-584;
wb[148].dx=-1360, wb[148].dy=-720;
wb[151].dx=-1360, wb[151].dy=-720;
wb[154].dx=-1280, wb[154].dy=-856;
wb[157].dx=-1192, wb[157].dy=-976;
wb[160].dx=-1088, wb[160].dy=-1088;
wb[163].dx=-1088, wb[163].dy=-1088;
wb[166].dx=-976, wb[166].dy=-1192;
wb[169].dx=-856, wb[169].dy=-1280;
wb[172].dx=-720, wb[172].dy=-1360;
wb[175].dx=-720, wb[175].dy=-1360;
wb[178].dx=-584, wb[178].dy=-1416;
wb[181].dx=-440, wb[181].dy=-1472;
wb[184].dx=-296, wb[184].dy=-1504;
wb[187].dx=-296, wb[187].dy=-1504;
wb[190].dx=-152, wb[190].dy=-1528;
wb[193].dx=152, wb[193].dy=-1528;
wb[196].dx=152, wb[196].dy=-1528;
wb[199].dx=296, wb[199].dy=-1504;
wb[202].dx=440, wb[202].dy=-1472;
wb[205].dx=584, wb[205].dy=-1416;
wb[208].dx=584, wb[208].dy=-1416;
wb[211].dx=720, wb[211].dy=-1360;
wb[214].dx=856, wb[214].dy=-1280;
wb[217].dx=976, wb[217].dy=-1192;
wb[220].dx=976, wb[220].dy=-1192;
wb[223].dx=1088, wb[223].dy=-1088;
wb[226].dx=1192, wb[226].dy=-976;
wb[229].dx=1280, wb[229].dy=-856;
wb[232].dx=1280, wb[232].dy=-856;
wb[235].dx=1360, wb[235].dy=-720;
wb[238].dx=1416, wb[238].dy=-584;
wb[241].dx=1472, wb[241].dy=-440;
wb[244].dx=1472, wb[244].dy=-440;
wb[247].dx=1504, wb[247].dy=-296;
wb[250].dx=1528, wb[250].dy=-152;
wb[253].dx=1536, wb[253].dy=0;
}

double sw[256];

void init_swinkel(void)
{
sw [0]= 0,0;
sw [3]= 3,6; 
sw [6]= 8,2; 
sw [9]= 12,7; 
sw[12]= 16,5;
sw[15]= 21,2; 
sw[18]= 25,2; 
sw[21]= 29,5; 
sw[24]= 33,5; 
sw[27]= 37,8; 
sw[30]= 41,7; 
sw[33]= 46,2; 
sw[36]= 50,8; 
sw[39]= 55,3; 
sw[42]= 59,4; 
sw[45]= 63,4; 
sw[48]= 67,5; 
sw[51]= 71,6; 
sw[54]= 76,1; 
sw[57]= 79,9; 
sw[60]= 84,5; 
sw[63]= 89,1; 
sw[66]= 92,8; 
sw[69]= 97,2; 
sw[72]= 101,8; 
sw[75]= 105,5; 
sw[78]= 110,2; 
sw[81]= 114,1; 
sw[84]= 118,1; 
sw[87]= 122,8; 
sw[90]= 126,7; 
sw[93]= 131,1; 
sw[96]= 135,0; 
sw[99]= 139,4; 
sw[102]= 143,3; 
sw[105]= 147,9; 
sw[108]= 151,9; 
sw[111]= 156,6; 
sw[114]= 160,7; 
sw[117]= 164,5; 
sw[120]= 169,2; 
sw[123]= 172,8; 
sw[126]= 177,3; 
sw[129]= 181,9; 
sw[132]= 185,5; 
sw[135]= 189,9; 
sw[138]= 194,5; 
sw[141]= 198,2; 
sw[144]= 203,0; 
sw[147]= 206,9; 
sw[150]= 211,0; 
sw[153]= 215,4; 
sw[156]= 220,0; 
sw[159]= 223,8; 
sw[162]= 227,5; 
sw[165]= 232,2; 
sw[168]= 235,9; 
sw[171]= 240,3; 
sw[174]= 245,1; 
sw[177]= 248,8; 
sw[180]= 252,7; 
sw[183]= 257,3; 
sw[186]= 261,1; 
sw[189]= 265,6; 
sw[192]= 270,0; 
sw[195]= 273,6; 
sw[198]= 278,2; 
sw[201]= 282,7; 
sw[204]= 286,5; 
sw[207]= 291,2; 
sw[210]= 295,0; 
sw[213]= 299,0; 
sw[216]= 303,5; 
sw[219]= 307,8; 
sw[222]= 311,7; 
sw[225]= 316,2; 
sw[228]= 320,0; 
sw[231]= 324,5; 
sw[234]= 328,6; 
sw[237]= 332,7; 
sw[240]= 336,6; 
sw[243]= 341,6; 
sw[246]= 345,3; 
sw[249]= 349,9; 
sw[252]= 354,5; 
sw[255]= 358,1; 
sw  [2]= 2,8; 
sw  [5]=  7,2; 
sw[  8]=  11,0; 
sw[ 11]=  15,5; 
sw[ 14]=  19,3; 
sw[ 17]=  23,4; 
sw[ 20]=  28,1; 
sw[ 23]=  32,8; 
sw[ 26]=  36,7; 
sw[ 29]=  40,6; 
sw[ 32]=  45,0; 
sw[ 35]=  49,4; 
sw[ 38]=  53,3; 
sw[ 41]=  57,2; 
sw[ 44]=  61,9; 
sw[ 47]=  66,6; 
sw[ 50]=  70,7; 
sw[ 53]=  74,5; 
sw[ 56]=  79,0; 
sw[ 59]=  82,8; 
sw[ 62]=  87,2; 
sw[ 65]=  91,9; 
sw[ 68]=  95,5; 
sw[ 71]= 100,1; 
sw[ 74]= 104,7; 
sw[ 77]= 108,4; 
sw[ 80]= 113,4; 
sw[ 83]= 117,3; 
sw[ 86]= 121,4; 
sw[ 89]= 125,6; 
sw[ 92]= 130,0; 
sw[ 95]= 133,8; 
sw[ 98]= 138,3; 
sw[101]= 142,2; 
sw[104]= 146,5; 
sw[107]= 151,0; 
sw[110]= 155,0; 
sw[113]= 158,8; 
sw[116]= 163,6; 
sw[119]= 167,3; 
sw[122]= 171,8; 
sw[125]= 176,6; 
sw[128]= 180,0; 
sw[131]= 184,4; 
sw[134]= 188,9; 
sw[137]= 192,7; 
sw[140]= 197,3; 
sw[143]= 201,2; 
sw[146]= 205,0; 
sw[149]= 209,7; 
sw[152]= 214,2; 
sw[155]= 217,8; 
sw[158]= 222,5; 
sw[161]= 226,2; 
sw[164]= 230,0; 
sw[167]= 234,6; 
sw[170]= 239,0; 
sw[173]= 243,1; 
sw[176]= 247,0; 
sw[179]= 251,8; 
sw[182]= 255,5; 
sw[185]= 260,1; 
sw[188]= 264,5; 
sw[191]= 268,1; 
sw[194]= 272,7; 
sw[197]= 277,2; 
sw[200]= 280,8; 
sw[203]= 285,5; 
sw[206]= 289,3; 
sw[209]= 293,4; 
sw[212]= 298,1; 
sw[215]= 302,2; 
sw[218]= 306,7; 
sw[221]= 310,6; 
sw[224]= 315,0; 
sw[227]= 318,9; 
sw[230]= 323,3; 
sw[233]= 327,2; 
sw[236]= 331,9; 
sw[239]= 335,9; 
sw[242]= 339,8; 
sw[245]= 344,5; 
sw[248]= 348,2; 
sw[251]= 352,8; 
sw[254]= 357,2; 
sw[  1]=  0,9; 
sw[  4]=  5,5; 
sw[  7]= 10,1; 
sw[ 10]= 13,9; 
sw[ 13]= 18,4;
sw[ 16]= 22,5; 
sw[ 19]= 26,6; 
sw[ 22]= 30,6; 
sw[25]= 34,7; 
sw[28]= 39,2; 
sw[31]= 43,8; 
sw[34]= 48,3; 
sw[37]= 52,2; 
sw[40]= 56,5; 
sw[43]= 60,5; 
sw[46]= 64,7; 
sw[49]= 68,8; 
sw[52]= 73,5; 
sw[55]= 77,3; 
sw[58]= 81,8; 
sw[61]= 86,4; 
sw[64]= 90,0; // senkrecht nach oben
sw[67]= 94,5; 
sw[70]= 98,9; 
sw[73]=102,7; 
sw[76]=107,3; 
sw[79]=111,2; 
sw[82]=115,3; 
sw[85]=120,2; 
sw[88]=124,2; 
sw[91]=127,8; 
sw[94]=132,5; 
sw[97]=136,1; 
sw[100]= 140,8; 
sw[103]= 145,3; 
sw[106]= 149,8; 
sw[109]= 153,9; 
sw[112]= 157,9; 
sw[115]= 161,8; 
sw[118]= 166,3; 
sw[121]= 170,1; 
sw[124]= 174,3; 
sw[127]= 179,1; 
sw[130]= 182,9; 
sw[133]= 187,2; 
sw[136]= 191,5; 
sw[139]= 195,6; 
sw[142]= 200,3; 
sw[145]= 204,1; 
sw[148]= 208,1; 
sw[151]= 212,1; 
sw[154]= 216,6; 
sw[157]= 221,0; 
sw[160]= 225,0; 
sw[163]= 228,9; 
sw[166]= 233,3; 
sw[169]= 237,8; 
sw[172]= 241,9; 
sw[175]= 245,9; 
sw[178]= 249,8; 
sw[181]= 254,5; 
sw[184]= 258,4; 
sw[187]= 262,8; 
sw[190]= 267,3; 
sw[193]= 270,9; 
sw[196]= 275,5; 
sw[199]= 279,9; 
sw[202]= 283,7; 
sw[205]= 288,2; 
sw[208]= 292,1; 
sw[211]= 296,1; 
sw[214]= 300,2; 
sw[217]= 304,7; 
sw[220]= 309,2; 
sw[223]= 313,8; 
sw[226]= 317,5; 
sw[229]= 322,2; 
sw[232]= 325,8; 
sw[235]= 329,8; 
sw[238]= 334,7; 
sw[241]= 338,8; 
sw[244]= 342,7; 
sw[247]= 347,2; 
sw[250]= 351,1; 
sw[253]= 355,5; 
}

inline void normxy(int &x, int &y)
{
   	while (x < -512) x += 1024;
	while (x > 511) x -= 1024;
	while (y < -384) y += 768;  // dy normalisieren auf -384 ... 383
	while (y > 383) y -= 768;
	
}

inline void normxy(double &x, double &y)
{
   	while (x < -512) x += 1024;
	while (x > 511) x -= 1024;
	while (y < -384) y += 768;  // dy normalisieren auf -384 ... 383
	while (y > 383) y -= 768;
	
}
int nshot=0;
#define MAX_NSHOT 6
#define OWNER_SHIP 0
#define OWNER_UFO  1
#define OWNER_UNDEF 2

struct shote
{
	double x;
	double y;
	double vx;
	double vy;
	int owner; 
	int lifetime;
	int matched;
} shot[MAX_NSHOT];

void add_shot(
			 double x,
			 double y,
			 double vx,
			 double vy,
			 int owner)
{
	if (nshot < MAX_NSHOT-1)
	{
       shot[nshot].x=x;
       shot[nshot].y=y;
       shot[nshot].vx=vx;
       shot[nshot].vy=vy;
       shot[nshot].owner=owner;
	   shot[nshot].lifetime=100000;
	   shot[nshot].matched=1;
	   ++nshot;
	}
	else
		printf("failed to add shot\n");
}

int find_shot 
( double x_neu,
   double y_neu,
   int owner
   )
{
	int found=-1;
	//printf("start match nast %d\n", nast);
for (int i=0; i< nshot; i++)
if (  shot[i].matched==0 &&
		   shot[i].owner==owner )
{
     double xpred=shot[i].x+shot[i].vx;
	 double ypred=shot[i].y+shot[i].vy;
	 
	 double xdiff=xpred-x_neu;
	 double ydiff=ypred-y_neu;
	 normxy(xdiff, ydiff);
	 double vxs=shot[i].vx, vys=shot[i].vy;
	 //printf("i %d diffxy %g %g\n", i, xdiff, ydiff);
	 if ( (vxs==0 && vys==0 &&
		   fabs(xdiff) < 16.0 &&
		   fabs(ydiff) < 16.0) ||
		   ((vxs!=0 || vys !=0)
		   &&fabs(xdiff) < 3.0 &&
		   fabs(ydiff) < 3.0)
		   )

	 {
		 found=i;
		 //printf("ex,ey %g %g\n", fabs(xdiff), fabs(ydiff));
		 
		 shot[i].vx=x_neu-shot[i].x;
		 shot[i].vy=y_neu-shot[i].y;
		 normxy(shot[i].vx, shot[i].vy);
		 if (vxs!=0 || vys!=0){
			  shot[i].vx=(shot[i].vx+vxs)/2;
			  shot[i].vy=(shot[i].vy+vys)/2;
		 }
		 
		 //printf("evxevy %g %g\n", fabs(vxa-ast[i].vx), fabs(vya-ast[i].vy));
		 shot[i].x=x_neu;
		 shot[i].y=y_neu;
		 shot[i].matched=1;
		 break;
	 }

}
return found;

}
void del_shot(int i)
{
	nshot--;
	if (nshot > 0 && i <nshot)
	shot[i]=shot[nshot];
}	
int nast=0;
#define MAX_NAST 30
struct aste
{
	double x;
	double y;
	double vx;
	double vy;
	int sf; // skalfaktor
	int type; 
	int matched;
	int lifetime;
}
ast[MAX_NAST];

void add_ast(
			 double x,
			 double y,
			 double vx,
			 double vy,
			 int sf,
			 int type)
{
	if (nast < MAX_NAST-1)
	{
       ast[nast].x=x;
       ast[nast].y=y;
       ast[nast].vx=vx;
       ast[nast].vy=vy;
       ast[nast].sf=sf;
       ast[nast].type=type;
	   ast[nast].matched=1;
	   ast[nast].lifetime=100000;
       ++nast;
	}
	else
		printf("failed to add ast\n");
}

int find_ast 
( double x_neu,
   double y_neu,
   int sf,
   int type
   )
{
	int found=-1;
	//printf("start match nast %d\n", nast);
for (int i=0; i< nast; i++)
if (  ast[i].matched==0 &&
		   ast[i].sf == sf &&
		   ast[i].type== type )
{
     double xpred=ast[i].x+ast[i].vx;
	 double ypred=ast[i].y+ast[i].vy;
	 
	 double xdiff=xpred-x_neu;
	 double ydiff=ypred-y_neu;
	 normxy(xdiff, ydiff);
	 double vxa=ast[i].vx, vya=ast[i].vy;
	 //printf("i %d diffxy %g %g\n", i, xdiff, ydiff);
	 if ( (vxa==0 && vya==0 &&
		   fabs(xdiff) < 16.0 &&
		   fabs(ydiff) < 16.0) ||
		   ((vxa!=0 || vya !=0)
		   &&fabs(xdiff) < 3.0 &&
		   fabs(ydiff) < 3.0)
		   )

	 {
		 found=i;
		 //printf("ex,ey %g %g\n", fabs(xdiff), fabs(ydiff));
		 
		 ast[i].vx=x_neu-ast[i].x;
		 ast[i].vy=y_neu-ast[i].y;
		 normxy(ast[i].vx, ast[i].vy);
		 if (vxa!=0 || vya!=0){
			  ast[i].vx=(ast[i].vx+vxa)/2;
			  ast[i].vy=(ast[i].vy+vya)/2;
		 }
		 
		 //printf("evxevy %g %g\n", fabs(vxa-ast[i].vx), fabs(vya-ast[i].vy));
		 ast[i].x=x_neu;
		 ast[i].y=y_neu;
		 ast[i].matched=1;
		 break;
	 }
}
return found;

}
void del_ast(int i)
{
	nast--;
	if (nast > 0 && i <nast)
	ast[i]=ast[nast];
}	



	double pi=4*atan((double)1.0);

double	vorhalt1(double dx, double dy, double diff_x, double diff_y,
				double ship_dx, double ship_dy, double *sx, double *sy);

double vorhalt(double dx, double dy, double diff_x, double diff_y,
				double ship_dx, double ship_dy, double *s_x, double *s_y, double *time_dreh, double *coll_dist)
{
    
	 *coll_dist=1e10;
	double time;
    double sum_time=0.0;
	*time_dreh=1e10;
	
	while (1)
	{
		time = vorhalt1(dx,dy,diff_x,diff_y,ship_dx, ship_dy, s_x, s_y);
	    if (time <0.0)
	   { 
		break;
	   }
    
       dx+=diff_x*time;
	   dy+=diff_y*time;
	   ship_dx=*s_x;
	   ship_dy=*s_y;

	   sum_time+=time;
	   if (time < 0.0001) break;
	   
	}

	if (sum_time >=0.0 && time >0.0 )
	{
		*time_dreh=sum_time;
		// in sum_time steht jetzt die gesamte fuer die Drehung
		// benoetigte Zeit
		// jetzt noch die fuer den schuss adddiern
        double d2=sqrt(dx*dx +dy*dy)/8.0;
        sum_time+=d2;
		*coll_dist=d2;
        return sum_time;
	}

		
//printf("sum_time %g\n", sum_time);
	return -1.0;

}

double	vorhalt1(double dx, double dy, double diff_x, double diff_y,
				double ship_dx, double ship_dy, double *s_x, double *s_y)
			{
            // dx,dy Ziel koordinaten, diffx, diff-y Zielgeschwindigkeit
            double time=-1.0;
            
			double v_schuss=8.0; // 8 Einheiten pro Frame, Schussgeschwindigkeit


			//int time= INVALID_TIME; // min_dist_sq / v_schuss; // Vorhaltzeit, grobe Näherung

			// Genauere Berechnung der Vorhaltzeit
			double a=diff_x*diff_x+diff_y*diff_y-v_schuss*v_schuss;
			double b=2*(diff_x*dx+diff_y*dy);
			double c=dx*dx+dy*dy;
			double w2=b*b-4.0*a*c;
			if(w2 >=0.0)
			{
			//printf("abc %g %g %g w2 %g ", a,b,c,w2);
			double w= sqrt(w2);
			int time1=(int)((-b+w)/(2.0*a));
			int time2=(int)((-b-w)/(2.0*a));
			//printf("time %d, %d, %d", time,time1, time2);

		
            if (time1 >0.0 )
			{
				if (time2>0.0)
				{ 
					time=time1;
					if (time2<time)
						time=time2;
				
				}
				else
					time=time1;
				}
			else 
			{
				 if (time2>0.0)
					 time=time2;
				 else
				 {
					 time = -1.0;
					 //printf("invalid time!\n");//keys.thrust(true);
					 // time2<=0 und time1 <= 0
					  // ziel nicht mehr treffbar
					  // verwende time grobnäherung
				 }
			 }
			}
			//printf("time taken: %d\n", time);
if (time >= 0.0)
{
			* s_x=dx+diff_x*time;
			* s_y=dy+diff_y*time;
            // s_x, s_y ist nicht auf betrag 1 normiert, dies braucht man
			// aber fuer folgende Rechnung nicht
              // winkeldifferenz berechnen
			double phi_ship= atan2(ship_dy, ship_dx);
			double phi_shot= atan2(*s_y, *s_x);
			double phi_diff= phi_shot-phi_ship;

			while (phi_diff > pi ) phi_diff-=2*pi;
            while (phi_diff < -pi) phi_diff+=2*pi;
			double frames_diff= (double) ((256.0/3.0)*phi_diff/(2*pi));
			//abs(85.333333333*phi_diff/(2*pi));
			
			time=frames_diff;
			if (time <0.0) time=-time;
			//printf(" time turn %g\n", time);
			//printf("a phi_diff %g frames %d time \n", phi_diff, frames_diff, frames_total);
             // take asteroid with min frames total
}
return time;
			}

double dl(double x, double y)
{
	return sqrt(x*x+y*y);
}

void Player::Run(void)
{
	

	FramePacket frame;
	KeysPacket keys;
	GameStatus game;
	char prevframe = 0;
	int t = 0;
	int sec=0, min=0;
	int sec_old=0;
    int shot_old=0;
int pause=0;
	int phi_b=0;
	int phi_delta=0;
	int phi_delta2=0;

	game.ship_x_old=0;
    game.ship_y_old=0;
	game.level = 0;
	game.nasteroids=1000;
    game.score_old=0;
	game.score=0;
	game.score_uebertrag=0;
bool running=false; // wird gebraucht wenn im laufenden Spiel connected wird

  int max_n_asteroids=0;
    //bool ast_ausgewaehlt=false;
    //int sf_ast_ausgewaehlt=0;
    //int index_ast_ausgewaehlt=0;
	//int type_ast_ausgewaehlt=0;
init_wb();
init_swinkel();

	for (;;)
	{
		++t;         // Zeit
		
		++keys.ping; // jedes gesendete Päckchen erhält eine individuelle Nummer zur Latenzmessung
		SendPacket(keys);
		ReceivePacket(frame);
	

		if (frame.frameno != ++prevframe || frame.ping != keys.ping)
		{
			printf("Latenz %d. %d Frames verloren.\n", keys.ping - frame.ping, frame.frameno - prevframe);
			prevframe = frame.frameno;
			phi_b -= phi_delta;
		}
        if (phi_b <0) phi_b+=256;

		InterpretScreen(frame, game);
     	if (game.score > game.score_old && game.score_old >0)
		{
			running=true;
		}
		if (running)
		if (game.score < game.score_old )
		{
			game.score_uebertrag+=100000;
		}
		game.score_old=game.score;

		sec=t/60;
		min= sec/60;
		sec=sec%60;
		if (sec%5==0 && sec!= sec_old){
			printf("frame %d  time %d:%02d min:sec ", t, min, sec);
	            printf(" score %d  lives %d level %d max n asteroids %d\n",
					game.score+game.score_uebertrag, game.lives, game.level,
					max_n_asteroids);
            
		}
		sec_old=sec;

		keys.clear();   // alle Tasten loslassen
		int min_dist = 0x7fffffff;
		int min_skal_dist = 0x7fffffff;
		int min_dist_orig= 0x7fffffff;
		double min_dx = 0;
		double min_dy = 0;
		double min_delta_dx=0;
		double min_delta_dy=0;
        double min_s_x=0.0, min_s_y=0.0;
        double s_x, s_y;
		double time_min=1.0e10;
		double time= -1.0;
		double time_dreh=1e10;
        double min_time_dreh=1e10;
        double min_radius2=8.0*8.0;
		
		if (game.ship_present)
		{
			
	         if (wb[phi_b].dx== game.ship_dx &&
				 wb[phi_b].dy== game.ship_dy)
			 {; //insync do nothing
			 }
			 else
			 {
				 printf("resync phi_b %d", phi_b);
				 for (int i=0; i<256; i++)
					 if (wb[i].dx == game.ship_dx &&
						 wb[i].dy == game.ship_dy)
					 { phi_b=i; break;}
				 printf("new phi_b %d\n", phi_b);
			 }
			 phi_b+=phi_delta;
			if (phi_b >255) phi_b-=256;
			if (phi_b <0) phi_b+=256;

   			double nx= (1536.0*cos(2*pi*(double)phi_b /256.0)); 
				double ny= (1536.0*sin(2*pi*(double)phi_b /256.0));
				//unsigned int phi_b3=(phi_b-3)&0xff;
				//printf("wb[%d].dx=%d, wb[%d].dy=%d;\n",
				//	 phi_b3, game.ship_dx, phi_b3, game.ship_dy);
            game.ship_dx = (int)nx;
	     	game.ship_dy = (int)ny;
				double ns=sqrt(nx*nx+ny*ny);
				nx/=ns;
				ny/=ns;

			
           //game.ship_dx = (int)(1536.0*cos(2*pi*(double)sw[phi_b] /360.0));
	     	//game.ship_dy = (int)(1536.0*sin(2*pi*(double)sw[phi_b] /360.0));
#if 0		
			double delta_phi=360.0*(double)phi_b/256.0 - sw[phi_b];
			if (delta_phi <-180.0) delta_phi+=360.0;
			if (delta_phi > 180.0) delta_phi-=360.0;

printf("delta phi %g\n", delta_phi);
#endif
			 // GM: delta zu vorherigen Koordinaten
			int ship_delta_x = game.ship_x - game.ship_x_old;
            int ship_delta_y = game.ship_y - game.ship_y_old;

			normxy(ship_delta_x, ship_delta_y);

	        game.ship_x_old=game.ship_x;
            game.ship_y_old=game.ship_y;		

			#if 0
			if (game.saucer_present)
			{
		//	printf("nshots %d\n", game.nshots);

            int startn=max(0, game.nshots-2);
			for (int i=startn; i<game.nshots; ++i)
			{
				
			    int dx = game.shots[i].x - game.ship_x;
				int dy = game.shots[i].y - game.ship_y;

				normxy(dx,dy);

				int shot_delta_x= game.shots[i].x - game.shots[i].x_old;
                int shot_delta_y= game.shots[i].y - game.shots[i].y_old;

				int dist = dx*dx+dy*dy;  // Quadrat des Abstands zu diesem Schuss
				int dist_orig=dist;

				normxy (shot_delta_x, shot_delta_y);

				int shot_v = shot_delta_x *shot_delta_x + shot_delta_y *shot_delta_y;
				int sv=(int)sqrt((double)shot_v);
				//printf("shot i %d v %d\n", i, sv);
				game.shots[i].x_old = game.shots[i].x;
				game.shots[i].y_old = game.shots[i].y;
				
				int skal= dx*shot_delta_x+ dy*shot_delta_y; //skalarprodukt, falls <0 kommt der Schuss auf das Schiff zu
				

				if (skal < 0)
				{
					 // UFO Schuss
				//	printf("ufo sschuss present %d\n",game.saucer_present);
					int one_step_x= dx + shot_delta_x;
					int one_step_y= dx+ shot_delta_y;
					int dist_one_step= one_step_x*one_step_x + one_step_y*one_step_y;
					
					if (dist < 10*10 || dist_one_step < 10*10 )
					{
						//printf("hspace dist %d dist_one_step %d\n",
						//	dist, dist_one_step);
						// GM:  Flucht, wenn Kollision unausweichlich
						// KEIN Hyperspace!!
				        //keys.hyperspace(true);
					}
				}
			}

			}
#endif

			
			 for (int i=0; i<nshot; i++)
				shot[i].matched=0;
            int matcheds=0;
            for (int i=0; i<game.nshots; i++)
			{
				int j=find_shot(game.shots[i].x, game.shots[i].y,
					OWNER_SHIP);
                
				if (j==-1){
					printf("add shot\n");
					add_shot(game.shots[i].x, game.shots [i].y, 0,0,
					OWNER_SHIP);
				}
				else{
			//		printf("%d matched %d\n", i,j);
					matcheds++;
				}
			}
			for (int i=0; i<nshot; i++)
				if (shot[i].matched==0)
				{
					del_shot(i);
					printf("del_shot\n");
				}
				printf("frame %d\n", frame.frameno);
            printf("%g %g shot %g shot %g  shot %g shot %g\n", (double)game.ship_x, (double)game.ship_y, 
				 dl(shot[0].x-(double)game.ship_x, shot[0].y-(double)game.ship_y),
				 dl(shot[1].x-(double)game.ship_x, shot[1].y-(double)game.ship_y),
				 dl(shot[2].x-(double)game.ship_x, shot[2].y-(double)game.ship_y),
				 dl(shot[3].x-(double)game.ship_x, shot[3].y-(double)game.ship_y)
				 );
			if (game.nasteroids >0 && game.nasteroids_vorher ==0)
			{
				++game.level;
			}
				game.nasteroids_vorher = game.nasteroids;
				if (game.nasteroids> max_n_asteroids)
					max_n_asteroids=game.nasteroids;

				double coll_dist =1e10;

					// Vorbereitung Probeschuss
				bool treffer=false;
				
			//	if (index_ast_ausgewaehlt>=game.nasteroids||
			//		game.asteroids[index_ast_ausgewaehlt].sf != sf_ast_ausgewaehlt ||
			//		game.asteroids[index_ast_ausgewaehlt].type != type_ast_ausgewaehlt)
			//		ast_ausgewaehlt=false;
//
  //          if (!ast_ausgewaehlt)
			//printf("n asteroids %d\n", game.nasteroids);
				//printf("start match\n");
		    for (int i=0; i<nast; i++)
				ast[i].matched=0;
            int matchedc=0;
            for (int i=0; i<game.nasteroids; i++)
			{
				int j=find_ast(game.asteroids[i].x, game.asteroids [i].y,
					game.asteroids[i].sf, game.asteroids[i].type);
                
				if (j==-1){
					//printf("add ast\n");
					add_ast(game.asteroids[i].x, game.asteroids [i].y, 0,0,
					game.asteroids[i].sf, game.asteroids[i].type);
				}
				else{
			//		printf("%d matched %d\n", i,j);
					matchedc++;
				}
			}
			for (int i=0; i<nast; i++)
				if (ast[i].matched==0)
				{
					del_ast(i);
					//printf("del_ast\n");
				}

			
			//printf("nast %d, %d %d \n", nast, game.nasteroids, matchedc);

 int fired=-1;
				for (int i=0; i<nast; ++i)
					if (ast[i].lifetime > 100)
			{   // nächstgelegenen Asteroiden suchen
				double dx = ast[i].x - game.ship_x;
				double dy = ast[i].y - game.ship_y;

				normxy(dx,dy);

				double ast_delta_x=ast[i].vx;
                double ast_delta_y= ast[i].vy;
                 normxy (ast_delta_x, ast_delta_y);

				//int ast_delta2_x=game.asteroids[i].x_old - game.asteroids[i].x_old2;
                //int ast_delta2_y= game.asteroids[i].y_old - game.asteroids[i].y_old2;

				//normxy (ast_delta2_x, ast_delta2_y);
				//double diff_ax=ast_delta1_x-ast_delta2_x;
				//double diff_ay=ast_delta1_y-ast_delta2_y;
				//double ast_delta_x=0.0; 
				//double ast_delta_y=0.0;
				//if (diff_ax*diff_ax+diff_ay*diff_ay <6.0*6.0)
				//{
				//ast_delta_x=(ast_delta1_x+ast_delta2_x)/2.0;
                //ast_delta_y=(ast_delta1_y+ast_delta2_y)/2.0;
				//}
				//game.asteroids[i].x_old2 = game.asteroids[i].x_old;
				//game.asteroids[i].y_old2 = game.asteroids[i].y_old;

	//			game.asteroids[i].x_old = game.asteroids[i].x;
	//			game.asteroids[i].y_old = game.asteroids[i].y;


				double dist = dx*dx+dy*dy;  // Quadrat des Abstands zu diesem Asteroiden
				for (int ii=1; ii<4; ii++)
				{
					double one_step_x=dx+ast_delta_x*ii;
					double one_step_y=dy+ast_delta_y*ii;
					double d2=one_step_x*one_step_x+one_step_y*one_step_y;
					if (d2 < dist)
						dist=d2;
				}

				double dist_orig=dist;
		        double d_dist=(double(dist));
				double skal= dx*ast_delta_x+ dy*ast_delta_y; //skalarprodukt, falls <0 kommt der Asteroid auf das Schiff zu
				//int cross = dx * ast_delta_y - dy * ast_delta_x ;
				//if (cross <0) cross = -cross;  // cross nahe null -> Kollsiionskurs!!!
        
				
              double coll_dist1=1e10;
			  double coll_time=1e10;
				if (skal <0)
			 {   double v2= ast_delta_x*ast_delta_x+ ast_delta_y *ast_delta_y;
				double time= -skal/v2;
				coll_time=time;
			     double d_min_x= dx+ ast_delta_x*time;
				 double d_min_y=dy +ast_delta_y*time;
				 double d2=d_min_x*d_min_x + d_min_y*d_min_y;
				 coll_dist1=sqrt((double)d2);
				 double coll_dist2= // r kreuz v bzw. d kreuz ast_delta
					 abs(dx*ast_delta_y - dy*ast_delta_x)/sqrt( v2);
				// printf("coll_dist1 %g coll_dist2 %g, time %g vbetrag %g\n",
				//	 coll_dist1, coll_dist2, time, sqrt(v2));
			 }
			 //coll = false;

			 
			 
			 
			 		 
			 	// Schiff in Richtung auf das nächstgelegene Objekt drehen
			// mathematisch wird hier das Kreuzprodukt aus den Vektoren 
			// ship_dx/y/0 und min_dx/y/0 berechnet
				 
			time = vorhalt((double) dx, (double) dy, (double) ast_delta_x, (double) ast_delta_y
				, (double)nx, (double)ny, &s_x, &s_y, &time_dreh, &coll_dist);


		//coll_dist1 statt coll_dist
                if (coll_dist1 <15.0 && coll_time <15.0 && coll_dist1 <coll_dist)
				  coll_dist=coll_dist1;

				if ( time >=0.0 &&
					 (coll_dist <time_min  )) // oder wenn dist kleiner skal_dist
  				
				{
					
					time_min=coll_dist;
					
					min_dist = (int) d_dist;
					min_dist_orig=(int) dist_orig;
					min_dx = dx;
					min_dy = dy;
					min_delta_dx= ast_delta_x;
					min_delta_dy= ast_delta_y;
                    min_s_x=s_x;
					min_s_y=s_y;
					min_time_dreh=time_dreh;
					//ast_ausgewaehlt=true;
					//sf_ast_ausgewaehlt=game.asteroids[i].sf;
					//i/ndex_ast_ausgewaehlt=i;
					//type_ast_ausgewaehlt=game.asteroids[i].type;
				
				// Probeschuss;

			
// Probeschuss
				int max_t=800;
				if (nast >10)
					max_t=600;
				//if (game.nasteroids > 20 )
				//	max_t=400;
				//if (game.nasteroids > 30 )
				//	max_t=300;

               //if (!game.saucer_present)
				double radius=8.0*8.0;  // radius zum Quadrat
                 switch (ast[i].sf)
				{	// Abstand um den ungefähren Radius des Asteroiden korrigieren
					case 0:  // großer Asteroid
						radius=40.0*40.0;
						break;
					case 15: // mittlerer Asteroid
						radius= 20.0*20.0;
						break;
					case 14: // kleiner Asteroid
						radius= 8.0*8.0;
						break;
				}
				 min_radius2=radius;
				if (!treffer)
				for (int tt=0; tt <max_t; tt +=8)
				{
                    double tts=20+(tt-16);
              		// Schuss
					double x=nx*(double)tts;
					double y=ny*(double)tts;
                     // Asteroid
					int tt1=tt;
					double ax=dx+ast_delta_x*tt1/8;
					double ay=dy+ast_delta_y*tt1/8;
                    double di_x=x-ax;
					double di_y=y-ay;
					normxy(di_x, di_y);
					double di=(di_x*di_x+di_y*di_y);
					
                   
					if (di <= radius)
					{
						treffer=true;
						fired=i;
						break;
					}
				}
				}
			}

			 //printf("taken ast time min: %g \n", time_min);

			if (game.saucer_present)
			{
				fired=-1;
				treffer=false;
				int dx = game.saucer_x - game.ship_x;
				int dy = game.saucer_y - game.ship_y;
				normxy(dx,dy);

				int soucer_delta_x = game.saucer_x -game.saucer_x_old;
			    int soucer_delta_y = game.saucer_y- game.saucer_y_old;
	            normxy(soucer_delta_x, soucer_delta_y);

			game.saucer_x_old=game.saucer_x;
			game.saucer_y_old=game.saucer_y;

				int dist = dx*dx+dy*dy;
				int dist_orig=dist;
				
					
          
			  time= vorhalt((double)dx,(double)dy, (double)soucer_delta_x, (double)soucer_delta_y, 
				  (double)game.ship_dx, (double)game.ship_dy,
			       &s_x, &s_y, &time_dreh, &coll_dist);

			  if (time>=0.0)
			  {
			  time_min=time;
			  //if (dist < min_dist)  //saucer hat nicht vorrang
				{
					if (dist < min_dist)
					min_dist = dist;
					min_dx = dx;
					min_dy = dy;
					min_dist_orig=dist_orig;
					min_delta_dx=soucer_delta_x;
					min_delta_dy=soucer_delta_y;
				
			       min_s_x=s_x;
					min_s_y=s_y;
					min_time_dreh =time_dreh;
					}
				}
			  
			
// Probeschuss 
			  if (!treffer)
				for (int tt=0; tt <800; tt +=8)
				{
					int tts=20+tt;
					// Schuss
					double x=nx*(double)tts;
					double y=ny*(double)tts;
					int tti=tt+8;
                     // Saucer
					double ax=dx+soucer_delta_x*tti/8;
					double ay=dy+soucer_delta_y*tti/8;
                    double di_x=x-ax;
					double di_y=y-ay;
					double di=(di_x*di_x+di_y*di_y);
					if (di < 8.0*8.0){

						treffer=true;
						
						break;}

				}
			}

			
			// Schiff in Richtung auf das nächstgelegene Objekt drehen
			// mathematisch wird hier das Kreuzprodukt aus den Vektoren 
			// ship_dx/y/0 und min_dx/y/0 berechnet
			
           
//printf("time taken %g\n", time);
         
            if (time_min>0.0)
			{
				double cross=0.0;
			//int cross = game.ship_dx * min_dy - game.ship_dy * min_dx ;
              // cross = game.ship_dx * min_s_y - game.ship_dy * min_s_x ;
			double phi_soll= atan2((double) min_s_y, (double) min_s_x);
            double act_phi= 2*pi*(double)phi_b/256.0; 
            double phi_diff= phi_soll-act_phi;
			if (phi_diff < pi) phi_diff+=2*pi;
			if (phi_diff > pi) phi_diff-=2*pi;
			//printf("phi diff %g cross %g\n", phi_diff, cross);
			phi_delta=0;

			if (phi_diff >0.0)
			{

				double phi_neu= 2*pi*(double)(phi_b+3)/256.0;
				double phi_diff_neu= phi_soll-phi_neu;
            if (phi_diff_neu < pi) phi_diff_neu+=2*pi;
			if (phi_diff_neu > pi) phi_diff_neu-=2*pi;
			    
				if (abs(phi_diff_neu ) > abs(phi_diff))
				{
                     phi_delta=0;
					 //printf("a1\n");
				}
				else
					phi_delta=+3;
			}
			else
				if (phi_diff <0.0)
				{

double phi_neu= 2*pi*(double)(phi_b-3)/256.0;
double phi_diff_neu= phi_soll-phi_neu;
            if (phi_diff_neu < pi) phi_diff_neu+=2*pi;
			if (phi_diff_neu > pi) phi_diff_neu-=2*pi;
			    
				if (abs(phi_diff_neu ) > abs(phi_diff))
				{
                   phi_delta=0;
				   //printf("a2\n");
				}
				else
					phi_delta=-3;
				}



			if (phi_delta > 0)
			{
				keys.left(true);
			
			}
			else if (phi_delta <0)
			{
				keys.right(true);
			}
			}




			// Kollisionsberechnung
			// shots und asteroiden

			for (int f=0; f< 100; f++) // 100 frames in Zukunft rechnen
			{
				 for (int i=0; i<nast; i++)
					 if (ast[i].lifetime>f)
				 {
			         double ax=ast[i].x+i*ast[i].vx;
                     double ay=ast[i].y+i*ast[i].vy;
					 double radius=8.0*8.0;  // radius zum Quadrat
                 switch (ast[i].sf)
				{	// Abstand um den ungefähren Radius des Asteroiden korrigieren
					case 0:  // großer Asteroid
						radius=40.0*40.0;
						break;
					case 15: // mittlerer Asteroid
						radius= 20.0*20.0;
						break;
					case 14: // kleiner Asteroid
						radius= 8.0*8.0;
						break;
				}
				    int explotion=0;

                     for (int j=0; j<nshot; j++)
						 if (shot[j].lifetime>f)
					 {
						 double sx=shot[j].x+i*shot[j].vx;
	
						 double sy=shot[j].y+i*shot[j].vy;

						 double xdiff=ax-sx;
						 double ydiff=ay-sy;
						 normxy(xdiff, ydiff);
						 double r2=xdiff*xdiff+ydiff*ydiff;
						 if (r2 <= radius)
						 {
							 explotion=1;
							   if (ast[i].sf== 14) //Kleiner asteroid
							      ast[i].lifetime=f;
							 shot[j].lifetime=f;
							 break;
						 }
					 }
					 if (explotion)
						 break;
				 }
			

			}
			for (int i=0; i<nshot; i++)
			{
				shot[i].lifetime--;
			if (shot[i].lifetime<=0)
				shot[i].lifetime =100000; 
			}
for (int i=0; i<nast; i++)
			{
				ast[i].lifetime--;
			if (ast[i].lifetime<=0)
				ast[i].lifetime =100000; 
			}
           //if (nast´<3)
		   {
			    printf("lifetime 0 %d lifetime 1 %d\n", ast[0].lifetime,
					ast[1].lifetime);
		   }
			//else // schneller schiessen wenn cross==0
			//		if (t%2) keys.fire(true);

            // GM: kein Tastendruck links/rechts falls cross==0

			// hyperspace mal nicht verwenden
			if (min_dist < min_radius2)  // GM: Entfernung modifiziert, Flucht, wenn Kollision unausweichlich
				keys.hyperspace(true);

			bool ziel_da= (min_dist != 0x7fffffff);
			if (min_dist > 300*300
				&& ziel_da ) // beschleunigen, wenn nichts in der Nähe, GM: aber mindestens ein Ziel vorhanden
				// GM: d.h. wenn kein Ziel vorhanden nicht beschleunigen
			{;}//keys.thrust(true);
			//printf("aphi_diff %g time %d\n", aphi_diff, time);
           

			if (shot_old)
			{shot_old=0;}
			else 
				// alternativ: (t %5==0)  GM : Feuerknopf drücken, nicht ganz so schnell es geht
			{
				
				
				if (pause==0)
				{
				//if (aphi_diff < .01)
				//if (min_time_dreh <10.0) // 3 frames
				if (treffer)
				{
				shot_old=1;
				keys.fire(true);
				printf("frame fired! %d\n", frame.frameno);
				   if (fired!=-1)
					   if (ast[fired].sf ==14) //kleiner Asteroid
						   ast[fired].lifetime=80;
				  pause=0;
				}
				}
				else
					pause--;
			}

		
		}
		else
	    {
		if (t%2)
		   keys.start(true);
		}
	}
}

void Player::InterpretScreen(FramePacket &packet, GameStatus& game)
{
	unsigned short *vector_ram = (unsigned short *)packet.vectorram;
	int dx, dy, sf, vx, vy, vz, vs;
	int v1x = 0;
	int v1y = 0;
	int shipdetect = 0;

	game.clear();
	if ((unsigned char)packet.vectorram[1] != 0xe0 && (unsigned char)packet.vectorram[1] != 0xe2)
		return; // sollte nicht vorkommen; erster Befehl ist immer ein JMPL

	int pc = 1;
	for (;;)
	{
		int op = vector_ram[pc] >> 12;
		switch (op)
		{
		case 0xa: // LABS
			vy = vector_ram[pc] & 0x3ff;
			vx = vector_ram[pc+1] & 0x3ff;
			vs = vector_ram[pc+1] >> 12;
			break;
		case 0xb: // HALT
			return;
		case 0xc: // JSRL
			switch (vector_ram[pc] & 0xfff)
			{
			case 0x8f3:
				game.asteroids[game.nasteroids++].set(vx, vy, 1, vs);
				break;
			case 0x8ff:
				game.asteroids[game.nasteroids++].set(vx, vy, 2, vs);
				break;
			case 0x90d:
				game.asteroids[game.nasteroids++].set(vx, vy, 3, vs);
				break;
			case 0x91a:
				game.asteroids[game.nasteroids++].set(vx, vy, 4, vs);
				break;
			case 0x929:
				game.saucer_present = true;
				game.saucer_x = vx;
				game.saucer_y = vy;
				game.saucer_size = vs;
				break;
			case 0xa6d:
				++game.lives;
				break;

				// Score decodieren
			case 0xb2c: // Leerzeichen
				if (vx == 100 && vy==876)
				    game.score=0;
					break;
		    case 0xadd: //'0'
				 if (vx == 100 && vy==876)
					game.score=10*game.score + 0;
                 break;
			case 0xb2e: //'1'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 1;
                 break;
            case 0xb32: //'2'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 2;
                 break;
		    case 0xb3a: //'3'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 3;
				break;
				case 0xb41: //'4'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 4;
				break;
				case 0xb48: //'5'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 5;
				   break;
				case 0xb4f: //'6'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 6;
				   break;
				case 0xb56: //'7'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 7;
				break;
				case 0xb5b: //'8'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 8;
				   break;
				case 0xb63: //'9'
				if (vx == 100 && vy==876) 
					game.score=10*game.score + 9;
				  break;
		
			}  
			break;
		case 0xd: // RTSL
			return;
		case 0xe: // JMPL
			/*
			pc = vector_ram[pc] & 0xfff;
			break;
			*/
			return;
		case 0xf: // SVEC
			/*
			dy = vector_ram[pc] & 0x300;
			if ((vector_ram[pc] & 0x400) != 0)
				dy = -dy;
			dx = (vector_ram[pc] & 3) << 8;
			if ((vector_ram[pc] & 4) != 0)
				dx = -dx;
			sf = (((vector_ram[pc] & 8) >> 2) | ((vector_ram[pc] & 0x800) >> 11)) + 2;
			vz = (vector_ram[pc] & 0xf0) >> 4;
			*/
			break;
		default:
			dy = vector_ram[pc] & 0x3ff;
			if ((vector_ram[pc] & 0x400) != 0)
				dy = -dy;
			dx = vector_ram[pc+1] & 0x3ff;
			if ((vector_ram[pc+1] & 0x400) != 0)
				dx = -dx;
			sf = op;
			vz = vector_ram[pc+1] >> 12;
			if (dx == 0 && dy == 0 && vz == 15){
				game.shots[game.nshots++].set(vx, vy);
				
				//printf("n %d sf %d vs %d\n", game.nshots, sf, vs);
			}
			if (op == 6 && vz == 12 && dx != 0 && dy != 0)
			{
				switch (shipdetect)
				{
				case 0:
					v1x = dx;
					v1y = dy;
					++shipdetect;
					break;
				case 1:
					game.ship_present = true;
					game.ship_x = vx;
					game.ship_y = vy;
					game.ship_dx = v1x - dx;
					game.ship_dy = v1y - dy;
					++shipdetect;
					break;
				}
			}
			else if (shipdetect == 1)
				shipdetect = 0;

			break;
		}
		if (op <= 0xa)
			++pc;
		if (op != 0xe) // JMPL
			++pc;
	}   

}


void Asteroid::set(int x, int y, int type, int sf)
{
	this->x = x;
	this->y = y;
	this->type = type;
	this->sf = sf;
}

void Shot::set(int x, int y)
{
	this->x = x;
	this->y = y;
}

void GameStatus::clear(void)
{
	ship_present = false;
	saucer_present = false;
	nasteroids = 0;
	nshots = 0;
	lives = 0;
	score = 0;
	
}

KeysPacket::KeysPacket(void)
{
	signature[0] = 'c';
	signature[1] = 't';
	signature[2] = 'm';
	signature[3] = 'a';
	signature[4] = 'm';
	signature[5] = 'e';
	keys = '@';
	ping = 0;
}

void KeysPacket::clear(void)
{
	keys = '@';
}

void KeysPacket::hyperspace(bool b)
{
	if (b)
		keys |= KEY_HYPERSPACE;
	else
		keys &= ~KEY_HYPERSPACE;
}

void KeysPacket::fire(bool b)
{
	if (b)
		keys |= KEY_FIRE;
	else
		keys &= ~KEY_FIRE;
}

void KeysPacket::thrust(bool b)
{
	if (b)
		keys |= KEY_THRUST;
	else
		keys &= ~KEY_THRUST;
}

void KeysPacket::left(bool b)
{
	if (b)
	{
		keys |= KEY_LEFT;
		right(false);
	}
	else
		keys &= ~KEY_LEFT;
}

void KeysPacket::right(bool b)
{
	if (b)
	{
		keys |= KEY_RIGHT;
		left(false);
	}
	else
		keys &= ~KEY_RIGHT;
}

void KeysPacket::start(bool b)
{
	if (b)
	{
		keys |= KEY_START;
	}
	else
		keys &= ~KEY_START;
}

void Player::ReceivePacket(FramePacket &packet)
{
	sockaddr_in sender;
	int sender_size = sizeof sender;
	fd_set readfds, writefds, exceptfds;

	do
	{
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);
		FD_ZERO(&exceptfds);
		FD_SET(sd, &readfds);
		FD_SET(sd, &exceptfds);
		select(sd+1, &readfds, &writefds, &exceptfds, NULL);
		int bytes_received = recv(sd, (char *)&packet, sizeof packet, 0);
		if (bytes_received != sizeof packet)
		{
			int err = WSAGetLastError();
			fprintf(stderr, "Fehler %d bei recvfrom().\n", err);
			exit(1);
		}
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);
		FD_ZERO(&exceptfds);
		FD_SET(sd, &readfds);
		timeval zero;
		zero.tv_sec = zero.tv_usec = 0;
		select(sd+1, &readfds, &writefds, &exceptfds, &zero);
	} while(FD_ISSET(sd, &readfds));
}

void Player::SendPacket(KeysPacket &packet)
{
	sockaddr_in server;
	memset(&server, 0, sizeof server);
	server.sin_family = AF_INET;
	server.sin_port = htons(1979);
	server.sin_addr.s_addr = server_ip;
	if (sizeof packet != sendto(sd, (char *)&packet, sizeof packet, 0, (sockaddr*)&server, sizeof server))
	{
#if defined(WINDOWS)
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			fprintf(stderr, "Fehler %d bei sendto().\n", err);
			exit(1);
		}
#else
		if (errno != EAGAIN)
		{
			perror("Fehler bei sendto()");
			exit(1);
		}
#endif
	}
}
