def test_model(self): steps_arr = [] scores_arr = [] for a in range(self.test_games): steps = 0 game_memory = [] game = Snake() _, score, snake, food = game.start() prev_observation = self.generate_observation(snake, food) for _ in range(self.goal_steps): done, score, snake, food, action, predictions = self._play( game, snake, prev_observation) game_memory.append([prev_observation, action]) if done: result_string = steps + snake + food + prev_observation + predictions print('-----') print('Game Test', a) print(result_string) with open("testing.txt", "a") as file: file.write(f'Test {a}\n {result_string}') break else: prev_observation = self.generate_observation(snake, food) steps += 1 steps_arr.append(steps) scores_arr.append(score) print('Average steps:', mean(steps_arr)) print(Counter(steps_arr)) print('Average score:', mean(scores_arr)) print(Counter(scores_arr)) step_str = str(mean(steps_arr)) score_str = str(mean(scores_arr)) with open("Stats.txt", "a") as file: file.write(step_str + " ---------- " + score_str + "\n")
def addStatus(self, Snake2, Score2, food2, frame_iteration, direction, old_record): Snake = [] food = [food2.x, food2.y] for itemSnack2 in Snake2: item = [itemSnack2.x, itemSnack2.y] Snake.append(item) self.statusGame.append( [Snake, Score2, food, frame_iteration, direction, old_record])
def visualise_game(self): while True: game = Snake(is_gui=True) _, score, snake, food = game.start() prev_observation = self.generate_observation(snake, food) for _ in range(self.goal_steps): done, score, snake, food, action, predictions = self._play( game, snake, prev_observation) if done: break else: prev_observation = self.generate_observation(snake, food)
def train(): # plot_scores = [] # plot_mean_scores = [] # total_score = 0 record = 0 old_record = 0 num_snake = 3 agents = [] snakes = [] global game Threads_training_snake = [] for i in range(num_snake): snake = Snake() snakes.append(snake) game = SnakeGameAI(num_snake=num_snake, Snake=snakes) for i in range(num_snake): agent = Agent() agents.append(agent) thread = threading.Thread(target=trainEachSnake, args=( agent, i, )) thread.start() Threads_training_snake.append(thread)
def initial_population(self): training_data = [] for i in range(self.init_games): print("Training Game:", i + 1) game = Snake() _, prev_score, snake, food = game.start() prev_observation = self.generate_observation(snake, food) prev_food_distance = self.get_food_distance(snake, food) for _ in range(self.goal_steps): action, game_action = self.generate_action(snake) done, score, snake, food = game.move(game_action) if done: training_data.append([ self.add_action_to_observation(prev_observation, action), -1 ]) # with open("training.txt", "a") as file: # file.write('Game' + str(i + 1) + '\t' + " ---------- " + str(training_data[-1]) + "\n") break else: food_distance = self.get_food_distance(snake, food) if score > prev_score or food_distance < prev_food_distance: training_data.append([ self.add_action_to_observation( prev_observation, action), 1 ]) else: training_data.append([ self.add_action_to_observation( prev_observation, action), 0 ]) prev_observation = self.generate_observation(snake, food) prev_food_distance = food_distance # with open("training.txt", "a") as file: # file.write('Game' + str(i+1)+'\t' + " ---------- " + str(training_data[-1]) + "\n") return training_data
def test_snake_move(): snake = Snake(3, 3, Position(1, 1), Direction.RIGHT) snake.move(None) assert snake.head.current_position.x == 2 assert snake.head.current_position.y == 1 assert snake.direction == Direction.RIGHT snake.move(Direction.UP) assert snake.head.current_position.x == 2 assert snake.head.current_position.y == 0 assert snake.direction == Direction.UP
def test_snake_calc_next_head_postion(): snake = Snake(3, 3, Position(1, 1), Direction.RIGHT) position = snake._calc_next_head_position(Direction.RIGHT) assert position.x == 2 assert position.y == 1 position = snake._calc_next_head_position(Direction.LEFT) assert position.x == 0 assert position.y == 1 position = snake._calc_next_head_position(Direction.UP) assert position.x == 1 assert position.y == 0 position = snake._calc_next_head_position(Direction.DOWN) assert position.x == 1 assert position.y == 2
import cv2 import matplotlib import matplotlib.pyplot as plt import torch from itertools import count import time device = torch.device("cuda" if torch.cuda.is_available() else "cpu") checkpoint = torch.load('policy_net_with_tail.pth') policy_net = convnet(config.BOARD_SIZE).float().to(device, non_blocking=True) policy_net.load_state_dict(checkpoint['model_state_dict']) policy_net.eval() env = Snake(config.BOARD_SIZE) while 1: done = False obs = env.reset() cum_reward = 0 render = True env.render() for step in count(1): action = select_action(obs, policy_net, 0, explore=False) new_obs, reward, done = env.step(action) cum_reward += reward obs = new_obs env.render()
def train(self, n, m, pars): """ (Game, int, int, dict()) -> None train game and run each step as sequence of frames n: row tiles of the screen m: col tiles of the screen pars" parameters passed in for each processors """ # initialize record = 0 game = Snake(n, m, pars.get('n_food', None)) agent = Agent(game, pars) while True: # get old state state_old = game.get_state() # get move final_move = agent.get_action(state_old) # perform move and get new state reward, done, score = game.play_step(final_move, pars) state_new = game.get_state() # train short memory agent.train_short_memory(state_old, final_move, reward, state_new, done) # remember agent.remember(state_old, final_move, reward, state_new, done) # end game if reached num_games from pars or DEFAULT_END_GAME_POINT # if set to -1 then run for ever if pars.get('num_games', DEFAULT_END_GAME_POINT) != -1: if agent.n_games > pars.get('num_games', DEFAULT_END_GAME_POINT): quit() break # when game is over if done: # reset game attributes # increase game generation # train the long memory game.reset() agent.n_games += 1 agent.train_long_memory() # new highscore if score > record: record = score # save the best model_state #agent.model.save() # takes away food depending on given probability, up until 1 food remains decrease_probability = pars.get('decrease_food_chance', DECREASE_FOOD_CHANCE) if (game.n_food > 1) and (random.random() < decrease_probability): game.n_food -= 1 # prints game information to console print('Game', agent.n_games, 'Score', score, 'Record:', record) # appends game information to txt filen at specified path self.save_to_file(f"graphs/{pars.get('graph', 'test')}.txt", agent.n_games, score, record)
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)
child_nns[i] = Snake_nn(NET_LAYERS, weights) speed = 0 pygame.init() pygame.font.init() font = pygame.font.SysFont('Comic Sans MS', 20) for generation in range(NUM_GENERATIONS): start_time = pytime.time() screen = pygame.display.set_mode((SCREEN_SIZE, SCREEN_SIZE+30)) screen.fill(BG_COLOR) manager = pygame_gui.UIManager((SCREEN_SIZE, SCREEN_SIZE+30)) rect = pygame.Rect((0, SCREEN_SIZE+10), (SCREEN_SIZE, SCREEN_SIZE+15)) slider = pygame_gui.elements.ui_horizontal_slider.UIHorizontalSlider(rect, speed, [0, 200], manager) clock = pygame.time.Clock() population_list = {} for i in range(POPULATION): snake = Snake(SCREEN_SIZE_CELLS//2*CELL_SIZE, SCREEN_SIZE_CELLS//2*CELL_SIZE, SNAKE_COLOR, screen) food_x = random.choice(range(0, SCREEN_SIZE - CELL_SIZE, CELL_SIZE)) food_y = random.choice(range(0, SCREEN_SIZE - CELL_SIZE, CELL_SIZE)) food = Food(food_x, food_y, FOOD_COLOR, screen) population_list[i] = [snake, food] if not child_nns: nn_list = {} for i in range(POPULATION): nn_list[i] = Snake_nn(NET_LAYERS, None) else: nn_list = child_nns scores = {} for i in nn_list.keys():
from turtle import Screen from game import Snake from food import Food from scoreboard import Scoreboard import time screen = Screen() screen.setup(width=600, height=600) screen.bgcolor("black") screen.title("My Snake Game") screen.tracer(0) snake = Snake() food = Food() scoreboard = Scoreboard() screen.listen() screen.onkey(snake.up, "Up") screen.onkey(snake.down, "Down") screen.onkey(snake.left, "Left") screen.onkey(snake.right, "Right") def run(): game_is_on = True while game_is_on: screen.update() time.sleep(0.1) snake.move() # Detect collision with food.
def move(): json = request.get_json() snake = Snake.from_json(json['you']) board = Board.from_json(json['board']) return play.move(snake, board, None)