Created
July 13, 2017 01:46
-
-
Save gjcourt/b631065f34cceda3ca58824099619695 to your computer and use it in GitHub Desktop.
Simple text-based minesweeper game
This file contains hidden or 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 math | |
import random | |
ROWS = 10 | |
COLUMNS = 10 | |
MINE_COUNT = 10 | |
BOARD = [] | |
MINES = set() | |
EXTENDED = set() | |
class Colors(object): | |
BLUE = '\033[94m' | |
GREEN = '\033[92m' | |
YELLOW = '\033[93m' | |
RED = '\033[91m' | |
ENDC = '\033[0m' | |
def colorize(s, color): | |
return '{}{}{}'.format(color, s, Colors.ENDC) | |
def get_index(i, j): | |
if 0 > i or i >= COLUMNS or 0 > j or j >= ROWS: | |
return None | |
return i * ROWS + j | |
def create_board(): | |
squares = ROWS * COLUMNS | |
# Create board | |
for _ in range(squares): | |
BOARD.append('[ ]') | |
# Create mines | |
while True: | |
if len(MINES) >= MINE_COUNT: | |
break | |
MINES.add(int(math.floor(random.random()*squares))) | |
def draw_board(): | |
lines = [] | |
for j in range(ROWS): | |
if j == 0: | |
lines.append(' '+''.join(' {} '.format(x) for x in range(COLUMNS))) | |
line = [' {} '.format(j)] | |
for i in range(COLUMNS): | |
line.append(BOARD[get_index(i, j)]) | |
lines.append(''.join(line)) | |
return '\n'.join(reversed(lines)) | |
def parse_selection(raw_selection): | |
try: | |
return [int(x.strip(','), 10) for x in raw_selection.split(' ')] | |
except Exception: | |
return None | |
def adjacent_squares(i, j): | |
num_mines = 0 | |
squares_to_check = [] | |
for di in [-1, 0, 1]: | |
for dj in [-1, 0, 1]: | |
# Skip current square | |
if di == dj == 0: | |
continue | |
coordinates = i + di, j + dj | |
# Skip squares off the board | |
proposed_index = get_index(*coordinates) | |
if not proposed_index: | |
continue | |
if proposed_index in MINES: | |
num_mines += 1 | |
squares_to_check.append(coordinates) | |
return num_mines, squares_to_check | |
def update_board(square, selected=True): | |
i, j = square | |
index = get_index(i, j) | |
EXTENDED.add(index) | |
# Check if we hit a mine, and if it was selected by the user or merely traversed | |
if index in MINES: | |
if not selected: | |
return | |
BOARD[index] = colorize(' X ', Colors.RED) | |
return True | |
else: | |
num_mines, squares = adjacent_squares(i, j) | |
if num_mines: | |
if num_mines == 1: | |
text = colorize(num_mines, Colors.BLUE) | |
elif num_mines == 2: | |
text = colorize(num_mines, Colors.GREEN) | |
else: | |
text = colorize(num_mines, Colors.RED) | |
BOARD[index] = ' {} '.format(text) | |
return | |
else: | |
BOARD[index] = ' ' | |
for asquare in squares: | |
aindex = get_index(*asquare) | |
if aindex in EXTENDED: | |
continue | |
EXTENDED.add(aindex) | |
update_board(asquare, False) | |
def reveal_mines(): | |
for index in MINES: | |
if index in EXTENDED: | |
continue | |
BOARD[index] = colorize(' X ', Colors.YELLOW) | |
def has_won(): | |
return len(EXTENDED | MINES) == len(BOARD) | |
if __name__ == '__main__': | |
create_board() | |
print 'Enter coordinates (ie: 0 3 or 0, 3)' | |
while True: | |
print draw_board() | |
square = parse_selection(raw_input('> ')) | |
if not square: | |
print 'Unable to parse indicies, try again...' | |
continue | |
mine_hit = update_board(square) | |
if mine_hit or has_won(): | |
if mine_hit: | |
reveal_mines() | |
print draw_board() | |
print 'Game over' | |
else: | |
print draw_board() | |
print 'You won!' | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment