0

我有一个函数可以将“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()

我不断得到错误列表索引超出范围。我该如何解决这个问题?

4

4 回答 4

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 怎么会出现在地图上_

于 2012-11-16T01:45:19.727 回答
0

避免索引错误的一种简单方法是defaultdict使用mat1mat2。作为奖励,代码更短:)

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()
于 2012-11-16T03:24:49.707 回答
0

比方说(x, y) = (9, 9),你得到了,IndexError因为你这样做:

if mat1[y+1][x] == "b":

它试图访问mat1[10]不存在的 index ,因为您的列表只有 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  
于 2012-11-16T01:46:11.447 回答
-1

如果 y 在 range(len(mat1)) 那么 y+1 不是...

于 2012-11-16T01:39:35.527 回答