0

我这里有一个 python 类方法的怪物。我能想到的唯一方法是一个巨大而丑陋的 if / elif / else 块。你们中的任何人都可以提出任何想法来使它变得更好吗?

对于上下文,这是 pygame 的网格制作库的一部分,并且是一个函数,它获取网格中的一个图块并返回周围的图块。如果 "horizo​​ntal" 设置为 false,它只返回与瓷砖垂直相邻的瓷砖,反之亦然。

def getSurroundingTiles(self, tile, horizontal = True, vertical = True):
    index = list(self.getTiles()).index(tile)
    maxtile = self.sqrtnum - 1 # Offset for 0 indexing

    i = int(math.floor(index / self.sqrtnum))
    j = int(index % self.sqrtnum)

    surroundingTiles = []

    if i == 0 and j == 0:
        #Top left corner
        if horizontal:
            surroundingTiles.extend((self[i + 1][j], self[i][j + 1]))
        if vertical:
            surroundingTiles.append(self[i + 1][j + 1])
    elif i >= maxtile and j == 0:
        #Top right corner
        if horizontal:
            surroundingTiles.extend((self[i - 1][j], self[i][j + 1]))
        if vertical:
            surroundingTiles.append(self[i - 1][j + 1])
    elif i == 0 and j >= maxtile:
        #Bottom left corner
        if horizontal:
            surroundingTiles.extend((self[i + 1][j], self[i][j - 1]))
        if vertical:
            surroundingTiles.append(self[i + 1][j - 1])
    elif i >= maxtile and j >= maxtile:
        #Bottom right corner
        if horizontal:
            surroundingTiles.extend((self[i - 1][j], self[i][j - 1]))
        if vertical:
            surroundingTiles.append(self[i - 1][j - 1])

    elif i == 0:
        #Top border
        if horizontal: 
            surroundingTiles.extend((self[i + 1][j], self[i][j + 1],
                                     self[i][j - 1]))
        if vertical:
            surroundingTiles.extend((self[i + 1][j + 1],
                                     self[i + 1][j - 1]))
    elif i >= maxtile:
        #Bottom border
        if horizontal:
            surroundingTiles.extend((self[i - 1][j], self[i][j + 1],
                                     self[i][j - 1]))
        if vertical:
            surroundingTiles.extend((self[i - 1][j + 1],
                                     self[i - 1][j - 1]))
    elif j == 0:
        #Left border
        if horizontal:
            surroundingTiles.extend((self[i + 1][j], self[i - 1][j],
                                     self[i][j + 1]))
        if vertical:
            surroundingTiles.extend((self[i + 1][j + 1],
                                     self[i - 1][j + 1]))
    elif j >= maxtile:
        #Right border
        if horizontal:
            surroundingTiles.extend((self[i + 1][j], self[i - 1][j],
                                     self[i][j - 1]))
        if vertical:
            surroundingTiles.extend((self[i + 1][j - 1],
                                    self[i - 1][j - 1]))

    else:
        if horizontal:
            surroundingTiles.extend((self[i + 1][j], self[i - 1][j],
                                     self[i][j + 1], self[i][j - 1]))
        if vertical:
            surroundingTiles.extend((self[i + 1][j + 1], self[i + 1][j - 1],
                                    self[i - 1][j + 1], self[i - 1][j - 1]))

    return surroundingTiles
4

2 回答 2

2

尝试这样的事情:

# indices 0 - 3 are for horizontal, 4 - 7 are for vertical
dij = [(0, 1), (1, 0), (0, -1), (-1, 0),
       (1, 1), (1, -1), (-1, 1), (-1, -1)]

def getSurroundingTiles(self, tile, horizontal = True, vertical = True):
    index = list(self.getTiles()).index(tile)
    maxtile = self.sqrtnum - 1 # Offset for 0 indexing

    i = int(math.floor(index / self.sqrtnum))
    j = int(index % self.sqrtnum)

    surroundingTiles = []

    startat = 0 if horizontal else 4
    stopat = 8 if vertical else 4

    for di, dj in dij[startat:stopat]:
        if 0 <= i + di <= maxtile and 0 <= j + dj <= maxtile:
            surroundingTiles.append(self[i + di][j + dj])

    return surroundingTiles

(未经测试。)它使用单位步骤相对计算相邻索引,因此您不必显式输入它们。它还同时测试所有out of bounds案例。

正如您的代码所暗示的那样,我假设horizontalandvertical您的意思是horizontally and vertically adjacentand 。diagonally adjacent

于 2012-12-08T20:18:38.097 回答
2

将@irrelephant 的想法更进一步(这是合乎逻辑的结论或归约荒谬,你决定):

d = (
    ( ( 0, 1), ( 1, 0), ( 0,-1), (-1, 0) ),
    ( ( 1, 1), ( 1,-1), (-1, 1), ( 1,-1) )
)

def getSurroundingTiles(self, tile, horizontal = True, vertical = True):
    index = list(self.getTiles()).index(tile)
    maxtile = self.sqrtnum - 1 # Offset for 0 indexing

    fhv = (horizontal, vertical)
    ij = ( int(math.floor(index / self.sqrtnum)),
           int(index % self.sqrtnum) )

    surroundingTiles = []
    for ihv in range(2):
        if fhv[ihv]:
            for k in range(4):
                n = [sum(p) for p in zip(ij, d[ihv][k])]
                if all([0 <= n[i] <= maxtile for i in range(2)]):
                    surroundingTiles.append(self[n[0]][n[1]])

    return surroundingTiles

请注意:此代码未经测试。

于 2012-12-08T21:02:35.903 回答