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