你能搞清楚吗?

时间:2012-12-08 20:09:22

标签: python function math if-statement pygame

我这里有一个python类方法的怪异。我能想到的唯一方法就是一个庞大而丑陋的if / elif / else块。你们有没有想出任何想法让这个更好?

对于上下文,这是pygame的网格制作库的一部分,并且是一个函数,它接收网格中的一个tile并返回周围的tile。如果“horizo​​ntal”设置为false,则仅返回与tile相邻的tile,反之亦然。

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

2 个答案:

答案 0 :(得分: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个案例。

我假设horizontalvertical表示horizontally and vertically adjacentdiagonally adjacent之类的内容,正如您的代码所示。

答案 1 :(得分: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

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