0

10x10 グリッドにランダムに散らばる 'z' 量の爆弾を配置する機能があります。このような感じです (「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

インデックスエラーを回避する簡単な方法は、と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

変化する

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

(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]。これはあなたが意図したものではないと私はかなり確信しています。

これを修正する簡単な方法は2つあります。

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)]

次に、配列内の要素にアクセスするときは、0ではなく1からインデックスを作成していることを確認してください。

#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 に答える