def test_get_next(self): c = Cell(0, [2, 3, 4, 5, 6, 7, 8, 9]) c1 = c.get_next() # c wasn't affected self.assertEqual(c, Cell(0, [3, 4, 5, 6, 7, 8, 9])) # c1 is sc's next, and hard-coded self.assertEqual(c1, Cell(2, []))
class TestCell(unittest.TestCase): def setUp(self): self.cell = Cell() def test_kill(self): self.cell.kill() self.assertEqual(self.cell.is_alive, False) def test_resurrect(self): self.cell.resurrect() self.assertEqual(self.cell.is_alive, True)
def test_rule_enforcement(self): b = Board("\ ??????4??\ ?9?7????5\ 17?9?4???\ 24?3??8??\ 8???????3\ ??3??2?91\ ???5?6?32\ 5????7?1?\ ??1??????\ ") b.sync_cells() self.assertEqual(Cell(0, [3, 6]), b.d[0][0]) self.assertEqual(Cell(8, []), b.d[6][1])
def test_tick_with_three_grid_with_horizontal_bar(self, three_grid_with_horizontal_bar): w = World(three_grid_with_horizontal_bar) w.tick() assert w.history[0] == three_grid_with_horizontal_bar expected_future = [ [Cell(False), Cell(True), Cell(False)], [Cell(False), Cell(True), Cell(False)], [Cell(False), Cell(True), Cell(False)] ] for y in range(2): for x in range(2): assert w.now.diagram[y][x].alive == expected_future[y][x].alive
def test_get_legal_moves(): h = 3 w = 4 ###################### # ____#V:07#____#____# ###################### # ____#W:09#____#____# ###################### # V:05#____#____#____# ###################### grid = { Coordinates(0, 0): Cell(VAMPIRE, 5), Coordinates(1, 1): Cell(WEREWOLF, 9), Coordinates(1, 2): Cell(VAMPIRE, 7), } state = State(grid=grid, height=h, width=w) vampire_legal_moves = state.get_legal_moves(VAMPIRE) werewolf_legal_moves = state.get_legal_moves(WEREWOLF) assert len(vampire_legal_moves) == 8 assert len(werewolf_legal_moves) == 8 vampire_expected = [ Move(Coordinates(0, 0), 5, Coordinates(1, 0)), Move(Coordinates(0, 0), 5, Coordinates(1, 1)), Move(Coordinates(0, 0), 5, Coordinates(0, 1)), Move(Coordinates(1, 2), 7, Coordinates(0, 2)), Move(Coordinates(1, 2), 7, Coordinates(0, 1)), Move(Coordinates(1, 2), 7, Coordinates(1, 1)), Move(Coordinates(1, 2), 7, Coordinates(2, 1)), Move(Coordinates(1, 2), 7, Coordinates(2, 2)), ] werewolf_expected = [ Move(Coordinates(1, 1), 9, Coordinates(2, 1)), Move(Coordinates(1, 1), 9, Coordinates(2, 2)), Move(Coordinates(1, 1), 9, Coordinates(1, 2)), Move(Coordinates(1, 1), 9, Coordinates(0, 2)), Move(Coordinates(1, 1), 9, Coordinates(0, 1)), Move(Coordinates(1, 1), 9, Coordinates(0, 0)), Move(Coordinates(1, 1), 9, Coordinates(1, 0)), Move(Coordinates(1, 1), 9, Coordinates(2, 0)), ] for m in vampire_expected: assert m in vampire_legal_moves for m in werewolf_expected: assert m in werewolf_legal_moves
class TestCell(unittest.TestCase): def setUp(self): self._cell = Cell(1, 1, '.') def test_hasState(self): self.assertIsNotNone(self._cell.state) def test_hasNeighbors(self): neighbors = self._cell.getNeighbors() self.assertGreaterEqual(len(neighbors), 1) self.assertLessEqual(len(neighbors), 8)
def test_compare_cells(self): self.assertTrue(Cell(1, [2, 3, 4]) == Cell(1, [2, 3, 4])) self.assertTrue(Cell(1, [2, 3, 4]) != Cell(7, [2, 3, 4])) self.assertTrue(Cell(1, [2, 3, 4]) != Cell(1, [3, 4]))
def test_rule(self): batch = [Cell(1), Cell(5), Cell(0, [1, 2, 3, 4, 5, 6])] impose_rule(batch) self.assertEqual(batch[2].v, 0, "The value didn't change") self.assertEqual(batch[2].o, [2, 3, 4, 6], "The options were reduced")
def setUp(self): self.cell = Cell()
def run_game(agent, game_number): # создать яблоко в позиции (20, 10) apple = Apple( Cell(WINDOW_WIDTH / WIDTH * round(WIDTH / 3), WINDOW_HEIGHT / HEIGHT * round(HEIGHT / 2), DISPLAY)) # создать змейку. Пусть она состоит из трех ячеек # в строке 10 и столбцах 3, 4, 5. # Какой тип данных удобен для представления змейки? snake = Snake( Cell(WINDOW_WIDTH / WIDTH * 4, WINDOW_HEIGHT / HEIGHT * round(HEIGHT / 4), DISPLAY), Cell(WINDOW_WIDTH / WIDTH * 3, WINDOW_HEIGHT / HEIGHT * round(HEIGHT / 4), DISPLAY), Cell(WINDOW_WIDTH / WIDTH * 2, WINDOW_HEIGHT / HEIGHT * round(HEIGHT / 4), DISPLAY)) # Reset player score. SCORE.player_score = 0 # Initialize list containing tuples: (action, current state). action_state_list = [] action_counter = 0 for event in pygame.event.get(): if event.type == pygame.QUIT: terminate() # обработайте событие pygame.KEYDOWN # и при необходимости измените направление движения змейки. if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: # ESC key pressed pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: snake.direction = get_direction( event.key, snake.direction) # Other key pressed # If any direction key was pressed - assign corresponding action. action = snake.direction steps = 0 # steps since the last positive reward while (not any( (snake_hit_self(snake), snake_hit_edge(snake)))) and (steps < 100): # Before snake does its first move, assign action = 'None'. action_counter += 1 action = 'none' # Previous snake direction. We'll use as one of the current state parameters for evaluation. snake_prev_direction = snake.direction if not params['train']: agent.epsilon = 0.01 else: # agent.epsilon is set to give randomness to actions agent.epsilon = 1 - (game_number * params['epsilon_decay_linear']) # get previous environment state. state_old = get_state( get_state_in_json(player_score=SCORE.player_score, high_score=SCORE.high_score, head_pos=get_snake_new_head(snake), snake_pos=snake.body, apple_pos=apple.apple, prev_direction=snake_prev_direction)) head_apple_distance_old_x, head_apple_distance_old_y = abs(get_snake_new_head(snake)[0] - apple.apple.x),\ abs(get_snake_new_head(snake)[1] - apple.apple.y) # perform random actions based on agent.epsilon, or choose the action if random.uniform(0, 1) < agent.epsilon: snake.turn(matrix=np.eye(3)[random.randint(0, 2)], prev_direction=snake_prev_direction, move_list=SNAKE_MOVE) else: # predict action based on the old state with torch.no_grad(): state_old_tensor = torch.tensor(state_old.reshape((1, 12)), dtype=torch.float32).to(DEVICE) prediction = agent(state_old_tensor) snake.turn(matrix=np.eye(3)[np.argmax( prediction.detach().cpu().numpy()[0])], prev_direction=snake_prev_direction, move_list=SNAKE_MOVE) # сдвинуть змейку в заданном направлении snake.move() # обработайте ситуацию столкновения змейки с яблоком. # В этом случае нужно: # * Увеличить размер змейки # * Создать новое яблоко. if snake_hit_apple(snake, apple): snake.grow() apple.spawn([(block.x, block.y) for block in snake.body ]) # check apple does not spawn on snake. SCORE.score() # Calculate new environment state after snake moved. state_new = get_state( get_state_in_json(player_score=SCORE.player_score, high_score=SCORE.high_score, head_pos=get_snake_new_head(snake), snake_pos=snake.body, apple_pos=apple.apple, prev_direction=snake_prev_direction)) head_apple_distance_new_x, head_apple_distance_new_y = abs(get_snake_new_head(snake)[0] - apple.apple.x),\ abs(get_snake_new_head(snake)[1] - apple.apple.y) # Set reward for the new state. reward = agent.set_reward(snake, apple, head_apple_distance_new_x, head_apple_distance_old_x, head_apple_distance_new_y, head_apple_distance_old_y) # If snake hit apple or moved towards it, reset steps counter to 0. if reward > 0: steps = 0 if params['train']: # train short memory base on the new action and state agent.train_short_memory( state_old, snake.turn_direction, reward, state_new, any((snake_hit_self(snake), snake_hit_edge(snake)))) # store the new data into a long term memory agent.remember(state_old, snake.turn_direction, reward, state_new, any((snake_hit_self(snake), snake_hit_edge(snake)))) # передать яблоко в функцию отрисовки кадра # передать змейку в функцию отрисовки кадра if params['display']: draw_frame(snake, apple, SCORE) FPS_CLOCK.tick(FPS) steps += 1 # Appending the current action (could be 'none') and the current state of the snake to # the list - "Action-State List". action_state_list.append( ({ f"Action {action_counter}": action }, get_state_in_json(player_score=SCORE.player_score, high_score=SCORE.high_score, head_pos=get_snake_new_head(snake), snake_pos=snake.body, apple_pos=apple.apple, prev_direction=snake_prev_direction))) # "Action-State List" to current game and write json on disk. STATE[f"Game #{game_number}"] = action_state_list # если змейка достигла границы окна, завершить игру. # Для проверки воспользуйтесь функцией snake_hit_edge. if snake_hit_edge(snake): write_state_to_file(STATE, CURRENT_TIME) # если змейка задела свой хвост, завершить игру. # Для проверки восппользуйтесь функцией snake_hit_self. if snake_hit_self(snake): write_state_to_file(STATE, CURRENT_TIME)
def test_apply_move(): h = 3 w = 4 ###################### # H:05#____#____#____# ###################### # V:06#W:17#____#V:01# ###################### # H:10#W:10#____#____# ###################### grid = { Coordinates(0, 2): Cell(HUMAN, 5), Coordinates(0, 1): Cell(VAMPIRE, 6), Coordinates(0, 0): Cell(HUMAN, 10), Coordinates(1, 1): Cell(WEREWOLF, 17), Coordinates(1, 0): Cell(WEREWOLF, 10), Coordinates(3, 1): Cell(VAMPIRE, 1), } state = State(grid=grid, height=h, width=w) with pytest.raises(IllegalMoveException): state.apply_moves([Move( Coordinates(0, 1), 7, Coordinates(0, 2), )], VAMPIRE) assert state.get_cell(0, 1) == Cell(VAMPIRE, 6) with pytest.raises(IllegalMoveException): state.apply_moves([Move( Coordinates(0, 1), 6, Coordinates(0, 2), )], WEREWOLF) assert state.get_cell(0, 1) == Cell(VAMPIRE, 6) state.apply_moves([Move( Coordinates(0, 1), 6, Coordinates(0, 2), )], VAMPIRE) assert state.get_cell(0, 1) is None assert state.get_cell(0, 2) == Cell(VAMPIRE, 11) state.apply_moves([Move( Coordinates(1, 1), 17, Coordinates(0, 2), )], WEREWOLF) assert state.get_cell(0, 1) is None assert state.get_cell(0, 2) == Cell(WEREWOLF, 17) state.apply_moves([Move( Coordinates(3, 1), 1, Coordinates(3, 0), )], VAMPIRE) assert state.get_cell(3, 1) is None assert state.get_cell(3, 0) == Cell(VAMPIRE, 1) state.apply_moves([Move( Coordinates(1, 0), 10, Coordinates(0, 0), )], WEREWOLF) assert state.get_cell(1, 0) is None cell = state.get_cell(0, 0) if cell is not None: assert cell.race in (WEREWOLF, HUMAN) assert 1 <= cell.count <= 20 else: warnings.warn("cell is None")
def setUp(self): self._cell = Cell(1, 1, '.')
def setUp(self): self.fst_cell = Cell(6, 6) self.snd_cell = Cell(5, 6) self.trd_cell = Cell(5, 7) self.fourth_cell = Cell(6, 7) self.fifth_cell = Cell(7, 5)
class GameOfLife(unittest.TestCase): def setUp(self): self.fst_cell = Cell(6, 6) self.snd_cell = Cell(5, 6) self.trd_cell = Cell(5, 7) self.fourth_cell = Cell(6, 7) self.fifth_cell = Cell(7, 5) def test_cell_neighbourhood(self): expected_neighbourhood = set([(6, 7), (5, 5), (5, 6), (7, 6), (5, 7), (7, 7), (7, 5), (6, 5)]) self.assertEqual(expected_neighbourhood, self.fst_cell.neighbourhood_locations()) def test_a_cell_without_neighbours_dies_after_tick(self): dying_cell = Cell(4, 4) my_board = Board([self.fst_cell, self.snd_cell, self.trd_cell, dying_cell]) my_board.tick() self.assertFalse(my_board.cell_alive_at(4, 4)) self.assertTrue(my_board.cell_alive_at(6, 6)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(5, 7)) def test_a_cell_with_2or3_neighbours_stays_alive_after_tick(self): my_board = Board([self.fst_cell, self.snd_cell, self.trd_cell, self.fourth_cell]) my_board.tick() self.assertTrue(my_board.cell_alive_at(6, 6)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(5, 7)) self.assertTrue(my_board.cell_alive_at(6, 7)) def test_a_cell_with_more_then_3_neighbours_dies(self): my_board = Board([self.fst_cell, self.snd_cell, self.trd_cell, self.fourth_cell, self.fifth_cell]) my_board.tick() # dying cells: first and fifth. self.assertFalse(my_board.cell_alive_at(6, 6)) self.assertFalse(my_board.cell_alive_at(7, 5)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(5, 7)) self.assertTrue(my_board.cell_alive_at(6, 7)) def test_a_died_cell_with_3_alive_neighbours_resurrects(self): my_board = Board([self.fst_cell, self.snd_cell, self.trd_cell]) my_board.tick() self.assertTrue(my_board.cell_alive_at(6, 6)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(5, 7)) # Having 3 alive neighbours comes back to life. self.assertTrue(my_board.cell_alive_at(6, 7)) def test_acceptance_different_generations(self): # simple spaceship pattern first = Cell(5, 5) second = Cell(6, 5) third = Cell(6, 6) fourth = Cell(7, 5) my_board = Board([first, second, third, fourth]) # First generation # cells: (5, 5), (6, 5), (6, 6), (7, 5) # and these new borns (6, 4), (5, 6), (7, 6) my_board.tick() self.assertTrue(my_board.cell_alive_at(5, 5)) self.assertTrue(my_board.cell_alive_at(6, 5)) self.assertTrue(my_board.cell_alive_at(6, 6)) self.assertTrue(my_board.cell_alive_at(7, 5)) self.assertTrue(my_board.cell_alive_at(6, 4)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(7, 6)) # Second generation # dying cells: (5, 5), (6, 5), (6, 6), (7, 5) # new borns: (5, 4), (6, 7), (7, 4) # alive cells: (5, 4), (6, 7), (7, 4), (5, 6), # (6, 4), (7, 6) my_board.tick() self.assertFalse(my_board.cell_alive_at(5, 5)) self.assertFalse(my_board.cell_alive_at(6, 5)) self.assertFalse(my_board.cell_alive_at(6, 6)) self.assertFalse(my_board.cell_alive_at(7, 5)) self.assertTrue(my_board.cell_alive_at(5, 4)) self.assertTrue(my_board.cell_alive_at(6, 7)) self.assertTrue(my_board.cell_alive_at(7, 4)) self.assertTrue(my_board.cell_alive_at(5, 6)) self.assertTrue(my_board.cell_alive_at(6, 4)) self.assertTrue(my_board.cell_alive_at(7, 6)) # Third generation: # dying cells: (5, 4), (5, 6), (7, 4), (7, 6) # new borns: (5, 5), (6, 3), (6, 6), (7, 5) # alive cells: (5, 5), (6, 3), (6, 6), (7, 5), # (6, 4), (6, 7) my_board.tick() self.assertFalse(my_board.cell_alive_at(5, 4)) self.assertFalse(my_board.cell_alive_at(5, 6)) self.assertFalse(my_board.cell_alive_at(7, 4)) self.assertFalse(my_board.cell_alive_at(7, 6)) self.assertTrue(my_board.cell_alive_at(5, 5)) self.assertTrue(my_board.cell_alive_at(6, 3)) self.assertTrue(my_board.cell_alive_at(6, 6)) self.assertTrue(my_board.cell_alive_at(7, 5)) self.assertTrue(my_board.cell_alive_at(6, 4)) self.assertTrue(my_board.cell_alive_at(6, 7))
def test_dead_cell_fate(self): assert Grid.will_live([Cell(True) for i in range(2)], False) is False assert Grid.will_live([Cell(True) for i in range(3)], False) is True assert Grid.will_live([Cell(True) for i in range(4)], False) is False assert Grid.will_live([Cell(True)], False) is False
def cell(): return Cell()