public BasePiece GetPiece(ChessPieceCoord from) { if (!from.IsValid()) { return(null); } return(Board[from.X + from.Y * Chess.BoardSize]); }
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); }
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)); }
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); }
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); } } } } }