Beispiel #1
0
        public BasePiece GetPiece(ChessPieceCoord from)
        {
            if (!from.IsValid())
            {
                return(null);
            }

            return(Board[from.X + from.Y * Chess.BoardSize]);
        }
Beispiel #2
0
        public bool CanAttack(ChessColor attacker, ChessPieceCoord victim)
        {
            for (uint x = 0; x < Chess.BoardSize; x++)
            {
                for (uint y = 0; y < Chess.BoardSize; y++)
                {
                    var piece = Board[x + y * Chess.BoardSize];
                    if (piece == null)
                    {
                        continue;
                    }

                    if (piece.Color != attacker)
                    {
                        continue;
                    }

                    if (piece.CanAttack(victim))
                    {
                        // the knight can jump over other pieces and the pawn can only attack a single space
                        if (piece.Type == ChessPieceType.Knight || piece.Type == ChessPieceType.Pawn)
                        {
                            return(true);
                        }

                        var range = Chess.PieceOffsets[piece.Type];
                        for (var i = 0; i < range.Count; i++)
                        {
                            var from = piece.Coord;
                            var to   = new ChessPieceCoord(from);

                            while (true)
                            {
                                to.MoveOffset(range[i]);
                                if (!to.IsValid())
                                {
                                    break;
                                }

                                var toPiece = GetPiece(to);
                                if (toPiece != null)
                                {
                                    if (to.Equals(victim))
                                    {
                                        return(true);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #3
0
        public ChessMoveResult DoMove(ChessColor color, ChessPieceCoord from, ChessPieceCoord to)
        {
            if (!from.IsValid())
            {
                return(ChessMoveResult.BadMoveDestination);
            }
            if (!to.IsValid())
            {
                return(ChessMoveResult.BadMoveDestination);
            }

            if (Turn != color)
            {
                return(ChessMoveResult.BadMoveNotYourTurn);
            }

            var fromPiece = GetPiece(from);

            if (fromPiece == null)
            {
                return(ChessMoveResult.BadMoveNoPiece);
            }

            if (fromPiece.Color != color)
            {
                return(ChessMoveResult.BadMoveNotYours);
            }

            var storage = new List <ChessMove>();

            GenerateMoves(fromPiece, true, storage);

            ChessMove foundMove = null;

            foreach (var move in storage)
            {
                if (move.From.Equals(from) && move.To.Equals(to))
                {
                    foundMove = move;
                    break;
                }
            }

            // if this fails the client and server failed to find a common valid move
            if (foundMove == null)
            {
                //return ChessMoveResult.BadMoveDestination;
                return(ChessMoveResult.BadMoveInvalidCommand);
            }

            return(FinalizeMove(foundMove));
        }
Beispiel #4
0
        public BasePiece AddPiece(ChessColor color, ChessPieceType type, uint x, uint y)
        {
            var to = new ChessPieceCoord((int)x, (int)y);

            Debug.Assert(to.IsValid());

            BasePiece piece = null;

            switch (type)
            {
            case ChessPieceType.Pawn:
                piece = new PawnPiece(color, to);
                break;

            case ChessPieceType.Rook:
                piece = new RookPiece(color, to);
                break;

            case ChessPieceType.Knight:
                piece = new KnightPiece(color, to);
                break;

            case ChessPieceType.Bishop:
                piece = new BishopPiece(color, to);
                break;

            case ChessPieceType.Queen:
                piece = new QueenPiece(color, to);
                break;

            case ChessPieceType.King:
                piece = new KingPiece(color, to);
                break;

            default:
                Debug.Assert(false);
                break;
            }

            return(Board[x + y * Chess.BoardSize] = piece);
        }
Beispiel #5
0
        public void GenerateMoves(BasePiece piece, bool single, List <ChessMove> storage)
        {
            var color = piece.Color;

            if (piece.Type == ChessPieceType.Pawn)
            {
                // single
                var from = new ChessPieceCoord(piece.Coord);
                var to   = new ChessPieceCoord(from);
                to.MoveOffset(Chess.PawnOffsets[(int)color, 0]);

                if (GetPiece(to) == null)
                {
                    BuildMove(storage, ChessMoveFlag.Normal, color, piece.Type, from, to);

                    // second
                    to = new ChessPieceCoord(from);
                    to.MoveOffset(Chess.PawnOffsets[(int)color, 1]);

                    if (GetPiece(to) == null && from.Rank == (color == ChessColor.White ? 2 : 7))
                    {
                        BuildMove(storage, ChessMoveFlag.BigPawn, color, piece.Type, from, to);
                    }
                }

                // capture
                for (uint i = 2; i < 4; i++)
                {
                    to = new ChessPieceCoord(from);
                    to.MoveOffset(Chess.PawnOffsets[(int)color, i]);
                    if (!to.IsValid())
                    {
                        continue;
                    }

                    var toPiece = GetPiece(to);
                    if (toPiece != null && toPiece.Color != color)
                    {
                        BuildMove(storage, ChessMoveFlag.Capture, color, piece.Type, from, to);
                    }
                    else if (to.Equals(EnPassantCoord))
                    {
                        BuildMove(storage, ChessMoveFlag.EnPassantCapture, color, piece.Type, from, EnPassantCoord);
                    }
                }
            }
            else
            {
                var range = Chess.PieceOffsets[piece.Type];
                for (var i = 0; i < range.Count; i++)
                {
                    var from = piece.Coord;
                    var to   = new ChessPieceCoord(from);

                    while (true)
                    {
                        to.MoveOffset(range[i]);
                        if (!to.IsValid())
                        {
                            break;
                        }

                        var toPiece = GetPiece(to);
                        if (toPiece != null)
                        {
                            if (toPiece.Color != color)
                            {
                                BuildMove(storage, ChessMoveFlag.Capture, color, piece.Type, from, to);
                            }
                            break;
                        }

                        BuildMove(storage, ChessMoveFlag.Normal, color, piece.Type, from, to);

                        // Knights and Kings can't move more than once
                        if (piece.Type == ChessPieceType.Knight || piece.Type == ChessPieceType.King)
                        {
                            break;
                        }
                    }
                }
            }

            // only check for castling during full board generation or for a single king
            if (!single || piece.Type == ChessPieceType.King)
            {
                if ((Castling[(int)color] & ChessMoveFlag.KingSideCastle | ChessMoveFlag.QueenSideCastle) != 0)
                {
                    var king      = GetPiece(color, ChessPieceType.King);
                    var kingCoord = king.Coord;

                    var opColor = Chess.InverseColor(color);

                    if ((Castling[(int)color] & ChessMoveFlag.KingSideCastle) != 0)
                    {
                        var castlingToK = new ChessPieceCoord(kingCoord);    // destination king
                        castlingToK.MoveOffset(2, 0);
                        var castlingToR = new ChessPieceCoord(kingCoord);    // destination rook
                        castlingToR.MoveOffset(1, 0);

                        if (GetPiece(castlingToR) == null &&
                            GetPiece(castlingToK) == null &&
                            !CanAttack(opColor, kingCoord) &&
                            !CanAttack(opColor, castlingToR) &&
                            !CanAttack(opColor, castlingToK))
                        {
                            BuildMove(storage, ChessMoveFlag.KingSideCastle, color, ChessPieceType.King, kingCoord, castlingToK);
                        }
                    }

                    if ((Castling[(int)color] & ChessMoveFlag.QueenSideCastle) != 0)
                    {
                        var castlingToK = new ChessPieceCoord(kingCoord);    // destination king
                        castlingToK.MoveOffset(-2, 0);
                        var castlingToR = new ChessPieceCoord(kingCoord);    // destination rook
                        castlingToR.MoveOffset(-1, 0);
                        var castlingToI = new ChessPieceCoord(kingCoord);    // intermediate
                        castlingToI.MoveOffset(-3, 0);

                        if (GetPiece(castlingToR) == null &&
                            GetPiece(castlingToK) == null &&
                            GetPiece(castlingToI) == null &&
                            !CanAttack(opColor, kingCoord) &&
                            !CanAttack(opColor, castlingToR) &&
                            !CanAttack(opColor, castlingToK))
                        {
                            BuildMove(storage, ChessMoveFlag.QueenSideCastle, color, ChessPieceType.King, kingCoord, castlingToK);
                        }
                    }
                }
            }
        }