def init_game_objects(self): self.grid = Grid(GRID_CELL_SIZE, GREY, pygame, self.screen, MAP_SIZE) self.player = Player(self.grid.center_x, self.grid.center_y, GRID_CELL_SIZE, BODY_LENGTH) self.food = Food(GRID_CELL_SIZE, self.grid.rows - 1, self.grid.columns - 1) self.controller = Controller(self.player)
def __init__(self, input_service, output_service): """The class constructor. Args: self (Director): an instance of Director. """ self._food = Food() self._input_service = input_service self._keep_playing = True self._output_service = output_service self._score = Score() self._snake = Snake()
def __init__(self, players): highscores = load_highscores() self.highscore = highscores[0].score if highscores else 0 self.players = players self.squares = (17, 15) self.game_surface: GameSurface = GameSurface(window) self.field: GameFieldSurface = GameFieldSurface( self.game_surface, self.squares) self.food = Food(self.field, Image.food_image) self.super_food = SuperFood(self.field, Image.super_food_image) self.food.recreate(self.players, self.super_food, self.field.grid_size) player_starting_xs = [ self.field.grid_size * (i * 3 + 4) for i in range(len(self.players)) ] for i in range(len(self.players)): self.players[i].x = player_starting_xs[i]
def __init__(self, code_id, log=False, visualization=False, fps=60): self.code_id = code_id self.snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2) self.food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE) self.food.spawn(self.snake) self.log = log self.visualization = visualization self.window, self.clock = self.init_visualization() self.fps = fps # basic infos self.alive = True self.score = 0 self.step = 0 # useful infos self.s_obstacles = self.get_surrounding_obstacles() self.food_angle = self.get_food_angle() self.food_distance = self.get_food_distance()
def main(): window = pygame.display.set_mode( (WINDOW_WIDTH * PIXEL_SIZE, WINDOW_HEIGHT * PIXEL_SIZE)) pygame.display.set_caption('SNAKE GAME') clock = pygame.time.Clock() score = 0 snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2) food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE) run = True while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False break elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: snake.change_direction(-1) break elif event.key == pygame.K_RIGHT: snake.change_direction(+1) break snake.move() if snake.collision_food(food.location): score += 1 food.state = False food.spawn(snake) if snake.collision_obstacles(): print('over') run = False if snake.get_length() == WINDOW_WIDTH * WINDOW_HEIGHT: print('win') run = False window.fill((0, 0, 0)) food.render(window) snake.render(window) pygame.display.set_caption('SNAKE GAME | Score: ' + str(score)) pygame.display.update() clock.tick(FPS)
class Game: def __init__(self, players): highscores = load_highscores() self.highscore = highscores[0].score if highscores else 0 self.players = players self.squares = (17, 15) self.game_surface: GameSurface = GameSurface(window) self.field: GameFieldSurface = GameFieldSurface( self.game_surface, self.squares) self.food = Food(self.field, Image.food_image) self.super_food = SuperFood(self.field, Image.super_food_image) self.food.recreate(self.players, self.super_food, self.field.grid_size) player_starting_xs = [ self.field.grid_size * (i * 3 + 4) for i in range(len(self.players)) ] for i in range(len(self.players)): self.players[i].x = player_starting_xs[i] def start(self): """Játékmenet vezérlője.""" end = False timer = pygame.time.Clock() pygame.event.set_allowed(pygame.KEYDOWN) while not end: # 60 FPS timer.tick(60) # Event loop events = pygame.event.get() for event in events: if event.type == pygame.QUIT: return True if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: end = True if event.type == pygame.KEYDOWN: for player in self.players: player.controlled_move(event, self.field.grid_size) for player in self.players: # ha nem mozdult gombokkal akkor mozdítsuk a kigyot a jelenlegi irányba tovább if not player.key_pressed: player.move(self.field.grid_size) # ha saját magába, vagy a falba ment, akkor a játéknak vége if player.detect_self_collision( self.field.grid_size) or player.detect_wall_collision( self.field): player.is_lost = True end = True winsound.PlaySound("assets/sounds/dead.wav", 1) # új highscore beállitása ha valamelyik player meghaladta az eddigi legmagasabbat if player.score > self.highscore: self.highscore = player.score # Alma felvétel kezelése if player.detect_food_collision(self.food, self.field.grid_size): self.food.recreate(self.players, self.super_food, self.field.grid_size) player.score += 1 player.length += 1 winsound.PlaySound("assets/sounds/eat.wav", 1) # Szuper alma felvétel kezelése if player.detect_food_collision(self.super_food, self.field.grid_size): player.score += 5 player.length += 1 self.super_food.handle_collision() winsound.PlaySound("assets/sounds/eat.wav", 1) # Alapértékre állítás, nem nyomott irányváltoztató gombot player.key_pressed = False # Esetleges új sebességek beállítása player.calculate_velocity() # Kétjátékos módban ha egymásba mentek akkor a játéknak vége if len(self.players) > 1: j = len(self.players) - 1 for i in range(len(self.players)): if self.players[i].detect_enemy_collision( self.players[j], self.field.grid_size): self.players[i].is_lost = True end = True winsound.PlaySound("assets/sounds/dead.wav", 1) j -= 1 # Szuper alma megfelelő számlálójának növelése self.super_food.update_counters() # Megnézzük és eltüntetjük a szuper almát ha kell self.super_food.check_for_remove() # Ha még nincs szuper almánk és idő van, 30% eséllyel spawnol egy self.super_food.check_for_spawn(self.players, self.food, self.field.grid_size) # újra rajzoljuk a képernyőt self.redraw() def redraw(self): """Újra rajzolja a képernyőt a játékállásnak megfelelően.""" self.game_surface.redraw(self.players, self.highscore) self.field.redraw() self.food.draw(self.field.surface) if self.super_food.visible: self.super_food.draw(self.field.surface) for i in range(len(self.players)): self.players[i].draw(self.field.surface) self.field.blit() self.game_surface.scaled_blit_to_parent() pygame.display.update()
class Agent: def __init__(self, code_id, log=False, visualization=False, fps=60): self.code_id = code_id self.snake = Snake(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2) self.food = Food(WINDOW_WIDTH, WINDOW_HEIGHT, PIXEL_SIZE) self.food.spawn(self.snake) self.log = log self.visualization = visualization self.window, self.clock = self.init_visualization() self.fps = fps # basic infos self.alive = True self.score = 0 self.step = 0 # useful infos self.s_obstacles = self.get_surrounding_obstacles() self.food_angle = self.get_food_angle() self.food_distance = self.get_food_distance() def init_visualization(self): if self.visualization: window = pygame.display.set_mode( (WINDOW_WIDTH * PIXEL_SIZE, WINDOW_HEIGHT * PIXEL_SIZE)) fps = pygame.time.Clock() return window, fps else: return None, None def get_random_move(self, random_n=10): # real random move, 1/random_n if random_n is not 0 and random.randint(1, random_n) == 1: return random.randint(-1, 1) s, a, d = self.get_state() # random move depend on state ops = [] # select move based on following the food angle and avoiding the obstacles if not s[0] and a < 0: ops.insert(-1, -1) if not s[1] and a == 0: ops.insert(-1, 0) if not s[2] and a > 0: ops.insert(-1, +1) # if no option if not ops: # select move based on avoiding obstacles if not s[0]: ops.insert(-1, -1) if not s[1]: ops.insert(-1, 0) if not s[2]: ops.insert(-1, +1) # again, if no option -> just die if not ops: return random.randint(-1, 1) else: return ops[random.randint(0, len(ops) - 1)] else: return ops[random.randint(0, len(ops) - 1)] def next_state(self, move_direction): self.step += 1 info = 'CodeID: {} | Step: {} | Score: {}'.format( self.code_id, self.step, self.score) self.snake.change_direction(move_direction) self.snake.move() if self.snake.collision_food(self.food.location): self.score += 1 self.food.state = False self.food.spawn(self.snake) if self.snake.collision_obstacles(): info += ' >> Game Over!' self.alive = False if self.snake.get_length() == WINDOW_WIDTH * WINDOW_HEIGHT: info += ' >> Win!' self.alive = False if self.log: print(info) if self.visualization: self.window.fill((0, 0, 0)) self.food.render(self.window) self.snake.render(self.window) pygame.display.set_caption(info) pygame.display.update() pygame.event.get() self.clock.tick(self.fps) return self.get_state() def get_state(self): return self.get_surrounding_obstacles(), self.get_food_angle( ), self.get_food_distance() def get_surrounding_obstacles(self): # check front snake_head = self.snake.head snake_heading_direction = self.snake.heading_direction left = self.snake.moves[(snake_heading_direction - 1) % len(self.snake.moves)] front = self.snake.moves[snake_heading_direction] right = self.snake.moves[(snake_heading_direction + 1) % len(self.snake.moves)] l_location = [snake_head[0] + left[0], snake_head[1] + left[1]] f_location = [snake_head[0] + front[0], snake_head[1] + front[1]] r_location = [snake_head[0] + right[0], snake_head[1] + right[1]] s_locations = [l_location, f_location, r_location] self.s_obstacles = [0, 0, 0] # check wall for i in range(0, len(s_locations)): if s_locations[i][0] < 0 or s_locations[i][0] >= WINDOW_WIDTH \ or s_locations[i][1] < 0 or s_locations[i][1] >= WINDOW_HEIGHT: self.s_obstacles[i] = 1 # check body for b in self.snake.body: if b in s_locations: self.s_obstacles[s_locations.index(b)] = 1 return self.s_obstacles def get_food_angle(self): # get direction of heading heading_direction = numpy.array( self.snake.moves[self.snake.heading_direction]) # get direction of food (distant) food_direction = numpy.array(self.food.location) - numpy.array( self.snake.head) h = heading_direction / numpy.linalg.norm(heading_direction) f = food_direction / numpy.linalg.norm(food_direction) fa = math.atan2(h[0] * f[1] - h[1] * f[0], h[0] * f[0] + h[1] * f[1]) / math.pi if fa == -1 or fa == 1: fa = 1 self.food_angle = fa return self.food_angle def get_food_distance(self): head = numpy.array(self.snake.head) food = numpy.array(self.food.location) max_dis = numpy.linalg.norm( numpy.array([0, 0]) - numpy.array([WINDOW_WIDTH - 1, WINDOW_HEIGHT - 1])) dis = numpy.linalg.norm(head - food) # normalize distance to the range 0 - 1 self.food_distance = dis / max_dis return self.food_distance
class Game: def __init__(self, max_games): pygame.init() pygame.display.set_caption('sNNake') self.icon = pygame.Surface((32, 32)) pygame.display.set_icon(self.icon) self.screen = pygame.display.set_mode(WINDOW_SIZE) self.clock = pygame.time.Clock() self.count = 1 self.max_games = max_games self.init_game_objects() def init_game_objects(self): self.grid = Grid(GRID_CELL_SIZE, GREY, pygame, self.screen, MAP_SIZE) self.player = Player(self.grid.center_x, self.grid.center_y, GRID_CELL_SIZE, BODY_LENGTH) self.food = Food(GRID_CELL_SIZE, self.grid.rows - 1, self.grid.columns - 1) self.controller = Controller(self.player) def game_status(self): #print("##### GAME START ##### game count: ", self.count) return def draw(self): # erase the screen self.screen.fill(BLACK) #draw objects self.food.draw(pygame, self.screen, WHITE) #draw body for el in self.player.body_list: el.draw(pygame, self.screen, WHITE) self.grid.draw() def exit_conditions(self): if (pygame.key.get_pressed()[pygame.K_RETURN] == 1): return #break if (pygame.key.get_pressed()[pygame.K_ESCAPE] == 1): sys.exit() for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() def check_isAlive(self, sensors): if (sensors.detect_walls(self.grid, self.player.position)): self.player.alive = False #self.player.position = [10,10] #print("WALL HIT") if (sensors.detect_body(self.player.position)): self.player.alive = False #print("BODY HIT") return def reset(self): self.init_game_objects() self.score = 0 def update_objects(self, sensors): self.controller.detect_keyboard() self.player.turn() self.player.update_body() self.check_isAlive(sensors) if (self.food.detect_colision(self.player)): self.score = self.score + 1 ### update pygame and close the step def finish_step(self): #msElapsed = clock.tick(30) pygame.display.update() pygame.time.delay(TIME_DELAY) def observation(self): return self.player, self.food # concept of step function from open ai: one step receaves a input and generates a observation. def step(self, sensors, action): self.exit_conditions() self.draw() self.update_objects(sensors) self.controller.input(action) ### STEP OBSERVATION CODE ### update all and close the step self.finish_step()
class Director: """A code template for a person who directs the game. The responsibility of this class of objects is to control the sequence of play. Stereotype: Controller Attributes: food (Food): The snake's target. input_service (InputService): The input mechanism. keep_playing (boolean): Whether or not the game can continue. output_service (OutputService): The output mechanism. score (Score): The current score. snake (Snake): The player or snake. """ def __init__(self, input_service, output_service): """The class constructor. Args: self (Director): an instance of Director. """ self._food = Food() self._input_service = input_service self._keep_playing = True self._output_service = output_service self._score = Score() self._snake = Snake() def start_game(self): """Starts the game loop to control the sequence of play. Args: self (Director): an instance of Director. """ while self._keep_playing: self._get_inputs() self._do_updates() self._do_outputs() sleep(constants.FRAME_LENGTH) def _get_inputs(self): """Gets the inputs at the beginning of each round of play. In this case, that means getting the desired direction and moving the snake. Args: self (Director): An instance of Director. """ direction = self._input_service.get_direction() self._snake.move_head(direction) def _do_updates(self): """Updates the important game information for each round of play. In this case, that means checking for a collision and updating the score. Args: self (Director): An instance of Director. """ self._handle_body_collision() self._handle_food_collision() def _do_outputs(self): """Outputs the important game information for each round of play. In this case, that means checking if there are stones left and declaring the winner. Args: self (Director): An instance of Director. """ self._output_service.clear_screen() self._output_service.draw_actor(self._food) self._output_service.draw_actors(self._snake.get_all()) self._output_service.draw_actor(self._score) self._output_service.flush_buffer() def _handle_body_collision(self): """Handles collisions between the snake's head and body. Stops the game if there is one. Args: self (Director): An instance of Director. """ head = self._snake.get_head() body = self._snake.get_body() for segment in body: if head.get_position().equals(segment.get_position()): self._keep_playing = False break def _handle_food_collision(self): """Handles collisions between the snake's head and the food. Grows the snake, updates the score and moves the food if there is one. Args: self (Director): An instance of Director. """ head = self._snake.get_head() if head.get_position().equals(self._food.get_position()): points = self._food.get_points() for n in range(points): self._snake.grow_tail() self._score.add_points(points) self._food.reset()