int main(int argc,char*argv[]){ const int num_iters=200000,num_shortlist_iters=1000000; srand(tick_count()); Player me,opponent; if(argc==5){ sscanf(argv[1],"%d",&me.health); sscanf(argv[2],"%d",&opponent.health); sscanf(argv[3],"%d",&me.honour); sscanf(argv[4],"%d",&opponent.honour); me.lastMove=WAIT; opponent.lastMove=WAIT; }else{ sscanf(argv[3],"%d",&me.health); sscanf(argv[4],"%d",&opponent.health); sscanf(argv[5],"%d",&me.honour); sscanf(argv[6],"%d",&opponent.honour); me.lastMove=decode_move(argv[1][strlen(argv[1])-1]); opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]); } struct SimulationStat results[6]; results[0].first_me_move=WAIT; results[0].win=0; results[0].draw=0; results[0].lose=num_iters; results[0].compound=-num_iters*2-1000; //waiting is worse than any other action for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){ results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent); struct SimulationStat *cur=&results[first_me_move]; cur->compound=cur->win*4+cur->draw*1-cur->lose*2; } qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare); for(int i=0;i<OVERHEAD-BOW+1;++i){ struct SimulationStat *cur=&results[i]; // fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound); } for(int i=0;i<2;++i){ results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent); struct SimulationStat *cur=&results[i]; cur->compound=cur->win*2+cur->draw*1; } qsort(results,2,sizeof(*results),stat_compare); for(int i=0;i<2;++i){ struct SimulationStat *cur=&results[i]; // fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound); } putchar("WBGIPO"[results[0].first_me_move]); return 0; }
/* Break up a single line of moves into a list of moves * comprising a positional variation. * In doing so, set GlobalState.depth_of_positional_search * if this variation is longer than the default. */ static Move * compose_positional_variation(char *line) { char *move; /* Build a linked list of the moves of the variation. */ Move *head = NULL, *tail = NULL; Boolean Ok = TRUE; /* Keep track of the depth. */ unsigned depth = 0; move = strtok(line," "); while(Ok && (move != NULL) && (*move != '*')){ if((move = strip_move_number(move)) == NULL){ /* Only a move number. */ } else{ Move *next = decode_move((unsigned char *) move); if(next == NULL){ fprintf(GlobalState.logfile,"Failed to identify %s\n",move); Ok = FALSE; } else{ /* Chain it on to the list. */ if(tail == NULL){ head = next; tail = next; } else{ tail->next = next; tail = next; } next->next = NULL; } depth++; } /* Pick up the next likely move. */ move = strtok(NULL," "); } if(Ok){ /* Determine whether the depth of this variation exceeds * the current default. * Depth is counted in move pairs. * Add some extras, in order to be surer of catching transpositions. */ depth = ((depth+1) / 2) + 4; if(depth > GlobalState.depth_of_positional_search){ GlobalState.depth_of_positional_search = depth; } } else{ if(head != NULL){ free_move_list(head); } head = NULL; } return head; }