Пример #1
0
        int EvaluateHeuristic(GameBoardState boardState, PlayerTurn maxTurn)
        {
            if (boardState.Winner != null)
            {
                return(boardState.Winner == maxTurn ? int.MaxValue : int.MinValue);
            }
            int score = 0;

            foreach (Point[] winningComb in WinningCombinations)
            {
                foreach (Point position in winningComb)
                {
                    PlayerTurn?piece = boardState.Board[position.Y, position.X];
                    if (piece == maxTurn)
                    {
                        score++;
                    }
                    else if (piece == GameLogicUtils.Next(maxTurn))
                    {
                        score--;
                    }
                }
            }
            return(score);
        }
Пример #2
0
        public GameState AddPlayer([DisallowNull] GameState gameState, [DisallowNull] Player newPlayer)
        {
            // TODO: Write assertion helpers
            if (gameState.Stage != GameStage.WAITING_FOR_OPPONENT)
            {
                throw new ArgumentException($"Invalid state: {gameState.Stage}.Game must be waiting for opponent to add another player");
            }
            if (gameState.Player1 == null)
            {
                throw new ArgumentException("Game must have a first player");
            }
            if (gameState.Player2 != null)
            {
                throw new ArgumentException("Second player must be null");
            }

            return(new GameState
            {
                Id = gameState.Id,
                Type = gameState.Type,
                StartTimeUtc = gameState.StartTimeUtc,
                Player1 = gameState.Player1,
                Player2 = newPlayer,
                Stage = GameStage.PLAYING,
                BoardState = GameLogicUtils.InitializeGameBoard(PlayerTurn.TWO)
            });
        }
Пример #3
0
        // We assume Winner field is updated and correct => No need to recalculate winner
        int Evaluate(GameBoardState boardState, PlayerTurn maxTurn, int currentDepth, int maxDepth)
        {
            bool maximizing = boardState.CurrentTurn == maxTurn;

            if (currentDepth == maxDepth || boardState.Winner != null)
            {
                return(EvaluateHeuristic(boardState, maxTurn));
            }

            List <GameAction> possibleActions = GameLogicUtils.GetAllAvailableActions(boardState);
            int evaluation;

            if (maximizing)
            {
                int maxEvaluation = int.MinValue;
                foreach (GameAction action in possibleActions)
                {
                    GameBoardState afterMove           = gameLogic.ApplyAction(boardState, action);
                    int            afterMoveEvaluation = Evaluate(afterMove, maxTurn, currentDepth + 1, maxDepth);
                    if (afterMoveEvaluation > maxEvaluation)
                    {
                        maxEvaluation = afterMoveEvaluation;
                    }
                }
                evaluation = maxEvaluation;
            }
            else
            {
                int minEvaluation = int.MaxValue;
                foreach (GameAction action in possibleActions)
                {
                    GameBoardState afterMove           = gameLogic.ApplyAction(boardState, action);
                    int            afterMoveEvaluation = Evaluate(afterMove, maxTurn, currentDepth + 1, maxDepth);
                    if (afterMoveEvaluation < minEvaluation)
                    {
                        minEvaluation = afterMoveEvaluation;
                    }
                }
                evaluation = minEvaluation;
            }
            return(evaluation);
        }
Пример #4
0
        public GameAction CalculateComputerMove(GameBoardState gameState, GameDifficulty difficulty)
        {
            int        maxDepth = ToRecursiveDepth(difficulty);
            PlayerTurn maxTurn  = gameState.CurrentTurn;

            List <GameAction> possibleActions = GameLogicUtils.GetAllAvailableActions(gameState);

            int        maxEvaluation = int.MinValue;
            GameAction bestMove      = null;

            foreach (GameAction action in possibleActions)
            {
                GameBoardState afterMove           = gameLogic.ApplyAction(gameState, action);
                int            afterMoveEvaluation = Evaluate(afterMove, maxTurn, 0, maxDepth);
                if (afterMoveEvaluation > maxEvaluation || (afterMoveEvaluation >= maxEvaluation && bestMove == null))
                {
                    maxEvaluation = afterMoveEvaluation;
                    bestMove      = action;
                }
            }
            return(bestMove);
        }
Пример #5
0
        public GameBoardState ApplyAction(GameBoardState boardState, GameAction action)
        {
            PlayerTurn currentTurn       = boardState.CurrentTurn;
            int        currentTurnNumber = boardState.TurnNumber;

            PlayerTurn?[,] currentBoard = boardState.Board;

            PlayerTurn?[,] newBoard = new PlayerTurn?[currentBoard.GetLength(0), currentBoard.GetLength(1)];
            Array.Copy(currentBoard, newBoard, currentBoard.Length);

            if (action is PutPieceAction putPieceAction)
            {
                newBoard[putPieceAction.Position.Y, putPieceAction.Position.X] = currentTurn;
            }
            else if (action is MovePieceAction movePieceAction)
            {
                newBoard[movePieceAction.To.Y, movePieceAction.To.X]     = currentTurn;
                newBoard[movePieceAction.From.Y, movePieceAction.From.X] = null;
            }

            PlayerTurn?winner = null;

            // No need to check if other player is winner
            if (GameLogicUtils.IsWinner(newBoard, currentTurn))
            {
                winner = currentTurn;
            }

            return(new GameBoardState
            {
                TurnNumber = currentTurnNumber + 1,
                Board = newBoard,
                CurrentTurn = GameLogicUtils.Next(currentTurn),
                GameMode = currentTurnNumber < 6 ? GameMode.PUT : GameMode.MOVE,
                Winner = winner
            });
        }
Пример #6
0
        public GameAction CalculateComputerMove(GameBoardState gameState, GameDifficulty difficulty)
        {
            List <GameAction> actions = GameLogicUtils.GetAllAvailableActions(gameState);

            return(actions[rand.Next(0, actions.Count)]);
        }