AIMove AI::getBestMove(Board& board, int player){ int rv = board.checkVictory(); if (rv == _aiPlayer){ return AIMove(10); } else if (rv == _humanPlayer){ return AIMove(-10); } else if (rv == TIE_VAL){ return AIMove(0); } std::vector<AIMove> moves; // recursive for (int y = 0; y < board.getSize(); y++){ for (int x = 0; x < board.getSize(); x++){ if (board.getVal(x, y) == NO_VAL){ AIMove move; move.x = x; move.y = y; board.setVal(x, y, player); if (player == _aiPlayer){ move.score = getBestMove(board, _humanPlayer).score; } else{ move.score = getBestMove(board, _aiPlayer).score; } moves.push_back(move); board.setVal(x, y, NO_VAL); } } } // pick the best move int bestMove = 0; if (player == _aiPlayer){ int bestScore = -1000000; for (int i = 0; i < moves.size(); i++){ if (moves[i].score > bestScore){ bestMove = i; bestScore = moves[bestMove].score; } } } else{ int bestScore = 1000000; for (int i = 0; i < moves.size(); i++){ if (moves[i].score < bestScore){ bestMove = i; bestScore = moves[bestMove].score; } } } return moves[bestMove]; }
TEST(AIMatchTest, CanGetMove) { auto board = Board(9); auto node = IntConstNode(1); auto move = getBestMove(board, node, BLACK); EXPECT_EQ(8, move.x); EXPECT_EQ(8, move.y); }
int bestMoveForState(GameState* gs, int player, int other_player, int look_ahead) { TranspositionTable* t1 = newTable(); GameTreeNode* n = newGameTreeNode(gs, player, other_player, 1, INT_MIN, INT_MAX, t1); int move = getBestMove(n, look_ahead); free(n); freeTranspositionTable(t1); return move; }
void SimpleTabuSearchReverse<TNeighborhood, TImprovement, TTabuList, TAspirationCriteria, TSolution>::run(const size_t numberOfSteps) { bool isMoveUp = false; TSolution currentSolution(bestSolution); size_t currentNumberOfUnchanged = 0; for (size_t i = 0; i < numberOfSteps; ++i) { std::cout << "Number of move " << i << std::endl; auto bestLocalMovePtr = getBestMove(currentSolution); if (nullptr == bestLocalMovePtr) { continue; } // apply move currentSolution.applyMove(*bestLocalMovePtr); ++currentNumberOfUnchanged; // std::cout << "number of unchanged " << currentNumberOfUnchanged << std::endl; if (currentSolution.getObjectiveValue() <= bestSolution.getObjectiveValue()) { bestSolution = currentSolution; currentNumberOfUnchanged = 0; } if (i >= 50) { isMoveUp = true; } double overheadsCoefficient = currentSolution.getOverheadsCoefficient() + 0.1; if (isMoveUp) { std::cout << "MOVE UP!!!" << std::endl; currentSolution.setOverheadsCoefficient(overheadsCoefficient); bestSolution.setOverheadsCoefficient(overheadsCoefficient); } if (0 == bestSolution.getObjectiveValue()) { // the objectives are achieved break; } // update tabuList and AspirationCriteria tabuList.update(*bestLocalMovePtr); aspirationCriteria.update(currentSolution); } }
TEST(AIMatchTest, DoesntMakeSuicideMoves) { auto board = Board(9); board.set(0, 1, BLACK); board.set(1, 1, BLACK); board.set(2, 0, BLACK); board.set(0, 0, WHITE); auto ai = PlayerScoreDeltaNode(); ai.setScale(-1); // really wants to give other player points auto move = getBestMove(board, ai, WHITE); ASSERT_NE((Move{1, 0}), move); }
Move AIShell::makeMove(){ //this part should be filled in by the student to implement the AI //Example of a move could be: Move move(1, 2); //this will make a move at col 1, row 2 if (lastMove.col == -1 && lastMove.row == -1) { Move m(numCols/2, numRows/2); return m; } AiMove bestMove = getBestMove(boardCopy, 1, 0, -1); //std::cout<<"BM: "<<bestMove.x<<bestMove.y<<std::endl; Move m = Move(bestMove.x, bestMove.y); //std::cout<<"Move made:"<<bestMove.x<<" "<<bestMove.y<<std::endl; return m; }
int setSelectedMoveToBest(){ if (movesOfSelectedPiece){ LinkedList_free(movesOfSelectedPiece); } movesOfSelectedPiece = LinkedList_new(&PossibleMove_free); if (!movesOfSelectedPiece){ return -1; } PossibleMove* bestMove = getBestMove(); if (!bestMove){ return -1; } selectedX = bestMove->fromX; selectedY = bestMove->fromY; if(LinkedList_add(movesOfSelectedPiece, bestMove)){ return -1; } return 0; }
/* * The computer turn procedure. */ int computerTurn(){ PossibleMove* bestMove = getBestMove(); if (!bestMove){ allocationFailed(); } if (displayMode == CONSOLE){ printf("Computer: move "); PossibleMove_print(bestMove); } Board_update(&board, bestMove); PossibleMove_free(bestMove); turn = !turn; if (display()){ return 1; } return 0; }
void AI::performMove(Board& board) { AIMove bestMove = getBestMove(board, _aiPlayer); board.setVal(bestMove.x, bestMove.y, _aiPlayer); }
void TabuSearch::run(string movetype, int maxiter) { initializeTabuLists(); initializeLeafsAndNeighborhood(); LSMove* bestMove = NULL; int nic = 1; int init_min = 0; int cardinality = (*tree).edges.size(); if (((*graph).vertices.size() - cardinality) < cardinality) { init_min = (*graph).vertices.size() - cardinality; } else { init_min = cardinality; } int init_length; if (init_min < ((int)(((double)(*graph).vertices.size()) / 5.0))) { init_length = init_min; } else { init_length = (int)(((double)(*graph).vertices.size()) / 5.0); } in_length = init_length; out_length = init_length; int max_length = (int)(((double)(*graph).vertices.size()) / 3.0); int increment = ((int)((max_length - in_length) / 4.0)) + 1; int max_unimpr_iters = increment; if (max_unimpr_iters < 100) { max_unimpr_iters = 200; } int iter = 1; while (iter <= maxiter) { if ((nic % max_unimpr_iters) == 0) { if (in_length + increment > max_length) { in_length = init_length; out_length = init_length; cutTabuLists(); } else { in_length = in_length + increment; out_length = out_length + increment; } } if (bestMove != NULL) { delete(bestMove); } if (movetype == "first_improvement") { bestMove = getFirstMove(tree->weight(),currentSol->weight()); } else { bestMove = getBestMove(tree->weight(),currentSol->weight()); } if (bestMove != NULL) { currentSol->addVertex((bestMove->in)->lVertex); currentSol->addEdge((bestMove->in)->lEdge); currentSol->remove((bestMove->out)->lEdge); currentSol->remove((bestMove->out)->lVertex); adaptLeafs(bestMove); adaptNeighborhood(bestMove); adaptTabuLists((bestMove->in)->getEdge(),(bestMove->out)->getEdge()); delete(bestMove->in); delete(bestMove->out); currentSol->setWeight(currentSol->weight() + (bestMove->weight_diff)); } if (currentSol->weight() < tree->weight()) { tree->copy(currentSol); nic = 1; in_length = init_length; out_length = init_length; cutTabuLists(); } else { nic = nic + 1; } iter = iter + 1; } if (bestMove != NULL) { delete(bestMove); } for (list<Leaf*>::iterator aL = leafs.begin(); aL != leafs.end(); aL++) { delete(*aL); } leafs.clear(); for (list<Leaf*>::iterator aL = neighborhood.begin(); aL != neighborhood.end(); aL++) { delete(*aL); } neighborhood.clear(); in_list_map.clear(); out_list_map.clear(); in_list.clear(); out_list.clear(); tree = NULL; }
void TicTacToe::compPlace() { int bestMove = getBestMove(); board.placeComp(bestMove); cout << "the computer choice is: " << endl; }
int main(void) { char inputMove, inputMove2, inputAI, gameOver; struct timeval t2, tLast; double elapsedTime; //initialize superBoard for (char i = 0; i < SUPER_BOARD_SIZE; i++) { superBoard[i] = -1; } while (1) { printf("\nWho will the AI play as? (X, O): "); scanf("%c", &inputAI); if (inputAI == 'X' || inputAI == 'x') { AI = X; break; } else if (inputAI == 'O' || inputAI == 'o') { AI = O; break; } //If we made it this far, invalid input printf("\nInvalid Selection\n"); } while (1) { printBoard(subBoard); printSuperBoard(superBoard); while (1) { if (AI == currentPlayer) { //Start Timer gettimeofday(&t1, NULL); gettimeofday(&tLast, NULL); printf("\nAI calculating best move in (region %d)...\n", allowedSuperSpot); //AI always chooses the first spot as its move, so just set it. if (moves == 0) { inputMove = 40; } else { for (char i = 4; i < 16; i++) { char levelMove; printf("Calculating to level %d...\n", i); levelMove = getBestMove(subBoard, superBoard, allowedSuperSpot, currentPlayer, i); gettimeofday(&t2, NULL); elapsedTime = t2.tv_sec - tLast.tv_sec; printf("%f seconds elapsed for level %d\n", elapsedTime, i); elapsedTime = t2.tv_sec - t1.tv_sec; if (elapsedTime < MAX_TURN_TIME) { inputMove = levelMove; } else { printf("Failed to complete level %d, using level %d move", i, i-1); break; } tLast = t2; } } // stop timer gettimeofday(&t2, NULL); elapsedTime = (t2.tv_sec - t1.tv_sec); printf("\nAI moved to spot: %d (region %d)\n", inputMove, getSuperBoardSpot(inputMove)); printf("Move took %f seconds\n", elapsedTime); } else { printf("\nEnter move (region %d): ", allowedSuperSpot); scanf("%d", &inputMove); } if (isOpenSpot(subBoard, superBoard, inputMove) && (getSuperBoardSpot(inputMove) == allowedSuperSpot || allowedSuperSpot == -1)) { break; } else { printBoard(subBoard); printf("\nInvalid move.\n"); } } allowedSuperSpot = doMove(subBoard, superBoard, currentPlayer, inputMove); moves++; if (currentPlayer == X) { currentPlayer = O; } else { currentPlayer = X; } //Check if the game is over gameOver = superBoardWon(superBoard); if (gameOver == X) { printBoard(subBoard); printf("\nGame over, X wins.\n"); exit(0); } else if (gameOver == O) { printBoard(subBoard); printf("\nGame over, O wins.\n"); exit(0); } else if (gameOver == 0) { printBoard(subBoard); printf("\nGame over, tie.\n"); exit(0); } } }
//============================================================================== bool ChessGame::ProcessMessage(const Message &msg) { Message::MessageType type = msg.GetMessageType(); std::string data = msg.GetData(); // START GAME // Engine color and difficulty have already been parsed // Send client its game ID if (type == Message::START_GAME) { std::string idStr = std::to_string(m_gameId); Message m(Message(Message::START_GAME, idStr)); return sendMessage(m); } // MAKE MOVE // Parse unambiguous PGN string from client // Send move back to client if valid, otherwise invalidate move else if (type == Message::MAKE_MOVE) { Move move(data, m_spBoard->GetPlayerInTurn()); Message m; // Try to make the move if (MakeMove(move)) { m = Message(Message::MAKE_MOVE, makeMoveAndStalemateMsg(move)); } else { m = Message(Message::INVALID_MOVE, move.GetPGNString()); } return sendMessage(m); } // GET MOVE // Use the engine to find a move and send to client else if (type == Message::GET_MOVE) { // Find a move. We know a move will be found - client will only // request a move if it knows one can be made. Move move = getBestMove(); Message m(Message::MAKE_MOVE, makeMoveAndStalemateMsg(move)); return sendMessage(m); } // DISCONNECT // End this game else if (type == Message::DISCONNECT) { return false; } // UNKNOWN TYPE // Unknown message received - log and end this game LOGW(m_gameId, "Unrecognized message: %d - %s", type, data); return false; }
AiMove AIShell::getBestMove(int** board, int player, int depth, int col, int row) { // Base case, check for end state int score = 0; if(col != -1) { score = getScore(col, row, player * -1); // getting score of the current state } if (depth == depth_limit || isFull(board) || (score <= -996) || (score >= 996)) //if depth or terminal node has been reached { AiMove move = AiMove(score); //std::cout<<move.score<<std::endl; //if (move.score == 2){std::cout<<"got 2!!!!" << std::endl;} move.x = col; move.y = row; move.level = depth; if(player == AI_PIECE) { //std::cout<<"Node value for AI move at "<<col<< ", " <<row<<": "<<score<<std::endl; } else { //std::cout<<"Node value for Opponent move at " <<col<< ", "<<row<<": "<<score<<std::endl; } //if(score <= -996 || score >= 996) //std::cout<<score<<std::endl; return move; } std::vector<AiMove> moves; // Do the recursive function calls and construct the moves vector for (int x = 0; x < numCols; x++) { for (int y = 0; y < numRows; y++) { //std::cout<<"Col:"<<x<<std::endl; //std::cout<<"Row:"<<y<<std::endl; //std::cout<<"Val:"<<board[x][y]<<std::endl; if (board[x][y] == 0) { AiMove move; //move.x = x; //move.y = y; board[x][y] = player; if (player == 1) { move = getBestMove(board, -1, depth+1,x,y); } else { move = getBestMove(board, 1, depth+1,x,y); } move.x = x; move.y = y; moves.push_back(move); //for (int i=0; i < moves.size(); i++){ //std::cout << i << ": " << moves[i].score << std::endl; //} board[x][y] = 0; if(gravityOn) break; } } } // Pick the best move for the current player //for (int i =0; i < moves.size();i++) //{ //std::cout<< "m: " << moves[i].score<< std::endl; //} /* if(depth == 1 || depth == 0) { std::cout<<player<<std::endl; if(depth == 1) std::cout<<"first print"<<std::endl; else std::cout<<"final choices"<<std::endl; for(int i = 0; i < moves.size(); i++) { std::cout<<moves[i].x<<" "<<moves[i].y<<" "<<moves[i].score<<" "<<moves[i].level<<std::endl; } std::cout<<"second print"<<std::endl; } */ int bestMove = 0; int lowestDepth = 999999999; // std::cout<<"Prints start here"<<std::endl; if (player == 1) { int bestScore = -1000000; for (int i = 0; i < moves.size(); i++) { //std::cout<<moves[i].x<<" "<<moves[i].y<<" "<<moves[i].score<<" "<<moves[i].level<<std::endl; if (moves[i].score > bestScore && moves[i].level <= lowestDepth) { bestMove = i; bestScore = moves[i].score; lowestDepth = moves[i].level; //if(lowestDepth == 2) //std::cout<<lowestDepth<<std::endl; } } } else { int bestScore = 1000000; for (int i = 0; i < moves.size(); i++) { //std`::cout<<moves[i].x<<" "<<moves[i].y<<" "<<moves[i].score<<" "<<moves[i].level<<std::endl; if (moves[i].score < bestScore && moves[i].level <= lowestDepth) { //std::cout<< "m: " <<moves[i].score<< std::endl; bestMove = i; bestScore = moves[i].score; lowestDepth = moves[i].level; //if(lowestDepth == 2) //std::cout<<lowestDepth<<std::endl; } } } //if(depth <= 1) //std::cout<<"Move chosen"<<moves[bestMove].x<<" "<<moves[bestMove].y<<" "<<moves[bestMove].score<<" "<<moves[bestMove].level<<std::endl; // Return the best move //std::cout<<"Prints end here"<<std::endl; return moves[bestMove]; }