def nsa(request, **kwargs): """The NSA game. They're always listening... Basically, the "NSA" listens to every event, so even a hover by the human triggers a move by the NSA. With each move, the occupied positions are sent to the view to determine when there is a win. Ironically, in this game, only NSA moves are recorded, so naturally, the human can't win against the NSA. (Just like life, man)""" move = kwargs.get('move', None) if move: try: g = Game() over = False result = {'result': ''} context = dict() g.take('machine', int(move)) winner = g.winner('machine') if winner: over = True result = {'result': list(winner)} context['move'] = 999 context['over'] = over context['result'] = result return HttpResponse(json.dumps(context), content_type="application/json") except: raise Http404 Game.reset() return render(request, 'nsa.html')
def standard(request, **kwargs): """The "standard" unwinnable game control.""" # Get the move from the GET args, if any move = kwargs.get('move', None) if move: try: # Start the game and initialize some useful variables g = Game() over = False result = {'result': ''} context = dict() # Take the position indicated by <move> g.take('human', int(move)) if len(g.available) != 0: # There are still moves available, so just make it feel like the computer is thinking a bit. # Response is otherwise pretty much instantaneous and doesn't "feel" very real. sleep(2) # Normally, I would expect this next operation to be necessary. Since there is no actual session being # started, any game state would be lost when the request completes so any subsequent requests would # have no memory of what moves had previously been made. It appears, however, that the Django runserver # preserves the game state between requests, so this isn't necessary if using the runserver. In the # real world, this would take all the moves that have been made so far, which are submitted from the UI, # and reconstruct the game state from them. # x = request.GET.get('x', None) # if x: # g.x = [int(i) for i in x.strip(',').split(',')] # o = request.GET.get('o', None) # if o: # g.o = [int(i) for i in o.strip(',').split(',')] take = g.next_move() g.take('machine', take) winner = g.winner('machine') # If the machine has won, set game over and the winning vector for return to UI if winner: over = True result = {'result': list(winner)} else: take = 9999 # No other moves are taken over = True result = {'result': 'draw'} if over: # The game is over, so reset the game--this actually doesn't seem to work with the runserver though for # some reason. You actually have to stop and restart the runserver to reset the game. Not sure why. Game.reset() # Set up the response dictionary and resturn as JSON for handling by the UI context['move'] = take context['over'] = over context['result'] = result return HttpResponse(json.dumps(context), content_type="application/json") except Exception: print traceback.format_exc() raise Http404 return render(request, 'standard.html')
class TicTacToeTest(unittest.TestCase): def setUp(self): self.board = Game() def tearDown(self): self.board.reset() def test_001(self): """Test the available move checker""" moves = self.board.available # Make sure all moves are available self.assertTrue(len(moves) == 9, 'Not all moves are available') self.assertTrue(moves == [0, 1, 2, 3, 4, 5, 6, 7, 8], 'Available moves do not match') def test_002(self): """Test position setter""" self.board.take('machine', 4) # Machine takes center position moves = self.board.available self.assertTrue(len(moves) == 8, 'Position not taken') self.assertTrue(moves == [0, 1, 2, 3, 5, 6, 7, 8], 'Available moves do not match') def test_003(self): """Test win detection""" self.board.take('machine', 1) # At this point we shoulnd't have a winner yet self.assertFalse(self.board.winner('machine'), 'We have a winner') self.board.take('machine', 7) # Now the machine player should have won self.assertTrue(self.board.winner('machine'), '{0} is not the winner'.format(PLAYERS['machine'])) self.assertTrue(self.board.winner('machine') == (1, 4, 7), 'Unexpected winning vector') def test_004(self): """Test win detection""" self.board.clear('machine', 1) # Now the machine player should have a winning move available self.assertTrue(self.board.winnable('machine') == 1, 'Exptected to be able to win') def test_005(self): """Test game evaulation -- Winning move""" self.board.take('human', 0) self.board.take('human', 3) move = self.board.eval_tree('machine') self.assertTrue(move == 1, 'Expected to choose position 1 for the win') def test_006(self): """Test game evaluation -- Blocking move""" Game.reset() self.board.take('human', 4) self.board.take('human', 2) self.board.take('machine', 0) self.board.take('machine', 1) move = self.board.eval_tree('machine') self.assertTrue(move == 6, 'Expected to choose position 6 for the block') def test_007(self): """Test game evaluation - minimax.""" Game.reset() self.board.take('human', 0) self.board.take('human', 4) self.board.take('machine', 8) move = self.board.next_move() self.assertTrue(move == 2 or move == 6, 'Expected to choose position 2 or 6 to lead to a draw')