/// <summary>Returns a list of legal moves from all pieces this turn.</summary>
        /// <param name="optionalJumping">Overrides the game's OptionalJumping parameter for the enumeration.</param>
        /// <returns>A list of legal moves.</returns>
        public CheckersMove[] EnumLegalMoves(bool optionalJumping)
        {
            if ((!isPlaying) && (winner == 0))
            {
                throw new InvalidOperationException("Operation requires game to be playing.");
            }
            Stack     incompleteMoves = new Stack();
            ArrayList moves           = new ArrayList();

            foreach (CheckersPiece piece in EnumMovablePieces(optionalJumping))
            {
                incompleteMoves.Push(BeginMove(piece));
            }
            while (incompleteMoves.Count > 0)
            {
                CheckersMove move = (CheckersMove)incompleteMoves.Pop();
                foreach (Point location in move.EnumMoves(optionalJumping))
                {
                    CheckersMove nextMove = move.Clone();
                    if (!nextMove.Move(location))
                    {
                        continue;
                    }
                    if (nextMove.CanMove)
                    {
                        incompleteMoves.Push(nextMove);
                    }
                    if (!nextMove.MustMove)
                    {
                        moves.Add(nextMove);
                    }
                }
            }
            return((CheckersMove[])moves.ToArray(typeof(CheckersMove)));
        }
        private CheckersMove IsMoveValidCore(CheckersPiece piece, Point[] path)
        {
            // Failsafe .. be sure piece is valid
            if (piece == null)
            {
                throw new ArgumentNullException("piece");
            }
            if (!pieces.Contains(piece))
            {
                throw new ArgumentException("Argument 'piece' must be a piece in play to the current game.");
            }
            // Be sure piece can be moved
            if (!CanMovePiece(piece))
            {
                throw new ArgumentException("Checkers piece cannot be moved on this turn.", "piece");
            }
            CheckersMove move = CheckersMove.FromPath(this, piece, path);

            if (!move.Moved)
            {
                return(null);         // No movement
            }
            if (move.MustMove)
            {
                return(null);       // A move must yet be made
            }
            // Success
            return(move);
        }
 /// <summary>Returns whether or not a move is valid.</summary>
 /// <param name="move">The CheckersMove object to check.</param>
 /// <returns>True if the move is valid.</returns>
 public bool IsValidMove(CheckersMove move)
 {
     if (move == null)
     {
         return(false);
     }
     return(IsValidMove(move.Piece, move.Path));
 }
        /// <summary>Moves a Checkers piece on the board.</summary>
        /// <param name="piece">The checkers piece to move.</param>
        /// <param name="path">The the location for the piece to be moved to, and the path taken to get there.</param>
        /// <returns>True if the piece was moved successfully.</returns>
        public bool MovePiece(CheckersPiece piece, Point[] path)
        {
            if (isReadOnly)
            {
                throw new InvalidOperationException("Game is read only.");
            }
            if (!isPlaying)
            {
                throw new InvalidOperationException("Operation requires game to be playing.");
            }
            // Check for valid move
            CheckersMove move = IsMoveValidCore(piece, path);

            // Remove jumped pieces
            foreach (CheckersPiece jumped in move.Jumped)
            {
                if (board[jumped.Location.X, jumped.Location.Y] == jumped)
                {
                    board[jumped.Location.X, jumped.Location.Y] = null;
                }
                pieces.Remove(jumped);
                jumped.RemovedFromPlay();
            }
            // Move the piece on board
            board[piece.Location.X, piece.Location.Y]             = null;
            board[move.CurrentLocation.X, move.CurrentLocation.Y] = piece;
            piece.Moved(move.CurrentLocation);
            // King a pawn if reached other end of board
            if (move.Kinged)
            {
                piece.Promoted();
            }
            // Remember last move
            lastMove = move;
            // Update player's turn
            int prevTurn = turn;

            if (++turn > PlayerCount)
            {
                turn = 1;
            }
            // Check for win by removal of opponent's pieces or by no turns available this turn
            if ((EnumPlayerPieces(prevTurn).Length == 0) || (EnumMovablePieces().Length == 0))
            {
                DeclareWinner(prevTurn);
            }
            else
            if (TurnChanged != null)
            {
                TurnChanged(this, EventArgs.Empty);
            }
            return(true);
        }
 /// <summary>Moves a Checkers piece on the board.</summary>
 /// <param name="move">The movement object to which the piece will move to.</param>
 /// <returns>True if the piece was moved successfully.</returns>
 public bool MovePiece(CheckersMove move)
 {
     if (isReadOnly)
     {
         throw new InvalidOperationException("Game is read only.");
     }
     if (move == null)
     {
         return(false);
     }
     return(MovePiece(move.Piece, move.Path));
 }
        /// <summary>Begins the checkers game.</summary>
        public void Play()
        {
            if (isReadOnly)
            {
                throw new InvalidOperationException("Game is read only.");
            }
            if (isPlaying)
            {
                throw new InvalidOperationException("Game has already started.");
            }
            Stop();
            isPlaying = true;

            for (int y = BoardSize.Height - 1; y >= 5; y--)
            {
                for (int x = 0; x < BoardSize.Width; x++)
                {
                    if ((x % 2) == (y % 2))
                    {
                        continue;
                    }
                    CheckersPiece piece = new CheckersPiece(this, 1, CheckersRank.Pawn, new Point(x, y), true);
                    board[x, y] = piece;
                    pieces.Add(piece);
                }
            }
            for (int y = 0; y < 3; y++)
            {
                for (int x = 0; x < BoardSize.Width; x++)
                {
                    if ((x % 2) == (y % 2))
                    {
                        continue;
                    }
                    CheckersPiece piece = new CheckersPiece(this, 2, CheckersRank.Pawn, new Point(x, y), true);
                    board[x, y] = piece;
                    pieces.Add(piece);
                }
            }

            // Set player's turn
            turn     = firstMove;
            lastMove = null;
            if (GameStarted != null)
            {
                GameStarted(this, EventArgs.Empty);
            }
        }
        /// <summary>Returns a list of movable pieces this turn.</summary>
        /// <param name="optionalJumping">Overrides the game's OptionalJumping parameter for the enumeration.</param>
        /// <returns>A list of pieces that can be moved this turn.</returns>
        public CheckersPiece[] EnumMovablePieces(bool optionalJumping)
        {
            if ((!isPlaying) && (winner == 0))
            {
                throw new InvalidOperationException("Operation requires game to be playing.");
            }
            ArrayList movable = new ArrayList();

            foreach (CheckersPiece piece in EnumPlayerPieces(turn))
            {
                CheckersMove move = new CheckersMove(this, piece, false);
                if (move.EnumMoves(optionalJumping).Length != 0)
                {
                    movable.Add(piece);
                }
            }
            return((CheckersPiece[])movable.ToArray(typeof(CheckersPiece)));
        }
示例#8
0
        // Métodos públicos
        #region Publicos

        /// <summary>
        /// Cria um movimento duplicado para que diferentes caminhos possam ser testados
        /// </summary>
        /// <returns>Novo movimento gerado</returns>
        public CheckersMove Clone()
        {
            // Clona o movimento
            CheckersMove move = new CheckersMove(this._Game, this._Piece, false)
            {
                _InitialGame     = this._InitialGame,
                _InitialPiece    = this._InitialPiece,
                _Board           = (CheckersPiece[, ]) this._Board.Clone(),
                _CurrentLocation = this._CurrentLocation,
                _Jumped          = (ArrayList)this._Jumped.Clone(),
                _Kinged          = this._Kinged,
                _Path            = (ArrayList)this._Path.Clone(),
                _CannotMove      = this._CannotMove
            };

            // Retorna o movimento clonado
            return(move);
        }
示例#9
0
        // Métodos internos
        #region Internos

        /// <summary>Cria um movimento a partir do caminho passado</summary>
        /// <param name="game">Jogo para o qual será criado o movimento</param>
        /// <param name="piece">A peça que será movida</param>
        /// <param name="path">O caminho pelo qual a peça será movida</param>
        /// <returns>O movimento resultante</returns>
        internal static CheckersMove FromPath(CheckersGame game, CheckersPiece piece, Point[] path)
        {
            // Cria um novo movimento
            CheckersMove move = new CheckersMove(game, piece, true);

            // Para cada casa no caminho passado
            foreach (Point p in path)
            {
                // Se não conseguiu mover a peça
                if (move.Move(p) == false)
                {
                    // Retorna null
                    return(null);
                }
            }

            // Se moveu a peça por todas localizações, retorna o movimento
            return(move);
        }
        /// <summary>Creates a duplicate Checkers game object.</summary>
        /// <returns>The new Checkers move object.</returns>
        public CheckersGame Clone()
        {
            CheckersGame game = new CheckersGame(optionalJumping);

            game.isReadOnly = isReadOnly;
            game.isPlaying  = isPlaying;
            game.firstMove  = firstMove;
            game.turn       = turn;
            game.winner     = winner;
            game.pieces     = new CheckersPieceCollection();
            game.board      = new CheckersPiece[BoardSize.Width, BoardSize.Height];
            foreach (CheckersPiece piece in pieces)
            {
                CheckersPiece newPiece = new CheckersPiece(game, piece.Player, piece.Rank, piece.Location, piece.InPlay);
                game.board[newPiece.Location.X, newPiece.Location.Y] = newPiece;
                game.pieces.Add(newPiece);
            }
            int lastMovePieceIndex = ((lastMove != null) ? (pieces.IndexOf(lastMove.Piece)) : (-1));

            game.lastMove = ((lastMovePieceIndex != -1) ? (CheckersMove.FromPath(game, game.pieces[lastMovePieceIndex], lastMove.Path)) : (null));
            return(game);
        }
 /// <summary>Stops a decided game or forces a game-in-progress to stop prematurely with no winner.</summary>
 public void Stop()
 {
     if (isReadOnly)
     {
         throw new InvalidOperationException("Game is read only.");
     }
     isPlaying = false;
     pieces.Clear();
     for (int y = 0; y < BoardSize.Height; y++)
     {
         for (int x = 0; x < BoardSize.Width; x++)
         {
             board[x, y] = null;
         }
     }
     lastMove = null;
     winner   = 0;
     turn     = 0;
     if (GameStopped != null)
     {
         GameStopped(this, EventArgs.Empty);
     }
 }