Here is my code for generating minesweeper gameboard.
import random
objects = []
class Minesweeper_gameboard():
def __init__(self, width, height, num_mines):
self.width = width
self.height = height
self.num_mines = num_mines
objects.append(self)
def game_board(self):
board = [[0 for i in range(self.height)] for j in range(self.width)]
number_of_mines = 0
while number_of_mines < self.num_mines:
x = random.randint(0, self.width - 1)
y = random.randint(0, self.height - 1)
#Create conditions, when test is true, adopt range: a_True; when test is false, adopt range: a_False
a_test = (x - 1) >= 0
b_test = (x + 1) < self.width
c_test = (y - 1) >= 0
d_test = (y + 1) < self.height
#when (x-1) is more or equal to 0, use (x-1) as the starting point of the range, vice versa
a_True = x-1
b_True = x+2
c_True = y-1
d_True = y+2
#when (x-1) is less than 0, x locate at the corner, use x as the starting point of the range, vice versa
a_False = x
b_False = x+1
c_False = y
d_False = y+1
condition_list = [[a_test, a_True, a_False], [b_test, b_True, b_False],
[c_test, c_True, c_False], [d_test, d_True, d_False]]
#Delete the condition that is not satisfied
for i in condition_list:
if i[0] == True:
del i[0]
del i[1]
else:
del i[0]
del i[0]
#Flatten the list with a nested loop
condition_list = [a for b in condition_list for a in b]
#Create Rules to illustrate mine locations
if board[x][y] != 'X':
board[x][y] = 'X'
number_of_mines += 1
try:
#call out the flatten condition_list as the range to illustrate the number of mines nearby
for i in range(condition_list[0], condition_list[1]):
for j in range(condition_list[2], condition_list[3]):
if board[i][j] != 'X':
board[i][j] += 1
except:
continue
else:
x = random.randint(0, self.width-1)
y = random.randint(0, self.height-1)
return board
def player_board(self):
player_board = [['-' for i in range(self.height)] for j in range(self.width)]
def display_board(self, board):
for row in board:
print(" ".join(str(cell) for cell in row))
print("")
#testing function
mine = Minesweeper_gameboard(10,10,10)
for object in objects:
object.game_board()
object.display_board(object.game_board())`
When I tried to generate:
mine = Minesweeper_gameboard(10, 10, 10)
the gameboard generator generates the correct gameboard:
X 2 0 0 1 1 1 0 0 0
X 2 0 0 1 X 2 1 0 0
1 1 0 0 1 2 X 1 0 0
0 1 2 2 1 1 1 1 0 0
1 2 X X 1 0 0 1 2 2
X 2 2 2 1 0 0 1 X X
1 1 0 0 0 0 0 1 2 2
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0
0 0 0 0 0 1 X 1 0 0
But when I tried to generate:
mine = Minesweeper_gameboard(10, 15, 30)
there's an error in the gameboard output:
0 0 0 0 1 X 2 X X X 3 1 X 1 0
0 1 1 2 2 2 3 4 7 X 3 1 1 1 0
2 **4** X 3 X 1 1 X X 3 2 0 1 1 1
X **5** X 4 2 2 2 2 2 1 0 0 1 X 1
3 5 X 3 2 X 1 0 1 1 2 1 2 1 1
X 2 1 2 X 2 2 2 4 X 3 X 1 0 0
1 2 1 2 1 1 1 X X X 4 1 2 1 1
0 1 X 2 1 0 1 3 X X 2 0 1 X 1
0 1 2 X 3 2 2 2 3 3 1 0 2 2 2
0 0 1 1 3 X 2 1 X 1 0 0 1 X 1
The numering of gameboard in the bold grid is incorrect. Number 4 should be 3, and numebr 5 should be 4 instead.
Can anyone figure out why when i tried to generate a board with 10*15 grids, 30 mines, number of mines nearby cannot be generated as expected? Thanks. You can copy my code and run in your devices as well.
Here's a different approach.
The board has a number of rows and columns. There needs to be a randomly placed number of mines. Cells that are not mines need to indicate the number of mines that are "nearby". A mine is considered to be in the centre of a 3x3 matrix. When considered the extremes of the matrix we have ensure that we don't go outside the bounds of the board.
Therefore:
Output (example):