Skip to content

Instantly share code, notes, and snippets.

@DDR0
Created January 15, 2012 03:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DDR0/1614090 to your computer and use it in GitHub Desktop.
Save DDR0/1614090 to your computer and use it in GitHub Desktop.
Minesweeper with the outside ring known.
#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