检查网格上对角线的简单方法是什么?

时间:2015-10-02 19:09:07

标签: python loops

我试图在网格上找到所有对角有效的正方形,并将它们的值设置为1.对角线的定义就像Bishop在国际象棋中的运动。

我目前有一些有用的东西,但感觉非常笨重。主要是因为我正在做很多检查,以确保所讨论的对角线方块在数组的范围内。

网格是8x8 ......

消除对角线

        for j in range (1,8):
            diagx1 = randx + j
            diagx2 = randx - j
            diagy1 = randy + j
            diagy2 = randy - j
            if diagx1 <= 7:
                if diagy1 <= 7:
                    setSquare(squares, diagx1, diagy1, 1)
                if diagy2 >= 0:
                    setSquare(squares, diagx1, diagy2, 1)
            if diagx2 >= 0:
                if diagy1 <= 7:
                    setSquare(squares, diagx2, diagy1, 1)
                if diagy2 >= 0:
                    setSquare(squares, diagx2, diagy2, 1)

1 个答案:

答案 0 :(得分:2)

基本上你的方法尽可能简单。您必须进行边界检查,并且必须添加和减去偏移量。你可以改变的是语法。

def in_bounds(coords: tuple) -> bool:
    """Ensures both x and y values are in range(8)"""
    return all( 0 <= coord <= 7 for coord in coords)

origin = (3, 3)
diagonals = []
for offset in range(-8, 8):    # -8, -7, -6, ..., 6, 7
    if offset == 0:  continue  # skip origin
    new_location = origin[0] + offset, origin[1] + offset
    if in_bounds(new_location):
        diagonals.append(in_bounds)

甚至更简单:

origin = (3, 3)
diagonals = [new_location for offset in range(-8, 8)
                          for new_location in [(origin[0] + offset,
                                                origin[1] + offset)]
                          if offset != 0 and in_bounds(new_location)]

您唯一的另一个选择是预先计算您的范围应该是什么,以保持自己的界限。类似的东西:

origin = (5, 3)
# diagonals should be
# # x  y     offset
# # 2, 0     -3
# # 3, 1     -2
# # 4, 2     -1
# # 6, 4      1
# # 7, 5      2

other_origin = (1, 1)
# diagonals should be
# # x  y     offset
# # 0, 0     -1
# # 2, 2      1
# # ...       ...
# # 7, 7      6

get_range(origin:tuple) -> range:
    """returns the range of offsets to produce diagonals"""
    small, large = min(origin), max(origin)
    from = 0 - small
    to = 8 - large
    return range(from, to)

origin = (3, 3)
diagonals = [(origin[0] + offset, origin[1] + offset) 
             for offset in get_range(origin)]

请注意,构建可以找到自己对角线的方块可能是值得的。

class Square(object):
    def __init__(self, x, y, parent=None):
        """A square in a coordinate plane"""
        self.x = x
        self.y = y
        self.parent = parent  # might be a larger container of squares?

    def __add__(self, other):
        if isinstance(other, tuple) and len(other) == 2:
            # hack the tuple into a square so we can add them easily
            other = Square(*tuple)
        try:
            return self.__class__((self.x + other.x, self.y + other.y))
        except AttributeError:
            raise TypeError("type Square can only add to other coordinate plane types")

    def __iter__(self):
        yield self.x
        yield self.y

    def __repr__(self):
        return "Square({}, {})".format(self.x, self.y)

    @staticmethod
    def find_diagonals(origin):
        diagonals = []
        for offset in range(1, 8):
            trial_vectors = [(offset, offset), (-offset, -offset),
                             (offset, -offset), (-offset, offset)]
            result_coords = [origin + vector for vector in trial_vectors]
            diagonals.extend(list(filter(
                origin._in_bounds, result_coords)))
        return diagonals

    @staticmethod
    def _in_bounds(coords):
        return all( 0 <= coord <= 7 for coord in coords)

origin = Square(3, 3)
diagonals = origin.find_diagonals(origin)
# [ Square(2, 2), Square(4, 4), Square(2, 4), Square(4, 2),
#   Square(1, 1), Square(5, 5), Square(1, 5), Square(5, 1),
#   Square(0, 0), Square(6, 6), Square(0, 6), Square(6, 0),
#                 Square(7, 7) ]