""" from trail import SnakeBodySegment class SnakeHead: """An Agent representing the snake's head. When the game starts, you control the snake head using the arrow keys. The SnakeHead always has a direction, and will keep moving in that direction every turn. When you press an arrow key, you change the SnakeHead's direction. Attributes: name: "Snake head" position: (0,0) character: ``'v'`` Depending on the snake head's direction, its character changes to ``'<'``, ``'^'``, ``'>'``, or ``'v'``. next_segment: Initially ``None``, this is a reference to a SnakeBodySegment. growing: When set to True, the snake will grow a new segment on its next move. """ RIGHT = (1, 0) UP = (0, -1) LEFT = (-1, 0) DOWN = (0, 1) name = "Snake head" position = (0, 0) direction = DOWN character = 'v' next_segment = None growing = False def play_turn(self, game): """On each turn, the snake head uses its position and direction to figure out its next position. If the snake head is able to move there (it's on the board and not occuppied by part of the snake's body), it moves. Then, if the snake head is on the Apple, the Apple moves to a new random position and ``growing`` is set to True. Now we need to deal with two situations. First, if ``next_segment`` is not None, there is a SnakeBodySegment attached to the head. We need the body to follow the head, so we call ``self.next_segment.move``, passing the head's old position (this will be the body's new position), a reference to the game, and a value for ``growing``. If the snake needs to grow, we need to pass this information along the body until it reaches the tail--this is where the next segment will be attached. If there is no ``next_segment`` but ``self.growing`` is True, it's time to add a body! We set ``self.next_segment`` to a new SnakeBodySegment, set its position to the head's old position, and add it to the game. We also add 1 to the game's score. """ x, y = self.position dx, dy = self.direction if self.can_move((x+dx, y+dy), game): self.position = (x+dx, y+dy) if self.is_on_apple(self.position, game): apple = game.get_agent_by_name("Apple") apple.relocate(game) self.growing = True if self.next_segment: self.next_segment.move((x, y), game, growing=self.growing) elif self.growing: self.next_segment = SnakeBodySegment(1, (x, y)) game.add_agent(self.next_segment) game.state['score'] += 1 self.growing = False def handle_keystroke(self, keystroke, game): """Checks whether one of the arrow keys has been pressed. If so, sets the SnakeHead's direction and character. """ x, y = self.position if keystroke.name == "KEY_RIGHT": self.direction = self.RIGHT self.character = '>' elif keystroke.name == "KEY_UP": self.direction = self.UP self.character = '^' elif keystroke.name == "KEY_LEFT": self.direction = self.LEFT self.character = '<' elif keystroke.name == "KEY_DOWN": self.direction = self.DOWN self.character = 'v' def can_move(self, position, game): on_board = game.on_board(position) empty = game.is_empty(position) on_apple = self.is_on_apple(position, game) return on_board and (empty or on_apple) def is_on_apple(self, position, game): apple = game.get_agent_by_name("Apple") return apple.position == position