基本上它应该采用一组坐标并返回它的邻居坐标列表。然而,当它到达这里时:
if result[i][0] < 0 or result[i][0] >= board.dimensions:
result.pop(i)
当i
为2时,它会给我一个索引错误。我可以设法打印结果[2] [0],但在if语句中它会抛出错误。为什么会这样?
def neighborGen(row,col,board):
"""
returns lists of coords of neighbors, in order of up, down, left, right
"""
result = []
result.append([row-1 , col])
result.append([row+1 , col])
result.append([row , col-1])
result.append([row , col+1])
#prune off invalid neighbors (such as (0,-1), etc etc)
for i in range(len(result)):
if result[i][0] < 0 or result[i][0] >= board.dimensions:
result.pop(i)
if result[i][1] < 0 or result[i][1] >= board.dimensions:
result.pop(i)
return result
答案 0 :(得分:4)
您可以从列表中迭代索引,然后继续从列表中删除元素。最终你会打到一个不再存在的索引。请使用列表推导来过滤。
result = [entry for entry in result if entry[0] >= 0 and
entry[0] < board.dimensions and entry[1] >= 0 and
entry[1] < board.dimensions]
答案 1 :(得分:2)
在for
循环期间,您弹出的元素会减小result
的大小。然而,i
仍将从0变为4。
答案 2 :(得分:2)
如果你弹出一个元素,那么它就不再在列表中了 - 但你的索引不会移动,所以它现在指向下一个元素。假设您弹出两个元素...之后您的列表大小为2,但for
循环仍将尝试转到4。
答案 3 :(得分:1)
def neighborGen(row,col,board):
"""
returns lists of coords of neighbors, in order of up, down, left, right
"""
return [
x for x in (
[row-1 , col], [row+1 , col], [row , col-1], [row , col+1]
)
if x[0] >= 0 and x[0] < board.dimensions and
x[1] >= 0 and x[1] < board.dimensions
]
答案 4 :(得分:1)
使用列表推导删除无效点。例如:
result = [coords for coords in result
if all(0 <= c < board.dimension for c in coords)]
答案 5 :(得分:0)
正如其他人所说,当您从列表中间删除元素时,其余元素的索引会发生变化。为避免出现问题,您可以处理从最后一个索引到第一个索引的元素:
for i in range(len(result)-1, -1, -1):
...
现在,当删除当前元素时,只有已处理元素的索引才会更改。由于这些元素已经处理过,不需要再次访问,因此它们的索引不再有效无关紧要。
答案 6 :(得分:0)
避免这种板外测试的规范方法是在板的边缘有一个或两行/列的缓冲区。董事会的职位,以及通常的“空”价值,或者哪一方拥有广场的什么类型的作品,一个特殊的“无效”代码。这通常与作为一维数组的电路板表示相结合。
例如,国际象棋将使用大小为120(10列×12行)的数组。你需要一个2的余量以迎合骑士...每一行2行,但你只需要一个垂直边距,因为它可以共享。
E.g。
KNIGHT_DELTAS = (-21, -19, -12, -8, 8, 12, 19, 21)
# I have a knight at "currpos"; what are its options?
for delta in KNIGHT_DELTAS:
newpos = currpos + delta
target = board[newpos]
if target & EMPTY:
can_move_to(newpos)
elif target & OTHER_TEAM:
can_capture(at=newpos, captured_piece=target & PIECE_VALUE)
else:
# Either off the board or occupied by MY_TEAM.
# Notice that we didn't even need to test explicitly for "off the board".
pass