static void simulate(){ for(int i = 0 ; i < NBPLAYER ; i ++) participants[i] = input[i]; for(int i = 0 ; i < (NBPLAYER - 1) ; i ++){ for(int j = i + 1 ; j < NBPLAYER ; j ++){ for(int k = 0 ; k < NBGAMES ; k ++){ if(participants[i].results[(NBGAMES * j) + k] == BLACKPLAY){ int r = rand() % 200; if(r < getLosingProbability(participants[i].Elo - participants[j].Elo)){ participants[i].results[(NBGAMES * j) + k] = BLACKLOSS; participants[j].results[(NBGAMES * i) + k] = WHITEWIN; } else { if(r < 3 * getLosingProbability(participants[i].Elo - participants[j].Elo)){ participants[i].results[(NBGAMES * j) + k] = BLACKDRAW; participants[j].results[(NBGAMES * i) + k] = WHITEDRAW; } else { participants[i].results[(NBGAMES * j) + k] = BLACKWIN; participants[j].results[(NBGAMES * i) + k] = WHITELOSS; } } } if(participants[i].results[(NBGAMES * j) + k] == WHITEPLAY){ int r = rand() % 200; if(r < getLosingProbability(participants[i].Elo - participants[j].Elo)){ participants[i].results[(NBGAMES * j) + k] = WHITELOSS; participants[j].results[(NBGAMES * i) + k] = BLACKWIN; } else { if(r < 3 * getLosingProbability(participants[i].Elo - participants[j].Elo)){ participants[i].results[(NBGAMES * j) + k] = WHITEDRAW; participants[j].results[(NBGAMES * i) + k] = BLACKDRAW; } else { participants[i].results[(NBGAMES * j) + k] = WHITEWIN; participants[j].results[(NBGAMES * i) + k] = BLACKLOSS; } } } } } } getScores(0); }
/*board is the board right now. lvl is the lvl of the node we are creating, row and col is the position of the most recently added piece. row and col are not relevant when lvl is 0 and are invalid*/ Cathy::Node* Cathy::GameTree::CreateTree(int board[][NUMSQUARES],int lvl){ Node* nn=new Node(); int whowon; int whomoves=(lvl%2)?-player_:player_; MoveList p1; MoveList p2; MoveList flips; int nump1,nump2; int r,c; int newboard[NUMSQUARES][NUMSQUARES]; wchar_t debugStr[255 + 1]; int maxOrMin = lvl%2; // 0 is max, 1 is min if(!canMove(board, p1, p2) || boardFull(board)){ //game over, neither player can move getScores(board,nump1,nump2); if(nump1==nump2) whowon=0; else if(nump1>nump2) whowon=1; else whowon=-1; //Base case 1: someone has won the game, game is over score is 100 if(whowon) { nn->score_=whowon * player_* MAXSCORE; //if player_ is 1 and they won the whowon would be +ve so //we have score being +1, otherwise if player_ is -1 and //player 2 won, then whowon would be -1 so score will still //be +1. } } else if(lvl==height_-1){ //tree has reached its max height nn->score_=Eval(board,player_, p1, p2); //always evaluate for player at root! } else{ if(whomoves==1){ if(p1.numMoves()==0){ nn->noMove_=CreateTree(board,lvl+1); } else{ for(int i=0,prev_r=0,prev_c=0;i<p1.numMoves();i++){ p1.getRowCol(i,r,c); flips.clear(); addPiece(board,r,c,1,flips); if( i == 0 ){ // if it is the first node, then create it nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } else{ if(maxOrMin == 0){ //otherwise, check before create, depending on lvl if(nn->child_[prev_r][prev_c]->score_ < Eval(board,player_,p1,p2) ){ nn->child_[prev_r][prev_c] = NULL; //delete nn->child_[prev_r][prev_c]; nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } } else if(maxOrMin ==1){ if(nn->child_[prev_r][prev_c]->score_ > Eval(board,player_,p1,p2) ){ nn->child_[prev_r][prev_c] = NULL; //delete nn->child_[prev_r][prev_c]; nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } } } /*undo the changes before testing the next move*/ board[r][c]=0; for(int j=0;j<flips.numMoves();j++){ flips.getRowCol(j,r,c); board[r][c]=-1; } } } } else{ if(p2.numMoves()==0){ nn->noMove_=CreateTree(board,lvl+1); } else{ for(int i=0,prev_r=0,prev_c=0;i<p2.numMoves();i++){ p2.getRowCol(i,r,c); flips.clear(); addPiece(board,r,c,-1,flips); if( i == 0 ){ // if it is the first node, the create it nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } else{ if(maxOrMin == 0){ //otherwise, check before create, depending on lvl if(nn->child_[prev_r][prev_c]->score_ < Eval(board,player_,p1,p2) ){ nn->child_[prev_r][prev_c] = NULL; //delete nn->child_[prev_r][prev_c]; nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } } else if(maxOrMin ==1){ if(nn->child_[prev_r][prev_c]->score_ > Eval(board,player_,p1,p2) ){ nn->child_[prev_r][prev_c] = NULL; //delete nn->child_[prev_r][prev_c]; nn->child_[r][c] = CreateTree(board,lvl+1); prev_r = r, prev_c = c; } } } /*undo the move before testing the next move*/ board[r][c]=0; for(int j=0;j<flips.numMoves();j++){ flips.getRowCol(j,r,c); board[r][c]=1; } } } } bool setgood=false; //StringCbPrintfW(debugStr,255,L"Create Tree is called %d \n", lvl%2); //OutputDebugStringW(debugStr); //NOTE: If you implement alpha beta pruning, you will have to track max/min in the //tree creation loop. if(lvl%2){ if(nn->noMove_){ nn->score_=nn->noMove_->score_; } else{ for(int i=0;i<NUMSQUARES;i++){ for(int j=0;j<NUMSQUARES;j++){ if(nn->child_[i][j]){ if(!setgood || nn->child_[i][j]->score_ < nn->score_){ nn->score_=nn->child_[i][j]->score_; setgood=true; } } }//for }//for } } else{ if(nn->noMove_){ nn->score_=nn->noMove_->score_; } else{ for(int i=0;i<NUMSQUARES;i++){ for(int j=0;j<NUMSQUARES;j++){ if(nn->child_[i][j]){ if(!setgood || nn->child_[i][j]->score_ > nn->score_){ nn->score_=nn->child_[i][j]->score_; setgood=true; if(lvl==0){ bestrow_=i; bestcol_=j; } } } }//for }//for } } } //end of tree creation loop return nn; }
int main(int argc, char * argv []){ srand((unsigned int)time(NULL)); char c; for(int i = 0 ; i < NBPLAYER ; i ++) { scanf("%s %d %d ", input[i].name, &(input[i].nbCrash), &(input[i].Elo)); for(int j = 0 ; j < NBPLAYER ; j ++){ for(int k = 0 ; k < NBGAMES ; k ++){ scanf("%c", &c); input[i].results[(j * NBGAMES) + k] = (int) c; } scanf(" "); } input[i].id = i; if(strlen(input[i].name) > maxNameLength) maxNameLength = strlen(input[i].name); } for(int i = 0 ; i < NBPLAYER ; i ++) participants[i] = input[i]; printf("\n *********************\n"); printf(" * Current standings *\n"); printf(" *********************\n\n"); getScores(1); printf("\nStarting a simulation with %d iterations\n", NBITER); printf("Simulation currently at 0%%"); fflush(stdout); for(int i = 0 ; i < NBITER ; i ++){ simulate(); if((100 * (i + 1) % NBITER == 0)){ int percentage = (100 * (i + 1)) / NBITER; printf("\r"); for(int k = 0 ; k < 80 ; k ++) printf(" "); printf("\rSimulation currently at %d%%", percentage); fflush(stdout); } } printf("\n\n **********************\n"); printf(" * Simulation results *\n"); printf(" **********************\n\n"); for(int i = 0 ; i < NBPLAYER ; i ++){ printf("%s ", input[i].name); for(int j = 0 ; j < (maxNameLength - strlen(input[i].name)) ; j++) printf(" "); switch (input[i].nbQualif){ case NBITER: printf("is qualified\n"); break; case 0: printf("is eliminated\n"); break; default: if((100 * input[i].nbQualif) % NBITER < NBITER / 2) printf("has %d%% chances to qualify\n", (100 * input[i].nbQualif / NBITER)); else printf("has %d%% chances to qualify\n", (100 * input[i].nbQualif / NBITER) + 1); break; } } return 0; }