Esempio n. 1
0
    /// <summary>
    /// When a penguin has no legal moves (i.e. is blocked by other penguins, or is alone on a single isloated tile),
    ///   clicking on it triggers removal of it and the single tile it's standing on from the board.
    /// </summary>
    /// <param name="penguin">Selected penguin to remove</param>
    /// <remarks>
    /// CALLED BY: SubStateMach_MainGame->State_Move_xxx::OnPenguinClicked()
    /// </remarks>
    ///
    public void RemoveUnmovablePenguin(GamePenguin penguin)
    {
        CurrentPlayer.AddFish(penguin.CurrentTile.FishScoreValue); // Player wins fish on this tile

        penguin.CurrentTile.Sink();                                // Animate sinking tile, and then remove it

        ExpungePenguin(penguin, penguinDepartPrefab);              // Remove Penguin

        // Update the internal board the AI uses
        //
        if (IsUsingAI)
        {
            Command.GameMove move = PortmanteauRemovePenguin(penguin.CurrentTile);

            ExecuteMove_Internal(move);
        }

        // TODO: Delete? -- StateParam_MovePending = true;   // Go to animation state while sinking tile anim plays

        // No point in waiting for the tile to vanish, so go directly to "NextPlayer" state
        //
        StateParam_PenguinRemoved = true;
        //
        StateTrigger_NextPlayer();
    }
Esempio n. 2
0
 /// <summary>
 /// Apply a move made by the human user to the AI's internal board
 /// </summary>
 /// <param name="move">"Command.Move" object instantiated from GamePenguin that just moved</param>
 /// <remarks>
 /// CALLED BY: ExecuteHumanMove(), ExecuteAIMove()
 /// </remarks>
 ///
 void ExecuteMove_Internal(Command.GameMove move)
 {
     // If a human just moved, update the internal board the AI uses
     //   (If the AI moved, the board is updated by the AI algorithms, so we need not do it here.)
     //
     m_refAIBoard.UpdateAIBoard(CurrentPlayer.Color, move);
 }
Esempio n. 3
0
    /// <summary>
    /// Remove one of al players' penguins when it can claim a
    ///   whole "island" of tiles
    /// </summary>
    /// <returns>
    /// The total number of fish of the tiles to be added to the player's score
    /// </returns>
    ///
    public int RemovePenguin(Player player, GamePenguin penguin)
    {
        m_refTileMgr.workTiles.Clear();   // Clear "workspace"

        int islandFishTally = TileManager.CheckForIsland(m_refTileMgr, penguin.CurrentTile, m_refTileMgr.workTiles, true);

        if (islandFishTally >= 0)                              // -1 = Penguin not alone on contiguous tiles
        {
            player.AddFish(islandFishTally);                   // Add all fish on local tiles to score

            ExpungePenguin(penguin, penguinDepartPrefab);      // Destroy penguin game object with particle effects

            m_refTileMgr.ExpungeTiles(m_refTileMgr.workTiles); // Sink/Destroy all tiles on penguin's "island"

            // Update the internal board the AI uses -- First apply penguin removal, then turn off the virtual tiles
            //
            if (IsUsingAI)
            {
                Command.GameMove move = PortmanteauRemovePenguin(penguin.CurrentTile);
                //
                ExecuteMove_Internal(move);
                ExpungeTiles_Internal(m_refTileMgr.workTiles);
            }

            // No point in waiting for all tiles to vanish, so go directly to "NextPlayer" state
            //
            StateParam_PenguinRemoved = true;
            //
            StateTrigger_NextPlayer();
        }

        return(islandFishTally);
    }
Esempio n. 4
0
 void MiniMaxDebugInfo(Command.GameMove move, float score)
 {
     if (_debugMode)
     {
         Debug.Log("Checking move: " + move.ToString() + "; HScore = " + score);
     }
 }
Esempio n. 5
0
    /*** Operations on move stack ***/

    public void PushMove(Command.GameMove testMove)
    {
        testMove.PlayMove(this);      // Apply move to internal board

        testMoveStack.Push(testMove); // Save move to the stack

        NextEvalPlayer();             // Advance to next player / ply
    }
Esempio n. 6
0
    /// <summary>
    /// Clear move list and store chosen move to return to GameManager
    /// </summary>
    ///
    void StoreMove(Command.GameMove foundMove, List <Command.GameMove> refMoveList)
    {
        Debug.Assert(foundMove != null);

        refMoveList.Clear();
        refMoveList.Add(foundMove);

        IsThinking = false;
    }
Esempio n. 7
0
    public Command.GameMove PopMove()
    {
        Command.GameMove lastMove = testMoveStack.Pop();   // Retrieve last move

        lastMove.HeuristicScore = GetHeuristicScore();

        lastMove.RollBack(this); // Undo move on internal board

        PrevEvalPlayer();        // Backup one ply

        return(lastMove);
    }
Esempio n. 8
0
    /// <summary>
    /// AI Method 2 -- Give a heuristc "weight" to every tile that can reached next
    ///   move and go there.
    /// </summary>
    /// <remarks>
    /// "Weight" of tile = Fish on tile + Sum of fish on all tiles accessible on next move
    ///    (Because we care about the penguins' mobility, a "sunk" tile = -1, so if a three-fish tile
    ///      is linked to only one other tile, the score with come out negative, and the tile will be avoided)
    /// </remarks>
    ///
    public void OnAI_HeuristicNextMove(List <Command.GameMove> allPossibleMoves)
    {
        // Get a list of all the candidate moves sorted by heuristic "weight"
        //
        m_refBoard.SortMovesHeuristic(allPossibleMoves);

        // Make highest scored move the pending move
        //
        Command.GameMove move = allPossibleMoves[0];
        //
        StoreMove(move, allPossibleMoves);
    }
Esempio n. 9
0
    /// <summary>
    /// After AI selects move and updates the internal board, then animate the move on the Game Board
    /// </summary>
    /// <param name="tile">Destination tile</param>
    /// <remarks>FLOW: AIBrain::MakeMove_***() -> OnExeAIMove() -> ExecuteAIMove()
    /// </remarks>
    ///
    public void ExecuteAIMove(Command.GameMove move)
    {
        ExecuteMove_Internal(move);

        // Simulate a penguin click from AI move
        //
        GamePenguin penguin = m_refTileMgr.tileTable[move.fromTile].CurrentPenguin;

        // Simulate a destination tile click from AI move
        //
        GameTile tile = m_refTileMgr.tileTable[move.toTile];

        // Execute move onscreen
        //
        ExecuteMove_GameWorld(penguin, tile);
    }
Esempio n. 10
0
    /*
     * /// <summary>
     * /// Internal move execution routine
     * /// </summary>
     * /// <param name="tile">Destination tile</param>
     * /// <param name="bHumanMove">Did a human (rather than the AI make this move?)</param>
     * ///
     * void ExecuteMove(GameTile tile, bool bHumanMove)
     * {
     *  if (CurrentPenguin.MoveTo(tile))  // If a legal move was selected, start animating the penguin's move
     *  {
     *      // Player acquires this tile's fish
     *      //
     *      CurrentPlayer.AddFish(CurrentTile.FishScoreValue);
     *
     *      // Start tile sinking animation for the tile just departed
     *      // TODO: *** This may be a bug -- Shouldn't CurrentTile be the *selected* (destination) tile??
     *      //
     *      CurrentTile.Sink();
     *
     *      // If a human just moved, update the internal board the AI uses
     *      //   (If the AI moved, the board is updated by the AI algorithms, so we need not do it here.)
     *      //
     *      if (IsUsingAI && bHumanMove)
     *      {
     *          m_refAIBoard.UpdateAIBoard(CurrentPlayer.Color, PortmanteauMovePenguin(CurrentTile, tile));
     *      }
     *
     *      // Go to "MovePending" state until all animations complete
     *      //
     *      StateParam_AIMove = false;
     *      StateParam_MovePending = true;
     *
     *      // Clear selections
     *      //
     *      CurrentPenguin = null;
     *      CurrentTile = null;
     *  }
     *  // Else continue to wait for a valid tile to be clicked
     * }
     */

    /// <summary>
    /// If user selected a valid normal penguin move, execute that move, both onscreen and internally
    /// </summary>
    /// <param name="tile">Destination tile</param>
    /// <remarks>
    /// CALLED BY: SubStateMach_MainGame->State_Move_Human::OnTileClicked()
    /// </remarks>
    ///
    public void ExecuteHumanMove(GameTile tile)
    {
        if (CurrentPenguin.ValidateDestination(tile))   // First check that selected tile is a legal move
        {
            ExecuteMove_GameWorld(CurrentPenguin, tile);

            if (IsUsingAI)   // Only need to do this bit if AI is in this Game
            {
                // Instantiate a command to send to the internal board
                //
                Command.GameMove move = PortmanteauMovePenguin(CurrentPenguin.CurrentTile, tile);

                // Tell the internal board to update to reflect the new move
                //
                ExecuteMove_Internal(move);
            }
        }
    }
Esempio n. 11
0
 // After a move the user has just made
 //
 public void ApplyMove(Command.GameMove move)
 {
     move.PlayMove(this);    // Apply move to internal board (Already done in Game World)
 }
Esempio n. 12
0
    /// <summary>
    /// Accept move just made by human player and apply it to AI board
    /// </summary>
    /// <param name=""></param>
    /// <param name=""></param>
    ///
    public void UpdateAIBoard(GamePenguin.PenguinColor playerColor, Command.GameMove move)
    {
        Debug.Assert(playerColor == colorCurrentPlayer); // Board should be on current player

        ApplyMove(move);                                 // Apply move to AI board ("move" object is polymorphic)
    }
Esempio n. 13
0
 /// <summary>
 /// Apply AI's move to the Game Board
 /// </summary>
 /// <param name="move">AI move just applied to internal board</param>
 ///
 public void OnAIMove_Apply(Command.GameMove move)
 {
 }