Exemplo n.º 1
0
        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;
        }