On Tue, 27 Mar 2007, Don Dailey wrote:
Would it be possible to publish a little library for others in C? I will have a place on the main page to download goodies like this.
Here is the code I am currently using. Christoph
/* ---------------------------------------------------------------------- * * cgos.c -> client.c * * 2006-09-05 Christoph C. Birk ([EMAIL PROTECTED]) * CGOS (cgos.boardspace.net 6867) interface * 2007-03-26 modified for new CGOS * * CGOS(pseudo-server) <-> Client <-> Engine(server) * * ---------------------------------------------------------------------- */ /* * the engine calls 'cgos_run()' in a loop like this: do { i = cgos_run(goban,host,port,myName,myPassword); if (i) sleep(30); } while (i != 0); */ /* ---------------------------------------------------------------------- */ #ifdef NDEBUG /* release version */ #define DEBUG 0 #else #ifndef DEBUG #define DEBUG 1 /* debug level */ #endif #endif #define USE_CGOS3 /* use new CGOS protocol */ /* INCLUDEs ------------------------------------------------------------- */ #include <stdlib.h> /* atof() */ #include <stdio.h> /* sprintf() */ #include <string.h> /* strlen(),memset() */ #include <time.h> /* time() */ #include <unistd.h> /* close() */ #include <fcntl.h> /* fcntl() */ #include <sys/types.h> #include <sys/socket.h> #include <sys/uio.h> #include <netdb.h> /* getprotobyname() */ #if 1 // my stuff #include "gutils.h" #include "evaluate.h" #endif /* DEFINEs -------------------------------------------------------------- */ #define PING_TIME 20 /* old CGOS only */ #define TOKSEP " \t" /* EXTERNs -------------------------------------------------------------- */ extern int nsims; /* function prototype(s) */ extern move_t genmove_1 (Goban*,int); /* STATICs -------------------------------------------------------------- */ static int cgos_sock=-1; /* function prototype(s) */ static int cgos_connect (const char*,u_short,const char*,const char*); static void cgos_disconnect (void); static int cgos_receive (char*,int); static int cgos_send (const char*); static int read_byte (int,char*,int); /* ---------------------------------------------------------------------- */ int cgos_run(Goban* goban,const char* host,u_short port, const char* name,const char* pass) { int i,r; time_t next_ping,last_game,max_time=600; char buffer[1024],*p; r = cgos_connect(host,port,name,pass); if (r < 0) return(-1); last_game = time(NULL); next_ping = last_game + PING_TIME; do { r = cgos_receive(buffer,2000); if (r < 0) break; if (r == 0) { #ifndef USE_CGOS3 if (next_ping) { /* send ping ? */ if (time(NULL) > next_ping) { cgos_send("ping"); next_ping = time(NULL)+PING_TIME; } } #endif } else if (!strncmp(buffer,"newgame",7)) { int d; float k,t; /* old CGOS */ if (sscanf(buffer,"newgame %d %f %f\n",&d,&k,&t) == 3) { komi = k; time_left = t; max_time = (int)t; } #if 1 // todo issue GTP commands here goban_init(goban); goban_show(goban,buffer); #endif last_game = time(NULL); next_ping = 0; } else if (!strncmp(buffer,"setup",5)) { int id,d,t0; float k; /* new CGOS */ if (sscanf(buffer,"setup %d %d %f %d",&id,&d,&k,&t0) == 4) { time_left = (float)t0/1000.0f; max_time = (int)time_left; } #if 1 // todo issue GTP commands here goban_init(goban); goban_show(goban,buffer); #endif last_game = time(NULL); } else if (!strncmp(buffer,"genmove",7)) { move_t move; /* genmove b 108584 */ #ifdef USE_CGOS3 for (i=1,p=strtok(buffer,TOKSEP); i<3; i++) p=strtok(NULL,TOKSEP); if (p) { time_left = (float)atof(p)/1000.0f; #if (DEBUG > 0) fprintf(stderr,"time_left= %.1f\n",time_left); #endif } #endif #if 1 // todo issue GTP commands here move = genmove_1(goban,nsims); goban_play_move(goban,move); goban_show(goban,move_string(move)); #endif cgos_send(move_string(move)); } else if (!strncmp(buffer,"play",4)) { /* play w B8 93827 */ for (i=1,p=strtok(buffer,TOKSEP); i<3; i++) p=strtok(NULL,TOKSEP); if (p) { #if 1 // todo issue GTP command here goban_play_move(goban,str2move(p)); goban_show(goban,p); #endif } else { fprintf(stderr,"%s: unrecognized move\n",__FILE__); } } else if (!strncmp(buffer,"time",4)) { /* old CGOS only */ for (i=1,p=strtok(buffer,TOKSEP); i<3; i++) p=strtok(NULL,TOKSEP); if (p) { time_left = (float)atof(p); #if (DEBUG > 0) fprintf(stderr,"time_left= %.1f\n",time_left); #endif } } else // todo 'gameover 2007-03-26 W+38.5 ' with USE_CGOS3 if (!strncmp(buffer,"gameover",8)) { float score; #if 1 // todo GTP commmand here score = score_board(goban->board,NULL,NULL); fprintf(stderr,"my_score= %.1f\n",score); #endif sprintf(buffer,"/tmp/%s.terminate",name); /* exit program? */ if (!unlink(buffer)) { r = 0; break; } next_ping = time(NULL) + PING_TIME; #ifdef USE_CGOS3 cgos_send("ready"); /* stay for another game */ #else cgos_send("ok"); /* stay for another game */ #endif } else if (!strncmp(buffer,"info",4)) { char *p; /* new CGOS only */ if ((p=strstr(buffer,"next round:")) != NULL) { int m,s; if (sscanf(p,"next round: %d:%d",&m,&s) == 2) { last_game = time(NULL) + m*60 + s; } } } else { fprintf(stderr,"unknown command from CGOS '%s'\n",buffer); } /* exit when no game is played for too long */ } while (time(NULL) < last_game+3*max_time); cgos_disconnect(); return(r); } /* ---------------------------------------------------------------------- */ static int cgos_connect(const char* host,u_short port, const char* name,const char* pass) { int r; char buffer[1024]; struct hostent *hostp; struct protoent *proto; struct sockaddr_in saddr; #if (DEBUG > 0) fprintf(stderr,"cgos_connect(%s:%d,%s,%s)\n",host,port,name,pass); #endif hostp = gethostbyname(host); /* get host IP address */ if (hostp == NULL) return(-1); proto = getprotobyname("tcp"); /* get protocol by name */ if (proto == NULL) return(-1); memset((void*)&saddr,0,sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons((u_short)port); memcpy(&saddr.sin_addr,hostp->h_addr_list[0],hostp->h_length); cgos_sock = socket(AF_INET,SOCK_STREAM,proto->p_proto); if (cgos_sock < 0) return(-1); (void)fcntl(cgos_sock,F_SETFD,FD_CLOEXEC); /* close connection on exec() */ r = connect(cgos_sock,(struct sockaddr *)&saddr,sizeof(saddr)); if (r == -1) { (void)close(cgos_sock); return(-1); } r = cgos_receive(buffer,5000); /* protocol */ #ifdef USE_CGOS3 if (r > 0) { if (strcmp(buffer,"protocol")) r = -1; else cgos_send("e1 myCtest"); } if (r > 0) r = cgos_receive(buffer,5000); /* username */ #endif if (r > 0) { if (strcmp(buffer,"username")) r = -1; else cgos_send(name); } if (r > 0) r = cgos_receive(buffer,5000); /* password */ if (r > 0) { if (strcmp(buffer,"password")) r = -1; else cgos_send(pass); } #ifndef USE_CGOS3 if (r > 0) r = cgos_receive(buffer,5000); /* successfull.. */ if (r > 0) { if (strncmp(buffer,"succe",5)) r = -1; } #endif if (r <= 0) { cgos_disconnect(); return(-1); } return(0); } /* ---------------------------------------------------------------------- */ static void cgos_disconnect(void) { #if (DEBUG > 0) fprintf(stderr,"cgos_disconnect(%d)\n",cgos_sock); #endif if (cgos_sock > 0) { close(cgos_sock); cgos_sock = -1; } } /* ---------------------------------------------------------------------- */ static int cgos_receive(char* answer,int timeout) { int i,r; char c=0; char buffer[1024]; *answer = '\0'; /* preset 'answer' */ r = read_byte(cgos_sock,&c,timeout); if (r <= 0) return(r); buffer[0] = c; i = 1; do { if (read_byte(cgos_sock,&c,timeout+5000) <= 0) break; if (c == 0x0d) continue; /* <CR> */ if (c == 0x0a) break; /* <LF> */ buffer[i] = c; i++; } while (i < sizeof(buffer)-1); buffer[i]= '\0'; #if (DEBUG > 0) fprintf(stderr,"CGOS-> '%s'\n",buffer); #endif strcpy(answer,buffer); return (i); } /* ---------------------------------------------------------------------- */ static int read_byte(int sock,char* c,int timeout) /* timeout (ms) */ { int r; fd_set rfd; struct timeval tout; do { /* wait for byte */ FD_ZERO(&rfd); FD_SET(sock,&rfd); tout.tv_sec = timeout/1000; tout.tv_usec = (timeout*1000) % 1000000; r = select(sock+1,&rfd,NULL,NULL,&tout); if (FD_ISSET(sock,&rfd)) break; } while (r > 0); if (r <= 0) return(r); r = recv(sock,c,1,0); /* read byte */ if (r <= 0) return(-1); return(r); } /* ---------------------------------------------------------------------- */ static int cgos_send(const char *text) { char message[1024]; #if (DEBUG > 0) fprintf(stderr,"cgos_send(%s)\n",text); #endif sprintf(message,"%s\n",text); if (send(cgos_sock,message,strlen(message),0) == -1) return(-1); return(0); } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
_______________________________________________ computer-go mailing list computer-go@computer-go.org http://www.computer-go.org/mailman/listinfo/computer-go/