0

私はここにpythonクラスメソッドの怪物を持っています。私が考えることができる唯一の方法は、大規模で醜いif / elif / elseブロックでした。これをより良くするためのアイデアを思いつくことができますか?

文脈上、これは pygame のグリッド作成ライブラリの一部であり、グリッド内のタイルの 1 つを取り、周囲のタイルを返す関数です。"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ケースを一度にテストします。

あなたのコードが示唆するように、あなたは andhorizontalverticalようなものを意味していると思います。horizontally and vertically adjacentdiagonally 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 に答える