int getIndex(){ list<Move> moveLst = PrevBoard.getValidMoves(other(ourTurn)); int i = 0; for(list<Move>::iterator it = moveLst.begin(); it != moveLst.end(); ++it, ++i){ if(it->x == PrevMove.x && it->y == PrevMove.y) return i; } return -1; }
int MyBot::alphaBeta(Turn turn, const OthelloBoard& board, int alpha, int beta, int ply) { if(ply==0) { return evaluationFunction(turn, board); } else { list<Move> moves = board.getValidMoves(turn); int noOfMoves = moves.size(); if(noOfMoves == 0) { list<Move> oppMoves = board.getValidMoves(other(turn)); if(oppMoves.size()!= 0){ return (- (alphaBeta (other(turn), board, -beta, -alpha, ply-1))); } else return finalValue(turn, board); } else { list<Move>::iterator it = moves.begin(); for(; it != moves.end(); it++){ OthelloBoard board2 = board; board2.makeMove(turn, *it); //val is alpha in the case of max and beta in the case of min int val = - alphaBeta(other(turn), board2, - beta, -alpha, (ply-1)); if(val >= beta) return val; if(val >= alpha) { alpha = val; if(ply == PLY) bestMove = &(*it); } } return alpha; } } }
Move MyBot::play(const OthelloBoard& board) { ourTurn = turn; store.clear(); threadSuccessfull = false; if (!strtGame) { pthread_join(RGThread, NULL); getPrevMove(board); setPlyDepth(); if(OpponentMoveDone){ pos = getIndex(); if(pos <= threadDone && pos != -1) threadSuccessfull = true; } } else if (ourTurn == BLACK) { strtGame = false; --gameMovesDone; setPlyDepth(); PrevBoard = OthelloBoard(board); list<Move> moveLst = PrevBoard.getValidMoves(ourTurn); list<Move>::iterator it = moveLst.begin(); int randNo = (rand() % 4); for (int i = 0; i < randNo - 1; ++it, ++i); FinalMove.x = it->x, FinalMove.y = it->y; PrevBoard.makeMove(ourTurn, FinalMove); ++gameMovesDone; /* Initializing the thread to RG opponenet before returning the move */ RGThreadStatus = pthread_create(&RGThread, NULL, threadFunc, (void*)NULL); return FinalMove; } strtGame = false; PrevBoard = OthelloBoard(board); Node* root = new Node(PrevBoard, ourTurn); if(!shallowDepthDone) shallowDepth(root); alphabetaMiniMax(root, 0, MIN_NUM, MAX_NUM, 0); PrevBoard.makeMove(ourTurn, FinalMove); ++gameMovesDone; /* Initializing the thread to RG opponenet before returning the move */ RGThreadStatus = pthread_create(&RGThread, NULL, threadFunc, (void*)NULL); return FinalMove; }
Move MyBot::play(const OthelloBoard& board ) { list<Move> moves = board.getValidMoves( turn ); if(moves.size()==0) return Move::pass(); OthelloBoard b; list<Move>::iterator it; int currbest = POSLARGE; Move *cm = 0; bool firstRun = true; int val; priority_queue<MovePair> pq; for(it=moves.begin(); it!=moves.end(); it++){ b = board; b.makeMove(turn,*it); int score = weights[it->x][it->y]; MovePair *tempm = new MovePair(&(*it), score); pq.push(*tempm); } while(!pq.empty()){ Move* m = pq.top().m; pq.pop(); b = board; b.makeMove(turn,*m); val = alphaBeta(other(turn), b, NEGLARGE, val, PLY); if(val<currbest || firstRun){ currbest = val; cm = m; firstRun = false; } } if(cm==0) cout<<"cm is null!!"<<endl<<moves.size()<<endl; return *cm; }
int alphabeta(const OthelloBoard& board,int depth,int alpha,int beta,Turn turn ,Turn max_player) { Turn next_turn = other(turn); int k; if (depth == 0) { return score_gen(board,max_player); } if(board.getValidMoves( turn ).empty() && board.getValidMoves( other( turn ) ).empty()) { return score_gen(board,max_player); } list<Move> Moves = board.getValidMoves(turn); int temp; OthelloBoard temp_board ; if (turn == max_player) { if(!Moves.empty()) { list<Move>::iterator it = Moves.begin(); if(depth == DEPTH) { bestMove = Move(*it); } for( ; it!=Moves.end() ; it++) { temp_board = board; temp_board.makeMove(turn,*it); /* if(distance(it,Moves.end())<DEPTH && depth == DEPTH) { k = DEPTH - distance(it,Moves.end()); } else { k=0; }*/ if(double(clock() - start)/CLOCKS_PER_SEC>4.98) { // cout<<"broke"; break; } temp = alphabeta(temp_board, depth - 1 , alpha, beta, next_turn, max_player); if(alpha < temp) { alpha = temp; if(depth == DEPTH) { bestMove = Move(*it); } } if (beta<=alpha) { break; } } return alpha; } } else { if(!Moves.empty()) { for( list<Move>::iterator it = Moves.begin() ; it!=Moves.end() ; it++) { temp_board = board; temp_board.makeMove(turn,*it); if(double(clock() - start)/CLOCKS_PER_SEC>4.98) { // cout<<"broke"; break; } temp = alphabeta(temp_board, depth - 1, alpha, beta, next_turn, max_player); if( beta > temp) { beta = temp; } if (beta<=alpha) { break; } } return beta; } } }
/*Function to calculate 2 levels of Moves*/ void* threadFunc(void* ptr){ int i, j; shallowDepthDone = false; threadDone = threadDone2 = -1; memset(thread2Done,false, sizeof(thread2Done)); Turn otherTurn = other(ourTurn); immediateSucc = PrevBoard.getValidMoves(otherTurn); list<Move>::iterator it, kj; OthelloBoard saveBoard = PrevBoard; for(i = 0, it = immediateSucc.begin(); it != immediateSucc.end(); ++it, ++i){ PrevBoard.makeMove(otherTurn, *it); moveLst1[i] = PrevBoard.getValidMoves(ourTurn); PrevBoard = saveBoard; ++threadDone; } for(i = 0, kj = immediateSucc.begin() ; kj != immediateSucc.end(); ++kj, ++i ){ PrevBoard.makeMove(otherTurn, *kj); OthelloBoard saveBoard1 = PrevBoard; for( j = 0, it = moveLst1[i].begin(); it != moveLst1[i].end(); ++it, ++j){ PrevBoard.makeMove(ourTurn, *it); moveLst2[i][j] = PrevBoard.getValidMoves(otherTurn); PrevBoard = saveBoard1; } thread2Done[i] = true; ++threadDone2; PrevBoard = saveBoard; } return NULL; }