Esempio n. 1
0
        public override GameMoveType GetNextMove(GameState gameState, IGameInteractionService interactionService)
        {
            var move = base.GetNextMove (gameState, interactionService);

            // Sleep to allow better visualization.
            // TODO: Sleep? Or make async?
            Thread.Sleep (1000);

            return move;
        }
Esempio n. 2
0
        public GameMoveType GetNextMove(GameState gameState, IGameInteractionService interactionService)
        {
            while(true)
            {
                var move = GameMoveType.None;
                var key = Console.ReadKey ().Key;

                switch(key)
                {
                // Quit the program if ESC is pressed.
                case ConsoleKey.Escape:
                    if(this.GameQuitRequested != null)
                    {
                        this.GameQuitRequested ();
                    }
                    return GameMoveType.None;

                case ConsoleKey.UpArrow:
                    // Arrow up = move the item below the empty space UP.
                    move = GameMoveType.MoveItemBelow;
                    break;

                case ConsoleKey.DownArrow:
                    // Arrow down = move the item above the empty space DOWN.
                    move = GameMoveType.MoveItemAbove;
                    break;

                case ConsoleKey.LeftArrow:
                    // Arrow left = move the item right of the empty space LEFT.
                    move = GameMoveType.MoveItemRight;
                    break;

                case ConsoleKey.RightArrow:
                    // Arrow right = move the item left of the empty space RIGHT.
                    move = GameMoveType.MoveItemLeft;
                    break;

                default:
                    Console.Beep ();
                    break;
                }

                if(interactionService.CanMove(gameState.GameField, move))
                {
                    return move;
                }
            }
        }
Esempio n. 3
0
 public GameMoveType GetNextMove(GameState gameState, IGameInteractionService interactionService)
 {
     return GameMoveType.None;
 }
Esempio n. 4
0
        public virtual GameMoveType GetNextMove(GameState gameState, IGameInteractionService interactionService)
        {
            var loggingService = ServiceContainer.Resolve<ILoggingService> ();
            var emptyLocation = gameState.GameField.GetUnusedItemLocation ();

            // Prepare a path to the target treasure if it hasn't happened yet. The AI decides first what path it will take, then it will follow it until
            // it fails or until it reaches the treasure. The current path is reset in UpdatePlayer() because this means that it's the other player's turn.
            if (this.currentPath == null || this.currentPath.Count <= 0)
            {
                #if EXTENSIVE_LOGGING
                loggingService.Log ("AI calculates a new path.");
                #endif

                // Populate the path finding algorithm and start at the unused item location.
                var populatedGrid = AIHelpers.PreparePathGrid (gameState.GameField, emptyLocation, gameState.GetActiveCard());

                // Get the location of the current active card. This may return NULL if the AI cannot remember the location.
                GridLocation currentTreasureLocation = this.GetPresumedLocationOfTreasure(gameState.GetActiveCard());

                // The AI has no clue where the active treasure is. It will pick a random location to move to.
                if (currentTreasureLocation == null)
                {
                    currentTreasureLocation = this.GetRandomLocationAvoidingTreasures (gameState);
                    #if EXTENSIVE_LOGGING
                    loggingService.Log ("AI has no clue where '{0}' is located. Will move to random location {1}.", gameState.GetActiveCard(), currentTreasureLocation);
                    #endif
                }

                // Log how AI calculates the distances.
                #if EXTENSIVE_LOGGING
                loggingService.Log ("AI sees the grid with these distances, starting at {0} to reach (presumed!) {1} at {2}:", emptyLocation, gameState.GetActiveCard(), currentTreasureLocation);
                for (int row = 0; row < populatedGrid.Rows; row++)
                {
                    string s = string.Empty;
                    for (int col = 0; col < populatedGrid.Columns; col++)
                    {
                        s += populatedGrid.GetItem (row, col).ToString ("000") + " |";
                    }

                    loggingService.Log (s);
                }
                #endif

                // Find the path from the current unused location to the treasure, avoiding all other treasures if possible.
                var pathList = AIHelpers.GetPathToLocation (gameState.GameField, populatedGrid, emptyLocation, currentTreasureLocation, gameState.GetActiveCard());

                // We need to reverse it to get the corret order when copying onto a stack.
                pathList.Reverse ();
                // Copy the path onto a stack for better processing.
                this.currentPath = new Stack<GridLocation>(pathList);
                pathList = null;

                // Log the path the AI will go.
                #if EXTENSIVE_LOGGING
                loggingService.Log ("AI's path to (presumed!) {0}:", gameState.GetActiveCard());
                for (int row = 0; row < populatedGrid.Rows; row++)
                {
                    string s = string.Empty;
                    for (int col = 0; col < populatedGrid.Columns; col++)
                    {

                        var isPath = (from pathItem in this.currentPath where pathItem.Row == row && pathItem.Column == col select pathItem).Any ();
                        if (isPath)
                        {
                            s += populatedGrid.GetItem (row, col).ToString ("000") + "X|";
                        } else
                        {
                            s += populatedGrid.GetItem (row, col).ToString ("000") + " |";
                        }
                    }

                    loggingService.Log (s);
                }
                #endif

                // A correct path has to contain at least two locations: the start and the target.
                if (this.currentPath.Count < 2)
                {
                    // The AI failed and could not find a path from the unused location to the active treasure. Stupid AI. Should not happen and means there is a problem in the algorithm.
                    loggingService.Log ("AI path is invalid. Path length: [{0}]. Next move will be random.", this.currentPath.Count.ToString ());
                    // Return a random move.
                    var randomMove = AIHelpers.GetRandomMove (gameState.GameField, emptyLocation, gameState.GetActiveCard());
                    loggingService.Log ("AI moves randomly: {0}", randomMove);

                    // Bail out.
                    return randomMove;
                }
                else
                {
                    // The found path is valid. Remove the first entry because this is the start location. No need to move, we're already there.
                    // TODO: Verify that if the next treaure is the one that is currently active, the AI will spot that it is already uncovered.
                    this.currentPath.Pop ();
                }
            }

            // Here the current path has either just been populated or we're following a previously populated path.
            // Get next location to move to.
            var moveLocation = this.currentPath.Pop ();
            // Remember that we visited that location. We want to avoid it for the next couple of moves.
            this.lastVisitedLocations.Enqueue (moveLocation);
            // Remember the treasure that has just been discoverd fully.
            this.LearnAboutTreasure (gameState.GameField.GetItem(moveLocation).Treasure, moveLocation);
            // Convert location to a move.
            var move = AIHelpers.GetMoveToAdjacentLocation (emptyLocation, moveLocation);
            loggingService.Log ("AI will move from [{0}] to [{1}], this is a move of type [{2}].", emptyLocation, moveLocation, move);

            // The AI forgets a bit after each move.
            this.ForgetTreasures ();

            return move;
        }
Esempio n. 5
0
        public override GameMoveType GetNextMove(GameState gameState, IGameInteractionService interactionService)
        {
            var move = base.GetNextMove (gameState, interactionService);

            return move;
        }