#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