def get_point(self, depth=0): """ Pick a point within the game boundaries and not currently occupied. """ if depth >= 30: error("Went too deep trying to generate a random point") return (0, 0) debug(f"Getting random point depth = {depth}") x = self.rand.randrange(0, self.width, self.size) y = self.rand.randrange(0, self.height, self.size) if x <= 0 or y <= 0: self._set_seed(self._seed + 10) return self.get_point(depth=depth + 1) # try to get a new random x,y point pseudo_segment = Segment([x, y, self.size, self.size], 0) debug(f"Checking point {depth} against obstacles") for wall in self.obstacles: if Snake.intersects(wall, pseudo_segment): debug(f"point {pseudo_segment} intersects with wall") return self.get_point(depth=depth + 1) # try to get a new random x,y point debug(f"Checking point {depth} against fruits") for fruit in self.rewards: if Snake.intersects(fruit, pseudo_segment): debug(f"point {pseudo_segment} intersects with fruit") return self.get_point(depth=depth + 1) # try to get a new random x,y point debug(f"Checking point {depth} against Snake segments") if self.snake is not None and Snake.intersects(self.snake, pseudo_segment): debug(f"point {pseudo_segment} intersects with Snake") return self.get_point(depth=depth + 1) # try to get a new random x,y point debug(f"Point {depth} approved") return (x, y)
def _get_snake(self, depth=0): """ Use the current attributes of the game to create a new snake object. """ # debug("Game._get_snake") heading = self.rand.randint(0, 3) # choose an integer between 0 and 3 to represent a cardinal direction position = self.get_point() if position is not None: try: snake = Snake([ position[0], position[1], self.size, self.starting_length * self.size ], heading) except Exception as err: snake = Snake([ position[0], position[1], self.size, self.starting_length * self.size ], (heading + 1) % 4) # safe_distance = int(round(min(self.width, self.height)/10)) safe_distance = 5 if self._peek(snake, snake.heading, safe_distance): # self.scribe.record_snake(snake) return snake else: if depth >= 30: error("Went too deep trying to get a safe spawn for snake") return None else: return self._get_snake(depth=depth + 1) # return a snake object that's within the game boundaries else: raise ValueError( "Failed to pick a random point to spawn the snake")
def __init__(self, grid_size_x, grid_size_y, screen_size_x, screen_size_y): self.grid_size_x = grid_size_x self.grid_size_y = grid_size_y self.screen_size_x = screen_size_x self.screen_size_y = screen_size_y self.block_size_x = self.screen_size_x / self.grid_size_x self.block_size_y = self.screen_size_y / self.grid_size_y self.snake = Snake(round(self.grid_size_x / 2), round(self.grid_size_y / 2), self.block_size_x, self.block_size_y) self.spawnFood()
def __init__(self, ind_game=0): pygame.init() pygame.display.set_caption("My snake game!") self._display_surf = pygame.display.set_mode( (self.WINDOW_WIDTH, self.WINDOW_HEIGHT), pygame.HWSURFACE) self.score = 0 self.ind_game = ind_game self._running = True self.flag_lost = False self.snake = Snake( length=1, step=self.SNAKE_STEP, x_max=self.WINDOW_WIDTH, y_max=self.WINDOW_HEIGHT, ) self.walls = Wall( self.HEADER_HEIGHT, self.WINDOW_HEIGHT, self.WINDOW_WIDTH, thickness=self.SNAKE_STEP, ) self.raspi = RasPi( x=self.SNAKE_STEP * (-1 + floor(self.WINDOW_WIDTH / 2 / self.SNAKE_STEP)), y=self.SNAKE_STEP * (floor(self.WINDOW_HEIGHT / 2 / self.SNAKE_STEP)), ) self.clock = pygame.time.Clock() if self.ind_game == 0: self.high_score = 0 if self.MODE == "AGENT": self.frame_rate = 60 if self.ind_game == 0: self.agent = Agent() self.num_games = self.NUM_GAMES_AGENT else: self.frame_rate = 15 self.num_games = 1
class Game: def __init__(self): self.screen = pygame.display.set_mode((GAME_HEIGHT, GAME_WIDTH)) self.clock = pygame.time.Clock() self.food = Food(FOOD_COLOR) self.snake = Snake(SNAKE_COLOR) self.game_over = False def run(self): # update core game components self.clock.tick(100 * (1 + len(self.snake.body) / 50)) self.screen.fill(pygame.Color(0,0,0)) # render the snake and food for the game self.food.render(self.screen) self.snake.render(self.screen) # update the snake and check for lose conditions self.snake.snake_controls(self.food) self.game_over = self.snake.check_lose() return self.game_over
def setUp(self): debug("TestGuiObjectKeySequencing.setUp") data = { # "height": 352, # "width": 352, "testing": True, "height": 640, "width": 640, # "frames": 60, "frames": 30, "score": 10, "snake_speed": 10, # "size": 11, "size": 10, "starting_length": 5, # "auto_tick": False, "auto_tick": True, "fruits": { "apple": lambda dimensions: Fruit( "apple", dimensions, 1, color=(200, 0, 0), frequency=0.05), # 1 in 20 chance of an apple appearing each second, worth 1 point "orange": lambda dimensions: Fruit("orange", dimensions, 1, color=(128, 128, 0), frequency=0.01), # 1 in 100 chance of an orange appearing each second, worth 10 points "bananna": lambda dimensions: Fruit("bananna", dimensions, 1, color=(255, 255, 0), frequency=0.005), # 1 in 200 chance of an bananna appearing each second, worth 10 points }, "reward_limit": 3, } starting_length = data.get("size") * data.get("starting_length") ourboros = Snake([ data.get("width") / 2, starting_length, data.get("size"), starting_length ], 2) self.game = SnakeGame(**data) self.game.snake = None self.game.snake = ourboros self.board = Gameboard(self.game) debug("TestGuiObjectKeySequencing.setUp complete")
class Level: def __init__(self, grid_size_x, grid_size_y, screen_size_x, screen_size_y): self.grid_size_x = grid_size_x self.grid_size_y = grid_size_y self.screen_size_x = screen_size_x self.screen_size_y = screen_size_y self.block_size_x = self.screen_size_x / self.grid_size_x self.block_size_y = self.screen_size_y / self.grid_size_y self.snake = Snake(round(self.grid_size_x / 2), round(self.grid_size_y / 2), self.block_size_x, self.block_size_y) self.spawnFood() def tick(self, screen, delta, control): self.snake.tick(screen, delta, control) self.food.tick(screen, delta) if self.snakeHasTouchedFood(): self.snake.grow() self.spawnFood() return 1 if self.snakeOutOfBounds() or self.snake.hasTouchedItself(): self.reset() return -1 return 0 def snakeHasTouchedFood(self): if self.snake.x == self.food.x and self.snake.y == self.food.y: return True else: return False def spawnFood(self): if len(self.snake.pieces) == self.grid_size_x * self.grid_size_y: self.reset() return x = random.randint(0, self.grid_size_x - 1) y = random.randint(0, self.grid_size_y - 1) if self.snake.contains(x, y): self.spawnFood() return food = Food(x, y, self.block_size_x, self.block_size_y) self.food = food def snakeOutOfBounds(self): if self.snake.x >= self.grid_size_x or self.snake.y >= self.grid_size_y or self.snake.x < 0 or self.snake.y < 0: return True else: return False def reset(self): self.foods = [] self.spawnCount = 0 self.snake = Snake(round(self.grid_size_x / 2), round(self.grid_size_y / 2), self.block_size_x, self.block_size_y) def getState(self): state = np.zeros((3, self.grid_size_x, self.grid_size_y)) state[0, self.snake.x, self.snake.y] = 1 pieces = self.snake.getPieces() for index in range(1, len(pieces)): piece = pieces[index] state[1, piece[0], piece[1]] = 1 state[2, self.food.x, self.food.y] = 1 return state.tolist() def getFoodSnakeDistance(self): return math.sqrt((self.snake.x - self.food.x)**2 + (self.snake.y - self.food.y)**2)
def reset(self): self.foods = [] self.spawnCount = 0 self.snake = Snake(round(self.grid_size_x / 2), round(self.grid_size_y / 2), self.block_size_x, self.block_size_y)
def play_game(): game_surface = initialize_screen() # Create our snake. good_snake = Snake(pygame.Color('purple'), [random.randint(0, GAME_WIDTH), random.randint(0, GAME_HEIGHT)]) good_snake.update(game_surface) # Create the bad snake. bad_snake = Snake(pygame.Color('grey'), [random.randint(0, GAME_WIDTH), random.randint(0, GAME_HEIGHT)]) bad_snake.update(game_surface) bad_snake_direction = random.choice(ARROW_KEYS) snake_food = create_food([], game_surface) game_clock = pygame.time.Clock() background = pygame.image.load(os.path.join('leaves.jpg')).convert() while True: game_clock.tick(FRAMERATE) #game_surface.fill(background) game_surface.blit(background, (0, 0)) # Detect and respond to user keypresses. for e in pygame.event.get(): if e.type == pygame.QUIT: pygame.quit() return False elif e.type == pygame.KEYDOWN: if e.key == pygame.K_ESCAPE: pygame.quit() return False elif e.key in ARROW_KEYS: good_snake.move(e.key, game_surface) # Move the bad snake. #bad_snake_direction = move_bad_snake(bad_snake, game_surface, #bad_snake_direction) # Detect any collisions. if detect_collisions(good_snake, bad_snake): return restart(game_surface) # Have both snakes eat any available food. good_snake.try_to_eat(snake_food) bad_snake.try_to_eat(snake_food) # Refresh the food supply. snake_food = create_food(snake_food, game_surface) # Update the snake and food pixels. good_snake.update(game_surface) bad_snake.update(game_surface) for f in snake_food: f.update(game_surface) pygame.display.update()
def loop(self): game_exit = False init_x, init_y = self.background.calculate_block_coordinates( int(self.background.width_blocks_count / 2), int(self.background.height_blocks_count / 2)) snake = Snake(init_x, init_y, self.background.block_width, self.background.block_height(), self.background) snake.set_wait_time(1000) self.push_object(snake) rand_x, rand_y = self.get_random_empty_tile() fruit = Fruit(rand_x, rand_y, self.background.block_width, self.background.block_height(), self.background, get_random_fruit_image_path('assets/fruits')) self.push_object(fruit) keyboard_controller = KeyboardController(snake) while not game_exit: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() keyboard_controller.read_movement(event) if fruit.has_something_collided(snake.x, snake.y): fruit.x, fruit.y = self.get_random_empty_tile() fruit.set_image(get_random_fruit_image_path('assets/fruits')) snake.spawn_block(keyboard_controller.last_direction) snake.speed_up() snake.move(keyboard_controller.last_direction) self.screen.fill(WHITE) self.background.draw() for obj in self.objects: obj.draw() if snake.is_collision(): message_center_display('Game over', self.screen, 72) time.sleep(5) break pygame.display.update() self.clock.tick(60)
def create_snake(self, client_uuid): x, y = self.world.get_empty_position() color = self.stack.get_available_snake_color() snake = Snake(client_uuid, x, y) snake.color = color self.stack.add(snake)
def main(): # initializing the pygame module pygame.init() # general information logo = pygame.image.load(ICON_PATH) pygame.display.set_icon(logo) pygame.display.set_caption('Snake') # creating screen screen = pygame.display.set_mode((GAME_WIDTH, GAME_HEIGHT)) screen.fill(BACKGROUND_COLOR) pygame.display.flip() # creating snake2 object snake = Snake(screen, SNAKE_START_LOCATION) # creating food object food = Food(screen) food.update(snake.last_locations) # creating highscore object highscore = Highscore() # creating highscore object # set game to running running = True clock = pygame.time.Clock() # initializing game_over variable game_over = False # mainloop while running: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: # other controls # restart if event.key == pygame.K_r: running = False main() # quit if event.key == pygame.K_ESCAPE: running = False # movement keys if event.key == pygame.K_RIGHT or event.key == pygame.K_d: snake.change_direction('r') if event.key == pygame.K_LEFT or event.key == pygame.K_a: snake.change_direction('l') if event.key == pygame.K_UP or event.key == pygame.K_w: snake.change_direction('u') if event.key == pygame.K_DOWN or event.key == pygame.K_s: snake.change_direction('d') if not game_over: # 'clears' the background screen.fill(BACKGROUND_COLOR) # moves snake2 snake.update() # checks if snake2 is on the screen. if not = Game Over if not snake.is_on_screen(): game_over = True # checks if the snake2 hit its tail if snake.hit_tail(): game_over = True # draws snake2 snake.draw() # check if snake2 hits food if snake.x == food.x and snake.y == food.y: snake.length += 1 food.update(snake.last_locations) # check if score is over the highscore if snake.length - 1 > highscore.get(): highscore.score = snake.length - 1 # draw food rectangle food.draw() # update score font = pygame.font.SysFont('bahnschrift', 20) tag = font.render(f'Score: {snake.length - 1}', True, WHITE) screen.blit(tag, (25, 25)) # update highscore font = pygame.font.SysFont('bahnschrift', 20) tag = font.render(f'Highscore: {highscore.get()}', True, WHITE) screen.blit(tag, (250, 25)) if game_over: screen.fill((194, 61, 128)) highscore.update() go_font = pygame.font.SysFont('times new roman', 40) go_tag = go_font.render('GAME OVER', True, WHITE) score_font = pygame.font.SysFont('bahnschrift', 30) score_tag = score_font.render(f'your score: {snake.length -1}', True, WHITE) ctrl_font = pygame.font.SysFont('bahnschrift', 30) ctrl_tag = ctrl_font.render('r: restart esc: quit', True, WHITE) screen.blits(((go_tag, GO_TAG_LOCATION), (score_tag, (GAME_WIDTH / 4, GAME_HEIGHT * 0.75)), (ctrl_tag, (GAME_WIDTH / 8, GAME_HEIGHT - 50)))) # update display pygame.display.flip()
def __init__(self): self.screen = pygame.display.set_mode((GAME_HEIGHT, GAME_WIDTH)) self.clock = pygame.time.Clock() self.food = Food(FOOD_COLOR) self.snake = Snake(SNAKE_COLOR) self.game_over = False
class Game: MODE = "AGENT" HEADER_HEIGHT = 48 WINDOW_WIDTH = 480 WINDOW_HEIGHT = 480 SNAKE_STEP = 16 EATING_REWARD = 1 NUM_GAMES_AGENT = 200 def __init__(self, ind_game=0): pygame.init() pygame.display.set_caption("My snake game!") self._display_surf = pygame.display.set_mode( (self.WINDOW_WIDTH, self.WINDOW_HEIGHT), pygame.HWSURFACE) self.score = 0 self.ind_game = ind_game self._running = True self.flag_lost = False self.snake = Snake( length=1, step=self.SNAKE_STEP, x_max=self.WINDOW_WIDTH, y_max=self.WINDOW_HEIGHT, ) self.walls = Wall( self.HEADER_HEIGHT, self.WINDOW_HEIGHT, self.WINDOW_WIDTH, thickness=self.SNAKE_STEP, ) self.raspi = RasPi( x=self.SNAKE_STEP * (-1 + floor(self.WINDOW_WIDTH / 2 / self.SNAKE_STEP)), y=self.SNAKE_STEP * (floor(self.WINDOW_HEIGHT / 2 / self.SNAKE_STEP)), ) self.clock = pygame.time.Clock() if self.ind_game == 0: self.high_score = 0 if self.MODE == "AGENT": self.frame_rate = 60 if self.ind_game == 0: self.agent = Agent() self.num_games = self.NUM_GAMES_AGENT else: self.frame_rate = 15 self.num_games = 1 def on_event(self, event): if event.type == QUIT: self._running = False Game.on_cleanup() exit() def on_loop(self): """ Method executed for each clock tick """ self.snake.update() if self.MODE == "AGENT": self.agent.store(self) self.flag_lost = self.snake.has_lost(self.walls) flag_snake_over_raspi = True if self.snake.has_eaten(self.raspi.x, self.raspi.y): self.score += self.EATING_REWARD self.snake.lengthen() while flag_snake_over_raspi: self.raspi.spawn_at_random( x_min=self.walls.x_min_inside + self.walls.thickness, x_max=self.walls.x_max_inside, y_min=self.walls.y_min_inside, y_max=self.walls.y_max_inside, step=self.SNAKE_STEP, ) flag_snake_over_raspi = self.snake.is_over( self.raspi.x, self.raspi.y) self._running = not self.flag_lost if self.MODE == "AGENT": self.agent.train_network_short_term() def on_render(self): self._display_surf.fill((0, 0, 0)) self.snake.render(self._display_surf) self.raspi.render(self._display_surf) self.walls.render(self._display_surf) self.display_message(f"Score: {self.score}", (50, 20), fontsize=16) self.display_message(f"High score: {self.high_score}", (self.WINDOW_WIDTH - 80, 20), fontsize=16) if self.MODE == "AGENT": self.display_message( f"Game n°: {self.ind_game} / {self.num_games}", (int(self.WINDOW_WIDTH / 2), 20), fontsize=16, ) pygame.display.flip() @staticmethod def on_cleanup(): pygame.quit() def on_execute(self): for i_games in range(self.num_games): while self._running: if self.MODE == "MANUAL": self.manual_move() elif self.MODE == "AGENT": self.agent_move() self.on_loop() self.on_render() self.clock.tick(self.frame_rate) if self.flag_lost: self.set_high_score() if self.MODE == "MANUAL": self.display_message( f"You lost, you big big loser! - final score: {self.score}", (self.WINDOW_WIDTH // 2, self.WINDOW_HEIGHT // 2), fontsize=16, ) self.display_message( f"Replay: press space, Quit: press escape", (self.WINDOW_WIDTH // 2, self.WINDOW_HEIGHT // 2 + 50), fontsize=16, ) accepted_replay = "undef" while accepted_replay == "undef": accepted_replay = self.propose_replay() elif self.MODE == "AGENT": self.agent.train_network() self.agent.summary(self) self.__init__(self.ind_game + 1) # Reinit game Game.on_cleanup() def manual_move(self): for event in pygame.event.get(): self.on_event(event) pygame.event.pump() keys = pygame.key.get_pressed() if keys[K_RIGHT] and self.snake.direction != "left": self.snake.move_right() if keys[K_LEFT] and self.snake.direction != "right": self.snake.move_left() if keys[K_UP] and self.snake.direction != "down": self.snake.move_up() if keys[K_DOWN] and self.snake.direction != "up": self.snake.move_down() if keys[K_ESCAPE]: self._running = False def agent_move(self): next_move = self.agent.next_move(self) if next_move == "right" and self.snake.direction != "left": self.snake.move_right() if next_move == "left" and self.snake.direction != "right": self.snake.move_left() if next_move == "up" and self.snake.direction != "down": self.snake.move_up() if next_move == "down" and self.snake.direction != "up": self.snake.move_down() def display_message(self, message_string, position, fontsize=32): font = pygame.font.Font("freesansbold.ttf", fontsize) text = font.render(message_string, True, (255, 255, 255), (0, 0, 0)) text_rect = text.get_rect() text_rect.center = position self._display_surf.blit(text, text_rect) pygame.display.flip() def propose_replay(self): pygame.event.pump() keys = pygame.key.get_pressed() if keys[K_SPACE]: self.__init__() return "yes" elif keys[K_ESCAPE]: self._running = False return "no" else: return "undef" def set_high_score(self): if self.score > self.high_score: self.high_score = self.score