public IReadOnlyList <CellId> ValidMovesForCell(CellId cellId, IChessBoard board) { var validMoveList = new List <CellId>(); var source = board.GetCell(cellId); for (int row = 0; row < board.NumRows; row++) { for (int col = 0; col < board.NumCols; col++) { // Figure out the status of the cell. // var target = board.GetCell(CellId.Create(row, col)); if (IsValidMove(source, target, board)) { validMoveList.Add(CellId.Create(row, col)); } } } return(validMoveList); }
private CellId keyFor(int row, int col) { return(CellId.Create(row, col)); }
private void setupQueenRules() { var queenRules = GameRule.Create().Filter(x => x.PieceType == EChessPieceType.Queen); queenRules.InvalidMove((s, t, c) => { // Can not move to our own position. This would cause an indexing issue. // if (s.ColIndex == t.ColIndex && s.RowIndex == t.RowIndex) { return(true); } // Can not move past another piece. // int colDiff = s.ColIndex - t.ColIndex; int rowDiff = s.RowIndex - t.RowIndex; int stepRow = rowDiff > 0 ? -1 : 1; int stepCol = colDiff > 0 ? -1 : 1; if (colDiff == 0) { stepCol = 0; } if (rowDiff == 0) { stepRow = 0; } // Check there is no piece on the way to the target. // for (int step = 1; ; step++) { int row = s.RowIndex + stepRow * step; int col = s.ColIndex + stepCol * step; if (row < 0 || row >= c.NumRows || col < 0 || col >= c.NumCols) { return(true); } // We reached the target it is not an invalid move. // if (row == t.RowIndex && col == t.ColIndex) { return(false); } if (row == c.NumCols - 1 && col == c.NumRows - 1) { return(true); } // We reached another piece, but it can not be the target of our move // therefore this move is not valid. // var cell = c.GetCell(CellId.Create(row, col)); if (cell.PieceType != EChessPieceType.Empty) { return(true); } } }); queenRules.InvalidMove((s, t, c) => { // Can not move to our own position. This would cause an indexing issue. // if (s.ColIndex == t.ColIndex && s.RowIndex == t.RowIndex) { return(true); } // Can not move past another piece. // int colDiff = s.ColIndex - t.ColIndex; int rowDiff = s.RowIndex - t.RowIndex; if (Math.Abs(colDiff) != Math.Abs(rowDiff)) { return(false); // Check its a diagonal move } int stepRow = rowDiff > 0 ? -1 : 1; int stepCol = colDiff > 0 ? -1 : 1; // Check there is no piece on the way to the target. // for (int step = 1; t.ColIndex != s.ColIndex + stepCol * step; step++) { int row = s.RowIndex + stepRow * step; int col = s.ColIndex + stepCol * step; // We reached the target it is not an invalid move. // if (row == t.RowIndex || col == t.ColIndex) { return(false); } if (row == c.NumCols - 1 && col == c.NumRows - 1) { return(true); } // We reached another piece, but it can not be the target of our move // therefore this move is not valid. // var cell = c.GetCell(CellId.Create(row, col)); if (cell.PieceType != EChessPieceType.Empty) { return(true); } } return(false); }); queenRules.ValidMove((s, t, c) => { // Rook can move diagonally or vertically. // int colDiff = Math.Abs(s.ColIndex - t.ColIndex); int rowDiff = Math.Abs(s.RowIndex - t.RowIndex); if (colDiff == 0 || rowDiff == 0) { return(true); } return(false); }); queenRules.ValidMove((s, t, c) => { // Bishop can move diagonally to take any piece. // int colDiff = Math.Abs(s.ColIndex - t.ColIndex); int rowDiff = Math.Abs(s.RowIndex - t.RowIndex); if (colDiff != rowDiff) { return(false); } return(true); }); _gameRules.Add(queenRules); }
private void setupKingRules() { var kingRules = GameRule.Create().Filter(x => x.PieceType == EChessPieceType.King); kingRules.InvalidMove((s, t, c) => { if (t.PieceColor != s.PieceColor) { return(false); } // Can not move to a piece of the same color unless it is a rook. // Some more castle rules are checked below. // if (t.PieceColor == s.PieceColor && t.PieceType == EChessPieceType.Rook) { return(false); } return(true); }); kingRules.ValidMove((s, t, c) => { int colDiff = Math.Abs(s.ColIndex - t.ColIndex); int rowDiff = Math.Abs(s.RowIndex - t.RowIndex); return(colDiff <= 1 && rowDiff <= 1); }); // Setup up the castle, it is only possible if the king and the rook have not been moved before and // there is no piece between the king and the rook. // kingRules.ValidMove((s, t, c) => { // Check the target is a friendly rook. // if (t.PieceType != EChessPieceType.Rook || s.PieceColor != t.PieceColor) { return(false); } // Check the rook and the king have not been moved. // if (c.HasMoved(s.Identifier) || c.HasMoved(t.Identifier)) { return(false); } // Check there is no piece between the king and the rook. // int colDiff = s.ColIndex - t.ColIndex; int colStep = colDiff > 0 ? -1 : 1; for (int step = 1; s.ColIndex + step * colStep != t.ColIndex; step++) { int col = s.ColIndex + step * colStep; var cell = c.GetCell(CellId.Create(s.RowIndex, col)); if (cell.PieceType != EChessPieceType.Empty) { return(false); } } return(true); }); _gameRules.Add(kingRules); }
private void setupBlackBishopRules() { var blackBishopRules = GameRule.Create().Filter(x => x.PieceColor == EChessPieceColor.Black && x.PieceType == EChessPieceType.Bishop); blackBishopRules.InvalidMove((s, t, c) => { // Can not move to a field occupied by a black piece. // return(t.PieceColor == EChessPieceColor.Black); }); blackBishopRules.InvalidMove((s, t, c) => { // Can not move past another piece. // int colDiff = s.ColIndex - t.ColIndex; int rowDiff = s.RowIndex - t.RowIndex; if (Math.Abs(colDiff) != Math.Abs(rowDiff)) { return(false); // Check its a diagonal move } int stepRow = rowDiff > 0 ? -1 : 1; int stepCol = colDiff > 0 ? -1 : 1; // Check there is no piece on the way to the target. // for (int step = 1; t.ColIndex != s.ColIndex + stepCol * step; step++) { int row = s.RowIndex + stepRow * step; int col = s.ColIndex + stepCol * step; // We reached the target it is not an invalid move. // if (row == t.RowIndex || col == t.RowIndex) { return(false); } // We reached another piece, but it can not be the target of our move // therefore this move is not valid. // var cell = c.GetCell(CellId.Create(row, col)); if (cell.PieceType != EChessPieceType.Empty) { return(true); } } return(false); }); blackBishopRules.ValidMove((s, t, c) => { // Bishop can move diagonally to take any piece. // int colDiff = Math.Abs(s.ColIndex - t.ColIndex); int rowDiff = Math.Abs(s.RowIndex - t.RowIndex); if (colDiff != rowDiff) { return(false); } return(true); }); _gameRules.Add(blackBishopRules); }