private Castle CalcNewCastlingOptions(Players player, PlayerPieceSet pieces, int base_row) { // We could deduce base_row value here, but let us pass it is as a // parameter for better(?) performance // Nevertheless, it is worth to check for typos Debug.Assert((player == Players.White && base_row == Chessboard.ROW_MIN) || (player == Players.Black && base_row == Chessboard.ROW_MAX)); var result = Castle.None; if (pieces.KingsCell == ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_E)) { var cell = ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_H); if (IsCanCastleShort(player) && pieces.IsOccupiedCell(cell) && pieces.IsRookAtCell(cell)) { result |= Castle.Short; } cell = ChessboardCell.CalculateValue(base_row, Chessboard.COLUMN_A); if (IsCanCastleLong(player) && pieces.IsOccupiedCell(cell) && pieces.IsRookAtCell(cell)) { result |= Castle.Long; } } return result; }
public static bool IsCellAttackedFromDir(ChessboardCell attacked_cell, ChessboardCell attack_origin, PlayerPieceSet attacker_pieces, PlayerPieceSet defender_pieces) { Debug.Assert(!attacked_cell.IsSame(attack_origin)); int delta_row = attack_origin.Row - attacked_cell.Row; int delta_column = attack_origin.Column - attacked_cell.Column; // Fast check if the two cells are on the same vertical or horizontal line // or one the same diagonal if (delta_row != 0 && delta_column != 0 && delta_row != delta_column && delta_row != -delta_column) { return false; } // Check the ray from attacked_cell towards attack_origin and possibly behind // attack_origin until we reach the edge of the chessboard bool result = false; int row_inc = 0; int column_inc = 0; int iter_count = int.MaxValue; if (delta_row < 0) { row_inc = -1; iter_count = attacked_cell.Row - Chessboard.ROW_MIN; } else if (delta_row > 0) { row_inc = 1; iter_count = Chessboard.ROW_MAX - attacked_cell.Row; } if (delta_column < 0) { column_inc = -1; iter_count = Math.Min(iter_count, attacked_cell.Column - Chessboard.COLUMN_MIN); } else if (delta_column > 0) { column_inc = 1; iter_count = Math.Min(iter_count, Chessboard.COLUMN_MAX - attacked_cell.Column); } int cur_row = attacked_cell.Row; int cur_column = attacked_cell.Column; for (int i = 0; i < iter_count; ++i) { cur_row += row_inc; cur_column += column_inc; Debug.Assert(cur_row >= Chessboard.ROW_MIN && cur_row <= Chessboard.ROW_MAX && cur_column >= Chessboard.COLUMN_MIN && cur_column <= Chessboard.COLUMN_MAX); int cur_cell = ChessboardCell.CalculateValue(cur_row, cur_column); if (defender_pieces.IsOccupiedCell(cur_cell)) { result = false; break; } if (attacker_pieces.IsOccupiedCell(cur_cell)) { if (attacker_pieces.IsQueenAtCell(cur_cell)) { result = true; } else if (row_inc == 0 || column_inc == 0) { result = attacker_pieces.IsRookAtCell(cur_cell); } else { result = attacker_pieces.IsBishopAtCell(cur_cell); } break; } } return result; }