def basic(self, commit=False, n=None, **kwargs): if n: return [self.basic(commit=commit, **kwargs) for _ in range(n)] game = Game(width=20, height=20, max_turns_to_next_food_spawn=12, **kwargs) if commit: game.save() return game
def start_game(self, snake_ids): """ Start a game given a tuple of snake id's. Returning a game id. """ if len(snake_ids) == 1: return game = Game(width=11, height=11, max_turns_to_next_food_spawn=12) game.save() logger.info(f"starting game id={game.id}") for s in Snake.objects.filter(id__in=snake_ids): game.snakes.add(s) GameSnake.objects.create(snake=s, game=game) game.save() game.create() game.run() GameLeaderboard(game=game).save()
def create(self, *args, **kwargs): heat = kwargs.get("heat") previous_game = heat.latest_game skip = [w.snake.id for w in heat.winners] if previous_game is not None: if previous_game.winner is None: raise PreviousGameTiedException() skip.append(previous_game.winner.snake.id) next_snakes = [ sh.snake for sh in previous_game.snakes if sh.snake.id not in skip ] else: next_snakes = [sh.snake for sh in heat.snakes] max_turns = 15 if heat.round.tournament_bracket.board_max_turns_to_next_food_spawn is not None: max_turns = heat.round.tournament_bracket.board_max_turns_to_next_food_spawn game = Game( width=heat.round.tournament_bracket.board_width, height=heat.round.tournament_bracket.board_height, max_turns_to_next_food_spawn=max_turns, engine_url=heat.round.tournament_bracket.tournament.engine_url, ) game.save() snake_ids = [snake.id for snake in next_snakes] snakes = (TournamentSnake.objects.filter( snake__id__in=snake_ids, bracket=heat.round.tournament_bracket).prefetch_related( "snake").prefetch_related("team")) for ts in snakes: game.snakes.add(ts.snake) GameSnake.objects.create(snake=ts.snake, game=game, name=ts.team.name) game.save() game.create() return super(HeatGameManager, self).create(*args, **kwargs, game=game)
def setUp(self): self.game_ip = Game.objects.get(name='Game One') self.game_r = Game.objects.get(name='Game Two') self.game_s = Game.objects.get(name='Game Three') self.game_r2 = Game.objects.get(name='Game Four') self.girl1 = Person.objects.get(username='******') self.girl2 = Person.objects.get(username='******') self.girl3 = Person.objects.get(username='******') self.girl4 = Person.objects.get(username='******') self.man1 = Person.objects.get(username='******') self.man2 = Person.objects.get(username='******') self.man3 = Person.objects.get(username='******') self.man4 = Person.objects.get(username='******') # Create game that is being initialised self.game_init = Game( name = "Game Initialising A", owner = self.girl1, status = GameStatus.objects.initialising, max_rounds = 4, max_players = 10, ) self.game_init.save()
class GameTestCase(TestCase): fixtures = ['players.json', 'basic_games.json'] def setUp(self): self.game_ip = Game.objects.get(name='Game One') self.game_r = Game.objects.get(name='Game Two') self.game_s = Game.objects.get(name='Game Three') self.game_r2 = Game.objects.get(name='Game Four') self.girl1 = Person.objects.get(username='******') self.girl2 = Person.objects.get(username='******') self.girl3 = Person.objects.get(username='******') self.girl4 = Person.objects.get(username='******') self.man1 = Person.objects.get(username='******') self.man2 = Person.objects.get(username='******') self.man3 = Person.objects.get(username='******') self.man4 = Person.objects.get(username='******') # Create game that is being initialised self.game_init = Game( name = "Game Initialising A", owner = self.girl1, status = GameStatus.objects.initialising, max_rounds = 4, max_players = 10, ) self.game_init.save() def testCanRegister(self): """ Tests if someone can register for a game. If the same is in progress, it can't register new people. If the person is a girl, she can register. If the man is already in the game, he can't register. """ self.assertEquals(self.game_ip.can_register(self.girl1), False) self.assertEquals(self.game_ip.can_register(self.man1), False) self.assertEquals(self.game_ip.can_register(self.girl2), False) self.assertEquals(self.game_ip.can_register(self.man4), False) self.assertEquals(self.game_r.can_register(self.girl1), False) self.assertEquals(self.game_r.can_register(self.man1), True) self.assertEquals(self.game_r.can_register(self.girl2), False) self.assertEquals(self.game_r.can_register(self.man4), False) def testRoundIsActive(self): """ Test that the is_active function of a round is working. """ r = self.game_s.active_round() self.assertTrue(r.is_active(self.man1)) self.assertRaises(GameError, r.is_active, self.man4) def testRoundIsEliminated(self): """ Test that the is_eliminated function of a round is working. """ r = self.game_s.active_round() self.assertFalse(r.is_eliminated(self.man1)) self.assertRaises(GameError, r.is_active, self.man4) def testActiveQuestion(self): """ Test that an active question can be found """ self.assertEquals(self.game_ip.get_active_question().question, "What is your best dance move?") # Registering games should not have an active round self.assertIsNone(self.game_r.get_active_question()) def testActiveRound(self): """ Test that an active round can be found """ self.assertEquals(self.game_ip.active_round().__class__, Round) self.assertEquals(self.game_ip.active_round().number, 1) self.assertIsNone(self.game_r.active_round(), None) def testStart(self): """ Test starting a game. When a game starts it should: - have it's status set to active - have the first round set to state answering - have all players registered in the game set to state active - enroll all registered players into the first round and set them to active - update the current round from 0 to 1 If the game is not full it cannot be started. A GameError should be thrown. """ # Attempt to start a non-full game. self.assertRaises(GameError, self.game_r.start) # Attempt to start a game already in progress self.assertRaises(GameError, self.game_ip.start) game = self.game_r2 game.start() # Ensure the current round has been set self.assertEquals(game.current_round, 1) # Ensure the active round has been set up active_round = game.active_round() self.assertIsNotNone(active_round) self.assertEquals(active_round.number, 1) self.assertIsNotNone(active_round.question) # Ensure the active round has the players # enrolled in it players = game.registered_players() round_players = active_round.registered_players() self.assertEquals(len(players), len(round_players)) for p in players: self.assertTrue(p in round_players) # Ensure player have active status # TODO pass def testHasAnswered(self): """ Test is a user has answered a question in a game round """ round = self.game_ip.active_round() # Man 1 is in the game but hasn't answered any questions, # so should be allowed to self.assertEquals(round.has_answered(self.man1), False) # Man 4 is not in this game, so an error should be raised self.assertRaises(GameError, round.has_answered, self.man4) def testCanAnswer(self): """ Test is a user can answer a question in a game. """ # If the method is called on a game not in # progress, an error should be thrown self.assertEquals(self.game_r.can_answer(self.man1), False) # If a game is in progress, but the active round # is in the scoring state, the user cannot answer self.assertEquals(self.game_s.can_answer(self.man1), False) # A girl cannot answer questions self.assertEquals(self.game_ip.can_answer(self.girl1), False) # A person not involved in the game should # not be able to answer self.assertEquals(self.game_ip.can_answer(self.man4), False) # A person in this game who has not given an # answer should be able to self.assertEquals(self.game_ip.can_answer(self.man1), True) # A person who has already given an answer in this # round should not be able to answer # A person involved in the game but who has # been eliminated should not be allowed to answer membership = self.man1.roundmembership_set.get(round=self.game_ip.active_round()) membership.status = PlayerStatus.objects.eliminated membership.save() self.assertEquals(self.game_ip.can_answer(self.man1), False) def testInitialiseRounds(self): """ Test the initialisation of a game rounds. After a game has been initialised it should have the following properties. - n pending rounds associated with it, where n is equal to game.max_rounds - game.current_round equal to 0 - game should be in a pending state - a question associated with each of the rounds - if too many questions are passed in, the game should throw an initialisation error """ # Test standard game initialisation game = self.game_init questions = [(1, 'q1'), (2, 'q2'), (3, 'q3'), (4, 'q4')] game.initialise(questions) self.assertEquals(game.current_round, 0) self.assertEquals(game.status, GameStatus.objects.registering) self.assertEquals(game.round_set.count(), 4) # Ensure all rounds have been correctly initialised for i, r in enumerate(game.round_set.all()): self.assertEquals(r.number, i+1) self.assertIsNotNone(r.question) self.assertEquals(r.question.question, questions[i][1]) # Ensure game is now in registering state self.assertEquals(game.status, GameStatus.objects.registering) def testInitialiseWrongQuestions(self): """ Test that an error is thrown if an invalid number of questions is passed to the initialise function. """ game = self.game_init too_many_questions = [(1, 'q1'), (2, 'q2'), (3, 'q3'), (4, 'q4'), (5, 'q5')] too_few_questions = [(1, 'q1'), (2, 'q2')] self.assertRaises(GameError, game.initialise, too_many_questions) self.assertRaises(GameError, game.initialise, too_few_questions) self.assertRaises(GameError, game.initialise, None) def testDeleteGame(self): """ Ensure that when registering games are deleted, the rounds and questions are deleted to. Any preset questions should not be deleted. """ def testAdvanceToScoring(self): """ Test game state change from in progress round to scoring round. When this happens, the currently active round should change to 'scoring' state. Players who have not responded should be given a score of zero and a no_show status. """ game = self.game_ip game.advance_to_scoring() # After advancing, the game should be in scoring state self.assertEquals(game.is_scoring, True) # After advancing, man1 and man2 should have # been set to no_show and given a score of zero self.assertEquals(game.active_round().score(self.man1), 0) self.assertEquals(game.active_round().score(self.man2), 0) # Man3 should not have been given a score yet self.assertIsNone(game.active_round().score(self.man3)) # The active round should be in state scoring self.assertEquals(game.active_round().status, RoundStatus.objects.scoring) # A game already in the scoring phase, cannot advance to scoring, so # raise an error self.assertRaises(GameError, game.advance_to_scoring) def testAdvanceRound(self): """ Test advancing a game round. Rounds should only be advanced when they are in the active round is in the scoring phase. Before advancing, any players who have not have their answers scored should be given a score of full marks. """ # Advance a game from the scoring phase. # The current_round variable should increase # by one, the round should be set to completed, # and the new round should be set to answering game = self.game_s r = game.active_round() n = game.current_round game.advance_round() self.assertEquals(game.current_round, n+1) self.assertEquals(game.round_set.get(number=n).status, RoundStatus.objects.completed) self.assertEquals(game.active_round().status, RoundStatus.objects.answering) # Ensure that players whose answers were not rated in time # are given top marks. self.assertEquals(r.score(self.man1), 100) # Ensure that the new round memberships have been created self.assertTrue(game.active_round().is_active(self.man1)) # Games that are not active with the round in the # scoring phase should thow an error # if you attempt to advance them self.assertRaises(GameError, self.game_r.advance_round) self.assertRaises(GameError, self.game_ip.advance_round) def testTick(self): # Attempt to advance a game from scoring phase r = self.game_s.active_round() n = self.game_s.current_round self.assertTrue(self.game_s.tick()) self.assertEquals(self.game_s.current_round, n+1) old_r = self.game_s.round_set.get(number=r.number) self.assertEquals(old_r.status, RoundStatus.objects.completed) new_r = self.game_s.round_set.get(number=r.number+1) self.assertEquals(new_r.status, RoundStatus.objects.answering) # Test advancing a game from answering phase n = self.game_ip.current_round self.assertTrue(self.game_ip.tick()) self.assertEquals(self.game_ip.current_round, n) # Test advancing a game that is not in progress self.assertFalse(self.game_init.tick()) self.assertFalse(self.game_r.tick()) def testEnroll(self): """ Test the enroll process. """ # Attempt to register someone in a game # that is already full self.assertRaises(EnrollFailed, self.game_r2.enroll, self.man1) # Attempt to register someone in a game # they are already registered for self.assertRaises(EnrollFailed, self.game_r.enroll, self.man4) # Attempt to register a girl in a game self.assertRaises(EnrollFailed, self.game_r.enroll, self.girl1) # Attempt to register someone in a game # that has already started self.assertRaises(EnrollFailed, self.game_ip.enroll, self.man1) self.assertRaises(EnrollFailed, self.game_s.enroll, self.man1) # Register someone in a valid game self.game_r.enroll(self.man1) players = self.game_r.registered_players() self.assertTrue(self.man1 in players) def testEliminate(self): """ When someone is eliminated, their status in the game and the round should be set to eliminated. People can only be eliminated in the scoring phase of a round. """ game = self.game_s game.eliminate(self.man1) self.assertTrue(game.is_eliminated(self.man1)) self.assertTrue(game.active_round().is_eliminated(self.man1)) # Attempt to elimiante someone who is not in the # game. game.eliminate(self.man4)