Esempio n. 1
0
        /// <summary>
        /// Calculate the best position for game AI to move according to current chessboard state.
        /// </summary>
        /// <param name="currentState">Current state of the chessboard.</param>
        /// <param name="playerMark">Chess piece mark of the player to move.</param>
        /// <param name="rowIndex">Row index of the best position to move calculated by Min-Max-Pruning.</param>
        /// <param name="columnIndex">Column index of the best position to move calculated by Min-Max-Pruning.</param>
        /// <remarks>
        /// The "player" here doesn't mean the human player of this game, it only means either AI or the player of this game.
        /// </remarks>
        public static void GetBestPosition(Chessboard currentState, ChessPiece playerMark, out int rowIndex, out int columnIndex)
        {
            // "out" parameter must be assigned.
            rowIndex    = 0;
            columnIndex = 0;

            // Get the opponent's mark.
            ChessPiece opponentMark = playerMark == ChessPiece.X ? ChessPiece.O : ChessPiece.X;

            // Initialize the "max" to int.MinValue.
            int max = int.MinValue;

            // Iterate through every blank cell for current player.
            for (int playerRowIndex = 0; playerRowIndex < Chessboard.Size; playerRowIndex++)
            {
                for (int playerColumnIndex = 0; playerColumnIndex < Chessboard.Size; playerColumnIndex++)
                {
                    if (currentState[playerRowIndex, playerColumnIndex] == ChessPiece.Blank)
                    {
                        // Make a deep copy of current state and put the player mark in the blank cell of the deep copy.
                        Chessboard nextStep = currentState.Copy();
                        nextStep.AddChessPiece(playerRowIndex, playerColumnIndex, playerMark);

                        // Initialize the "min" to int.MaxValue.
                        int min = int.MaxValue;

                        // Iterate through every blank cell for current player's opponent.
                        for (int opponentRowIndex = 0; opponentRowIndex < Chessboard.Size; opponentRowIndex++)
                        {
                            for (int opponentColumnIndex = 0; opponentColumnIndex < Chessboard.Size; opponentColumnIndex++)
                            {
                                if (nextStep[opponentRowIndex, opponentColumnIndex] == ChessPiece.Blank)
                                {
                                    // Make a deep copy of current state and put the opponent's mark in the blank cell of the deep copy.
                                    Chessboard nextNextStep = nextStep.Copy();
                                    nextNextStep.AddChessPiece(opponentRowIndex, opponentColumnIndex, opponentMark);

                                    // Evaluate the state according to the player score and opponent score.
                                    int stateScore = PlayerScore(nextNextStep, playerMark) - OpponentScore(nextNextStep, opponentMark);

                                    // Keep tracking the min value.
                                    if (stateScore < min)
                                    {
                                        min = stateScore;
                                    }
                                }
                            }
                        }

                        // If min > max, then current (playerRowIndex, playerColumnIndex) is better than any other cell searched before.
                        if (min > max)
                        {
                            max         = min;
                            rowIndex    = playerRowIndex;
                            columnIndex = playerColumnIndex;
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Returns a deep copy of the input <see cref="Chessboard" /> will all blank cells are filled with the specified mark.
        /// </summary>
        /// <param name="chessboard">The input (original) <see cref="Chessboard" />.</param>
        /// <param name="mark">The chess piece mark to fill the blank cells.</param>
        /// <returns>A deep copy of the input <see cref="Chessboard" /> will all blank cells are filled with the specified mark.</returns>
        private static Chessboard FillChessboard(Chessboard chessboard, ChessPiece mark)
        {
            Chessboard filledChessboard = chessboard.Copy();

            for (int i = 0; i < Chessboard.Size; i++)
            {
                for (int j = 0; j < Chessboard.Size; j++)
                {
                    if (filledChessboard[i, j] == ChessPiece.Blank)
                    {
                        filledChessboard.AddChessPiece(i, j, mark);
                    }
                }
            }

            return(filledChessboard);
        }