Exemple #1
0
        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;
        }