Ejemplo n.º 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);
            }
        }
 private void MakeMove(Move move)
 {
     int currentTurn = _gameManager.GetTurn();
     eState moveState = new StatePlayerConverter().GetPlayerState(currentTurn);
     bool moveMade = _gridData.PlaceMove(move, moveState);
     if(moveMade)
     {
         _gameManager.UpdateTurn();
         EventManager.OnMoveMadeEvent(move, moveState);
         if(_gridData.HasWinner())
         {
             EventManager.OnGameWonEvent(currentTurn, _gridData.GetWinningLine());
         }
         else if(_gridData.IsStalemate())
         {
             _gameManager.ResetScene();
         }
     }
 }
Ejemplo n.º 3
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;
            }
        }