简体   繁体   中英

' ValueError: too many values to unpack '

I'm trying to write a basic version of minesweeper.You get the number of rows, columns,bombs and their location from the user. you should count number of bombs surrounding each element. consider the example below: input

4 3
5
1 1
4 3
1 3
4 2
3 2

output is:

* 2 *
2 3 2
2 * 3
2 * *

Here's my code:

n, m = [int(x) for x in input().split()]


k = int(input()) #number of bombs

#location of bombs
bomb = []
for i in range(k):
    r,c = [int(r) - 1 for r in input().split()]
    bomb.append([r,c])

#making the grid
map = []
for x in range(n):
    map.append([])
    for y in range(m):
        map[x].append(0)

#locate bombs       
for i, j in bomb:
    map[i][j] = '*'

#count the bombs
Ns = 0
for i, j in map:
    for x in range(-1, 2):
        for y in range(-1, 2):
            if map[i + x][j + y] == '*':
                Ns += 1

    map[i][j] = Ns

print(map)

My problem is finding bombs in surrendering. I get ValueError: too many values to unpack for line 25 . Any idea how can i fix it?

for i, j in map:

is invalid. map is a list of lists, something akin to a 4x3 array.

You seem to be trying to iterate through the indices of map , and have confused those with the list contents. Try

for i in range(len(map)):
    for j in range(len(map[i])):
        ...

There's two potential problems in your code.

Firstly, your map actually has 3 values to unpack for each value (since your m is 3), rather than two. This is the line that you need to fix:

for i, j in map:

Instead, what you need is probably to unpack each value for map, like so:

for x in range(len(map)):
    for y in range(len(map[i])):
        square = map[x][y]

Secondly, your code for checking the surroundings can run into issues because you simply decrement/increment the x and y of the mine by 1, this will make your code try to find indexes in the map that doesn't exist. Eg, if x is 2, incrementing by 1 will give you 3. breaking your list.

What you probably want is:

for i in range(max(0,x-1),min(x+1,n-1)+1):
    for j in range(max(0,y-1),min(y+1,m-1)+1):

This only takes in the values that are both in the surroundings, and do not violate the array bounds. Max(0, x-1) prevents us from giving negative array bounds, and min(x+1, n-1) prevents us from going over the max array bounds. Similarly so for y.

Combined, the code would probably look something like this:

#count the bombs
for x in range(len(map)):
    for y in range(len(map[i])):
        # if x,y is not a mine
        if map[x][y] != '*':
            # check the surroundings of x,y for mines
            Ns = 0
            for i in range(max(0,x-1),min(x+1,n-1)+1):
                for j in range(max(0,y-1),min(y+1,m-1)+1):
                    # if this surrounding block is a mine, add to Ns
                    if (map[i][j]) == '*':
                        Ns += 1
                        print("Not safe: " + str(Ns))
            # append the Ns number to the x,y block
            map[x][y] = Ns

for layer in map:
    print(layer)

Outputs:

['*', 2, '*']
[2, 3, 2]
[2, '*', 3]
[2, '*', '*']

Note that this is definitely not the most optimized solution for the problem; the best way is to save values as we go along so we don't have to check all the 3 to 8 surrounding tiles for every tile, but hopefully this helps you understand the base case for dealing with minesweeper.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM