我有一个功能,可以将“z”数量的炸弹随机分散在10x10网格中。它看起来像这样(“b”表示炸弹所在的位置。)我需要放置一个数字,表示“0”旁边有多少个炸弹(包括对角线),我不知道该怎么做。
0 0 0 0 0 0 0 0 b 0
b 0 0 b 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 b 0 0 0
0 0 0 b 0 0 0 0 0 0
0 0 b 0 0 0 0 0 0 b
0 0 0 0 0 0 0 b 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 b 0 b 0 0 0 0
0 0 0 0 0 0 0 0 0 0
from random import*
mat1 = []
mat2 = []
def makemat(x):
for y in range(x):
list1 = []
list2 = []
for z in range(x):
list1.append(0)
list2.append("-")
mat1.append(list1)
mat2.append(list2)
makemat(5)
def printmat(mat):
for a in range(len(mat)):
for b in range(len(mat)):
print(str(mat[a][b]) + "\t",end="")
print("\t")
def addmines(z):
count = 0
while (count < z):
x = randrange(0,len(mat1))
y = randrange(0,len(mat1))
if mat1[y][x] == "b":
count -= 1
else:
mat1[y][x] = "b"
count += 1
printmat(mat1)
addmines(10)
这是我尝试放置数字的功能:
def addscores():
for x in range(len(mat1)):
for y in range(len(mat1)):
if mat1[y][x] != "b":
if mat1[y+1][x] == "b":
mat1[y][x] = 1
if mat1[y-1][x] == "b":
mat1[y][x] = 1 #...ETC
else:
mat1[y][x] == "b"
addscores()
我不断收到错误列表索引超出范围。我该如何解决这个问题?
答案 0 :(得分:0)
变化
if mat1[y+1][x] == "b":
到
if safeEquals(mat1, y+1, x, "b"):
并将safeEquals定义为
def safeEquals(mat, y, x, value):
try:
return mat1[y][x] == "b"
except IndexError as e:
return False
如果您在地图位置之外编制索引,这实质上允许您提供默认行为。
PS条件后执行的代码:
mat1[y][x] = 1
应该是
mat1[y][x] += 1
因为相邻炸弹的存在会使炸弹计数器增加(否则3会如何出现在地图上_
答案 1 :(得分:0)
让我们说(x, y) = (9, 9)
,你得到IndexError
,因为你这样做:
if mat1[y+1][x] == "b":
尝试访问索引mat1[10]
,该索引不存在,因为您的列表只有10个元素长。
另外,让我们说(x, y) = (0, 0)
。然后当你这样做:
if mat1[y-1][x] == "b":
您可以访问索引mat[-1]
,这相当于mat[9]
。我很确定这不是你想要的。
有两种简单的方法可以解决这个问题:
1)包含一组额外的if
语句,以确保您不会尝试访问列表边界之外的列表元素:
变化:
if mat1[y+1][x] == "b":
mat1[y][x] = 1
if mat1[y-1][x] == "b":
mat1[y][x] = 1
要:
#parentheses in if statements added for clarity
if (y < len(mat1) - 1) and (mat1[y+1][x] == "b"):
mat1[y][x] = 1
if (y > 0) and (mat1[y-1][x] == "b"):
mat1[y][x] = 1
2)这是我喜欢的方法。在数组周围添加一层“填充”。首次创建阵列时,请执行以下操作:
WIDTH = 10
HEIGHT = 10
myMap = [[0 for i in range(WIDTH + 2)] for j in range(HEIGHT + 2)]
然后,当您访问数组中的元素时,只需确保从1开始索引,而不是0:
#do this
firstElement = myMap[1][1]
#not this
firstElement = mayMap[0][0]
#do this
for i in range(1, len(myMap) - 1): pass
#not this
for i in range(len(myMap)): pass
答案 2 :(得分:0)
避免索引错误的一种简单方法是使用defaultdict
来保留mat1
和mat2
。作为奖励,代码更短:)
from random import randrange
from collections import defaultdict
mat1 = defaultdict(int)
mat2 = defaultdict(lambda:"-")
size = 5
def printmat(mat):
for a in range(size):
print("\t".join(str(mat[a, b]) for b in range(size)))
def addmines(count):
while (count):
x = randrange(0,size)
y = randrange(0,size)
if mat1[y, x] != "b":
mat1[y, x] = "b"
count -= 1
printmat(mat1)
addmines(10)
def addscores():
for x in range(size):
for y in range(size):
if mat1[y, x] != "b":
if mat1[y+1, x] == "b":
mat1[y, x] = 1 # should be +=
if mat1[y-1, x] == "b":
mat1[y, x] = 1 #...ETC
else:
mat1[y, x] == "b"
addscores()
答案 3 :(得分:-1)
如果y在范围内(len(mat1))则y + 1不是......