Welcome, guest | Sign In | My Account | Store | Cart

Minesweeper expects the user to enter properly bounded integers for moves. Should the user enter something unexpected, the resulting exception can be caught and handled in some way other than exiting.

Python, 129 lines
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 "minesweeper" from UserDict import UserDict class Game(UserDict): def __init__(self, **kwargs): "initialize board" d = {"ROWS":8,"COLS":8,"BOMBS":10} d.update(kwargs) UserDict.__init__(self,d) self.reset() def random_bombs(self): "returns list of coordinates in tuple form" from random import choice coords = [] for i in range(self['BOMBS']): while 1: row_idx = choice(range(self['ROWS'])) col_idx = choice(range(self['COLS'])) if not (row_idx,col_idx) in coords: break coords.append((row_idx,col_idx)) return coords def inc_neighbors(self,row_idx,col_idx): for r, c in [(r,c) for r in (-1,0,1) for c in (-1,0,1)]: try: ri = r + row_idx ci = c + col_idx if ri < 0 or ci < 0: raise IndexError, "smaller than 0" v = self['BOARD'][ri][ci] self['BOARD'][ri][ci] = v + 1 except: pass def reset(self): "reset board" self['BOARD'] = map ((lambda x,d=self: [0] * d['ROWS']), range(self['COLS'])) self['PLAYER'] = map ((lambda x,d=self: ['.'] * d['ROWS']), range(self['COLS'])) for (row,col) in self.random_bombs(): self['BOARD'][row][col] = 'B' self.inc_neighbors(row,col) def to_string(self,board): str = '' for r in board: rstr = '' for c in r: rstr = rstr + '%s' % c str = str + '%s\n' % rstr return str def __repr__(self): board = self['BOARD'] return self.to_string(board) def find_edges(self,row,col): "check up down left right" board = self['BOARD'] player = self['PLAYER'] to_explore = [(row,col)] try: if row < 0 or col < 0: raise IndexError, "smaller than 0" if player[row][col] is '.': v = board[row][col] player[row][col] = v ##print "updated,", row, col if v is 0: for (r,c) in zip((0,0,-1,-1,-1,1,1,1),(-1,1,0,-1,1,0,-1,1)): ri = row + r ci = col + c self.find_edges(ri,ci) except: pass def venture(self,row,col): msg = '' board = self['BOARD'] player = self['PLAYER'] v = board[row][col] if v is 'B': player[row][col] = 'X' msg = 'You lost!\n' elif v is 0: self.find_edges(row,col) else: player[row][col] = v if self.winp(): msg = 'You won!\n' print msg + self.to_string(player) def winp(self): for (cb, cp) in zip(self['BOARD'], self['PLAYER']): cp = list(cp) for i in range(len(cp)): if cp[i] is '.': cp[i] = 'B' if tuple(cp) != tuple(cb): return 0 return 1 if __name__ == '__main__': import string g = Game(ROWS=8,COLS=8, BOMBS=10) print '*' * 80 print '*', "solution:" print '*' * 80 print g while 1: try: r = string.atoi( raw_input('row:')) c = string.atoi( raw_input('col:')) g.venture(r,c) except: import sys print sys.exc_type, sys.exc_value if sys.exc_type is KeyboardInterrupt: raise KeyboardInterrupt print '*' * 80 print '*', "solution:" print '*' * 80 print g

John Lee 20 years, 5 months ago

Multiple except:s. A slightly nicer way of doing this is to explicitly catch the exceptions you're not interested in, rather than checking the exception type (for which purpose, by the way, the identity operator seems rather strict). It's also useful to print a debug message when you're testing the code, because the except: can easily mask real problems. For example, if you have a function called load which can raise IOError:

import traceback
from cStringIO import StringIO

DEBUG = 1

def debug(msg):
print msg

try:
# Some code that might raise IOError, or another exception that you
# weren't expecting, if the user is imaginitive enough...
except (KeyboardInterrupt, IOError):
# NOTE WELL the brackets around the exception classes -- an except
# with two arguments means something quite different!
raise
except:
if DEBUG:
f = StringIO()
traceback.print_exc(None, f)
debug("uncaught exception:\n%s" % f.getvalue())
raise IOError, "invalid file '%s'" % filename