Skip to content

Instantly share code, notes, and snippets.

@gjcourt
Created July 13, 2017 01:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gjcourt/b631065f34cceda3ca58824099619695 to your computer and use it in GitHub Desktop.
Save gjcourt/b631065f34cceda3ca58824099619695 to your computer and use it in GitHub Desktop.
Simple text-based minesweeper game
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