#! /usr/bin/env python #12-Feb-2008-Morning Pilpilon 001 #12-Feb-2008-Noon Pilpilon 002 #13-Feb-2008-Evening Pilpilon 003 #18-Feb-2008-Evening Pilpilon 004 Added options from random import randrange prompt = """enter s X Y for shot(open field), enter m X Y for mark mine, enter u X Y for unmark mine\n""" excl = ["\nI mean, letter and two integers, please!\n", "\nnever've heard of such a command!\n"] comms = { "s":"shot", "m":"mark" , "u":"unmark"} def bordhead( width): return ["\n\ny\\x %s\n" % " ".join(["%2d" % k for k in range(width)])] class Field : def __init__ (self, a, b ): self.coord = (a,b) def __eq__ (self , other): return self.coord == other.coord def __str__(self): return `self.coord` def neigh (self , other): a,b = [self.coord[i] - other.coord[i] for i in (0,1)] return -1 <= a <= 1 and -1 <= b <= 1 class Board : def __init__ ( self, num = 10, width = 10, height = 10): self.fields = [] self.width = width self.height = height self.num = num while len(self.fields) < num : f = Field ( randrange(0,width),randrange(0,height)) if f not in self.fields: self.fields.append(f) def shot( self, a, b): f = Field(a,b) res = f in self.fields around = len([x for x in self.fields if f.neigh(x)]) return (res, around) def __ch (self, a,b): if Field(a,b) in self.fields : return 'X' else : return '0' def __str__ (self): a = bordhead + ["%d " % j +" ".join([ self.__ch(i,j) for i in range(self.width)]) for j in range(self.height)] return "\n".join(a) class Gameboard: def __init__ ( self, num = 10, width = 10, height = 10): self.board = Board(num, width, height) self.openedfields = {} self.ingame = True self.win = False def __ch (self, a,b): return self.openedfields.get( (a,b), "C") def __test (self, a,b): return self.openedfields.has_key((a,b)) or not self.ingame or a < 0 or a >= self.board.width or b < 0 or b >= self.board.height def __win(self): return len([self.openedfields[x] for x in self.openedfields if self.openedfields[x] !="M"])+ self.board.num >= self.board.width * self.board.height def __str__ (self): a = bordhead(self.board.width) + ["%2d " % j + " ".join([ self.__ch(i,j) for i in range(self.board.width)]) for j in range(self.board.height)] return "\n".join(a) def shot ( self, a, b): if self.__test(a,b) : return re, nu = self.board.shot(a,b) if re : self.__reveal("X") self.ingame = False else: self.openedfields[(a,b)] = `nu` self.win = self.__win() self.ingame = not self.win if not self.ingame: self.__reveal("D") if nu == 0 : self.__shotaround(a,b) def __reveal ( self, letter): for f in self.board.fields : self.openedfields[f.coord] = letter def __shotaround( self, a,b): for u in [ ( c,d) for c in range( a-1, a+2) for d in range( b-1, b+2) if (c, d ) != (a,b)]: self.shot(u[0],u[1]) def mark (self, a,b): if self.__test(a,b) : return self.openedfields[(a,b)] = "M" def unmark (self, a,b): if self.openedfields.get( (a,b), "C") == "M" : self.openedfields.pop((a,b)) if __name__ == "__main__": from optparse import OptionParser parser = OptionParser() parser.add_option("-w", "--width", action="store", type="int", dest="width", default=10, help = "width of the gameboard" ) parser.add_option("-t", "--height", action="store", type="int", dest ="height", default=10, help = "height of the gameboard") parser.add_option("-n", "--number", action="store", type="int", dest ="number", default=10, help = "number of mines") (options, args) = parser.parse_args() a = Gameboard(options.number, options.width, options.height) while a.ingame: print a pr = raw_input(prompt) l = pr.split() while len(l) >= 3 : c, l = l[:3],l[3:] if not all( [getattr(x, "isdigit")() for x in c[1:]]): print excl[0] break if not comms.has_key(c[0]) : print excl[1] break getattr(a, comms[c[0]])(int(c[1]),int(c[2])) print a if a.win : print "you win" else : print "you lose"