Created
January 15, 2012 03:06
-
-
Save DDR0/1614090 to your computer and use it in GitHub Desktop.
Minesweeper with the outside ring known.
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
#MineSweeper variant #10841 | |
#For Python 3 | |
import random, os | |
## {{{ http://code.activestate.com/recipes/134892/ (r2) | |
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() | |
getch = _Getch() | |
## end of http://code.activestate.com/recipes/134892/ }}} | |
def rungame(x,y,mines): | |
size = (x,y) | |
def generateGrid(x,y,mines): | |
grid = [[False for y in range(y)] for x in range(x)] | |
validLocations = [] | |
for x in range(len(grid)): | |
for y in range(len(grid[x])): | |
validLocations += [(x,y)] | |
random.shuffle(validLocations) | |
for location in validLocations[0:mines]: | |
x,y=location | |
grid[x][y] = True | |
return grid | |
def display(grid, cursor): | |
for x in range(25): print() | |
for x in range(len(grid)): | |
for y in range(len(grid[x])): | |
string = 'e' | |
if grid[x][y] == 0: | |
string = ' ' | |
elif grid[x][y] == -1: | |
string = '□' | |
elif grid[x][y] == -2: | |
string = '⚐' | |
elif grid[x][y] == -3: | |
string = '☠' | |
elif grid[x][y] == -4: | |
string = '⚙' | |
else: | |
string = str(grid[x][y]) | |
if(cursor != (x,y)): | |
string = ' ' + string + ' ' | |
else: | |
string = '[' + string + ']' | |
print(string, end='') | |
print() | |
def reveal(mines, grid, cursor): #returns elxposed grid, plus if we survived. | |
def isInRange(grid, location): | |
lx,ly = location | |
return lx >= 0 and ly >= 0 and lx < len(grid) and ly < len(grid[lx]) | |
def ismined(mines, location): | |
lx,ly=location | |
lx-=1 | |
ly-=1 | |
if isInRange(mines, (lx,ly)): | |
return mines[lx][ly] | |
return False | |
def reveal(mines, grid, locations): | |
if len(locations) == 0: | |
return True | |
else: | |
if ismined(mines, locations[0]): | |
lx,ly=locations[0] | |
grid[lx][ly] = -3 | |
return False | |
else: | |
lx,ly=locations[0] | |
minedCount = 0 | |
potlocs = [] | |
for location in [(lx-1,ly-1), (lx,ly-1), (lx+1,ly-1), (lx-1,ly), (lx+1,ly), (lx-1,ly+1), (lx,ly+1), (lx+1,ly+1)]: | |
if ismined(mines, location): minedCount +=1 | |
tx,ty=location | |
if isInRange(grid, location) and grid[tx][ty] == -1: potlocs += [location] | |
grid[lx][ly] = minedCount | |
if minedCount == 0: | |
locations += potlocs | |
return reveal(mines, grid, locations[1:len(locations)]) | |
return reveal(mines, grid, [cursor]) | |
def minesFound(hidden, grid): | |
for lin in range(len(hidden)): | |
for col in range(len(hidden[lin])): | |
if hidden[lin][col]: | |
if not grid[lin+1][col+1] in [-3,-4]: return False | |
else: | |
if not grid[lin+1][col+1] >= 0: return False | |
return True | |
cursor=(int(x/2)+1,int(y/2)+1) | |
hidden = generateGrid(x,y,mines) | |
#-4 = potential mine -3 = mine -2 = flag -1 = unshown 0+ = number of mines in surrounding 8. | |
grid = [[-1 for y in range(y+2)] for x in range(x+2)] | |
press = 'Use the [arrow key]s to move. Use [enter]\nto sweep, [m] to mark mine, [f] to flag.' | |
for x in range(size[0]+1): | |
reveal(hidden, grid, (x,0)) | |
reveal(hidden, grid, (x,size[1]+1)) | |
for y in range(size[1]+1): | |
reveal(hidden, grid, (0,y)) | |
reveal(hidden, grid, (size[0]+1,y)) | |
while press != 'q': | |
display(grid, cursor) | |
print(' > ' + press) | |
if minesFound(hidden, grid): | |
print(' > A winner is you.') | |
return True | |
press = getch() | |
if ord(press) == 27: #Escape codes! … suffice to say, this breaks [esc]. | |
press = getch() | |
if press == '[': | |
press = getch() | |
if press == 'A': | |
press = 'up' | |
elif press == 'B': | |
press = 'down' | |
elif press == 'C': | |
press = 'right' | |
elif press == 'D': | |
press = 'left' | |
else: press = '?' | |
if press == 'left': | |
cy,cx = cursor | |
cursor = (cy,(cx-1)%(size[1]+2)) | |
elif press == 'right': | |
cy,cx = cursor | |
cursor = (cy,(cx+1)%(size[1]+2)) | |
elif press == 'up': | |
cy,cx = cursor | |
cursor = ((cy-1)%(size[0]+2),cx) | |
elif press == 'down': | |
cy,cx = cursor | |
cursor = ((cy+1)%(size[0]+2),cx) | |
elif ord(press) in [13]: #enter - space could be 32# | |
if reveal(hidden, grid, cursor): | |
press='You survived.' | |
else: | |
press='q' | |
elif press == 'f': | |
cx,cy=cursor | |
grid[cx][cy] = -2 | |
elif press == 'm': | |
cx,cy=cursor | |
grid[cx][cy] = -4 | |
elif press == 'q': | |
print(' > You retired.') | |
return False | |
display(grid, (-1,-1)) | |
print(' > You stepped on a mine and died.\n > Game over.') | |
return False | |
rungame(11,13,random.randint(30,40)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment