我这里有一个python类方法的怪异。我能想到的唯一方法就是一个庞大而丑陋的if / elif / else块。你们有没有想出任何想法让这个更好?
对于上下文,这是pygame的网格制作库的一部分,并且是一个函数,它接收网格中的一个tile并返回周围的tile。如果“horizontal”设置为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
答案 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
个案例。
我假设horizontal
和vertical
表示horizontally and vertically adjacent
和diagonally 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
请注意:此代码未经测试。