⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 RoboCup 2D 仿真组冠军源代码之1998年冠军队——CMUnited98源代码
💻 C
字号:
/* -*- Mode: C -*- *//* client.C * CMUnited98 (soccer client for Robocup98) * Peter Stone <pstone@cs.cmu.edu> * Computer Science Department * Carnegie Mellon University * Copyright (C) 1998 Peter Stone * * CMUnited-98 was created by Peter Stone, Manuela Veloso, and Patrick Riley * * You may copy and distribute this program freely as long as you retain this notice. * If you make any changes or have any comments we would appreciate a message. *//* client.C contains the main program loop  * It is partially based on Player.C from the turnballclient of Alessandro Bissacco   */#include "client.h"#include "types.h"#include "netif.h"#include "Memory.h"#include "parse.h"#include "utils.h"#include "behave.h"void      send_initialize_message();void      parse_initialize_message(char *);Bool      wait_for_signals(sigset_t *);sigset_t  init_handler();void      sigio_handler(); void      sigalrm_handler();void      send_action();void      resend_last_action();/* Global variables -- don't want to reallocate buffers each time */sigset_t sigiomask, sigalrmask;//Memory  Global_Mem;//Memory *const Mem = &Global_Mem;Memory *Mem;char     recvbuf[MAXMESG];	char     sendbuf[MAXMESG];	char     *GLOBAL_sense_body_message = "(sense_body)";int      alrsigs_since_iosig=0;/****************************************************************************************/main(int argc, char *argv[]){  Mem = new Memory();  if ( Mem == NULL ){    my_error("couldn't allocate Mem");    exit(0);  }  Mem->GetOptions(argc,argv);  Socket sock = init_connection(Mem->SP_host,Mem->SP_port);  Mem->sock = &sock;  if(Mem->sock->socketfd == -1) {    cerr << "Can't open connection for player" << endl;    abort();  }  send_initialize_message();  wait_message(recvbuf, Mem->sock);  parse_initialize_message(recvbuf);  Mem->Initialize();  sigset_t sigfullmask = init_handler();	        while ( Mem->ServerAlive == TRUE && wait_for_signals(&sigfullmask) );  if (Mem->sock->socketfd != -1) close_connection(Mem->sock);  printf("Shutting down player %d\n",Mem->MyNumber);}/****************************************************************************************//****************************************************************************************//****************************************************************************************//* Send initialize message */void send_initialize_message(){  if (Mem->IP_reconnect)    sprintf(sendbuf, "(reconnect %s %d)", Mem->MyTeamName, Mem->IP_reconnect);  else if ( Mem->CP_goalie == TRUE && Mem->SP_version >= 4.00){    sprintf(sendbuf, "(init %s (version %.2f) (goalie))", Mem->MyTeamName, Mem->SP_version);  }  else    sprintf(sendbuf, "(init %s (version %.2f))", Mem->MyTeamName, Mem->SP_version);  if(send_message(sendbuf, Mem->sock) == -1) abort(); }/****************************************************************************************//* Parse initialize message */void parse_initialize_message(char *recvbuf){  char mode[100];  if ( !(strncmp(recvbuf,"(init",4)) ) {    /* It's an init msg */    sscanf(recvbuf,"(init %c %d %[^)]",&Mem->MySide, &Mem->MyNumber, mode);    Mem->ServerAlive = TRUE;  }  else if ( !(strncmp(recvbuf,"(reconnect",4)) ) {    /* It's a reconnect msg */    sscanf(recvbuf,"(reconnect %c %[^)]",&Mem->MySide, mode);    Mem->MyNumber = Mem->IP_reconnect;    printf("reconnecting to %d on side %c!\n",Mem->MyNumber,Mem->MySide);    Mem->ServerAlive = TRUE;  }  else    Mem->ServerAlive = FALSE;  if ( Mem->CP_goalie && Mem->FP_goalie_number != Mem->MyNumber )    my_error("goalie number inconsistent with me being goalie");  if ( !Mem->CP_goalie && Mem->FP_goalie_number == Mem->MyNumber )    my_error("I should be the goalie");    if ( mode[0] == 'b' ){ /* Before_kick_off */     Mem->SetPlayMode(PM_Before_Kick_Off);    if ( Mem->MySide == 'l' )      Mem->KickOffMode = KO_Mine;    else       Mem->KickOffMode = KO_Theirs;  }  else                  /* Act as if the game's in progress */    Mem->SetPlayMode(PM_Play_On);  printf( "------------------------------------------------------------------------\n");  printf( "Connected player %d on team %s\n",Mem->MyNumber,Mem->MyTeamName);  printf( "------------------------------------------------------------------------\n");  printf( "CMUnited98 was created by Peter Stone, Manuela Veloso, and Patrick Riley\n");  printf( "Copyright 1998.  All rights reserved.\n");  printf( "------------------------------------------------------------------------\n\n");  }/****************************************************************************************//****************************************************************************************//****************************************************************************************//* set time interval between the sensor receiving and command sending */ inline void set_timer() {  struct itimerval itv;  itv.it_interval.tv_sec = 0;  itv.it_interval.tv_usec = Mem->TimerInterval * 1000;  itv.it_value.tv_sec = 0;  itv.it_value.tv_usec = Mem->TimerInterval * 1000;  setitimer(ITIMER_REAL, &itv, NULL);}inline void set_timer(int usec) {  struct itimerval itv;  itv.it_interval.tv_sec = 0;  itv.it_interval.tv_usec = Mem->TimerInterval * 1000;  itv.it_value.tv_sec = 0;  itv.it_value.tv_usec = usec;  setitimer(ITIMER_REAL, &itv, NULL);}/****************************************************************************************/sigset_t init_handler() {   sigemptyset(&sigalrmask);  sigaddset(&sigalrmask, SIGALRM);  sigemptyset(&sigiomask);  sigaddset(&sigiomask, SIGIO);    struct sigaction sigact;  sigact.sa_flags = 0;  sigact.sa_mask = sigiomask;#ifdef Solaris  sigact.sa_handler = (void (*)(int))sigalrm_handler; #else  sigact.sa_handler = (void (*)(int))sigalrm_handler; #endif  sigaction(SIGALRM, &sigact, NULL);  sigact.sa_mask = sigalrmask;#ifdef Solaris  sigact.sa_handler = (void (*)(int))sigio_handler; #else  sigact.sa_handler = (void (*)(int))sigio_handler; #endif  sigaction(SIGIO, &sigact, NULL);  set_timer();  sigprocmask(SIG_UNBLOCK, &sigiomask, NULL);  sigprocmask(SIG_UNBLOCK, &sigalrmask, NULL);  sigset_t sigsetmask;  sigprocmask(SIG_BLOCK, NULL, &sigsetmask);   /* Get's the currently unblocked signals */  return sigsetmask;   }/****************************************************************************************//* suspend the process until one of the signals comes through *//* could check for situation to kill client, return FALSE     *//* i.e. too many actions with no sensory input coming in      */Bool wait_for_signals(sigset_t *mask){  sigsuspend(mask);  return TRUE;}/****************************************************************************************//* SIGIO handler: receive and parse messages from server */void sigio_handler() {  sigprocmask(SIG_BLOCK, &sigalrmask, NULL);    int counter = 0;  Time StartTime = Mem->CurrentTime;  while (receive_message(recvbuf, Mem->sock) == 1) {    Parse(recvbuf);    counter++;  }  if ( Mem->CurrentTime - StartTime > 1 && StartTime.s == 0 && Mem->CurrentTime.s == 0 )    my_error("Received several steps at once -- missing action ops!!! (%d %d)",	     StartTime.t,StartTime.s);  sigprocmask(SIG_UNBLOCK, &sigalrmask, NULL);    alrsigs_since_iosig=0;  // if (counter>1) printf("Got %d messages\n",counter);}/****************************************************************************************//* SIGALRM handler: send something to the server */void sigalrm_handler() {  sigprocmask(SIG_BLOCK, &sigiomask, NULL);    if (Mem->ClockStopped)    Mem->StoppedClockMSec += Mem->TimerInterval;  if (alrsigs_since_iosig++ > 40) Mem->ServerAlive = FALSE;  else if ( Mem->CurrentTime > Mem->LastActionOpTime ){    if ( Mem->CurrentTime-1 != Mem->LastActionOpTime && Mem->LastActionOpTime != 0 )      my_error("Missed a cycle!!  (%d %d)",Mem->LastActionOpTime.t,Mem->LastActionOpTime.s);    if ( Mem->NewSight ) Mem->FirstActionOpSinceLastSight = TRUE;    Mem->update();    behave();    Mem->LastActionOpTime = Mem->CurrentTime;    Mem->FirstActionOpSinceLastSight = FALSE;  }  if ( Mem->Action->valid() ) {    send_action();  }  else if ( Mem->ResendNeeded() ){    resend_last_action();  }#ifndef RELEASE_VERSION  else if ( Mem->Communicate() ){     send_message( Mem->SayBuffer(), Mem->sock );   } #endif  else if ( Mem->ChangeView.valid() ){    if ( Mem->ChangeView.time < Mem->CurrentTime-1 ) my_error("old change_view");    send_message( Mem->ChangeView.command, Mem->sock );    Mem->ChangeView.type = CMD_none; /* so it's no longer valid */  }  else {    send_message(GLOBAL_sense_body_message,Mem->sock);    }  sigprocmask(SIG_UNBLOCK, &sigiomask, NULL);  }/****************************************************************************************//****************************************************************************************//****************************************************************************************//* insert turn/dash/kick commands in commandlist */void turn(AngleDeg ang) {  NormalizeAngleDeg(&ang);   /* turn so that the actual turn is the desired turn */  /* pos.rotate( ang/(1.0 + SP_inertia_moment * MySpeed()) ); */  if ( Mem->MyVelConf() ) ang *= (1 + Mem->SP_inertia_moment * Mem->MySpeed());  if ( ang > Mem->SP_max_moment ) ang = Mem->SP_max_moment;  if ( ang < Mem->SP_min_moment ) ang = Mem->SP_min_moment;  if (ang < .1 && ang > -.1) {    Mem->Action->type = CMD_none;    return;          /* No turn           */  }  Mem->Action->type = CMD_turn;  Mem->Action->power = 0;  Mem->Action->angle = ang;  Mem->Action->time = Mem->CurrentTime;  sprintf(Mem->Action->command,"(turn %.2f)", ang);}  /****************************************************************************************/void dash(float power) {  if ( Mem->PlayMode == PM_Before_Kick_Off ) return;  if (power > Mem->SP_max_power) my_error("Can't dash that fast: %.1f",power);  if (power < Mem->SP_min_power) my_error("Can't dash that 'slow': %.1f",power);  /* Factor for stamina--don't dash more than stamina or more than necessary to get you to max speed */  Mem->VerifyDash(&power);  if (fabs(power) < 1){    Mem->Action->type = CMD_none;    return;                         /* No dash           */  }    Mem->Action->type = CMD_dash;  Mem->Action->power = power;  Mem->Action->angle = 0;  Mem->Action->time = Mem->CurrentTime;  sprintf(Mem->Action->command, "(dash %.2f)", power);}/****************************************************************************************/void kick(float power, AngleDeg dir) {  if ( !(Mem->BallKickable()) ) my_error("Can't kick a ball that's too far away");  if ( Mem->PlayMode == PM_Before_Kick_Off ) return;  if (power > Mem->SP_max_power) my_error("Can't kick that hard");  if (power < 0 ) my_error("Can't kick < 0");  NormalizeAngleDeg(&dir);  Mem->Action->type = CMD_kick;  Mem->Action->power = power;  Mem->Action->angle = dir;  Mem->Action->time = Mem->CurrentTime;  sprintf(Mem->Action->command, "(kick %.2f %.2f)", power, dir);}/****************************************************************************************/void goalie_catch(AngleDeg dir) {  if ( !(Mem->BallCatchable()) ) my_error("Can't catch a ball that's too far away");  if ( !Mem->CP_goalie ) my_error("Only goalies can catch");  if ( Mem->PlayMode == PM_Before_Kick_Off ) return;  NormalizeAngleDeg(&dir);  Mem->Action->type = CMD_catch;  Mem->Action->power = 0;  Mem->Action->angle = dir;  Mem->Action->time = Mem->CurrentTime;  sprintf(Mem->Action->command, "(catch %.2f)", dir);}/****************************************************************************************/void move(float x, float y) {  if ( Mem->PlayMode != PM_Before_Kick_Off )     my_error("Can only move in before kickoff mode");  /* Perhaps here convert to a position on the field */  if ( fabs(y) > Mem->SP_pitch_width/2 || x > 0 || x < -Mem->SP_pitch_length/2 )    my_error("Must move to a place on the pitch");  Mem->Action->type = CMD_move;  Mem->Action->x = x;  Mem->Action->y = y;  Mem->Action->time =  Mem->CurrentTime;  sprintf(Mem->Action->command, "(move %.2f %.2f)", x, y);}/****************************************************************************************/void disconnect(){  Mem->Action->type = CMD_bye;  Mem->Action->time =  Mem->CurrentTime;  sprintf(Mem->Action->command, "(bye)");}/****************************************************************************************/void change_view(Vqual qual, Vwidth width) {  if ( qual==Mem->ViewQuality  && width==Mem->ViewWidth )    return;  /* my_error("Nothing to change about view"); */  Mem->ChangeView.type  = CMD_change_view;  Mem->ChangeView.qual  = qual;  Mem->ChangeView.width = width;  Mem->ChangeView.time  = Mem->CurrentTime;  char qual_string[10], width_string[10];  switch (qual){  case VQ_High: sprintf(qual_string,"high"); break;  case VQ_Low:  sprintf(qual_string,"low");  break;  }  switch (width){  case VW_Narrow: sprintf(width_string,"narrow"); break;  case VW_Normal: sprintf(width_string,"normal"); break;  case VW_Wide:   sprintf(width_string,"wide");   break;  }  sprintf(Mem->ChangeView.command, "(change_view %s %s)", width_string, qual_string);}/****************************************************************************************/void send_action(){	  if ( !(Mem->Action->valid(Mem->CurrentTime)) )    my_error("Old action %d %d",Mem->Action->time.t,Mem->Action->time.s);  send_message(Mem->Action->command, Mem->sock);  switch (Mem->Action->type){  case CMD_kick: Mem->kicks++;  break;  case CMD_dash: Mem->dashes++; break;  case CMD_turn: Mem->turns++;  break;  default: ;  }  Command *tmp = Mem->LastAction;  Mem->LastAction = Mem->Action;  Mem->Action     = tmp;  Mem->Action->type = CMD_none; /* So it's invalid */  Mem->NewAction = TRUE;}/****************************************************************************************/void resend_last_action(){  if ( Mem->LastActionType() == Mem->ResendType ){    my_stamp; printf("resending\n");    send_message(Mem->LastAction->command, Mem->sock);    switch (Mem->LastActionType()){    case CMD_kick: Mem->kicks++;  break;    case CMD_dash: Mem->dashes++; break;    case CMD_turn: Mem->turns++;  break;    default: ;    }  }  else     my_error("last action isn't a %d",Mem->ResendType);  Mem->RequestResend = FALSE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -