//checks if same colour public bool isSameColour(Piece P) { if (P.getColour() == this.colour) { return(true); } else { return(false); } }
// Returns a list of all covered squares public static List<Tuple<uint, uint>> getCover(Board board, Piece piece) { int x, y; int yMod = (piece.getColour() == "white" ? 1 : -1); List<Tuple<uint, uint>> cover = new List<Tuple<uint, uint>>(); x = (int)piece.getX() - 1; y = (int)piece.getY() + yMod; if (board.withinBoard(x, y)) { cover.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } x = (int)piece.getX() + 1; if (board.withinBoard(x, y)) { cover.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } return cover; }
//checks if same colour public bool isSameColour(Piece P) { if (P.getColour() == this.colour) return true; else return false; }
public bool makeMove(string col, Move move) { uint x1 = move.FromX; uint y1 = move.FromY; uint x2 = move.ToX; uint y2 = move.ToY; Piece p = getPieceAt(x1, y1); Square s1 = getSquareAt(x1, y1); Square s2 = getSquareAt(x2, y2); bool castling = false; bool enPassant = false; // Check if squares are ok. if (s1 == null || s2 == null) { return(false); } // Check if piece is ok. if (p == null) { return(false); } if (p.getColour() != col) { return(false); } // Move is legal //Check if this is a castling if ((p is King) && (((x1 - x2) == 2) || ((x2 - x1) == 2))) { castling = true; } // Special handling for pawns if ((p is Pawn)) { // Check double step if (Math.Abs((int)move.FromY - (int)move.ToY) == 2) { ((Pawn)p).setDoubleStepTurn(getTurn()); } //Check if en passant if ((getSquareAt(x2, y2).getPiece() == null) && (x1 != x2)) { enPassant = true; } } // Remove from old position s1.removePiece(); // Add to new position if ((p is Pawn && p.getColour() == "white" && y2 == 7) || (p is Pawn && p.getColour() == "black" && y2 == 0)) { p = new Queen(x1, y1, p.getColour()); } s2.setPiece(p); p.move(x2, y2); // Handles the special castling case if (castling) { uint x2rook; uint x1rook; if (x2 > x1)// Castling right { x1rook = 7; x2rook = x2 - 1; } else { x1rook = 0; x2rook = x2 + 1; } Square s3 = getSquareAt(x1rook, y1); Piece p3 = s3.getPiece(); Square s4 = getSquareAt(x2rook, y1); s3.removePiece(); s4.setPiece(p3); p3.move(x2rook, y2); } // Handles the special en passant case if (enPassant) { int yMod; if (p.getColour() == "white") { yMod = -1; } else { yMod = 1; } Square s3 = getSquareAt(x2, (uint)(y2 + yMod)); Piece p3 = s3.getPiece(); s3.removePiece(); } updateCover(); return(true); }
// Check if black piece at x, y public bool isBlack(uint x, uint y) { Piece p = getPieceAt(x, y); return(p != null && p.getColour() == COLOUR_BLACK); }
// Check if white piece at x, y public bool isWhite(uint x, uint y) { Piece p = getPieceAt(x, y); return(p != null && p.getColour() == COLOUR_WHITE); }
public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece) { List<Tuple<uint, uint>> moves = new List<Tuple<uint, uint>>(); // Check down moves int x = (int)piece.getX(); int y = (int)piece.getY(); while (true) { y--; if (!board.withinBoard(x, y)) { break; } Piece p = board.getPieceAt((uint)x, (uint)y); if (p == null) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } else { if (p.getColour() != piece.getColour()) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); break; } else { break; } } } // Check up moves x = (int)piece.getX(); y = (int)piece.getY(); while (true) { y++; if (!board.withinBoard(x, y)) { break; } Piece p = board.getPieceAt((uint)x, (uint)y); if (p == null) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } else { if (p.getColour() != piece.getColour()) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); break; } else { break; } } } // Check right moves x = (int)piece.getX(); y = (int)piece.getY(); while (true) { x++; if (!board.withinBoard(x, y)) { break; } Piece p = board.getPieceAt((uint)x, (uint)y); if (p == null) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } else { if (p.getColour() != piece.getColour()) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); break; } else { break; } } } // Check left moves x = (int)piece.getX(); y = (int)piece.getY(); while (true) { x--; if (!board.withinBoard(x, y)) { break; } Piece p = board.getPieceAt((uint)x, (uint)y); if (p == null) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); } else { if (p.getColour() != piece.getColour()) { moves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); break; } else { break; } } } // Filter for check situations CommonRules.checkFilter(ref moves, board, piece); // Done, all moves found return moves; }
// Returns a list of all possible moves public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece) { List<Tuple<uint, uint>> tmpList = new List<Tuple<uint, uint>>(); short yMod; short passantRow; if (piece.getColour() == "white") { yMod = 1; passantRow = 4; } else { yMod = -1; passantRow = 3; } // Take left if (board.withinBoard((int) piece.getX() - 1, (int) piece.getY() + yMod)) { Piece P = board.getPieceAt((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod)); if (P != null) { if (!piece.isSameColour(P)) { tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() - 1), (uint)(piece.getY() + yMod))); } } } //Take right if (board.withinBoard((int)piece.getX() + 1, (int)piece.getY() + yMod)) { Piece P = board.getPieceAt((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod)); if (P != null) { if (!piece.isSameColour(P)) { tmpList.Add(new Tuple<uint, uint>((uint)(piece.getX() + 1), (uint)(piece.getY() + yMod))); } } } //Move 1 if (board.withinBoard((int)piece.getX(), (int)piece.getY() + yMod)) { Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod)); if (P == null) { tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + yMod))); } } //Move 2 (Only first move) if (!piece.movedFromInit()) { if (board.withinBoard((int)piece.getX(), (int)piece.getY() + 2 * yMod)) { Piece P = board.getPieceAt(piece.getX(), (uint)(piece.getY() + 2 * yMod)); Piece P2 = board.getPieceAt(piece.getX(), (uint)(piece.getY() + yMod)); if (P == null && P2 == null) { tmpList.Add(new Tuple<uint, uint>(piece.getX(), (uint)(piece.getY() + 2 * yMod))); //((Pawn)piece).setDoubleStepTurn(board.getTurn()); } } } //En Passant if (piece.getY() == passantRow) { if ((piece.getX() + 1) < Board.BOARD_SIZE_X) { Piece P1 = board.getPieceAt(piece.getX() + 1, piece.getY()); if (P1 != null) { if (P1 is Pawn) if (((Pawn)P1).getDoubleStepTurn() == board.getTurn() - 1) tmpList.Add(new Tuple<uint, uint>(piece.getX() + 1, (uint)(piece.getY() + yMod))); } } if ((int)piece.getX() - 1 >= 0) { Piece P2 = board.getPieceAt(piece.getX() - 1, piece.getY()); if (P2 != null) { if (P2 is Pawn) if (((Pawn)P2).getDoubleStepTurn() == board.getTurn() - 1) tmpList.Add(new Tuple<uint, uint>(piece.getX() - 1, (uint)(piece.getY() + yMod))); } } } // Filter for check situations CommonRules.checkFilter(ref tmpList, board, piece); return tmpList; }
public static List<Tuple<uint, uint>> getPossibleMoves(Board board, Piece piece) { List<Tuple<uint, uint>> moves = new List<Tuple<uint, uint>>(); int x = (int)piece.getX(); int y = (int)piece.getY(); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) { // Standing still is not a move continue; } int nx = x + i; int ny = y + j; if (board.withinBoard(nx, ny)) { Square s = board.getSquareAt((uint)nx, (uint)ny); if ((piece.getColour() == "white" && s.getBlackCover() == 0) || (piece.getColour() == "black" && s.getWhiteCover() == 0)) { Piece p = s.getPiece(); if (p == null) { moves.Add(new Tuple<uint, uint>((uint)nx, (uint)ny)); } else { if (p.getColour() != piece.getColour()) { moves.Add(new Tuple<uint, uint>((uint)nx, (uint)ny)); } } } } } } // Castling Square tmp = board.getSquareAt(piece.getX(), piece.getY()); if ((!piece.movedFromInit()) && (!tmp.getEnemyCover(piece.getColour()))) { for (int i = 1; i < 5; i++) { Square s = board.getSquareAt((uint)(x - i), (uint)y); if ((i < 4) && ((s.getPiece() != null) || s.getEnemyCover(piece.getColour()))) break; else if ((s.getPiece() != null) && (i == 4)) if ((s.getPiece() is Rook) && (!s.getPiece().movedFromInit())) moves.Add(new Tuple<uint, uint>((uint)(x - 2), (uint)y)); } for (int i = 1; i < 4; i++) { Square s = board.getSquareAt((uint)(x + i), (uint)y); if ((i < 3) && ((s.getPiece() != null) || s.getEnemyCover(piece.getColour()))) break; else if ((s.getPiece() != null) && (i == 3)) if ((s.getPiece() is Rook) && (!s.getPiece().movedFromInit())) moves.Add(new Tuple<uint, uint>((uint)(x + 2), (uint)y)); } } // Remove squares with enemy king reach foreach (Tuple<uint, uint> reach in getEnemyKingReach(board, piece)) { moves.Remove(reach); } // Remove any moves that create new checks checkFilter(ref moves, board, piece); // Done, all moves found return moves; }
// Special King function used to make sure the Kings can't move next to each other private static List<Tuple<uint, uint>> getEnemyKingReach(Board board, Piece piece) { // Find enemy king List<Tuple<uint, uint>> enemyKingReach = new List<Tuple<uint, uint>>(); bool found = false; for (uint j = 0; j < Board.BOARD_SIZE_Y; j++) { for (uint i = 0; i < Board.BOARD_SIZE_X; i++) { Piece p = board.getPieceAt(i, j); if (p != null && p is King && p.getColour() != piece.getColour()) { found = true; enemyKingReach = getReach(board, p); break; } if (found) { break; } } } return enemyKingReach; }
private static void checkFilter(ref List<Tuple<uint,uint>> moves, Board board, Piece king) { uint kx = king.getX(); uint ky = king.getY(); List<Piece> threats = new List<Piece>(); // Make sure no new checks are created by King moving. if (board.getSquareAt(kx, ky).getEnemyCover(king.getColour())) { // King is in check, get all threats for (uint y = 0; y < Board.BOARD_SIZE_Y; y++) { for (uint x = 0; x < Board.BOARD_SIZE_X; x++) { Piece p = board.getPieceAt(x, y); if (p != null && p.getColour() != king.getColour()) { List<Tuple<uint,uint>> cover = Rules.getCover(board, p); if (cover.Contains(new Tuple<uint,uint>(kx, ky))) { threats.Add(p); } } } } } foreach (Piece threat in threats) { if (threat is Pawn || threat is King || threat is Knight) { continue; } // Get relative position of threat uint tx = threat.getX(); uint ty = threat.getY(); int xMod; int yMod; if (tx > kx) xMod = -1; else if (tx < kx) xMod = 1; else xMod = 0; if (ty > ky) yMod = -1; else if (ty < ky) yMod = 1; else yMod = 0; // Get square on the other side of king relative to the threat. int x = (int) kx + xMod; int y = (int) ky + yMod; if (board.withinBoard(x, y)) { List<Tuple<uint, uint>> tmp = new List<Tuple<uint, uint>>(moves); foreach (Tuple<uint,uint> move in tmp) { if (move.Item1 == x && move.Item2 == y) { moves.Remove(move); } } } } }
// Filters out moves that would result in a check on the king. public static void checkFilter(ref List<Tuple<uint, uint>> moves, Board board, Piece piece) { string colour = piece.getColour(); // Find king square Square kingSquare = null; for (uint j = 0; j < Board.BOARD_SIZE_Y; j++) { for (uint i = 0; i < Board.BOARD_SIZE_X; i++) { kingSquare = board.getSquareAt(i, j); if (kingSquare.getPiece() is King && kingSquare.getPiece().getColour() == colour) { break; } } if (kingSquare.getPiece() is King && kingSquare.getPiece().getColour() == colour) { break; } } // Get king position uint xKing = kingSquare.getX(); uint yKing = kingSquare.getY(); // Check if king has more than one threat if ((colour == "white" && kingSquare.getBlackCover() > 1) || (colour == "black" && kingSquare.getWhiteCover() > 1)) { moves.Clear(); } else if ((colour == "white" && kingSquare.getBlackCover() == 1) || (colour == "black" && kingSquare.getWhiteCover() == 1)) { Piece threat = null; // Get all squares with cover of king Piece possibleThreat; for (uint j = 0; j < Board.BOARD_SIZE_Y; j++) { for (uint i = 0; i < Board.BOARD_SIZE_X; i++) { possibleThreat = board.getPieceAt(j, i); if (possibleThreat != null && possibleThreat.getColour() != colour) { // Enemy piece, check if threat List<Tuple<uint, uint>> cover = Rules.getCover(board, possibleThreat); foreach (Tuple<uint, uint> t in cover) { if (t.Item1 == xKing && t.Item2 == yKing) { // Threat threat = possibleThreat; break; } } } if (threat != null) break; } if (threat != null) break; } // Remove all moves that do not resolve the check List<Tuple<uint, uint>> tmpMoves = new List<Tuple<uint, uint>>(moves); Piece p = threat; if (p is Knight || p is Pawn) { // Must take threat foreach (Tuple<uint, uint> move in tmpMoves) { if (move.Item1 != threat.getX() || move.Item2 != threat.getY()) { // Will not take, remove moves.Remove(move); } } } tmpMoves = new List<Tuple<uint, uint>>(moves); if (p is Rook || p is Queen) { // Must take or block threat foreach (Tuple<uint, uint> move in tmpMoves) { if (xKing == p.getX()) { // Same x if (!(move.Item1 == xKing && // Move will move to same x ((yKing > move.Item2 && move.Item2 >= p.getY()) || // Move will block or take when King to the right of Rook (yKing < move.Item2 && move.Item2 <= p.getY())))) // Move will block or take when King to the left of Rook { // Will not block or take moves.Remove(move); } } else if (yKing == p.getY()) { // Same y if (!(move.Item2 == yKing && // Move will move to same y ((xKing > move.Item1 && move.Item1 >= p.getX()) || // Move will block or take when King above Rook (xKing < move.Item1 && move.Item1 <= p.getX())))) // Move will block or take when King below Rook { // Will not block or take moves.Remove(move); } } } } tmpMoves = new List<Tuple<uint, uint>>(moves); if ((p is Bishop || p is Queen) && !(xKing == p.getX() || yKing == p.getY())) { // Must take or block threat int xMod = (xKing > p.getX() ? -1 : 1); int yMod = (yKing > p.getY() ? -1 : 1); // Step from King to Threat int steps = (int)Math.Abs((int)xKing - (uint)p.getX()); foreach (Tuple<uint, uint> move in tmpMoves) { // Search for any blocking or taking moves int x = (int)xKing; int y = (int)yKing; bool foundGoodMove = false; for (int i = 0; i < steps; i++) { x += xMod; y += yMod; if (move.Item1 == x && move.Item2 == y) { foundGoodMove = true; break; } } // Remove if no good move if (!foundGoodMove) { moves.Remove(move); } } } } // ---------------------------------------------------------------------------------------- // Make sure that no new check is created by a move if (board.getSquareAt(piece.getX(), piece.getY()).getEnemyCover(colour)) { // Empty list of squares with cover of this square List<Piece> threats = new List<Piece>(); // Get all squares with cover of self Piece p; for (uint j = 0; j < Board.BOARD_SIZE_X; j++) { for (uint i = 0; i < Board.BOARD_SIZE_Y; i++) { p = board.getPieceAt(j, i); if (p != null && p.getColour() != colour) { // Remove impossible cases if (p is King || p is Knight || p is Pawn) { continue; } // Enemy piece, check if threat List<Tuple<uint, uint>> cover = Rules.getCover(board, p); foreach (Tuple<uint, uint> t in cover) { if (t.Item1 == piece.getX() && t.Item2 == piece.getY()) { // Threat threats.Add(p); } } } } } // Check each threat for possible new check Piece realThreat = null; int xMod = 0, yMod = 0; foreach (Piece threat in threats) { int threatX = (int)threat.getX(); int threatY = (int)threat.getY(); int x = (int)piece.getX(); int y = (int)piece.getY(); // Find relative position of the threat if (threatX > x) xMod = -1; // Threat to the right else if (threatX == x) xMod = 0; // Threat at same x else xMod = 1; // Treat to the left if (threatY > y) yMod = -1; // Threat above else if (threatY == y) yMod = 0; // Threat at same y else yMod = 1; // Treat below // Step from self away from threat. // If king is the first piece found, this is the real threatening piece. Piece firstPiece; while (true) { x += xMod; y += yMod; if (!board.withinBoard(x, y)) { break; } firstPiece = board.getPieceAt((uint)x, (uint)y); if (firstPiece != null) { if (firstPiece is King && firstPiece.getColour() == piece.getColour()) { // This is the friendly king. realThreat = threat; } break; } } if (realThreat != null) { // Real threat found. break; } } // If a real new threat is found; remove any moves that do not end on the // line between this and king. if (realThreat != null) { int x = (int)realThreat.getX(); int y = (int)realThreat.getY(); List<Tuple<uint, uint>> possibleMoves = new List<Tuple<uint, uint>>(); // First get all the squares that are on a line between the threat piece and the king, // including the threat, excluding the king. while (true) { possibleMoves.Add(new Tuple<uint, uint>((uint)x, (uint)y)); x += xMod; y += yMod; if (x == xKing && y == yKing) { // End of possible moves. break; } } // Remove any moves not in possible list. List<Tuple<uint, uint>> tmp = new List<Tuple<uint, uint>>(moves); foreach (Tuple<uint, uint> move in tmp) { if (!possibleMoves.Contains(move)) { moves.Remove(move); } } } } }