X-Git-Url: http://royale.zerezo.com/git/?p=zeRace;a=blobdiff_plain;f=bot.c;fp=bot.c;h=ef93b046ad758ad83889a29f623272b97445a098;hp=0000000000000000000000000000000000000000;hb=ee6ec6d95d78f74973a2ba97077cc94709bb6c61;hpb=dde2df6289f6daf23ee1632560c4c89061ef2f4a diff --git a/bot.c b/bot.c new file mode 100644 index 0000000..ef93b04 --- /dev/null +++ b/bot.c @@ -0,0 +1,266 @@ +#include "bot.h" + +#define DELAY 7 +#define MAXRECORDKEYS 9999 + +/* tracklist */ +struct _tracklist *tracklist; + +/* user setup */ +struct _config +{ + char pseudo[MAXLINELENGTH]; + char url[MAXLINELENGTH]; + int fullscreen; + int sound; + int tire; + SDLKey up; + SDLKey down; + SDLKey left; + SDLKey right; + int color; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6}; + +/* full script for a lap */ +struct _record +{ + float x,y,angle,speed; + char keys[MAXRECORDKEYS]; + int time; +}; + +/* network stuff */ +UDPsocket udpsock=NULL; +UDPpacket *packet; +int network_speed=1; +int aleas; + + +/* exit the game and clean */ +void zeRace_exit() +{ + printf("quit\n"); + SDLNet_Quit(); + SDL_Quit(); + exit(0); +} + + +/* initialize the game */ +void zeRace_init() +{ + /* do a clean exit in case of emergency */ + signal(SIGINT,zeRace_exit); + signal(SIGTERM,zeRace_exit); + + /* get the list of local tracks */ + if (!zeRace_get_tracks(&tracklist)) zeRace_exit(); + + srand(time(NULL)); + + /* robot configuration */ + sprintf(config.pseudo,"\"%s\" bot(%d)",bot_name(),aleas); + config.color=rand()%12; + + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) + { + fprintf(stderr,"could not initialize SDL : %s\n",SDL_GetError()); + zeRace_exit(); + } + atexit(SDL_Quit); + + if (SDLNet_Init()==-1) + { + fprintf(stderr,"could not initialize SDLNet : %s\n",SDLNet_GetError()); + zeRace_exit(); + } + + packet=SDLNet_AllocPacket(1024); + if (!packet) + { + fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError()); + zeRace_exit(); + } +} + + +/* launch a new race */ +void zeRace_launch(int alltime,int go) +{ + SDL_Surface *cir,*fun; + int ku=0,kd=0,kl=0,kr=0,i; + struct _car car; + int delay=DELAY; + int lastack=alltime; + struct _record net; + + cir=IMG_Load(tracklist->full); + fun=IMG_Load(tracklist->function); + + car.speed=0; + car.angle=tracklist->a*2*M_PI/360; + car.ox=car.x=tracklist->x; + car.oy=car.y=tracklist->y; + car.lastcheck=0; + car.w=30; + car.h=30; + net.time=0; + + /* startup countdown */ + for (i=4;i>=-1;i--) + { + if (!go) break; + if (i!=-1) SDL_Delay(1000); + } + + /* main loop */ + for (;;) + { + /* call the IA */ + bot_ia(tracklist->name,&car,fun,&ku,&kd,&kl,&kr); + + /* random movement if asked */ + if (aleas) if (rand()%aleas==0) + { + ku=rand()%2; + kl=rand()%2; + kr=rand()%2; + kd=rand()%2; + } + + if (udpsock) + { + net.keys[net.time]=(ku<<3 | kd<<2 | kl<<1 | kr)+'A'; + net.keys[net.time+1]='\0'; + } + + delay=DELAY; + /* if we are in network mode */ + if (udpsock!=NULL) + { + char *tmp; + while (SDLNet_UDP_Recv(udpsock,packet)) if (strcmp(packet->data,"positions")==0) + { + int servertime,clienttime,nb; + servertime=SDLNet_Read32(packet->data+strlen("positions")+1); + clienttime=SDLNet_Read32(packet->data+strlen("positions")+1+4); + nb=SDLNet_Read16(packet->data+strlen("positions")+1+4+4); + if (clienttime>lastack) + { + memcpy(net.keys,net.keys+clienttime-lastack,net.time+1); + net.time-=clienttime-lastack; + if (clienttime>servertime+5) delay+=DELAY; + if (clienttimedata; + strcpy(tmp,"keys"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(lastack,tmp); + tmp+=4; + strcpy(tmp,net.keys); + tmp+=strlen(tmp)+1; + packet->len=(void *)tmp-(void *)packet->data+10; + if (net.time%network_speed==0) if (!SDLNet_UDP_Send(udpsock,-1,packet)) + { + fprintf(stderr,"SDLNet_UDP_Send: %s\n",SDLNet_GetError()); + exit(2); + }; + } + } + + /* move the car */ + move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); + + /* let the system breath */ + SDL_Delay(delay); + + /* game time */ + net.time++; + if (udpsock && net.time>MAX_LAG) + { + fprintf(stderr,"timeout !\n"); + SDL_FreeSurface(cir); + SDL_FreeSurface(fun); + return; + } + alltime++; + } +} + + +/* connect to a server */ +void zeRace_connect(char *host,int port) +{ + char *tmp; + int lag=0; + udpsock=SDLNet_UDP_Open(0); + if (udpsock==NULL) + { + fprintf(stderr,"SDLNet_UDP_Open: %s\n",SDLNet_GetError()); + zeRace_exit(); + } + SDLNet_ResolveHost(&packet->address,host,port); + tmp=packet->data; + strcpy(tmp,"connect"); + tmp+=strlen(tmp)+1; + strcpy(tmp,config.pseudo); + tmp+=strlen(tmp)+1; + SDLNet_Write16(config.color,tmp); + tmp+=2; + packet->len=(void *)tmp-(void *)packet->data; + SDLNet_UDP_Send(udpsock,-1,packet); + /* network loop */ + while (SDLNet_UDP_Recv(udpsock,packet) || lagdata; + if (strcmp(tmp,"track")==0) + { + struct _tracklist *loopcheck=tracklist; + int time; + char go; + tmp+=strlen(tmp)+1; + go=*tmp++; + printf("server asked for track : %s\n",tmp); + while (tracklist->next!=loopcheck) if (strcmp(tracklist->name,tmp)==0) break; else tracklist=tracklist->next; + if (strcmp(tracklist->name,tmp)!=0) + { + fprintf(stderr,"unknown track : %s\n",tmp); + zeRace_exit(); + } + tmp+=strlen(tmp)+1; + time=SDLNet_Read32(tmp); + tmp+=4; + network_speed=SDLNet_Read32(tmp); + zeRace_launch(time,go); + if (strcmp(packet->data,"finish")==0) SDL_Delay(5000); + lag=0; + } + SDL_Delay(7); + lag++; + } + SDLNet_UDP_Close(udpsock); + udpsock=NULL; +} + + +/* main program */ +int main(int argc,char *argv[]) +{ + if (argc!=4) { fprintf(stderr,"Usage : %s host port random\n host : host or ip of the server to connect to\n port : port number of the server to connect to\n random : frequency of random moves (0 = no random moves, 1 = only random, 1000 = 1/1000 random moves)\n",argv[0]); exit(1); } + aleas=atoi(argv[3]); + zeRace_init(); + zeRace_connect(argv[1],atoi(argv[2])); + zeRace_exit(); + return 0; +}