简体   繁体   中英

Minesweeper Reveal Element Python

I'm trying to make a function for a minesweeper game I'm making. This function's purpose is to reveal an element given the x and y (where it is located). This is probably not the most elegant way to accomplish it, but I'm making a list of ['-'] for each tile (this is called newField and the grid is a square). A '-' represents a hidden block (where you don't know if its a bomb or how many bombs are surrounding it). Then, I change one element from the newField to equal its corresponding block from the listField (which is a list of lists). Each list within it represents a row). Next, I'm trying to add '\\n' after every 10 values into the newField because my goal is to then make it a string and after each row, a new line starts ('\\n' makes a new line). However, this gives me the error:

AttributeError: 'NoneType' object has no attribute 'insert' on line 18 in main.py. 

I would like some advice on this. Thanks!

Note: the wl variable represents the width/length.

listField = 
        [['1', '1', '0', '0', '0', '0', '0', '0', '1', 'X'], 
        ['X', '2', '2', '2', '2', '2', '2', '1', '1', '1'], 
        ['1', '2', 'X', 'X', '2', 'X', 'X', '2', '2', '2'], 
        ['1', '2', '3', '2', '2', '2', '3', '4', 'X', 'X'], 
        ['1', 'X', '1', '0', '0', '1', '3', 'X', 'X', '3'], 
        ['1', '2', '2', '1', '0', '1', 'X', 'X', '4', '2'], 
        ['2', '3', 'X', '1', '0', '1', '2', '2', '2', 'X'], 
        ['X', 'X', '2', '1', '1', '1', '1', '0', '1', '1'], 
        ['4', '5', '4', '3', '3', 'X', '2', '1', '0', '0'], 
        ['X', 'X', 'X', 'X', 'X', '3', 'X', '1', '0', '0']]


wl = 10

def revealElement(wl, x, y):
  yReal = y-1
  xReal = x-1
  newField = ['-' for i in range(wl*wl)]
  newField[yReal*wl + xReal] = listField[yReal][xReal]

  for i in range(wl-1):
    a = wl+1
    b = i+1
    newField = newField.insert(a*b, '\n')
  return newField


print revealElement(wl, 10, 6)

The insert method modifies the list in-place, and does not return it.

Moreover, you'll get a better result if you make your loop go backwards:

def revealElement(wl, x, y):
  yReal = y-1
  xReal = x-1
  newField = ['-' for i in range(wl*wl)]
  newField[yReal*wl + xReal] = listField[yReal][xReal]

  for i in range(wl-1, -1, -1): # go backwards
      newField.insert(wl*i, '\n')
  return "".join(newField) # make it a string

What Andrej Kesely said was correct...

Also you can replace your for loop logic with this:

  for i in range(1, wl):
    newField.insert(wl*i, '\n')

It's really important to understand what @Andrej Kesely said that insert returns None

Return Value from insert()

The insert() method only inserts the element to the list. It doesn't return anything; returns None.

So, you just need to do:

newField.insert(wl*i, '\n')

Also, you could initialize the vector like that:

newField = ['-'] * wl * wl

For the end, if you really want to add the \\n in the end, probably you could just keeping work with list of lists.

For example, to print that list you could do this:

def print_board:
    for row in newField :
        print(row + '\n')

And this would function for every minesweeper board that you have. Other function that you could add is transform list of lists to a single list and the opposite based you your size variable wl .

As @Andrej Kesely mentioned in the comments, your code fails to run because the insert function returns nothing.

You can check this by running something like this:

a = list()
print(type(a.insert(1,'a')) # This prints class "NoneType"

Changing newField = newField.insert(a*b, '\\n') to newField.insert(a*b, '\\n') would solve your problem!

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