class testNannon(unittest.TestCase): def setUp(self): self.to = Nannon() self.bo = Board(board = [-1,-1,0,0,1,1],homes = {-1:1,1:1}) self.bo2 = Board(board = [-1,-1,0,1,0,1],homes = {-1:1,1:1}) def testCheckWin(self): self.to = Nannon() #: unplayed game can't be finished self.assertFalse(self.to.board.checkWin()) self.to.gameLoop(1,auto=True) #after we've played the game, it should be finished self.assertTrue(self.to.board.checkWin()) self.to.newGame(auto=True) self.assertFalse(self.to.board.checkWin()) def testDie(self): for i in range(1000): self.assertIn(self.to.die.roll(),range(1,7)) k = 1000000 s = float(0) for i in range(k): s = s + self.to.die.roll()/float(k) self.assertAlmostEqual(s,3.5,2) def testValidMoves(self): self.assertIn((1,3),self.bo.validMoves(2,-1)) self.assertNotIn((2,5),self.bo.validMoves(3,-1)) self.assertNotIn((2,6),self.bo.validMoves(4,-1)) self.assertNotIn((2,1),self.bo.validMoves(4,-1)) self.assertNotIn((2,3),self.bo.validMoves(4,-1)) self.assertIn((2,4),self.bo2.validMoves(2,-1)) def testConsequences(self): boTemp = Board(board = [-1,-1,0,1,0,1],homes = {-1:1,1:1}) self.assertIn((2,4),boTemp.validMoves(2,-1)) boTemp.move(2,4) self.assertDictEqual(boTemp.homes,{-1:1,1:2}) self.assertListEqual(boTemp.board,[-1,0,0,-1,0,1]) def testPrime(self): self.assertTrue(self.bo.prime(5)) self.assertTrue(self.bo.prime(6)) self.assertTrue(self.bo2.prime(6)) self.assertFalse(self.bo2.prime(4)) def testColor(self): self.assertEqual(-1,self.bo.color(1))
class Nannon: """A class that implements the Nannon game""" board = None #: The board the game is played on die = None #: The die used to play the game points = {-1:0,1:0} #: How many points each side has. Note, -1 is used to represent white, and 1 black games = 0 #: Games played current = 0 #: The current player. 0 at start of game intToColor = lambda self, x: "white" if x == -1 else "tied" if x == 0 else "black" def __init__(self): """ #Use: s = Nannon() #Pre: None #Post: s is a new Nannon game """ self.board = Board() self.die = Die() self.points = {-1:0,1:0} self.games = 0 self.current = 0 def roll(self,current=0): """ #Use: k = s.roll(j) #Pre: s is a Nannon game. #Post: Alea iacta est. The dies are cast for the initial throw if current is 0, or just rolled if current is something else/not provided """ if current == 0: whiteDie = self.die.roll() blackDie = self.die.roll() if whiteDie == blackDie: return self.roll() else: self.current = 1 if whiteDie < blackDie else -1 return abs(whiteDie-blackDie) else: return self.die.roll() def getInput(self,lv=None): """ #Use: ch = s.getInput(i) #Pre: i is an integer, s is a Nannon object #Post: ch is an integer from stdin in [0,...,lv] """ try: ch = raw_input("Choice: ") if len(ch) == 0: ch = 0 ch = int(ch) if lv is not None: if ch not in range(lv): raise ValueError return ch except ValueError: print "Invalid choice!" return self.getInput(lv) def newGame(self,auto=False): """ #Use: s.newGame(a) #Pre: a is boolean #Post: The gameboard has been set up for a new game, and a messaged printed if the optional auto is false """ if not auto: print "New game, game %d \n\n" % (self.games) self.board = Board([-1,-1,0,0,1,1],{-1:1,1:1}) self.current = 0 self.gameOver = False def gameLoop(self,gamesToPlay = 1, auto = False): """ #Use: s.gameLoop(i,a) #Pre: i is an integer, a is boolean, both optional #Post: The game has been played for i rounds, 1 if i not provided, automatically if auto is True """ while self.games < gamesToPlay: self.newGame(auto) while self.gameOver is False: self.current = self.current*-1 roll = self.roll(self.current) v = self.board.validMoves(roll,self.current) if v == []: if not auto: print "It's %s's turn. The roll was %d." % (self.intToColor(self.current), roll) print "No available moves." print continue if not auto: print "It's %s's turn. The roll was %d." % (self.intToColor(self.current), roll) print self.board print "Choose from the following moves (default 0):" self.printMoves(v,self.current) ch = self.getInput(len(v)+1) if not auto else 0 #Biased for black, len(v)-1 is biased for white fr,to = v[int(ch)] self.gameOver = self.board.move(fr,to) if not auto: print self.points[self.current] = self.points[self.current]+1 if not auto: print "The winner of this round is %s!" % (self.intToColor(self.current)) self.printScore self.games = self.games+1 def printScore(self): """ #Use: s.printScore() #Pre: s i s a Nannon object #Post: The current score has been printed """ winner = -1 if self.points[-1] > self.points[1] else 0 if self.points[-1] == self.points[1] else 1 pointString = (self.points[winner],self.points[winner*-1]) if winner != 0 else (self.points[1],self.points[1]) print "The score is %s with %s points, after %d games." % (self.intToColor(winner), "%d to %d" % pointString ,self.games) def printMoves(self,moves,color): """ #Use: s.printMoves(m,c) #Pre: s is a nannon object, m is a list of valid moves, color is the color of the player who can preform the moves #Post: The current score has been printed """ for i,r in enumerate(moves): f,t = r rangelist = [k for k in range(-6,14) if k != 0 and k != 7] chart = dict(zip(rangelist,map(lambda x: x if x in range(1,7) else "safety",rangelist))) chart[self.board.home(color)] = "home" chart[self.board.safety(color)] = "safety" print " %d: Move %s checker from %s to %s" %(i,self.intToColor(color),str(chart[f]),str(chart[t])) for k in range(i,2): print
def testConsequences(self): boTemp = Board(board = [-1,-1,0,1,0,1],homes = {-1:1,1:1}) self.assertIn((2,4),boTemp.validMoves(2,-1)) boTemp.move(2,4) self.assertDictEqual(boTemp.homes,{-1:1,1:2}) self.assertListEqual(boTemp.board,[-1,0,0,-1,0,1])