#Minesweeper
import random
def drawBoard(board, dimensionx, dimensiony):
print(' ', end='')
for i in range(int(dimensionx[0]) + 1): #Print tens digits
print(i, end='')
print(' ' * 9, end='')
print()
print(' ', end='')
for i in range(int(dimensionx[0])): #Print ones digits
print('0123456789', end='')
for i in range(int(dimensionx[1]) +1): #Print remainder ones digits
if i == int(dimensionx[1]):
print(i) #Don't continue the line after the last digits
else:
print(i, end='')
for i in range(dimensiony + 1): #Print rows
if i < 10: #Add extra space if row number is single digit
extraSpace = ' '
else:
extraSpace = ''
print(' %s%s |%s| %s' %(i, extraSpace,rowData(board, dimensionx, i), i))
print(' ', end='')
for i in range(int(dimensionx[0])): #Print ones digits
print('0123456789', end='')
for i in range(int(dimensionx[1]) +1): #Print remainder ones digits
if i == int(dimensionx[1]):
print(i) #Don't continue the line after the last digits
else:
print(i, end='')
print(' ', end='')
for i in range(int(dimensionx[0]) + 1): #Print tens digits
print(i, end='')
print(' ' * 9, end='')
print()
print()
def rowData(board, dimensionx, i): #Show what's currently on the board in the row
rowDisplay = ''
xValue = int(''.join(dimensionx))
for x in range(xValue + 1):
rowDisplay += board[x][i]
return rowDisplay
def newBoard(board, dimensionx, dimensiony): #Gets theoretical board to start game
xValue = int(''.join(dimensionx))
yValue = dimensiony
for x in range(xValue + 1):
board.append([])
for y in range(yValue + 1):
board[x].append('*')
def getNumMines(xValue, yValue): #Sets the mines on the board
area = float(xValue * yValue)
numMines = int(area* .1) # 10% of the map is loaded with mines
return numMines
def makeMines(xValue, yValue, numMines):
mines = []
for i in range(numMines): #Place the mines randomly on the board
mines.append([random.randint(0,xValue), random.randint(0,yValue)])
return mines
def clearZeros(board, moveX, moveY, numMines, mines, xValue, yValue):
board[moveX][moveY] = ' ' #Erase zero of the value currently being evaluated
#All conditionals make sure that the max and min values of the board
#have not been exceeded
if moveX + 1 <= xValue and board[moveX+1][moveY] != ' ':
checkBoard(board, moveX+1, moveY, numMines, mines, xValue, yValue) #Checks the space to the right of the player's move
if moveX - 1 >= 0 and board[moveX-1][moveY] != ' ':
checkBoard(board, moveX-1, moveY, numMines, mines, xValue, yValue) #Checks space to the left of the player's move
if moveY + 1 <= yValue and board[moveX][moveY+1] != ' ':
checkBoard(board, moveX, moveY+1, numMines, mines, xValue, yValue) #Checks space above player's move
if moveY - 1 >= 0 and board[moveX][moveY-1] != ' ':
checkBoard(board, moveX, moveY-1, numMines, mines, xValue, yValue) #Checks space below player's move
if moveX + 1 <= xValue and board[moveX+1][moveY] == '0': #Repeats process for each new 0 found
clearZeros(board, moveX+1, moveY, numMines, mines, xValue, yValue)
if moveX - 1 >= 0 and board[moveX-1][moveY] == '0':
clearZeros(board, moveX-1, moveY, numMines, mines, xValue, yValue)
if moveY + 1 <= yValue and board[moveX][moveY+1] == '0':
clearZeros(board, moveX, moveY+1, numMines, mines, xValue, yValue)
if moveY - 1 >= 0 and board[moveX][moveY-1] == '0':
clearZeros(board, moveX, moveY-1, numMines, mines, xValue, yValue)
def checkBoard(board, moveX, moveY, numMines, mines, xValue, yValue):
dupeBoard= []
for x in range(xValue + 1): #Create a duplicate board to check
dupeBoard.append([])
for y in range(yValue + 1):
dupeBoard[x].append(board[x][y])
if makeMove(dupeBoard, [str(moveX), str(moveY)], mines, numMines, xValue, yValue) == '0':
board[moveX][moveY] = '0'
#If the analyzed space has adjacent mines next to it, display the number
if makeMove(dupeBoard, [str(moveX), str(moveY)], mines, numMines, xValue, yValue) in '123456789':
makeMove(board, [str(moveX), str(moveY)], mines, numMines, xValue, yValue)
def makeMove(board, move, mines, numMines, xValue, yValue):
moveX = int(move[0])
moveY = int(move[1])
adjacentMines = 0
for i in range(len(move)): #if a spot has been flagged, mark it and exit the function
if move[i].lower() == 'flag' and board[moveX][moveY] == 'F': #If a flag is already there, remove it
board[moveX][moveY] = '*'
return board[moveX][moveY]
if move[i].lower() == 'flag':
board[moveX][moveY] = 'F'
return board[moveX][moveY]
for i in range(numMines):
if moveX == mines[i][0] and moveY == mines[i][1]:
board[moveX][moveY] = 'X'
return board[moveX][moveY]
for i in range(numMines):
if abs(moveX - mines[i][0]) <= 1 and abs(moveY - mines[i][1]) <= 1: #If mine is adjacent, increment the number
adjacentMines += 1
board[moveX][moveY] = str(adjacentMines)
return board[moveX][moveY]
def getDimensions():
dimensions = []
dimensionx = []
dimensiony = 0 #y does not need to have its digits separated
xint = 0
yint = 0
while (xint < 10 or xint > 99) or (yint < 10 or yint > 99):
print('Please enter the size of your game board (x y) (min: 10 max: 99)')
dimensions = input().split()
if dimensions[0].isdigit() and dimensions[1].isdigit():
xint = int(dimensions[0])
yint = int(dimensions[1])
for i in range(2): #split the x value entered into its 2
dimensionx.append(dimensions[0][i]) #digits, and add them to the x list
return [dimensionx, yint]
def validMove(move, xValue, yValue):
moveX = int(move[0])
moveY = int(move[1])
return(move[0].isdigit() and move[1].isdigit and moveX <= xValue and moveX >= 0 and moveY <=yValue and moveY >= 0)
def playAgain():
print('Would you like to play again?')
return input().lower().startswith('y')
while True: #Game loop
board = []
dimensionx, dimensiony = getDimensions()
xValue = int(''.join(dimensionx)) #Create integers of the dimensions to use in functions
yValue = dimensiony
newBoard(board, dimensionx, dimensiony) #Create a new board at the start of every new game
drawBoard(board, dimensionx, dimensiony) #Print a board for the player to see
numMines = getNumMines(xValue, yValue)
mines = makeMines(xValue, yValue, numMines)
while True: #Input loop
print('Input x and y coordinates (x y). If you want to flag a spot, type "Flag" after the coordinates.') #Get a valid move from the player
move = list(input().split())
while not validMove(move, xValue, yValue):
print('Input x and y coordinates (x y). If you want to flag a spot, type "Flag" after the coordinates.')
move = list(input().split())
moveX = int(move[0]) #Create integers of the move coordinates for some functions
moveY = int(move[1])
moveCheck = makeMove(board, move, mines, numMines, xValue, yValue)
if moveCheck == '0':
clearZeros(board, moveX, moveY, numMines, mines, xValue, yValue)
drawBoard(board, dimensionx, dimensiony)
if board[int(move[0])][int(move[1])] == 'X': #If a mine is hit, break out of the input loop and ask to play again.
print('You hit a mine! Game over!')
break
markedMines = 0
for i in range(numMines): #After every move, check to see if all of the mines have been flagged
mineX, mineY = mines[i]
if board[mineX][mineY] == 'F':
markedMines += 1
if markedMines == numMines: #If all mines have been flagged, display winning message and break out of input loop
print('Congratulations! You\'ve cleared the minefield!')
break
if not playAgain():
break
No comments:
Post a Comment