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]; }
// method on AI move void Game::OnAIMove() { if (GetPlayer(m_iTurn) == AI) { AIMove(); InvalidateRect(m_hwnd, NULL, FALSE); m_pRenderGame->OnPaint(this); if (CheckEndGame()) { InvalidateRect(m_hwnd, NULL, FALSE); m_pRenderGame->OnPaint(this); PostMessage(m_hwnd, WM_ENDGAME, 0, 0); } else if (GetPlayer(m_iTurn) == AI) { MSG msg; // check for urgent messages during lengthy calculation while (m_iMoveCounter > 2 && PeekMessage(&msg, m_hwnd, 0, 0, PM_REMOVE)) { // if(msg.hwnd == m_hwnd) DefMDIChildProc(m_hwnd, msg.message, msg.wParam, msg.lParam); // else if (msg.hwnd == g_hWndFrame) // DefFrameProc(g_hWndFrame, g_hWndMDIClient, msg.message, msg.wParam, msg.lParam); } PostMessage(m_hwnd, WM_AIMOVE, 0, 0); } } }
//------------------------------------------------------------------------------ int CApp::OnExecute() { if(OnInit() == false) { return -1; } SDL_Event Event; while(Running) { if(AIenabled && CurrentPlayer && GameState == GAME_STATE_RUNNING) { GameClick(AIMove()); } while(SDL_PollEvent(&Event)) { OnEvent(&Event); } OnLoop(); OnRender(); } OnCleanup(); return 0; }
// ctor Game::Game(HWND hwnd, GameMode Mode) : m_hwnd(hwnd), m_Mode(Mode), m_iTurn(WHITE), m_iMoveCounter(0), m_iWinner(EMPTY), m_LastMove({0,0,0}), m_WinnerRowFirst({ 0,0,0 }), m_WinnerRowLast({ 0,0,0 }) { // intialize empty initial position m_GamePosition.assign(EMPTY); m_EmptySquareMask.assign(TRUE); // check first for fast (hidden) AI game mode if (m_Mode == TwoAIsFast) { m_Players.assign(AI); m_AIBrains.push_back(AIBrain()); m_AIBrains.push_back(AIBrain()); while (!CheckEndGame()) AIMove(); // destroy AI brains Destroy(); } else { // create rendering unit m_pRenderGame = new RenderGame(hwnd); m_pRenderGame->Create(); // assign players depending on the mode switch (m_Mode) { case TwoAIs: m_Players.assign(AI); m_AIBrains.push_back(AIBrain()); m_AIBrains.push_back(AIBrain()); break; case TwoHumans: m_Players.assign(Human); break; case HumanAI: m_Players.at(0) = Human; m_Players.at(1) = AI; m_AIBrains.push_back(AIBrain()); break; case AIHuman: m_Players.at(0) = AI; m_Players.at(1) = Human; m_AIBrains.push_back(AIBrain()); break; } if (GetPlayer(m_iTurn) == AI) PostMessage(m_hwnd, WM_AIMOVE, 0, 0); } //end if }
int main(int argc, char* argv[]) { SnakeGameInfo state; Direction d; readGameState(state); while(state.snakes[state.currentPlayer].alive){ d = AIMove(state.currentPlayer, state); switch(d){ case Up: std::cout << 'u'; break; case Down: std::cout << 'd'; break; case Left: std::cout << 'l'; break; default: std::cout << 'r'; break; } std::cout.flush(); readGameState(state); } return 0; }
AIMove Game::minimax(bool turn, Game game, int num) { if(turn == true) { //larva turn if(game.assess_win_condition1() == true || game.assess_win_condition3() == true) { return AIMove(1000); } else if(num == 0) { return AIMove(game.naive_h()); } } else { if(game.assess_win_condition2()) { return AIMove(-1000); } else if(num == 0) { return AIMove(game.naive_h()); } } std::vector<AIMove> moves; std::vector<std::vector<int>> bird_moves = game.all_possible_bird_move_AI(); std::vector<std::vector<int>> larva_moves = game.possible_larva_move_AI(); if(turn == true) { for(int i=0; i<larva_moves.size(); i++) { AIMove m; m.move = larva_moves.at(i); game.move_larva(m.move); m.score = minimax(false, game, num-1).score; moves.push_back(m); game.undo_larva_move(m.move); } } else { for(int i=0; i<bird_moves.size(); i++) { AIMove m; m.move = bird_moves.at(i); game.move_bird(m.move); m.score = minimax(true, game, num-1).score; moves.push_back(m); game.undo_bird_move(m.move); } } int best_move = 0; if(turn == true) { int best_score = -1000000; for(int i=0; i<moves.size(); i++) { if(moves.at(i).score > best_score) { best_move = i; best_score = moves.at(i).score; } } } else { int best_score = 1000000; for(int i=0; i<moves.size(); i++) { if(moves.at(i).score < best_score) { best_move = i; best_score = moves.at(i).score; } } } if(moves.size() == 0) { AIMove m(naive_h()); return m; } else { return moves.at(best_move); } }