Exemple #1
0
        public async Task <GameNotification> SendGameActionAsync(GameActionRequest actionRequest)
        {
            GameState gameState = serverState.GetGameState(actionRequest.GameId);

            if (!gameLogic.ValidateGameAction(actionRequest, gameState))
            {
                // TODO: make error messages clearer
                throw new ArgumentException("Invalid move");
            }
            GameState newState = gameLogic.ApplyAction(gameState, actionRequest.Action);

            Player player = GameLogicUtils.GetCurrentPlayer(newState);

            if (player.Type == PlayerType.COMPUTER)
            {
                if (newState.Stage == GameStage.GAME_OVER)
                {
                    return(new GameNotification {
                        NewGameState = newState
                    });
                }
                // Get computer's move and return new state to player
                GameAction computerAction    = gameAI.CalculateComputerMove(newState.BoardState, newState.Difficulty);
                GameState  afterComputerMove = gameLogic.ApplyAction(newState, computerAction);

                serverState.UpdateGameState(afterComputerMove);
                return(new GameNotification {
                    LastAction = computerAction,
                    NewGameState = afterComputerMove
                });
            }
            else
            {
                serverState.UpdateGameState(newState);
                // Notify opponent
                var notification = new GameNotification
                {
                    NewGameState = newState,
                    LastAction   = actionRequest.Action
                };
                await Clients.Client(player.Id).ReceiveGameStateUpdate(notification).ConfigureAwait(false);

                return(notification);
            }
        }
Exemple #2
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);
        }