public ChessBoard(ChessBoard copy) { // init piece position lists Pieces = new Dictionary<Player, List<position_t>>(); Pieces.Add(Player.BLACK, new List<position_t>()); Pieces.Add(Player.WHITE, new List<position_t>()); // init board grid to copy locations Grid = new piece_t[8][]; for (int i = 0; i < 8; i++) { Grid[i] = new piece_t[8]; for (int j = 0; j < 8; j++) { Grid[i][j] = new piece_t(copy.Grid[i][j]); // add piece location to list if (Grid[i][j].piece != Piece.NONE) Pieces[Grid[i][j].player].Add(new position_t(j, i)); } } // copy last known move LastMove = new Dictionary<Player, position_t>(); LastMove[Player.BLACK] = new position_t(copy.LastMove[Player.BLACK]); LastMove[Player.WHITE] = new position_t(copy.LastMove[Player.WHITE]); // copy king locations Kings = new Dictionary<Player, position_t>(); Kings[Player.BLACK] = new position_t(copy.Kings[Player.BLACK]); Kings[Player.WHITE] = new position_t(copy.Kings[Player.WHITE]); }
BitboardLayer[] pieceLocations; //0 is white, 1 is black #endregion Fields #region Constructors public AttackedSquaresGetter(ChessBoard c) { lastUpdated = new int[64]; this.c = c; pieceLocations = new BitboardLayer[2]; currAttackedSquares = new BitboardLayer[2][]; kingAttackedSquares = new BitboardLayer[2]; allAttackedSq = new BitboardLayer[2]; allValidMoves = new BitboardLayer[2]; currValidMoves = new BitboardLayer[2][]; currPinnedPcs = new List<int[]>[2]; currCheckers = new List<int[]>[2]; canCastle = new bool[2][]; for (int i = 0; i < 2; i++) { pieceLocations[i] = new BitboardLayer(); currAttackedSquares[i] = new BitboardLayer[64]; kingAttackedSquares[i] = new BitboardLayer(); currValidMoves[i] = new BitboardLayer[64]; allValidMoves[i] = new BitboardLayer(); allAttackedSq[i] = new BitboardLayer(); currPinnedPcs[i] = new List<int[]>(); canCastle[i] = new bool[] { false, false }; currCheckers[i] = new List<int[]>(); for (int j = 0; j < 64; j++) { currAttackedSquares[i][j] = new BitboardLayer(); currValidMoves[i][j] = new BitboardLayer(); } } numIterations = 0; updatePosition(true, new int[] { 63, 63 }); updatePosition(false, new int[] { 0, 0 }); }
private void Awake() { data.seed = DateTime.Now.ToString(); board = new Chess.ChessBoard(); searchP1 = new CurveSearch <Chess.ChessBoard, Chess.ChessMove, ChessStrategy, ChessTactic>(board, data, strategies); searchP2 = new CurveSearch <Chess.ChessBoard, Chess.ChessMove, ChessStrategy, ChessTactic>(board, data, strategies); searchP1.PlayerOne = true; searchP2.PlayerOne = false; pieces = new VisualPiece[32]; for (int i = 0; i < 32; i++) { pieces[i] = new VisualPiece(); } boardVisualStart = -size / 2 + size / 16; nodeSize = size / 8; SpriteRenderer renderer = boardVisual.GetComponent <SpriteRenderer>(); Bounds bounds = renderer.sprite.bounds; float boundsSize = bounds.size.x; boardVisual.localScale = new Vector2(size, size) / boundsSize; UpdateBoard(); thread = new Thread(Cycle) { IsBackground = true }; //thread.Start(); }
Dictionary<ulong[][], int> transTable; //stores transpositions - pre-calculated positions we've already searched for and already know the point value of #endregion Fields #region Constructors public AI(ChessBoard c, bool isWhite, int searchDepth, MainForm f) { transTable = new Dictionary<ulong[][], int>(); expectedMovesTable = new Dictionary<ulong[][], int[]>(); this.searchDepth = searchDepth; gui = f; }
public int[][] alphaBeta(ChessBoard cb, bool isWhite, int depth, int alpha, int beta, int[] move, bool isMyMove) { numIterations++; if (numIterations == 32974) { gui.addText("Found error"); } //GOAL: minimize beta (starts at infinity) and maximize alpha (starts at neg. infinity) bool isWhiteMove = isWhite ^ isMyMove; //problem is in sortalphabeta List<int[]> possibleMoves = depth > 1 ? sortAlphaBeta(cb, isWhiteMove, getPossibleMoves(cb, isWhiteMove)) : getPossibleMoves(cb, isWhiteMove); int numMoves = possibleMoves.Count; if (depth == 0 || numMoves == 0) { int i = Rating.rating(isWhite, cb, numMoves, searchDepth); return new int[][] { move, new int[] { i } }; } isMyMove = !isMyMove; foreach (int[] currMove in possibleMoves) { numIterations++; if (depth == searchDepth) { gui.stepProgBarBy((int)(100 / possibleMoves.Count)); gui.addText("Currently searching move: [" + currMove[0] + ", " + currMove[1] + "] (alpha = " + alpha + ", beta = " + beta + ")\n"); } if (numIterations == 5053) { gui.addText("Found error!"); } cb.movePiece(isWhiteMove, currMove[0], currMove[1], true); int[][] retVal = alphaBeta(cb, isWhite, depth - 1, alpha, beta, currMove, isMyMove); cb.undoMove(isWhiteMove); if (!matchesMoveList(cb)) { gui.addText("Found error!"); } if (!isMyMove) { //is min node if (retVal[1][0] <= beta) { beta = retVal[1][0]; if (depth == searchDepth) move = retVal[0]; } } else { //is max node if (retVal[1][0] > alpha) { alpha = retVal[1][0]; if (depth == searchDepth) move = retVal[0]; } } if (alpha >= beta) { if (!isMyMove) return new int[][] { move, new int[] { beta } }; else return new int[][] { move, new int[] { alpha } }; } } if (!isMyMove) return new int[][] { move, new int[] { beta } }; else return new int[][] { move, new int[] { alpha } }; }
public ChessBoard(ChessBoard c) { for (int i = 0; i <= pieceIndex.FLAGS; i++) { white[i] = new BitboardLayer(c.getDict(true)[i]); black[i] = new BitboardLayer(c.getDict(false)[i]); } white_ep = c.getEP(true); black_ep = c.getEP(false); moveList = new List<int[]>(c.getMoveList()); moveNum = c.getMoveNum(); ASG = c.getASG(); }
private static int mimaab(ChessBoard board, Player turn, int depth, int alpha, int beta) { // base case, at maximum depth return board fitness if (depth >= DEPTH) return board.fitness(MAX); else { List<ChessBoard> boards = new List<ChessBoard>(); // get available moves / board states from moves for the current player foreach (position_t pos in board.Pieces[turn]) { if (STOP) return -1; // interupts List<position_t> moves = LegalMoveSet.getLegalMove(board, pos); foreach (position_t move in moves) { if (STOP) return -1; // interupts ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, move)); boards.Add(b2); } } int a = alpha, b = beta; if (turn != MAX) // minimize { foreach (ChessBoard b2 in boards) { if (STOP) return -1; // interupt b = Math.Min(b, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b)); if (a >= b) return a; } return b; } else // maximize { foreach (ChessBoard b2 in boards) { if (STOP) return -1; // interupt a = Math.Max(a, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b)); if (a >= b) return b; } return a; } } }
static void Main(string[] args) { ChessBoard masa = new ChessBoard(); //masa.placeWhiteFigures(); //masa.placeBlackFigures(); //Console.WriteLine(masa); Console.WriteLine(masa); Queen C = new Queen('A', 2, true); Queen D = new Queen('B',3, true); Queen S = new Queen('C', 4, true); masa.placeFigure(C); masa.placeFigure(D); masa.placeFigure(S); Console.WriteLine(masa.PathBetweenBoxesFree(masa.getChessBoxByCoordinates('C', 4), masa.getChessBoxByCoordinates('A', 2))); Console.WriteLine(masa); }
public Form1() { InitializeComponent(); var context =new Context(); var board = new ChessBoard(context); board.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0); Text = "Chess"; //this.Controls.Add(board); ClientSize = new Size(board.ClientSize.Width + 50, board.ClientSize.Height) ; var panel = new FlowLayoutPanel(); panel.Size = ClientSize; this.Controls.Add(panel); panel.Controls.Add(board); var pnl2 = createPanel(board.ClientSize.Height,string.Empty); panel.Controls.Add(pnl2); pnl2.Controls.Add(createPanel(board.ClientSize.Height/2, context.Players[PlayerNo.One].PlayerName )); pnl2.Controls.Add(createPanel(board.ClientSize.Height / 2, context.Players[PlayerNo.Two].PlayerName)); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; }
public bool matchesMoveList(ChessBoard cb) { ChessBoard test = new ChessBoard(null, null); var moveList = cb.getMoveList(); for (int i = 0; i < moveList.Count; i++) { test.movePiece(i % 2 == 0, moveList[i][0], moveList[i][1], true); } //return cb.equals(test); return displayBoard(cb).Equals(displayBoard(test)); }
List<int[]> getPossibleMoves(ChessBoard c, bool isWhite) { var retVal = new List<int[]>(); BitboardLayer[] dict = c.getDict(isWhite); BitboardLayer[] enemyDict = c.getDict(!isWhite); foreach (int i in dict[pieceIndex.ALL_LOCATIONS].getTrueIndicies()) { BitboardLayer pieceMoves = c.getValidMoves(isWhite, i); foreach (int j in pieceMoves.getTrueIndicies()) { retVal.Add(new int[] { i, j }); } } return retVal; }
protected void changeTileForPiece(ref Tile startingTile, ref Tile destinationTile, ref ChessBoard chess) // moves pieces ignoring conditions { if (destinationTile.PieceInside != null) { for (int i = 0; i < 32; i++) { if (chess.Pieces[i] != null) { if (chess.Pieces[i].Position == destinationTile) { chess.Pieces[i] = null; break; } } } } for (int i = 0; i < 32; i++) { if (chess.Pieces[i] != null) { if (chess.Pieces[i].Position == startingTile) { Position.PieceInside = null; chess.Pieces[i].Position = destinationTile; chess.Pieces[i].Position.PieceInside = chess.Pieces[i]; if (chess.Pieces[i] is Pawn) // pawns' first movement { Pawn p = (Pawn)chess.Pieces[i]; p.HasMoved = true; } startingTile = null; return; } } } }
public int[][] getAIMove(ChessBoard cb, bool isWhite, int depth) { gui.resetProgBar(); searchDepth = depth; int[][] retVal = alphaBeta(cb, isWhite, depth, int.MinValue, int.MaxValue, new int[0], false); gui.addText("***\nAlphabeta is done.\n***"); gui.stepProgBarBy(100); return retVal; }
public override bool move(ref Tile startingTile, ref Tile destinationTile, ChessBoard chess) { if (destinationTile.PieceInside != null) { if (destinationTile.PieceInside.IsWhite == IsWhite) { return(false); } } King blackKing = (King)chess.Pieces[20]; King whiteKing = (King)chess.Pieces[21]; bool isClear = true; if (destinationTile.RowInBoard > Position.RowInBoard && destinationTile.ColumnInBoard > Position.ColumnInBoard && Math.Abs(Position.RowInBoard - destinationTile.RowInBoard) == Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard)) { for (int i = 1; i < Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard); i++) { if (chess.Tiles[Position.RowInBoard + i, Position.ColumnInBoard + i].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } if (destinationTile.RowInBoard > Position.RowInBoard && destinationTile.ColumnInBoard < Position.ColumnInBoard && Math.Abs(Position.RowInBoard - destinationTile.RowInBoard) == Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard)) { for (int i = 1; i < Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard); i++) { if (chess.Tiles[Position.RowInBoard + i, Position.ColumnInBoard - i].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } if (destinationTile.RowInBoard < Position.RowInBoard && destinationTile.ColumnInBoard < Position.ColumnInBoard && Math.Abs(Position.RowInBoard - destinationTile.RowInBoard) == Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard)) { for (int i = 1; i < Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard); i++) { if (chess.Tiles[Position.RowInBoard - i, Position.ColumnInBoard - i].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } if (destinationTile.RowInBoard < Position.RowInBoard && destinationTile.ColumnInBoard > Position.ColumnInBoard && Math.Abs(Position.RowInBoard - destinationTile.RowInBoard) == Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard)) { for (int i = 1; i < Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard); i++) { if (chess.Tiles[Position.RowInBoard - i, Position.ColumnInBoard + i].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } int minPosition; if (destinationTile.ColumnInBoard == Position.ColumnInBoard) { minPosition = Math.Min(Position.RowInBoard, destinationTile.RowInBoard); for (int i = 1; i < Math.Abs(Position.RowInBoard - destinationTile.RowInBoard); i++) { if (chess.Tiles[minPosition + i, Position.ColumnInBoard].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } if (destinationTile.RowInBoard == Position.RowInBoard) { minPosition = Math.Min(Position.ColumnInBoard, destinationTile.ColumnInBoard); for (int i = 1; i < Math.Abs(Position.ColumnInBoard - destinationTile.ColumnInBoard); i++) { if (chess.Tiles[Position.RowInBoard, minPosition + i].PieceInside != null) { isClear = false; break; } } if (IsWhite) { if (isClear && allowMove(ref chess, ref destinationTile) && whiteKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } else { if (isClear && allowMove(ref chess, ref destinationTile) && blackKing.canMoveBeforeKing(ref chess, ref destinationTile, this) && !IsWhite) { changeTileForPiece(ref startingTile, ref destinationTile, ref chess); return(true); } } isClear = true; } return(false); }
public override List <Position> GetAListOfMoves(ChessBoard chessBoard, TypeMove typeMove) { List <Position> listOfMoves = new List <Position>(); int side; if (this.color == ChessColor.White) { side = -1; } else { side = +1; } if (typeMove == TypeMove.Move) { ChessBoard tmpChessBoard = (ChessBoard)chessBoard.Clone(); tmpChessBoard.Move(this.position, new Position { V = this.position.V + (1 * side), H = this.position.H }); //UP if (chessBoard.Board[this.position.V + (1 * side), this.position.H].piece == null && tmpChessBoard.CheckKingAttacked(this.color) ) { listOfMoves.Add(new Position { V = this.position.V + (1 * side), H = this.position.H }); //UP2 if (first && chessBoard.Board[this.position.V + (2 * side), this.position.H].piece == null) { listOfMoves.Add(new Position { V = this.position.V + (2 * side), H = this.position.H }); } } //L if (this.position.H - 1 > 0) { if ( ( chessBoard.Board[this.position.V + (1 * side), this.position.H - 1].piece != null && chessBoard.Board[this.position.V + (1 * side), this.position.H - 1].piece.color != this.color ) || ( chessBoard.Board[this.position.V, this.position.H - 1].piece is Pawn && ((Pawn)chessBoard.Board[this.position.V, this.position.H - 1].piece).takeOnTheAisle && chessBoard.Board[this.position.V, this.position.H - 1].piece.color != this.color ) ) { tmpChessBoard = (ChessBoard)chessBoard.Clone(); tmpChessBoard.Move(this.position, new Position { V = this.position.V + (1 * side), H = this.position.H - 1 }); if (tmpChessBoard.CheckKingAttacked(this.color)) { listOfMoves.Add(new Position { V = this.position.V + (1 * side), H = this.position.H - 1 }); } } } //R if (this.position.H + 1 < 9) { if ( ( chessBoard.Board[this.position.V + (1 * side), this.position.H + 1].piece != null && chessBoard.Board[this.position.V + (1 * side), this.position.H + 1].piece.color != this.color ) || ( chessBoard.Board[this.position.V, this.position.H + 1].piece is Pawn && ((Pawn)chessBoard.Board[this.position.V, this.position.H + 1].piece).takeOnTheAisle && chessBoard.Board[this.position.V, this.position.H + 1].piece.color != this.color ) ) { tmpChessBoard = (ChessBoard)chessBoard.Clone(); tmpChessBoard.Move(this.position, new Position { V = this.position.V + (1 * side), H = this.position.H + 1 }); if (tmpChessBoard.CheckKingAttacked(this.color)) { listOfMoves.Add(new Position { V = this.position.V + (1 * side), H = this.position.H + 1 }); } } } } else { //L if (this.position.H - 1 > 0) { listOfMoves.Add(new Position { V = this.position.V + (1 * side), H = this.position.H - 1 }); } //R if (this.position.H + 1 < 9) { listOfMoves.Add(new Position { V = this.position.V + (1 * side), H = this.position.H + 1 }); } } return(listOfMoves); }
private static List<position_t> Pawn(ChessBoard board, position_t pos, bool verify_check = true) { List<position_t> moves = new List<position_t>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == Piece.NONE) return moves; // gather relative moves List<position_t> relative = new List<position_t>(); relative.Add(new position_t(-1, 1 * ((p.player == Player.BLACK) ? -1 : 1))); relative.Add(new position_t(0, 1 * ((p.player == Player.BLACK) ? -1 : 1))); relative.Add(new position_t(0, 2 * ((p.player == Player.BLACK) ? -1 : 1))); relative.Add(new position_t(1, 1 * ((p.player == Player.BLACK) ? -1 : 1))); // iterate moves foreach (position_t move in relative) { position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number); // bounds check if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) continue; // double forward move if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE && Math.Abs(moved.number - pos.number) == 2) { // check the first step int step = -((moved.number - pos.number) / (Math.Abs(moved.number - pos.number))); bool hasnt_moved = pos.number == ((p.player == Player.BLACK) ? 6 : 1); if (board.Grid[moved.number + step][moved.letter].piece == Piece.NONE && hasnt_moved) { moves.Add(moved); } } // if it's not blocked we can move forward else if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == Piece.NONE) { moves.Add(moved); } // angled attack else if (moved.letter != pos.letter && board.Grid[moved.number][moved.letter].piece != Piece.NONE && board.Grid[moved.number][moved.letter].player != p.player) { moves.Add(moved); } // en passant else if(isEnPassant(board, new move_t(pos,moved))) { moves.Add(moved); } } if (verify_check)// make sure each move doesn't put us in check { for (int i = moves.Count - 1; i >= 0; i--) { ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i])); if (isCheck(b2, p.player)) { moves.RemoveAt(i); } } } return moves; }
/// <summary> /// Slide along the path steps until you hit something. Return path to point and if it ends attacking with the attack. /// </summary> private static List<position_t> Slide(ChessBoard board, Player p, position_t pos, position_t step) { List<position_t> moves = new List<position_t>(); for (int i = 1; i < 8; i++) { position_t moved = new position_t(pos.letter + i * step.letter, pos.number + i * step.number); if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) break; if (board.Grid[moved.number][moved.letter].piece != Piece.NONE) { if (board.Grid[moved.number][moved.letter].player != p) moves.Add(moved); break; } moves.Add(moved); } return moves; }
private static List<position_t> Knight(ChessBoard board, position_t pos, bool verify_check = true) { List<position_t> moves = new List<position_t>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == Piece.NONE) return moves; // collect all relative moves possible List<position_t> relative = new List<position_t>(); relative.Add(new position_t(2, 1)); relative.Add(new position_t(2, -1)); relative.Add(new position_t(-2, 1)); relative.Add(new position_t(-2, -1)); relative.Add(new position_t(1, 2)); relative.Add(new position_t(-1, 2)); relative.Add(new position_t(1, -2)); relative.Add(new position_t(-1, -2)); // iterate moves foreach (position_t move in relative) { position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number); // bounds check if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) continue; // if empty space or attacking if (board.Grid[moved.number][moved.letter].piece == Piece.NONE || board.Grid[moved.number][moved.letter].player != p.player) moves.Add(moved); } if (verify_check)// make sure each move doesn't put us in check { for (int i = moves.Count - 1; i >= 0; i--) { ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i])); if (isCheck(b2, p.player)) { moves.RemoveAt(i); } } } return moves; }
private static List<position_t> Rook(ChessBoard board, position_t pos, bool verify_check = true) { List<position_t> moves = new List<position_t>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == Piece.NONE) return moves; // slide along vert/hor for possible moves moves.AddRange(Slide(board, p.player, pos, new position_t(1, 0))); moves.AddRange(Slide(board, p.player, pos, new position_t(-1, 0))); moves.AddRange(Slide(board, p.player, pos, new position_t(0, 1))); moves.AddRange(Slide(board, p.player, pos, new position_t(0, -1))); if (verify_check)// make sure each move doesn't put us in check { for (int i = moves.Count - 1; i >= 0; i--) { ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moves[i])); if (isCheck(b2, p.player)) { moves.RemoveAt(i); } } } return moves; }
private static bool allowCastle(ChessBoard board, Player player, position_t pos, bool isRight) { bool isValid = true; int rookPos; int kingDirection; if (isRight) { rookPos = 7; kingDirection = 1; } else { rookPos = 0; kingDirection = -1; } //Check for valid right castling // Is the peice at H,7 a rook owned by the player and has it moved if (board.Grid[pos.number][rookPos].piece == Piece.ROOK && board.Grid[pos.number][rookPos].player == player && board.Grid[pos.number][rookPos].lastPosition.Equals(new position_t(-1,-1))) { // Check that the adjacent two squares are empty for (int i = 0; i < 2; i++) { if (board.Grid[pos.number][pos.letter + (i + 1) * kingDirection].piece != Piece.NONE) { isValid = false; break; } } // Don't bother running secondary checks if the way isn't even clear if (isValid) { for (int i = 0; i < 2; i++) { // Move kings postion over i squares to check if king is passing over an attackable // square ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, new position_t(pos.letter + (i + 1) * kingDirection, pos.number))); // Attackable square is in between king and rook so // its not possible to castle to the right rook if (isCheck(b2, player)) { isValid = false; break; } } } } else { isValid = false; } return isValid; }
private static List<position_t> King(ChessBoard board, position_t pos, bool verify_check = true) { List<position_t> moves = new List<position_t>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == Piece.NONE) return moves; // collect all relative moves possible List<position_t> relative = new List<position_t>(); relative.Add(new position_t(-1, 1)); relative.Add(new position_t(0, 1)); relative.Add(new position_t(1, 1)); relative.Add(new position_t(-1, 0)); relative.Add(new position_t(1, 0)); relative.Add(new position_t(-1, -1)); relative.Add(new position_t(0, -1)); relative.Add(new position_t(1, -1)); // Iterate moves foreach (position_t move in relative) { position_t moved = new position_t(move.letter + pos.letter, move.number + pos.number); // bound check if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) continue; // if it's not blocked we can move if (board.Grid[moved.number][moved.letter].piece == Piece.NONE || board.Grid[moved.number][moved.letter].player != p.player) { if (verify_check) // make sure we don't put ourselves in check { ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, moved)); if(!isCheck(b2, p.player)) { moves.Add(moved); } } else { moves.Add(moved); } } } // Castling /* A king can only castle if: * king has not moved * rook has not moved * king is not in check * king does not end up in check * king does not pass through any other peieces * king does not pass through any squares under attack * king knows secret handshake */ if (verify_check) { if (!isCheck(board, p.player) && p.lastPosition.Equals(new position_t(-1,-1))) { bool castleRight = allowCastle(board, p.player, pos, true); bool castleLeft = allowCastle(board, p.player, pos, false); if (castleRight) { moves.Add(new position_t(6, pos.number)); } if (castleLeft) { moves.Add(new position_t(2, pos.number)); } } } return moves; }
/// <summary> /// Checks to see if the king for a player is in check. This function /// works by pretending the king is each of the different board pieces and seeing if it can attack /// any of the same type of price from its current position. /// </summary> /// <param name="b">Board state</param> /// <param name="king">the currnet player</param> /// <returns>Is in check</returns> public static bool isCheck(ChessBoard b, Player king) { if (b.Kings.Count == 0) return true; position_t king_pos = b.Kings[king]; if (king_pos.number < 0 || king_pos.letter < 0) return true; Piece[] pieces = { Piece.PAWN, Piece.ROOK, Piece.KNIGHT, Piece.BISHOP, Piece.QUEEN, Piece.KING }; ChessBoard tempBoard = new ChessBoard(b); for (int i = 0; i < 6; i++) { tempBoard.Grid[king_pos.number][king_pos.letter] = new piece_t(pieces[i], king); List<position_t> moves = getLegalMove(tempBoard, king_pos, false); foreach (var move in moves) { if (b.Grid[move.number][move.letter].piece == pieces[i] && b.Grid[move.number][move.letter].player != king) { return true; } } } return false; }
public abstract bool move(ref Tile startingTile, ref Tile destinationTile, ChessBoard chess); // checks if the move is valid and moves if valid
public static bool isEnPassant(ChessBoard b, move_t m) { // step = where opposite pawn is int step = ((b.Grid[m.from.number][m.from.letter].player == Player.WHITE) ? -1 : 1); // true if // move is pawn // space is blank // move is diagonal // opposite pawn exists at step // the last move for opposite player was the pawn // the last move for opposite pawn was the double jump return ( b.Grid[m.from.number][m.from.letter].piece == Piece.PAWN && b.Grid[m.to.number][m.to.letter].piece == Piece.NONE && m.to.letter != m.from.letter && b.Grid[m.to.number + step][m.to.letter].piece == Piece.PAWN && b.LastMove[(b.Grid[m.from.number][m.from.letter].player == Player.WHITE) ? Player.BLACK : Player.WHITE].Equals(new position_t(m.to.letter, m.to.number + step)) && Math.Abs(b.Grid[m.to.number + step][m.to.letter].lastPosition.number - (m.to.number + step)) == 2 //jumped from last position ); }
public GameView() { board = new ChessBoard(playerwhite, playerblack); rules = new RulesEngine(board); }
public ChessBoard(ChessBoard b) : this(b.Board.Clone() as int[]) { }
/// <summary> /// Determine if the provided player has any valid moves. /// </summary> /// <param name="b">The state of the game.</param> /// <param name="player">The player.</param> /// <returns>True if the player has moves.</returns> public static bool hasMoves(ChessBoard b, Player player) { foreach(position_t pos in b.Pieces[player]) if (b.Grid[pos.number][pos.letter].piece != Piece.NONE && b.Grid[pos.number][pos.letter].player == player && getLegalMove(b, pos).Count > 0) return true; return false; }
public override void attackTile(ref ChessBoard chess) { for (int i = Position.RowInBoard + 1; i < 8; i++) { if (chess.Tiles[i, Position.ColumnInBoard].PieceInside == null) { if (IsWhite) { chess.Tiles[i, Position.ColumnInBoard].UnderWhiteAttack = true; } else { chess.Tiles[i, Position.ColumnInBoard].UnderBlackAttack = true; } } else { if (IsWhite) { chess.Tiles[i, Position.ColumnInBoard].UnderWhiteAttack = true; } else { chess.Tiles[i, Position.ColumnInBoard].UnderBlackAttack = true; } break; } } for (int i = Position.RowInBoard - 1; i >= 0; i--) { if (chess.Tiles[i, Position.ColumnInBoard].PieceInside == null) { if (IsWhite) { chess.Tiles[i, Position.ColumnInBoard].UnderWhiteAttack = true; } else { chess.Tiles[i, Position.ColumnInBoard].UnderBlackAttack = true; } } else { if (IsWhite) { chess.Tiles[i, Position.ColumnInBoard].UnderWhiteAttack = true; } else { chess.Tiles[i, Position.ColumnInBoard].UnderBlackAttack = true; } break; } } for (int i = Position.ColumnInBoard + 1; i < 8; i++) { if (chess.Tiles[Position.RowInBoard, i].PieceInside == null) { if (IsWhite) { chess.Tiles[Position.RowInBoard, i].UnderWhiteAttack = true; } else { chess.Tiles[Position.RowInBoard, i].UnderBlackAttack = true; } } else { if (IsWhite) { chess.Tiles[Position.RowInBoard, i].UnderWhiteAttack = true; } else { chess.Tiles[Position.RowInBoard, i].UnderBlackAttack = true; } break; } } for (int i = Position.ColumnInBoard - 1; i >= 0; i--) { if (chess.Tiles[Position.RowInBoard, i].PieceInside == null) { if (IsWhite) { chess.Tiles[Position.RowInBoard, i].UnderWhiteAttack = true; } else { chess.Tiles[Position.RowInBoard, i].UnderBlackAttack = true; } } else { if (IsWhite) { chess.Tiles[Position.RowInBoard, i].UnderWhiteAttack = true; } else { chess.Tiles[Position.RowInBoard, i].UnderBlackAttack = true; } break; } } }
public override void attackTile(ref ChessBoard chess) { if (IsWhite) { try { chess.Tiles[Position.RowInBoard + 1, Position.ColumnInBoard + 2].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 1, Position.ColumnInBoard + 2].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 1, Position.ColumnInBoard - 2].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 1, Position.ColumnInBoard - 2].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 2, Position.ColumnInBoard + 1].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 2, Position.ColumnInBoard + 1].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 2, Position.ColumnInBoard - 1].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 2, Position.ColumnInBoard - 1].UnderWhiteAttack = true; } catch (IndexOutOfRangeException) { } } else { try { chess.Tiles[Position.RowInBoard + 1, Position.ColumnInBoard + 2].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 1, Position.ColumnInBoard + 2].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 1, Position.ColumnInBoard - 2].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 1, Position.ColumnInBoard - 2].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 2, Position.ColumnInBoard + 1].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 2, Position.ColumnInBoard + 1].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard + 2, Position.ColumnInBoard - 1].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } try { chess.Tiles[Position.RowInBoard - 2, Position.ColumnInBoard - 1].UnderBlackAttack = true; } catch (IndexOutOfRangeException) { } } }
public override List <Position> GetAListOfMoves(ChessBoard chessBoard, TypeMove typeMove) { List <Position> listOfMoves = new List <Position>(); //UL bool ul = checkMove(new Position { V = this.position.V - 1, H = this.position.H - 1 }, chessBoard, typeMove); for (int i = this.position.V - 1, j = this.position.H - 1; ul && i > 0 && j > 0; i--, j--) { if (chessBoard.Board[i, j].piece == null) { listOfMoves.Add(new Position { V = i, H = j }); } else { if (chessBoard.Board[i, j].piece.color != this.color) { listOfMoves.Add(new Position { V = i, H = j }); } break; } } //UR bool ur = checkMove(new Position { V = this.position.V - 1, H = this.position.H + 1 }, chessBoard, typeMove); for (int i = this.position.V - 1, j = this.position.H + 1; ur && i > 0 && j < 9; i--, j++) { if (chessBoard.Board[i, j].piece == null) { listOfMoves.Add(new Position { V = i, H = j }); } else { if (chessBoard.Board[i, j].piece.color != this.color) { listOfMoves.Add(new Position { V = i, H = j }); } break; } } //DL bool dl = checkMove(new Position { V = this.position.V + 1, H = this.position.H - 1 }, chessBoard, typeMove); for (int i = this.position.V + 1, j = this.position.H - 1; dl && i < 9 && j > 0; i++, j--) { if (chessBoard.Board[i, j].piece == null) { listOfMoves.Add(new Position { V = i, H = j }); } else { if (chessBoard.Board[i, j].piece.color != this.color) { listOfMoves.Add(new Position { V = i, H = j }); } break; } } //DR bool dr = checkMove(new Position { V = this.position.V + 1, H = this.position.H + 1 }, chessBoard, typeMove); for (int i = this.position.V + 1, j = this.position.H + 1; dr && i < 9 && j < 9; i++, j++) { if (chessBoard.Board[i, j].piece == null) { listOfMoves.Add(new Position { V = i, H = j }); } else { if (chessBoard.Board[i, j].piece.color != this.color) { listOfMoves.Add(new Position { V = i, H = j }); } break; } } return(listOfMoves); }
public Rook(ChessBoard boad, Color color) : base(color, boad) { }
public override bool isLegal(ChessBoard board, Location tryToMoveTo) { return(isLegalBishopMove(board, tryToMoveTo)); }
public string displayBoard(ChessBoard c) { //for debugging purposes //capital letters are white, n's are knights char[] whiteLetters = new char[] { 'P', 'R', 'N', 'B', 'Q', 'K' }; char[] blackLetters = new char[] { 'p', 'r', 'n', 'b', 'q', 'k' }; char[] retVal = new char[64]; for (int i = 0; i < 64; i++) retVal[i] = Convert.ToChar("+"); BitboardLayer[] white = c.getDict(true); BitboardLayer[] black = c.getDict(false); for (int i = 0; i <= pieceIndex.KING; i++){ foreach (int j in white[i].getTrueIndicies()) retVal[j] = whiteLetters[i]; foreach (int j in black[i].getTrueIndicies()) retVal[j] = blackLetters[i]; } string s = ""; for (int i = 0; i < 64; i++){ s += retVal[i]; if (i % 8 == 7) s += "\n"; } var ml = c.getMoveList(); for (int i = 0; i < ml.Count; i++) { s += (i % 2 == 0 ? "White" : "Black") + ": [" + ml[i][0] + ", " + ml[i][1] + "]\n"; } return s; }
public void SetBoard(ChessBoard board) { // if a thread called this, invoke recursion if (this.InvokeRequired) { this.Invoke(new Action(() => SetBoard(board))); return; } // update all tiles on board for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) SetPiece(board.Grid[i][j].piece, board.Grid[i][j].player, j, i); }
public int[] getMoveList(ChessBoard cb) { List<int> retVal = new List<int>(); var moveList = cb.getMoveList(); foreach (int[] i in moveList) { retVal.Add(i[0]); retVal.Add(i[1]); } return retVal.ToArray(); }
/// <summary> /// Get any legal move from the current position on the provided board. /// </summary> /// <param name="board">The state of the game.</param> /// <param name="pos">The piece/position to check for valid moves.</param> /// <param name="verify_check">Whether or not to recurse and check if the current move puts you in check.</param> /// <returns>A list of positions the piece can move to.</returns> public static List<position_t> getLegalMove(ChessBoard board, position_t pos, bool verify_check = true) { piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == Piece.NONE) return new List<position_t>(); switch (p.piece) { case Piece.PAWN: return LegalMoveSet.Pawn(board, pos, verify_check); case Piece.ROOK: return LegalMoveSet.Rook(board, pos, verify_check); case Piece.KNIGHT: return LegalMoveSet.Knight(board, pos, verify_check); case Piece.BISHOP: return LegalMoveSet.Bishop(board, pos, verify_check); case Piece.QUEEN: return LegalMoveSet.Queen(board, pos, verify_check); case Piece.KING: return LegalMoveSet.King(board, pos, verify_check); default: return new List<position_t>(); } }
public List<int[]> sortAlphaBeta(ChessBoard cb, bool isWhite, List<int[]> possibleMoves) { List<int[]> retVal = new List<int[]>(); List<int> valueSet = new List<int>(); for (int i = 0; i < possibleMoves.Count; i++) { numIterations++; if (numIterations == 33000) { gui.addText("Found bug"); } int[] currMove = possibleMoves[i]; cb.movePiece(isWhite, currMove[0], currMove[1], true); valueSet.Add(Rating.rating(isWhite, cb, possibleMoves.Count, searchDepth)); cb.undoMove(isWhite); if (!matchesMoveList(cb)) { gui.addText("More errors!"); } } while (valueSet.Count > 0) { int index = indexOfMax(valueSet); retVal.Add(possibleMoves[index]); possibleMoves.RemoveAt(index); valueSet.RemoveAt(index); } return retVal; }
public static bool PlaceQueens(List <ChessBoard> solutions, ChessBoard board = null, int column = 0) { throw new NotImplementedException(); }
public abstract bool move(ref Tile startingTile, ref Tile destinationTile, ChessBoard chess); // checks if the move is valid and moves if valid public abstract void attackTile(ref ChessBoard chess); // assigns logical attack on tiles
/// <summary> /// Get all legal moves for the player on the current board. /// </summary> /// <param name="b">The state of the game.</param> /// <param name="player">The player whose moves you want.</param> /// <returns>A 1-to-many dictionary of moves from one position to many</returns> public static Dictionary<position_t, List<position_t>> getPlayerMoves(ChessBoard b, Player player) { Dictionary<position_t, List<position_t>> moves = new Dictionary<position_t, List<position_t>>(); foreach (position_t pos in b.Pieces[player]) if (b.Grid[pos.number][pos.letter].piece != Piece.NONE) { if (!moves.ContainsKey(pos)) moves[pos] = new List<position_t>(); moves[pos].AddRange(LegalMoveSet.getLegalMove(b, pos)); } return moves; }
public King(ChessBoard board, Color color, ChessMatch match) : base(board, color) { this.match = match; }
public static move_t MiniMaxAB(ChessBoard board, Player turn) { RUNNING = true; // we've started running STOP = false; // no interupt command sent MAX = turn; // who is maximizing // gather all possible moves Dictionary<position_t, List<position_t>> moves = LegalMoveSet.getPlayerMoves(board, turn); // because we're threading safely store best result from each thread int[] bestresults = new int[moves.Count]; move_t[] bestmoves = new move_t[moves.Count]; // thread the generation of each move Parallel.ForEach(moves, (movelist,state,index) => { if (STOP) // interupt { state.Stop(); return; } // initialize thread best bestresults[index] = int.MinValue; bestmoves[index] = new move_t(new position_t(-1, -1), new position_t(-1, -1)); // for each move for the current piece(thread) foreach (position_t move in movelist.Value) { if (STOP) // interupt { state.Stop(); return; } // make initial move and start recursion ChessBoard b2 = LegalMoveSet.move(board, new move_t(movelist.Key, move)); int result = mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, 1, Int32.MinValue, Int32.MaxValue); // if result is better or best hasn't been set yet if (bestresults[index] < result || (bestmoves[index].to.Equals(new position_t(-1, -1)) && bestresults[index] == int.MinValue)) { bestresults[index] = result; bestmoves[index].from = movelist.Key; bestmoves[index].to = move; } } }); // interupted if (STOP) return new move_t(new position_t(-1, -1), new position_t(-1, -1)); // find the best of the thread results int best = int.MinValue; move_t m = new move_t(new position_t(-1, -1), new position_t(-1, -1)); for(int i = 0; i < bestmoves.Length; i++) { if (best < bestresults[i] || (m.to.Equals(new position_t(-1,-1)) && !bestmoves[i].to.Equals(new position_t(-1,-1)))) { best = bestresults[i]; m = bestmoves[i]; } } return m; }
public Rook(ChessBoard board, Color color) : base(board, color) { }
/// <summary> /// Performs all necessary steps to update the game state and move the pieces. /// </summary> /// <param name="b">The state of the game.</param> /// <param name="m">The desired move.</param> /// <returns>The new state of the game.</returns> public static ChessBoard move(ChessBoard b, move_t m) { // create a copy of the board ChessBoard b2 = new ChessBoard(b); // determine if move is enpassant or castling bool enpassant = (b2.Grid[m.from.number][m.from.letter].piece == Piece.PAWN && isEnPassant(b2, m)); bool castle = (b2.Grid[m.from.number][m.from.letter].piece == Piece.KING && Math.Abs(m.to.letter - m.from.letter) == 2); // update piece list, remove old position from piece list for moving player b2.Pieces[b2.Grid[m.from.number][m.from.letter].player].Remove(m.from); // if move kills a piece directly, remove killed piece from killed player piece list if (b2.Grid[m.to.number][m.to.letter].piece != Piece.NONE && b2.Grid[m.from.number][m.from.letter].player != b2.Grid[m.to.number][m.to.letter].player) b2.Pieces[b2.Grid[m.to.number][m.to.letter].player].Remove(m.to); else if(enpassant) { // if kill was through enpassant determine which direction and remove the killed pawn int step = (b.Grid[m.from.number][m.from.letter].player == Player.WHITE) ? -1 : 1; b2.Pieces[b2.Grid[m.to.number + step][m.to.letter].player].Remove(new position_t(m.to.letter, m.to.number + step)); } else if (castle) { // if no kill but enpassant, update the rook position if (m.to.letter == 6) { b2.Pieces[b2.Grid[m.to.number][m.to.letter].player].Remove(new position_t(7, m.to.number)); b2.Pieces[b2.Grid[m.to.number][m.to.letter].player].Add(new position_t(5, m.to.number)); } else { b2.Pieces[b2.Grid[m.to.number][m.to.letter].player].Remove(new position_t(0, m.to.number)); b2.Pieces[b2.Grid[m.to.number][m.to.letter].player].Remove(new position_t(3, m.to.number)); } } // add the new piece location to piece list b2.Pieces[b2.Grid[m.from.number][m.from.letter].player].Add(m.to); // update board grid b2.Grid[m.to.number][m.to.letter] = new piece_t(b2.Grid[m.from.number][m.from.letter]); b2.Grid[m.to.number][m.to.letter].lastPosition = m.from; b2.Grid[m.from.number][m.from.letter].piece = Piece.NONE; if (enpassant) { // if kill was through enpassant determine which direction and remove the killed pawn int step = (b.Grid[m.from.number][m.from.letter].player == Player.WHITE) ? -1 : 1; b2.Grid[m.to.number + step][m.to.letter].piece = Piece.NONE; } else if (castle) { // if no kill but enpassant, update the rook position if (m.to.letter == 6) { b2.Grid[m.to.number][5] = new piece_t(b2.Grid[m.to.number][7]); b2.Grid[m.to.number][7].piece = Piece.NONE; } else { b2.Grid[m.to.number][3] = new piece_t(b2.Grid[m.to.number][0]); b2.Grid[m.to.number][0].piece = Piece.NONE; } } //promotion if (b2.Grid[m.to.number][m.to.letter].piece == Piece.PAWN) { for (int i = 0; i < 8; i++) { if (b2.Grid[0][i].piece == Piece.PAWN) b2.Grid[0][i].piece = Piece.QUEEN; if (b2.Grid[7][i].piece == Piece.PAWN) b2.Grid[7][i].piece = Piece.QUEEN; } } // update king position if (b2.Grid[m.to.number][m.to.letter].piece == Piece.KING) { b2.Kings[b2.Grid[m.to.number][m.to.letter].player] = m.to; } // update last move b2.LastMove[b2.Grid[m.to.number][m.to.letter].player] = m.to; return b2; }
public bool equals(ChessBoard c) { BitboardLayer[] test_white = c.getDict(true); BitboardLayer[] test_black = c.getDict(false); for (int i = 0; i <= pieceIndex.FLAGS; i++) { if (test_white[i].getLayerData() != white[i].getLayerData()) return false; if (test_black[i].getLayerData() != black[i].getLayerData()) return false; } return true; }
public override bool CanMoveToLocation(int targetCol, int targetRow, ChessBoard gameBoard) { LinkedList <ChessSquare> path = gameBoard.GetDiagonalSquares(Col, Row, targetCol, targetRow); return(CanFollowPath(targetCol, targetRow, path, path.Count)); }
// This abstract method is defined but not implemented by AbstractChessPiece. // Each derived class will have to implement their own version. abstract public bool CanMoveToLocation(int targetCol, int targetRow, ChessBoard gameBoard);
public abstract bool CanMoveTo(ChessBoard board, BoardTile currentTile, BoardTile destinationTile);