Beispiel #1
0
        private int MiniMax(Move move, GridData gridData, int turn, int depth)
        {
            // The MiniMax method gives the best possible move for the current grid data.
            // This works by, effectively, playing each possible game. If that game results
            // in a CPU win, then return a positive score; if it results in a CPU loss,
            // then return a negative score.
            // The CPU and Player alternate turns. The Player is aiming to get the lowest
            // possible score (i.e. a CPU loss / a Player win). Therefore, when the lowest
            // score possible for the Player is positive, then a perfect-playing CPU will
            // eventually win, and that is the move it should take.

            // We limit the depth, in order to create a beatable CPU.

            eState moveState = new StatePlayerConverter().GetPlayerState(turn);
            gridData.PlaceMove(move, moveState);
            if(gridData.HasWinner())
            {
                int winScore = 10 - depth;
                return IsCPUMove(turn) ? winScore: -winScore;
            }
            else if(gridData.IsStalemate() || depth == _maxDepth)
            {
                return 0;
            }
            else
            {
                // Game is neither won nor a stalemate. Therefore, we'll keep playing.
                int nextTurn = (turn + 1) % 2;
                int bestScore = -20;

                List<Move> nextMoves = gridData.GetPossibleMoves();
                foreach(Move nextMove in nextMoves)
                {
                    int score = MiniMax(nextMove, gridData.Copy(), nextTurn, depth + 1);
                    // Player move will return a negative score if it has won. Negate it for
                    // now so that it is positive and will be seen as the player's best move.
                    score = IsCPUMove(nextTurn) ? score : -score;
                    if(score > bestScore)
                    {
                        bestScore = score;
                    }
                }
                // Player move has negated to find the best score. Turn it back, so that it
                // gives an accurate score for CPU move.
                return IsCPUMove(nextTurn) ? bestScore: -bestScore;
            }
        }
Beispiel #2
0
 public CPUMoveFinder(GridData gridData, bool isBeatable)
 {
     _gridData = gridData;
     _maxDepth = isBeatable ? 4 : -1;
 }
Beispiel #3
0
 public CPUMoveFinder(GridData gridData, bool isBeatable)
 {
     _gridData = gridData;
     _maxDepth = isBeatable ? 4 : -1;
 }