internal bool WillPlaceKingInCheck(Player p, SquareCoordinates from, Move move) { //temporarily moves a piece from the square 'from' to the square 'to' //without showing it on the board, and checks GameLogic to see if we are in check. //no matter the result, the board will be restored right afterwards. //perhaps just create a copy of the board so we don't have to restore the old pieces? SquareCoordinates to = move.Coordinates; SquareCoordinates taken = move.TakenPiece; ChessPiece fromPiece = pieces[from.File, from.Rank]; ChessPiece takenPiece = pieces[taken.File, taken.Rank]; pieces[taken.File, taken.Rank] = null; pieces[to.File, to.Rank] = fromPiece; pieces[from.File, from.Rank] = null; bool movedKing = fromPiece.IsA(PieceType.KING) && fromPiece.White == p.White; bool inCheck = GameLogic.KingInCheck(this, movedKing ? to : p.Material.KingSquare, p.White); pieces[from.File, from.Rank] = fromPiece; pieces[to.File, to.Rank] = null; pieces[taken.File, taken.Rank] = takenPiece; return inCheck; }
internal void UpdateLastMove(SquareCoordinates from, Move m, ChessPiece moved, ChessPiece taken) { moveLabel.Text = MoveRecorder.GetMoveNotation(from, m, moved, taken); if (m.Overtaken) WaitingPlayer().Material.Pieces.Remove(m.TakenPiece); }
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); }
//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); }
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); }
internal static string GetMoveNotation(SquareCoordinates start, Move m, ChessPiece moved, ChessPiece taken) { string notation = PieceTypeInitial(moved.Type); notation += start.ToString().ToLower(); //long algebraic notation doesn't actually specify the piece initial of the taken piece, but this is more consistent so just do it notation += !m.Overtaken ? "-" : ("x" + PieceTypeInitial(taken.Type)); notation += m.Coordinates.ToString().ToLower(); return notation; }