I’m trying to write minesweeper in python. A bomb is a cell with a value less than 0. The values of cells that differ from the position of the bomb cell by one column and one row in all directions should increase by 1. But the values of cells that are far from the bomb often increase. Please help me
import numpy as np from random import randint #Settings rows = 10 columns = 10 bombs = 10 def createfield(rows=rows, columns=columns, bombs=bombs): minefield = np.full((rows, columns), 0) def createbomb(): bombcount = 0 random_cell = ((randint(0,rows-1), randint(0,columns-1))) minefield[random_cell] = -9 for item in minefield.flat: if item < 0: bombcount +=1 if bombcount < bombs: createbomb() createbomb() return minefield def setnumbers(array=createfield()): for item in (tuple(zip(*(np.nonzero(array < 0))))): row, column = item print(row, column) try: array[row-1, column-1] += 1 except IndexError: pass try: array[row-1, column] += 1 except IndexError: pass try: array[row-1, column+1] += 1 except IndexError: pass try: array[row, column-1] += 1 except IndexError: pass try: array[row, column+1] += 1 except IndexError: pass try: array[row+1, column-1] += 1 except IndexError: pass try: array[row+1, column] += 1 except IndexError: pass try: array[row+1, column+1] += 1 except IndexError: pass return array field = setnumbers() print(field)
Replacing np.full with np.zeros, changes in the replacement algorithm do not help
New setnumbers function:
def setnumbers(array=createfield()): for row in range(rows-1): for column in range(columns-1): if array[row,column] < 0: print(row, column) for rs in range(-1, 2): for cs in range(-1, 2): try: array[row-rs, column-cs] += 1 except IndexError: pass return array
Advertisement
Answer
The problem is: since indexing negative positions in numpy arrays returns actual elements of the structure (e.g. a[-1] returns the last element), you are adding more than what is necessary because the except IndexError: doesn’t catch any error (-1 is a valid index).
def setnumbers(array=createfield()): for item in (tuple(zip(*(np.nonzero(array < 0))))): row, column = item print(row, column) if row-1 >= 0 and column-1 >= 0: array[row-1, column-1] += 1 if row-1 >= 0: array[row-1, column] += 1 try: if row-1 >= 0: array[row-1, column+1] += 1 except IndexError: pass if column - 1 >= 0: array[row, column-1] += 1 try: array[row, column+1] += 1 except IndexError: pass try: if column-1 >= 0: array[row+1, column-1] += 1 except IndexError: pass try: array[row+1, column] += 1 except IndexError: pass try: array[row+1, column+1] += 1 except IndexError: pass return array
I removed the unnecessary except
.
There are much more pythonic and efficent ways of checking index overflow (e.g. compare it with array.shape
).