3 Minesweeper (50 points) You are going to write the game of Minesweeper The Min
ID: 3756710 • Letter: 3
Question
3 Minesweeper (50 points) You are going to write the game of Minesweeper The Minesweeper board H graphical grid of squares. A certain nmmber of squares, chosen randomly, conceal dangerons mines. Play proceeds when a user left-clicks on a square. If that square hides a mine, the game is over and the player loses. If not, then stepping on the square reveals the mber of mines hidden by squares adjacent to that square a number between D and 8. A player can right-click on a square that has not yet been stepped on to mark it as being potentially mined, and remove the mark with another right click Figure 4 shows a game in progress. Nubers represent squares that have been clicked, 'E's are places the player has placed a flag, and's are squnres that have not yet been clickexl. This is a singularly unattractive gameboard, you are welcome to add ieons or grid squares or any other inds of graphics to liven up your own version Yon are responsible for designing and implementing the whole game. This is a big task; start early Here are some suggestions.Explanation / Answer
import re
import time
from string import ascii_lowercase
def setupgrid(gridsize, start, numberofmines):
emptygrid = [['0' for i in range(gridsize)] for i in range(gridsize)]
mines = getmines(emptygrid, start, numberofmines)
for i, j in mines:
emptygrid[i][j] = 'X'
grid = getnumbers(emptygrid)
return (grid, mines)
def showgrid(grid):
gridsize = len(grid)
horizontal = ' ' + (4 gridsize '-') + '-'
# Print top column letters
toplabel = ' '
for i in ascii_lowercase[:gridsize]:
toplabel = toplabel + i + ' '
print(toplabel + ' ' + horizontal)
# Print left row numbers
for idx, i in enumerate(grid):
row = '{0:2} |'.format(idx + 1)
for j in i:
row = row + ' ' + j + ' |'
print(row + ' ' + horizontal)
print('')
def getrandomcell(grid):
gridsize = len(grid)
a = random.randint(0, gridsize - 1)
b = random.randint(0, gridsize - 1)
return (a, b)
def getneighbors(grid, rowno, colno):
gridsize = len(grid)
neighbors = []
for i in range(-1, 2):
for j in range(-1, 2):
if i == 0 and j == 0:
continue
elif -1 < (rowno + i) < gridsize and -1 < (colno + j) < gridsize:
neighbors.append((rowno + i, colno + j))
return neighbors
def getmines(grid, start, numberofmines):
mines = []
neighbors = getneighbors(grid, *start)
for i in range(numberofmines):
cell = getrandomcell(grid)
while cell == start or cell in mines or cell in neighbors:
cell = getrandomcell(grid)
mines.append(cell)
return mines
def getnumbers(grid):
for rowno, row in enumerate(grid):
for colno, cell in enumerate(row):
if cell != 'X':
# Gets the values of the neighbors
values = [grid[r][c] for r, c in getneighbors(grid,
rowno, colno)]
# Counts how many are mines
grid[rowno][colno] = str(values.count('X'))
return grid
def showcells(grid, currgrid, rowno, colno):
# Exit function if the cell was already shown
if currgrid[rowno][colno] != ' ':
return
# Show current cell
currgrid[rowno][colno] = grid[rowno][colno]
# Get the neighbors if the cell is empty
if grid[rowno][colno] == '0':
for r, c in getneighbors(grid, rowno, colno):
# Repeat function for each neighbor that doesn't have a flag
if currgrid[r][c] != 'F':
showcells(grid, currgrid, r, c)
def playagain():
choice = input('Play again? (y/n): ')
return choice.lower() == 'y'
def parseinput(inputstring, gridsize, helpmessage):
cell = ()
flag = False
message = "Invalid cell. " + helpmessage
pattern = r'([a-{}])([0-9]+)(f?)'.format(ascii_lowercase[gridsize - 1])
validinput = re.match(pattern, inputstring)
if inputstring == 'help':
message = helpmessage
elif validinput:
rowno = int(validinput.group(2)) - 1
colno = ascii_lowercase.index(validinput.group(1))
flag = bool(validinput.group(3))
if -1 < rowno < gridsize:
cell = (rowno, colno)
message = ''
return {'cell': cell, 'flag': flag, 'message': message}
def playgame():
gridsize = 9
numberofmines = 10
currgrid = [[' ' for i in range(gridsize)] for i in range(gridsize)]
grid = []
flags = []
starttime = 0
helpmessage = ("Type the column followed by the row (eg. a5). "
"To put or remove a flag, add 'f' to the cell (eg. a5f).")
showgrid(currgrid)
print(helpmessage + " Type 'help' to show this message again. ")
while True:
minesleft = numberofmines - len(flags)
prompt = input('Enter the cell ({} mines left): '.format(minesleft))
result = parseinput(prompt, gridsize, helpmessage + ' ')
message = result['message']
cell = result['cell']
if cell:
print(' ')
rowno, colno = cell
currcell = currgrid[rowno][colno]
flag = result['flag']
if not grid:
grid, mines = setupgrid(gridsize, cell, numberofmines)
if not starttime:
starttime = time.time()
if flag:
# Add a flag if the cell is empty
if currcell == ' ':
currgrid[rowno][colno] = 'F'
flags.append(cell)
# Remove the flag if there is one
elif currcell == 'F':
currgrid[rowno][colno] = ' '
flags.remove(cell)
else:
message = 'Cannot put a flag there'
# If there is a flag there, show a message
elif cell in flags:
message = 'There is a flag there'
elif grid[rowno][colno] == 'X':
print('Game Over ')
showgrid(grid)
if playagain():
playgame()
return
elif currcell == ' ':
showcells(grid, currgrid, rowno, colno)
else:
message = "That cell is already shown"
if set(flags) == set(mines):
minutes, seconds = divmod(int(time.time() - starttime), 60)
print(
'You Win. '
'It took you {} minutes and {} seconds. '.format(minutes,
seconds))
showgrid(grid)
if playagain():
playgame()
return
showgrid(currgrid)
print(message)
playgame()
import random
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.