Skip to content

Instantly share code, notes, and snippets.

@cr0sh
Created September 27, 2015 04:57
Show Gist options
  • Save cr0sh/9e61eccdadb5f9f56432 to your computer and use it in GitHub Desktop.
Save cr0sh/9e61eccdadb5f9f56432 to your computer and use it in GitHub Desktop.
from os import system
from sys import exit
from platform import platform
from random import choice
from time import time
from math import floor
from sys import version_info
if version_info[0] != 3:
print('Python 3 required')
exit()
fx = 14
fy = 12
ratio = 10
cursor = [int(fx/2), int(fy/2)]
field = [[[None, '@'] for i in range(fx)] for i in range(fy)] # y-x 2d matrix of tuples. (bomb? , visual)]
sels = 0
t_ = 0
if platform()[:7] == 'Windows':
clear = lambda: system('cls')
else:
clear = lambda: system('clear')
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
def print_f(*args):
global field, cursor
out = ''
for y, ff in enumerate(field):
for x, f in enumerate(ff):
if list(cursor) == [x, y]:
out += '[%s]' % f[1]
else:
if out != '' and out[-1] == ']':
out += f[1]
else:
out += ' %s' % f[1]
out += '\n'
clear()
print(args[-1] + '\n' + out, end='')
def near(x, y):
global field
if field[y][x][0]:
return -1
else:
return sum([1 for x_ in range(max(x-1, 0), min(x+2, len(field[0]))) for y_ in range(max(y-1, 0), min(y+2, len(field))) if field[y_][x_][0]])
def sel(x, y):
ret = (False, '')
global field, t_
if field[0][0][0] is None: # First selection
rand = [(x, y) for x in range(fx) for y in range(fy)]
for i in range(max(x-1, 0), min(x+2, fx)):
for ii in range(max(y-1, 0), min(y+2, fy)):
rand.remove((i, ii))
field = [[[False, '@'] for f in ff] for ff in field]
for i in range(int(len(field[0]) * len(field) / ratio)):
r = choice(rand)
field[r[1]][r[0]][0] = True
t_ = time()
if field[y][x][0]:
boom()
print_f('BOOM! You died :P Time used: %.2f secs' % (time() - t_))
exit(0)
else:
checkQueue = [(x, y)]
cnt = 0
while len(checkQueue) > 0:
cnt += 1
tmp = checkQueue[0]
if field[tmp[1]][tmp[0]][1] != '@':
checkQueue.remove(tmp)
continue
n = near(checkQueue[0][0], checkQueue[0][1])
if n > 0:
field[tmp[1]][tmp[0]][1] = str(near(checkQueue[0][0], checkQueue[0][1]))
else:
if n < 0:
checkQueue.remove(tmp)
continue
field[tmp[1]][tmp[0]][1] = ' '
[checkQueue.append(a) for a in [(x_, y_) for x_ in range(max(tmp[0]-1, 0), min(tmp[0]+2, len(field[0]))) for y_ in range(max(tmp[1]-1, 0), min(tmp[1]+2, len(field))) if (tmp[0] != x_ or tmp[1] != y_) and (field[y_][x_][1] == '@' or field[y_][x_] == '?')]]
checkQueue.remove(tmp)
return ret
def boom():
global field
for y, ff in enumerate(field):
for x, f in enumerate(ff):
if f[0]:
f[1] = '*'
else:
if near(x, y) > 0:
f[1] = str(near(x, y))
else:
f[1] = ' '
def check_answer():
for ff in field:
for f in ff:
if f[0] and f[1] != 'm':
return False
return True
def get():
while True:
try:
tmp = input('<s(elect)/m(ark)/q(estion)> <coordinate>: ').upper().split(' ')
except EOFError:
exit(0)
if len(tmp) < 2 or len(tmp[0]) != 1 or len(tmp[1]) != 2 or CHARS.find(tmp[1][0]) < 0 or CHARS.find(tmp[1][1]) < 0 or 'SMQ'.find(tmp[0]) < 0:
print_f('Invalid command')
continue
return tmp
getch = _Getch()
while True:
if sels == int(len(field[0]) * len(field) / ratio) and check_answer():
boom()
print_f('You win! Time used: %.2f secs' % (time() - t_))
exit(0)
else:
pre = 'a: select, x: mark, c: question-mark ctrl-arrow: move 4 blocks %i/%i (%ix%i)' % (sels, int(len(field[0]) * len(field) / ratio), fx, fy)
print_f(pre)
ch = getch()
if ch[0] == '^':
mult = 4
else:
mult = 1
if ch == b'\x03' or ch == b'\x1a':
print('Bye!', end='')
exit(0)
elif ch == b'K': # left
cursor[0] = max(cursor[0]-1, 0)
elif ch == b'P': # down
cursor[1] = min(cursor[1]+1, fy-1)
elif ch == b'M': # right
cursor[0] = min(cursor[0]+1, fx-1)
elif ch == b'H': # up
cursor[1] = max(cursor[1]-1, 0)
elif ch == b's': # left
cursor[0] = max(cursor[0]-4, 0)
elif ch == b'\x91': # down
cursor[1] = min(cursor[1]+4, fy-1)
elif ch == b't': # right
cursor[0] = min(cursor[0]+4, fx-1)
elif ch == b'\x8d': # up
cursor[1] = max(cursor[1]-4, 0)
elif ch == b'a':
if field[cursor[1]][cursor[0]][1] == '@':
sel(cursor[0], cursor[1])
elif ch == b'x':
if field[cursor[1]][cursor[0]][1] == 'm':
field[cursor[1]][cursor[0]][1] = '@'
sels -= 1
elif field[cursor[1]][cursor[0]][1] == '@':
field[cursor[1]][cursor[0]][1] = 'm'
sels += 1
elif ch == b'c':
if field[cursor[1]][cursor[0]][1] == '@':
field[cursor[1]][cursor[0]][1] = '?'
elif field[cursor[1]][cursor[0]][1] == '?':
field[cursor[1]][cursor[0]][1] = '@'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment