예제 #1
0
        /// <summary>
        /// Undoes the last move, restoring the game to its state before the move was applied.
        /// </summary>
        public void UndoLastMove()
        {
            OthelloMove m = mMoveHistory.Last();

            // Note: there is a bug in this code.
            if (!m.IsPass)
            {
                // Reset the board at the move's position.
                SetPlayerAtPosition(m.Position, 0);

                // Iterate through the move's recorded flipsets.
                foreach (var flipSet in mFlipSets.Last())
                {
                    BoardPosition pos = m.Position;
                    // For each flipset, walk along the flipset's direction resetting pieces.
                    for (int i = 0; i < flipSet.Count; i++)
                    {
                        pos = pos.Translate(flipSet.Direction);
                        // At this moment, CurrentPlayer is actually the enemy of the move that
                        // we are undoing, whose pieces we must restore.
                        SetPlayerAtPosition(pos, CurrentPlayer);
                    }
                }

                // Check to see if the second-to-last move was a pass; if so, set PassCount.
                if (mMoveHistory.Count > 1 && mMoveHistory[mMoveHistory.Count - 2].IsPass)
                {
                    PassCount = 1;
                }
            }
            else
            {
                PassCount--;
            }
            // Reset the remaining game state.
            SetAdvantage();
            mCurrentPlayer = -mCurrentPlayer;
            mMoveHistory.RemoveAt(mMoveHistory.Count - 1);
            mFlipSets.RemoveAt(mFlipSets.Count - 1);
        }
예제 #2
0
        /// <summary>
        /// Undoes the last move, restoring the game to its state before the move was applied.
        /// </summary>
        public void UndoLastMove()
        {
            OthelloMove m = MoveHistory[MoveHistory.Count - 1];

            // Note: there is a bug in this code.
            if (!m.IsPass)
            {
                // Reset the board at the move's position.
                mBoard[m.Position.Row, m.Position.Col] = 0;
                Value += mCurrentPlayer;

                // Iterate through the move's recorded flipsets.
                foreach (var flipSet in m.FlipSets)
                {
                    BoardPosition pos = m.Position;
                    // For each flipset, walk along the flipset's direction resetting pieces.
                    for (int i = 1; i <= flipSet.Count; i++)
                    {
                        pos = pos.Translate(flipSet.RowDelta, flipSet.ColDelta);
                        mBoard[pos.Row, pos.Col] = (sbyte)mCurrentPlayer;
                        Value += 2 * mCurrentPlayer;
                    }
                }

                // Check to see if the second-to-last move was a pass; if so, set PassCount.
                if (MoveHistory.Count > 1 && MoveHistory[MoveHistory.Count - 2].IsPass)
                {
                    PassCount = 1;
                }
            }
            else
            {
                PassCount--;
            }
            // Reset the remaining game state.
            mCurrentPlayer = -mCurrentPlayer;
            MoveHistory.RemoveAt(MoveHistory.Count - 1);
        }
예제 #3
0
        public void ApplyMove(OthelloMove m)
        {
            if (m == null)
            {
                throw new ArgumentNullException(nameof(m));
            }

            List <FlipSet> currentFlips = new List <FlipSet>();

            m.Player = CurrentPlayer;
            // If the move is a pass, then we do very little.
            if (m.IsPass)
            {
                PassCount++;
            }
            else
            {
                PassCount = 0;
                // Otherwise update the board at the move's position with the current player.
                SetPlayerAtPosition(m.Position, CurrentPlayer);
                mAdvantageValue += mCurrentPlayer;

                // Iterate through all 8 directions radially from the move's position.
                foreach (BoardDirection dir in BoardDirection.CardinalDirections)
                {
                    // Repeatedly move in the selected direction, as long as we find "enemy" squares.
                    BoardPosition newPos = m.Position;
                    int           steps  = 0;
                    do
                    {
                        newPos = newPos.Translate(dir);
                        steps++;
                    } while (PositionIsEnemy(newPos, CurrentPlayer));

                    // This is a valid direction of flips if we moved at least 2 squares, and ended in bounds and on a
                    // "friendly" square.
                    if (steps > 1 && GetPlayerAtPosition(newPos) == CurrentPlayer)
                    {
                        // Record a FlipSet for this direction
                        currentFlips.Add(new FlipSet(dir, (sbyte)(steps - 1)));

                        var reverse = -dir;
                        // Repeatedly walk back the way we came, updating the board with the current player's piece.
                        do
                        {
                            newPos = newPos.Translate(reverse);
                            SetPlayerAtPosition(newPos, CurrentPlayer);
                            mAdvantageValue += 2 * mCurrentPlayer;

                            steps--;
                        }while (steps > 1);
                    }
                }
            }

            // Update the rest of the board state.
            mCurrentPlayer = -mCurrentPlayer;
            SetAdvantage();
            mMoveHistory.Add(m);
            mFlipSets.Add(currentFlips);
        }
예제 #4
0
        /// <summary>
        /// Applies the given move to the board state.
        /// </summary>
        /// <param name="m">a move that is assumed to be valid</param>
        public void ApplyMove(OthelloMove m)
        {
            // If the move is a pass, then we do very little.
            if (m.IsPass)
            {
                PassCount++;
            }
            else
            {
                PassCount = 0;
                // Otherwise update the board at the move's position with the current player.
                mBoard[m.Position.Row, m.Position.Col] = (sbyte)mCurrentPlayer;
                Value += mCurrentPlayer;

                // Iterate through all 8 directions radially from the move's position.
                for (int rDelta = -1; rDelta <= 1; rDelta++)
                {
                    for (int cDelta = -1; cDelta <= 1; cDelta++)
                    {
                        if (rDelta == 0 && cDelta == 0)
                        {
                            continue;
                        }

                        // Repeatedly move in the selected direction, as long as we find "enemy" squares.
                        BoardPosition newPos = m.Position;
                        int           steps  = 0;
                        do
                        {
                            newPos = newPos.Translate(rDelta, cDelta);
                            steps++;
                        } while (PositionInBounds(newPos) && PositionIsEnemy(newPos, mCurrentPlayer));

                        // This is a valid direction of flips if we moved at least 2 squares, and ended in bounds and on a
                        // "friendly" square.
                        if (steps > 1 && PositionInBounds(newPos) && mBoard[newPos.Row, newPos.Col] == mCurrentPlayer)
                        {
                            // Record this direction in the move's flipsets so the move can be undone.
                            m.AddFlipSet(
                                new OthelloMove.FlipSet()
                            {
                                RowDelta = rDelta,
                                ColDelta = cDelta,
                                Count    = steps - 1
                            });
                            // The FlipSet constructor takes no parameters; this syntax allows us to construct a FlipSet
                            // and initialize many of its properties in one expression.

                            // Repeatedly walk back the way we came, updating the board with the current player's piece.
                            newPos = newPos.Translate(-rDelta, -cDelta);
                            while (steps > 1)
                            {
                                mBoard[newPos.Row, newPos.Col] = (sbyte)mCurrentPlayer;
                                Value += 2 * mCurrentPlayer;

                                newPos = newPos.Translate(-rDelta, -cDelta);
                                steps--;
                            }
                        }
                    }
                }
            }
            // Update the rest of the board state.
            mCurrentPlayer = -mCurrentPlayer;
            MoveHistory.Add(m);
        }