Created
February 11, 2023 09:40
-
-
Save Tomi-3-0/6e62b6355863b4bc5c654c911611dc1f to your computer and use it in GitHub Desktop.
A simple implementation of a command-line mine sweeper game in python from Kylie Ying (Github: https://www.github.com/kying18 )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import re | |
# create a class called board to represent the minesweeper game | |
class Board: | |
def __init__(self, dim_size, num_bombs): | |
# keep track | |
self.dim_size = dim_size | |
self.num_bombs = num_bombs | |
# helper functions | |
self.board = self.make_new_board() | |
self.assign_values_to_board() | |
# store row and cols dug in this set | |
self.dug = set() | |
def make_new_board(self): | |
# generate new board | |
# this generates a new board that looks: | |
# [[None, None, ...., None], | |
# [None, None, ...., None], | |
# [None, None, ...., None]] | |
board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)] | |
# plant bombs | |
bombs_planted = 0 | |
while bombs_planted < self.num_bombs: | |
location = random.randint(0, self.dim_size ** 2 - 1) | |
# number of times dim_size goes into location | |
row = location // self.dim_size | |
# the remainder tells us what index in that row | |
col = location % self.dim_size | |
# check for already planted bombs | |
if board[row][col] == '*': | |
continue | |
# plant bombs | |
board[row][col] = '*' | |
bombs_planted += 1 | |
return board | |
# assigns a number between 0 - 8 for all the empty spaces, reps number of neigbouring bombs | |
def assign_values_to_board(self): | |
# loop through rows | |
for i in range(self.dim_size): | |
# loop through columns | |
for j in range(self.dim_size): | |
if self.board[i][j] == '*': | |
# if bomb exits, don't calculate | |
continue | |
self.board[i][j] = self.get_neighbouring_bombs(i, j) | |
# get neigbouring bombs | |
def get_neighbouring_bombs(self, row, col): | |
num_of_neighbouring_bombs = 0 | |
for r in range(max(0, row-1), min(self.dim_size-1, row+1) + 1): | |
for c in range(max(0, col-1), min(self.dim_size -1, col+1) + 1): | |
if r == row and c == col: | |
# don't check our original location | |
continue | |
if self.board[r][c] == '*': # presence of a neighbouring bomb | |
num_of_neighbouring_bombs += 1 | |
return num_of_neighbouring_bombs | |
def dig(self, row, col): | |
# dig at a particular location | |
self.dug.add((row, col)) #keep track of dig | |
if self.board[row][col] == '*': | |
return False | |
elif self.board[row][col] > 0: | |
return True | |
# if self.board[row][col] == 0 | |
for r in range(max(0, row-1), min(self.dim_size-1, row+1) + 1): | |
for c in range(max(0, col-1), min(self.dim_size -1, col+1) + 1): | |
if (r, c) in self.dug: | |
continue | |
self.dig(r, c) | |
return True | |
# function that prints out what this function returns when you call print on this object | |
# return a string that shows the board to the player | |
def __str__(self): | |
visible_board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)] | |
for row in range(self.dim_size): | |
for col in range(self.dim_size): | |
if (row, col) in self.dug: | |
visible_board[row][col] = str(self.board[row][col]) | |
else: | |
visible_board[row][col] = ' ' | |
# putting together in a string | |
# put this together in a string | |
string_rep = '' | |
# get max column widths for printing | |
widths = [] | |
for idx in range(self.dim_size): | |
columns = map(lambda x: x[idx], visible_board) | |
widths.append( | |
len( | |
max(columns, key = len) | |
) | |
) | |
# print the csv strings | |
indices = [i for i in range(self.dim_size)] | |
indices_row = ' ' | |
cells = [] | |
for idx, col in enumerate(indices): | |
format = '%-' + str(widths[idx]) + "s" | |
cells.append(format % (col)) | |
indices_row += ' '.join(cells) | |
indices_row += ' \n' | |
for i in range(len(visible_board)): | |
row = visible_board[i] | |
string_rep += f'{i} |' | |
cells = [] | |
for idx, col in enumerate(row): | |
format = '%-' + str(widths[idx]) + "s" | |
cells.append(format % (col)) | |
string_rep += ' |'.join(cells) | |
string_rep += ' |\n' | |
str_len = int(len(string_rep) / self.dim_size) | |
string_rep = indices_row + '-'*str_len + '\n' + string_rep + '-'*str_len | |
return string_rep | |
# play game | |
def play(dim_size = 10, num_bombs = 10): | |
# create board and plant the bombs | |
board = Board(dim_size, num_bombs) | |
safe = True | |
while len(board.dug) < board.dim_size ** 2 - num_bombs: | |
print(board) | |
user_input = re.split(', (\\s)*', input("Where would you like to dig? Input as row, col: ")) | |
row, col = int(user_input[0]), int(user_input[-1]) | |
if row < 0 or row >= board.dim.size or col < 0 or col >= dim_size: | |
print("Not a valid location, try again.") | |
continue | |
# if valid | |
safe = board.dig(row, col) | |
if not safe: | |
break #game over | |
#ways to end loop | |
if safe: | |
print("Congratulations!!!") | |
else: | |
print("Game over") | |
board.dug = [(r, c) for r in range(board.dim_size) for c in range(board.dim_size)] | |
print(board) | |
if __name__ == '__main__': | |
play() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment