internal static KingStatus KingConcern(ChessBoard board, Player p) { MoveSet moves = KingMoves(board, p.Material.KingSquare, p); SquareCoordinates[] attackingPieces = Attackers(board, p.Material.KingSquare, p.White, true); if (attackingPieces.Length != 0) { if (moves.LegalMoves.Length != 0) return KingStatus.CHECK; foreach (SquareCoordinates coord in attackingPieces) if (Attackers(board, coord, !p.White, true).Length == 0 && !CanInterpose(board, coord, p.Material.KingSquare, p)) return KingStatus.CHECKMATE; //there is one opponent piece that can reach our king and is unable to be captured or blocked return KingStatus.CHECK; } else { if (moves.LegalMoves.Length != 0) return KingStatus.NO_IMMEDIATE_CONCERN; foreach (SquareCoordinates coord in p.Material.Pieces) if (MoveSet(board, coord, p).LegalMoves.Length != 0) return KingStatus.NO_IMMEDIATE_CONCERN; //there is one friendly piece we can move return KingStatus.STALEMATE; } }
internal static bool CanCastle(ChessBoard board, SquareCoordinates coord, Player p) { ChessPiece piece = board.GetPiece(coord); if (piece != null && piece.IsA(PieceType.ROOK) && piece.IsFriendly(p.White) && piece.HasNotMoved()) { SquareCoordinates kingSq = p.White ? new SquareCoordinates("E1") : new SquareCoordinates("E8"); piece = board.GetPiece(kingSq); if (piece != null && piece.IsA(PieceType.KING) && piece.IsFriendly(p.White) && piece.HasNotMoved() && !KingInCheck(board, p)) { if (coord.File == 0) { if (!board.WillPlaceKingInCheck(p, new SquareCoordinates[] { new SquareCoordinates(4, coord.Rank), new SquareCoordinates(0, coord.Rank) }, new SquareCoordinates[] { new SquareCoordinates(2, coord.Rank), new SquareCoordinates(3, coord.Rank) })) { for (int file = 1, rank = coord.Rank; file < 4; file++) if (board.GetPiece(coord = new SquareCoordinates(file, rank)) != null || Attackers(board, coord, p.White, true).Length > 0) return false; return true; } } else if (coord.File == 7) { if (!board.WillPlaceKingInCheck(p, new SquareCoordinates[] { new SquareCoordinates(4, coord.Rank), new SquareCoordinates(7, coord.Rank) }, new SquareCoordinates[] { new SquareCoordinates(6, coord.Rank), new SquareCoordinates(5, coord.Rank) })) { for (int file = 5, rank = coord.Rank; file < 7; file++) if (board.GetPiece(coord = new SquareCoordinates(file, rank)) != null || Attackers(board, coord, p.White, true).Length > 0) return false; return true; } } } } return false; }
protected override void PerformedCastle(ChessBoard board, bool kingSide, MoveSet moves) { if (moves != null) { foreach (Move legalMove in moves.LegalMoves) board.UnhighlightSquare(legalMove.Coordinates); foreach (SquareCoordinates checkedMoves in moves.CheckableMoves) board.UnhighlightSquare(checkedMoves); foreach (SquareCoordinates checkedMoves in moves.BlockedSquareMoves) board.UnhighlightSquare(checkedMoves); } if (remoteOpponent != null) remoteOpponent.SendMessage(ChessPacketWriter.WriteCastle(kingSide)); }
private static MoveSet QueenMoves(ChessBoard board, SquareCoordinates coord, Player p) { //Queen's allowed moves are basically a combination of those of rook (diagonals) and bishop (vertical/horizontal) //so just call the methods to get rook and bishop moves and return a union of them return new MoveSet(RookMoves(board, coord, p), BishopMoves(board, coord, p)); }
private static MoveSet KnightMoves(ChessBoard board, SquareCoordinates coord, Player p) { List<Move> allowedMoves = new List<Move>(); List<SquareCoordinates> movesWithCheck = new List<SquareCoordinates>(); List<SquareCoordinates> blockedMoves = new List<SquareCoordinates>(); bool boardOrientation = board.WhiteOnBottom; bool white = p.White; //SquareCoordinates opponentEnPassantPawn; ChessPiece existingPiece; Move m; int nextFile, nextRank; ProcessSquare proc = delegate(SquareCoordinates to) { if ((existingPiece = board.GetPiece(to)) == null) /*if ((opponentEnPassantPawn = EnPassant(board, to, p.White)).File != -1 && opponentEnPassantPawn.Rank != -1) if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, opponentEnPassantPawn))) allowedMoves.Add(m); else movesWithCheck.Add(to); else*/ if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to))) allowedMoves.Add(m); else movesWithCheck.Add(to); else if (!existingPiece.IsFriendly(p.White)) if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, to))) allowedMoves.Add(m); else movesWithCheck.Add(to); else blockedMoves.Add(to); }; nextFile = coord.File + 1; if (nextFile < 8) { nextRank = coord.Rank + 2; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank < 8) proc(new SquareCoordinates(nextFile, nextRank)); //right 1 up 2 nextRank = coord.Rank - 2; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank >= 0) proc(new SquareCoordinates(nextFile, nextRank)); //right 1 down 2 } nextFile = coord.File + 2; if (nextFile < 8) { nextRank = coord.Rank + 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank < 8) proc(new SquareCoordinates(nextFile, nextRank)); //right 2 up 1 nextRank = coord.Rank - 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank >= 0) proc(new SquareCoordinates(nextFile, nextRank)); //right 2 down 1 } nextFile = coord.File - 1; if (nextFile >= 0) { nextRank = coord.Rank + 2; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank < 8) proc(new SquareCoordinates(nextFile, nextRank)); //left 1 up 2 nextRank = coord.Rank - 2; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank >= 0) proc(new SquareCoordinates(nextFile, nextRank)); //left 1 down 2 } nextFile = coord.File - 2; if (nextFile >= 0) { nextRank = coord.Rank + 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank < 8) proc(new SquareCoordinates(nextFile, nextRank)); //left 2 up 1 nextRank = coord.Rank - 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextRank >= 0) proc(new SquareCoordinates(nextFile, nextRank)); //left 2 down 1 } return new MoveSet(allowedMoves, movesWithCheck, blockedMoves); }
private static SquareCoordinates EnPassant(ChessBoard board, SquareCoordinates moveTo, bool white) { if (white) { if (moveTo.Rank != 5) return new SquareCoordinates(-1, -1); ChessPiece pawn = board.GetPiece(new SquareCoordinates(moveTo.File, 4)); if (pawn == null || !pawn.IsA(PieceType.PAWN) || pawn.IsFriendly(white)) return new SquareCoordinates(-1, -1); if (pawn.LastMove != board.CurrentMove - 1 || pawn.LastSquare != new SquareCoordinates(moveTo.File, 6)) return new SquareCoordinates(-1, -1); return new SquareCoordinates(moveTo.File, moveTo.Rank - 1); } else { if (moveTo.Rank != 2) return new SquareCoordinates(-1, -1); ChessPiece pawn = board.GetPiece(new SquareCoordinates(moveTo.File, 3)); if (pawn == null || !pawn.IsA(PieceType.PAWN) || pawn.IsFriendly(white)) return new SquareCoordinates(-1, -1); if (pawn.LastMove != board.CurrentMove - 1 || pawn.LastSquare != new SquareCoordinates(moveTo.File, 1)) return new SquareCoordinates(-1, -1); return new SquareCoordinates(moveTo.File, moveTo.Rank + 1); } }
private static SquareCoordinates[] Attackers(ChessBoard board, SquareCoordinates pieceLoc, bool pieceWhite, bool allowPawnDiagonal) { List<SquareCoordinates> attackingPieces = new List<SquareCoordinates>(); int file, rank; ChessPiece existingPiece; SquareCoordinates coord; //go vertically/horizontally and see if there's an unblocked opponent queen or rook. existingPiece = null; coord = new SquareCoordinates(-1, -1); for (file = pieceLoc.File + 1, rank = pieceLoc.Rank; file < 8 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file++) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.ROOK) || existingPiece.IsA(PieceType.QUEEN))) attackingPieces.Add(coord); existingPiece = null; coord = new SquareCoordinates(-1, -1); for (file = pieceLoc.File - 1, rank = pieceLoc.Rank; file >= 0 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file--) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.ROOK) || existingPiece.IsA(PieceType.QUEEN))) attackingPieces.Add(coord); existingPiece = null; coord = new SquareCoordinates(-1, -1); for (file = pieceLoc.File, rank = pieceLoc.Rank + 1; rank < 8 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; rank++) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.ROOK) || existingPiece.IsA(PieceType.QUEEN) || !allowPawnDiagonal && pieceWhite && rank - pieceLoc.Rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); existingPiece = null; coord = new SquareCoordinates(-1, -1); for (file = pieceLoc.File, rank = pieceLoc.Rank - 1; rank >= 0 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; rank--) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.ROOK) || existingPiece.IsA(PieceType.QUEEN) || !allowPawnDiagonal && !pieceWhite && pieceLoc.Rank - rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); //go diagonally and see if there's an unblocked opponent queen or bishop (or pawn if only one diagonal away). existingPiece = null; for (file = pieceLoc.File + 1, rank = pieceLoc.Rank + 1; file < 8 && rank < 8 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file++, rank++) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.BISHOP) || existingPiece.IsA(PieceType.QUEEN) || allowPawnDiagonal && pieceWhite && file - pieceLoc.File == 1 && rank - pieceLoc.Rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); existingPiece = null; for (file = pieceLoc.File + 1, rank = pieceLoc.Rank - 1; file < 8 && rank >= 0 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file++, rank--) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.BISHOP) || existingPiece.IsA(PieceType.QUEEN) || allowPawnDiagonal && !pieceWhite && file - pieceLoc.File == 1 && pieceLoc.Rank - rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); existingPiece = null; for (file = pieceLoc.File - 1, rank = pieceLoc.Rank + 1; file >= 0 && rank < 8 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file--, rank++) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.BISHOP) || existingPiece.IsA(PieceType.QUEEN) || allowPawnDiagonal && pieceWhite && pieceLoc.File - file == 1 && rank - pieceLoc.Rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); existingPiece = null; for (file = pieceLoc.File - 1, rank = pieceLoc.Rank - 1; file >= 0 && rank >= 0 && (existingPiece = board.GetPiece((coord = new SquareCoordinates(file, rank)))) == null; file--, rank--) ; if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && (existingPiece.IsA(PieceType.BISHOP) || existingPiece.IsA(PieceType.QUEEN) || allowPawnDiagonal && !pieceWhite && pieceLoc.File - file == 1 && pieceLoc.Rank - rank == 1 && existingPiece.IsA(PieceType.PAWN))) attackingPieces.Add(coord); //go through all 8 L-shapes and see if there's a knight in each (doesn't matter if another piece is in the way). file = pieceLoc.File + 2; rank = pieceLoc.Rank + 1; if (file < 8 && rank < 8) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File + 2; rank = pieceLoc.Rank - 1; if (file < 8 && rank >= 0) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File + 1; rank = pieceLoc.Rank + 2; if (file < 8 && rank < 8) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File + 1; rank = pieceLoc.Rank - 2; if (file < 8 && rank >= 0) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File - 2; rank = pieceLoc.Rank + 1; if (file >= 0 && rank < 8) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File - 2; rank = pieceLoc.Rank - 1; if (file >= 0 && rank >= 0) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File - 1; rank = pieceLoc.Rank + 2; if (file >= 0 && rank < 8) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } file = pieceLoc.File - 1; rank = pieceLoc.Rank - 2; if (file >= 0 && rank >= 0) { coord = new SquareCoordinates(file, rank); existingPiece = board.GetPiece(coord); if (existingPiece != null && !existingPiece.IsFriendly(pieceWhite) && existingPiece.IsA(PieceType.KNIGHT)) attackingPieces.Add(coord); } return attackingPieces.ToArray(); }
internal static bool KingInCheck(ChessBoard board, Player p) { return KingInCheck(board, p.Material.KingSquare, p.White); }
internal void Castle(ChessBoard board, bool kingSide) { MoveSet prevMoves = moves; if (moves != null) { ResetSelected(); board.UnhighlightSquare(firstSelection); } SquareCoordinates kingStart, kingEnd, rookStart, rookEnd; ChessPiece piece; int rank = white ? 0 : 7; kingStart = new SquareCoordinates(4, rank); if (kingSide) { kingEnd = new SquareCoordinates(6, rank); rookStart = new SquareCoordinates(7, rank); rookEnd = new SquareCoordinates(5, rank); } else { kingEnd = new SquareCoordinates(2, rank); rookStart = new SquareCoordinates(0, rank); rookEnd = new SquareCoordinates(3, rank); } //rookEnd = new SquareCoordinates((kingStart.File + kingEnd.File) / 2, rank); piece = board.ClearSquare(kingStart); piece.LastSquare = kingStart; piece.LastMove = board.CurrentMove; board.DrawPiece(kingEnd, piece); material.MovePiece(PieceType.KING, kingStart, kingEnd); piece = board.ClearSquare(rookStart); piece.LastSquare = rookStart; piece.LastMove = board.CurrentMove; board.DrawPiece(rookEnd, piece); material.MovePiece(PieceType.ROOK, rookStart, rookEnd); PerformedCastle(board, kingSide, prevMoves); board.UpdateLastMoveFromCastle(kingSide); board.NextTurn(); }
protected override void Unselected(ChessBoard board, SquareCoordinates coord, MoveSet moves) { }
protected override void PerformedCastle(ChessBoard board, bool kingSide, MoveSet moves) { }
protected override void MadeMove(ChessBoard board, ChessPiece movedPiece, SquareCoordinates from, SquareCoordinates to, MoveSet moves) { }
internal NetworkPlayer(ChessBoard board, bool white, Material material) : base(white, material) { }
protected override void Unselected(ChessBoard board, SquareCoordinates coord, MoveSet moves) { foreach (Move legalMove in moves.LegalMoves) board.UnhighlightSquare(legalMove.Coordinates); foreach (SquareCoordinates checkedMoves in moves.CheckableMoves) board.UnhighlightSquare(checkedMoves); foreach (SquareCoordinates checkedMoves in moves.BlockedSquareMoves) board.UnhighlightSquare(checkedMoves); if (remoteOpponent != null) remoteOpponent.SendMessage(ChessPacketWriter.WriteSelectSquare(coord)); }
protected override void FirstSquareSelected(ChessBoard board, SquareCoordinates coord, MoveSet moves) { if (board.ShowLegalMoves) foreach (Move legalMove in moves.LegalMoves) board.HighlightSquare(legalMove.Coordinates, Color.Green); if (board.ShowCheckedMoves) foreach (SquareCoordinates checkedMoves in moves.CheckableMoves) board.HighlightSquare(checkedMoves, Color.Indigo); if (board.ShowBlockedMoves) foreach (SquareCoordinates checkedMoves in moves.BlockedSquareMoves) board.HighlightSquare(checkedMoves, Color.Red); if (remoteOpponent != null) remoteOpponent.SendMessage(ChessPacketWriter.WriteSelectSquare(coord)); }
internal static bool KingInCheck(ChessBoard board, SquareCoordinates kingSquare, bool white) { return Attackers(board, kingSquare, white, true).Length != 0; }
internal void PromotePiece(ChessBoard board, SquareCoordinates coord, PieceType promotedType) { PromotePiece(board, coord, promotedType, board.GetPiece(coord)); }
internal static MoveSet MoveSet(ChessBoard board, SquareCoordinates coord, Player p) { switch (board.GetPiece(coord).Type) { case PieceType.PAWN: return PawnMoves(board, coord, p); case PieceType.KNIGHT: return KnightMoves(board, coord, p); case PieceType.BISHOP: return BishopMoves(board, coord, p); case PieceType.ROOK: return RookMoves(board, coord, p); case PieceType.QUEEN: return QueenMoves(board, coord, p); case PieceType.KING: return KingMoves(board, coord, p); default: return new MoveSet(); } }
internal void Select(ChessBoard board, SquareCoordinates coord) { ChessPiece selectedPiece = board.GetPiece(coord); if (moves == null) { if (selectedPiece != null && selectedPiece.White == white) { firstSelection = coord; moves = GameLogic.MoveSet(board, coord, this); board.HighlightSquare(coord, Color.Yellow); FirstSquareSelected(board, coord, moves); } } else { if (coord == firstSelection) { MoveSet prevMoves = moves; ResetSelected(); board.UnhighlightSquare(coord); Unselected(board, coord, prevMoves); } else { Move m = GetMove(moves, coord); if (m != null) { ChessPiece movedPiece, takenPiece = null; MoveSet prevMoves = moves; ResetSelected(); board.UnhighlightSquare(firstSelection); if (m.Overtaken) takenPiece = board.ClearSquare(m.TakenPiece); movedPiece = board.ClearSquare(firstSelection); movedPiece.LastSquare = firstSelection; movedPiece.LastMove = board.CurrentMove; board.DrawPiece(coord, movedPiece); material.MovePiece(movedPiece.Type, firstSelection, coord); MadeMove(board, movedPiece, firstSelection, coord, prevMoves); board.UpdateLastMove(firstSelection, m, movedPiece, takenPiece); board.NextTurn(); } else if (moves.CheckableMoves.Contains(coord) && !board.ShowCheckedMoves) { MessageBox.Show(board, "You may not place the selected piece there\nsince it will either place your king in check\nor will leave your king in check.", "Illegal Move", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } }
private static bool CanInterpose(ChessBoard board, SquareCoordinates from, SquareCoordinates to, Player p) { switch (board.GetPiece(from).Type) { case PieceType.PAWN: return false; //if pawns cannot be captured, they cannot be blocked by friendly pieces! case PieceType.KNIGHT: return false; //if knights cannot be captured, they cannot be blocked by friendly pieces! case PieceType.BISHOP: if (from.File - to.File == from.Rank - to.Rank) { for (int file = Math.Min(from.File, to.File) + 1, rank = Math.Min(from.Rank, to.Rank) + 1; file < Math.Max(from.File, to.File); file++, rank++) if (Attackers(board, new SquareCoordinates(file, rank), !p.White, false).Length > 0) return true; } else if (from.File - to.File == -(from.Rank - to.Rank)) { for (int file = Math.Min(from.File, to.File) + 1, rank = Math.Max(from.Rank, to.Rank) + 1; file < Math.Max(from.File, to.File) && rank < 8; file++, rank--) if (Attackers(board, new SquareCoordinates(file, rank), !p.White, false).Length > 0) return true; } return false; case PieceType.ROOK: if (from.File == to.File) { for (int file = from.File, rank = Math.Min(from.Rank, to.Rank) + 1; rank < Math.Max(from.Rank, to.Rank); rank++) if (Attackers(board, new SquareCoordinates(file, rank), !p.White, false).Length > 0) return true; } else if (from.Rank == to.Rank) { for (int file = Math.Min(from.File, to.File) + 1, rank = from.Rank; file < Math.Max(from.File, to.File); file++) if (Attackers(board, new SquareCoordinates(file, rank), !p.White, false).Length > 0) return true; } return false; case PieceType.QUEEN: if (from.File == to.File || from.Rank == to.Rank) goto case PieceType.ROOK; else if (Math.Abs(from.File - to.File) == Math.Abs(from.Rank - to.Rank)) goto case PieceType.BISHOP; return false; default: return false; } }
protected abstract void MadeMove(ChessBoard board, ChessPiece movedPiece, SquareCoordinates from, SquareCoordinates to, MoveSet moves);
protected abstract void PerformedCastle(ChessBoard board, bool kingSide, MoveSet moves);
protected void PromotePiece(ChessBoard board, SquareCoordinates coord, PieceType promotedType, ChessPiece piece) { piece.Type = promotedType; board.ClearSquare(coord); board.DrawPiece(coord, piece); }
//TODO: promotion (pawn reaching opponent's end of board -> any piece) private static MoveSet PawnMoves(ChessBoard board, SquareCoordinates coord, Player p) { List<Move> allowedMoves = new List<Move>(); List<SquareCoordinates> movesWithCheck = new List<SquareCoordinates>(); List<SquareCoordinates> blockedMoves = new List<SquareCoordinates>(); bool boardOrientation = board.WhiteOnBottom; bool white = p.White; SquareCoordinates nextSquare; ChessPiece existingPiece; Move m; int nextRank, nextFile; //check if piece would go out of bounds if (white && (nextRank = coord.Rank + 1) < 8 || !white && (nextRank = coord.Rank - 1) >= 0) { nextSquare = new SquareCoordinates(coord.File, nextRank); existingPiece = board.GetPiece(nextSquare); if (existingPiece == null) //move up 1 if no piece is in that space if (!board.WillPlaceKingInCheck(p, coord, m = new Move(nextSquare))) allowedMoves.Add(m); else movesWithCheck.Add(nextSquare); else blockedMoves.Add(nextSquare); //diagonal take SquareCoordinates opponentEnPassantPawn; ProcessSquare diagonalProc = delegate(SquareCoordinates to) { if ((existingPiece = board.GetPiece(to)) != null) { if (!existingPiece.IsFriendly(white)) if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, to))) allowedMoves.Add(m); else movesWithCheck.Add(to); } else if ((opponentEnPassantPawn = EnPassant(board, to, p.White)).File != -1 && opponentEnPassantPawn.Rank != -1) { if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, opponentEnPassantPawn))) allowedMoves.Add(m); else movesWithCheck.Add(nextSquare); } }; nextFile = coord.File + 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextFile < 8) diagonalProc(new SquareCoordinates(nextFile, nextRank)); //move diagonally up right if an opponent piece is in that space nextFile = coord.File - 1; //check if we are in bounds and that either no piece exists there, or the piece is not a friendly if (nextFile >= 0) diagonalProc(new SquareCoordinates(nextFile, nextRank)); //move diagonally up left if an opponent piece is in that space } //check if we are still in the home position if (white && (nextRank = coord.Rank + 2) == 3 || !white && (nextRank = coord.Rank - 2) == 4) { nextSquare = new SquareCoordinates(coord.File, nextRank); SquareCoordinates betweenSquare = new SquareCoordinates(coord.File, (nextRank + coord.Rank) / 2); existingPiece = board.GetPiece(nextSquare); ChessPiece betweenPiece = board.GetPiece(betweenSquare); if (existingPiece == null && betweenPiece == null) //move up 2 spaces if no piece is at that space and no piece is in between if (!board.WillPlaceKingInCheck(p, coord, m = new Move(nextSquare))) allowedMoves.Add(m); else movesWithCheck.Add(nextSquare); else blockedMoves.Add(nextSquare); } return new MoveSet(allowedMoves, movesWithCheck, blockedMoves); }
protected abstract void Unselected(ChessBoard board, SquareCoordinates coord, MoveSet moves);
private static MoveSet RookMoves(ChessBoard board, SquareCoordinates coord, Player p) { List<Move> allowedMoves = new List<Move>(); List<SquareCoordinates> movesWithCheck = new List<SquareCoordinates>(); List<SquareCoordinates> blockedMoves = new List<SquareCoordinates>(); bool boardOrientation = board.WhiteOnBottom; bool white = p.White; SquareCoordinates nextSquare/*, opponentEnPassantPawn*/; Move m; int nextFile, nextRank; ProcessSquare linearProc = delegate(SquareCoordinates to) { /*if ((opponentEnPassantPawn = EnPassant(board, to, p.White)).File != -1 && opponentEnPassantPawn.Rank != -1) if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, opponentEnPassantPawn))) allowedMoves.Add(m); else movesWithCheck.Add(to); else*/ if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to))) allowedMoves.Add(m); else movesWithCheck.Add(to); }; ProcessSquare blockingPieceProc = delegate(SquareCoordinates to) { if (!board.GetPiece(to).IsFriendly(white)) if (!board.WillPlaceKingInCheck(p, coord, m = new Move(to, to))) allowedMoves.Add(m); else movesWithCheck.Add(to); else blockedMoves.Add(to); }; nextFile = coord.File; nextRank = coord.Rank; while (++nextFile < 8 && board.GetPiece(nextSquare = new SquareCoordinates(nextFile, nextRank)) == null) linearProc(nextSquare); //we stop the loop if we encounter any piece, or if we start going out of bounds off the board. //if we did not stop at the edge of the board, check to see if the piece we stopped at is an opponent piece. if it is, we can move there as well if (nextFile < 8) blockingPieceProc(new SquareCoordinates(nextFile, nextRank)); nextFile = coord.File; nextRank = coord.Rank; while (++nextRank < 8 && board.GetPiece(nextSquare = new SquareCoordinates(nextFile, nextRank)) == null) linearProc(nextSquare); //we stop the loop if we encounter any piece, or if we start going out of bounds off the board. //if we did not stop at the edge of the board, check to see if the piece we stopped at is an opponent piece. if it is, we can move there as well if (nextRank < 8) blockingPieceProc(new SquareCoordinates(nextFile, nextRank)); nextFile = coord.File; nextRank = coord.Rank; while (--nextFile >= 0 && board.GetPiece(nextSquare = new SquareCoordinates(nextFile, nextRank)) == null) linearProc(nextSquare); //we stop the loop if we encounter any piece, or if we start going out of bounds off the board. //if we did not stop at the edge of the board, check to see if the piece we stopped at is an opponent piece. if it is, we can move there as well if (nextFile >= 0) blockingPieceProc(new SquareCoordinates(nextFile, nextRank)); nextFile = coord.File; nextRank = coord.Rank; while (--nextRank >= 0 && board.GetPiece(nextSquare = new SquareCoordinates(nextFile, nextRank)) == null) linearProc(nextSquare); //we stop the loop if we encounter any piece, or if we start going out of bounds off the board. //if we did not stop at the edge of the board, check to see if the piece we stopped at is an opponent piece. if it is, we can move there as well if (nextRank >= 0) blockingPieceProc(new SquareCoordinates(nextFile, nextRank)); return new MoveSet(allowedMoves, movesWithCheck, blockedMoves); }
internal LocalPlayer(ChessBoard board, bool white, NetworkInterface remoteOpponent, Material material) : base(white, material) { this.remoteOpponent = remoteOpponent; }
internal ChessPacketHandler(NetworkPlayer p, ChessBoard board) { this.player = p; this.board = board; }
protected override void MadeMove(ChessBoard board, ChessPiece movedPiece, SquareCoordinates from, SquareCoordinates to, MoveSet moves) { foreach (Move legalMove in moves.LegalMoves) board.UnhighlightSquare(legalMove.Coordinates); foreach (SquareCoordinates checkedMoves in moves.CheckableMoves) board.UnhighlightSquare(checkedMoves); foreach (SquareCoordinates checkedMoves in moves.BlockedSquareMoves) board.UnhighlightSquare(checkedMoves); PieceType promoted = PieceType.UNDEFINED; if (movedPiece.IsA(PieceType.PAWN) && (White && to.Rank == 7 || !White && to.Rank == 0)) PromotePiece(board, to, promoted = new PromotionSelect().Prompt(board)); if (remoteOpponent != null) { remoteOpponent.SendMessage(ChessPacketWriter.WriteSelectSquare(to)); if (promoted != PieceType.UNDEFINED) remoteOpponent.SendMessage(ChessPacketWriter.WritePromotion(to, promoted)); } }