private MinimaxResult MinimaxStep(BoardData p_board, Players p_player, int p_currentDepth) { GameResults t_gameResult = p_board.GetGameResult(); if (t_gameResult != GameResults.Unfinished) { int t_score = t_gameResult == GameResults.Win ? MAX_SCORE : -MAX_SCORE; return(new MinimaxResult(t_score, null)); } else if (p_currentDepth > MAX_DEPTH) { return(m_boardEvaluator.EvaluateBoard(p_board, p_player)); } Move t_bestMove = null; int t_bestScore = 0; if (p_board.CurrentPlayer == Players.Human) { t_bestScore = -INFINITE; } else { t_bestScore = INFINITE; } List <Move> t_moves = new List <Move>(); p_board.GetMoves(t_moves); foreach (Move t_move in t_moves) { BoardData t_newBoard = p_board.GetNewBoard(t_move); MinimaxResult t_result = MinimaxStep(t_newBoard, p_player, p_currentDepth + 1); if (p_board.CurrentPlayer == Players.Human) { if (t_bestScore < t_result.Score) { t_bestScore = t_result.Score; t_bestMove = t_move; } } else { if (t_result.Score < t_bestScore) { t_bestScore = t_result.Score; t_bestMove = t_move; } } } return(new MinimaxResult(t_bestScore, t_bestMove)); }
/* * BoardsScores explanation: * * BoardScores are checked from the highest score to the lowest, if a * board fits in a BoardScores score, the that score is returned and * there is no further checking. * What a BoardScores score consists of is explained below: * * TERMINAL: board with two CHECK where the enemy will lose whatever move * he does. * X · O * · O · * X · X * * TRIPLETRAP: board where by placing one more tile there would be three CHECK * X · @ @ = By placing another X here there would be three CHECK * · · · * X O · * * DOUBLETRAP: same as before, but by placing the said tile there would be two CHECK * · · @ @ = By placing another X here there would be three CHECK * · · · * X O X * * EASYTRAP: DOUBLETRAP that is at the same time a CHECK * · · · * · O · * X · X * * CHECK: board where by placing one more tile the game would be a win * O · · * X X · * O · · * * CORNER: board where the tile is in a corner * X · · * · · · * · · · */ public MinimaxResult EvaluateBoard(BoardData p_board, Players p_player) { int t_score = 0; Tiles t_currentPlayerTile = p_board.HumanTile; if (Players.AI == p_player) { t_currentPlayerTile = p_board.HumanTile ^ (Tiles)1; } GameResults t_gameResult = p_board.GetGameResult(); if (t_gameResult == GameResults.Tie) { t_score = 0; } else if (t_gameResult == GameResults.Unfinished) { t_score = ScoreUnfinishedBoard(p_board, t_currentPlayerTile); } else { if (t_gameResult == GameResults.Win) { t_score = Minimax.MAX_SCORE; } else { t_score = -Minimax.MAX_SCORE; } } if (p_player == Players.AI) { t_score *= -1; } return(new MinimaxResult(t_score, null)); }