""" class SnakeBodySegment: """Finally, we need an Agent for the snake's body segments. SnakeBodySegment doesn't have ``play_turn`` or ``handle_keystroke`` methods because it never does anything on its own. It only moves when the SnakeHead, or the previous segment, tells it to move. Arguments: segment_id (int): Keeps track of how far back this segment is from the head. This is used to give the segment a unique name, and also to keep track of how many points the player earns for eating the next apple. position (int, int): The initial position. Attributes: character: '*' next_segment: Initially ``None``, this is a reference to a SnakeBodySegment when this segment is not the last one in the snake's body. """ character = '*' next_segment = None def __init__(self, segment_id, position): self.segment_id = segment_id self.name = f"Snake body segment {segment_id}" self.position = position def move(self, new_position, game, growing=False): """When SnakeHead moves, it sets off a chain reaction, moving all its body segments. Whenever the head or a body segment has another segment (``next_segment``), it calls that segment's ``move`` method. This method updates the SnakeBodySegment's position. Then, if ``self.next_segment`` is not None, calls that segment's ``move`` method. If there is no next segment and ``growing`` is True, then we set ``self.next_segment`` to a new SnakeBodySegment in this segment's old position, and update the game's score. Arguments: new_position (int, int): The new position. game (Game): A reference to the current game. growing (bool): (Default False) When True, the snake needs to add a new segment. """ old_position = self.position self.position = new_position if self.next_segment: self.next_segment.move(old_position, game, growing=growing) elif growing: self.next_segment = SnakeBodySegment(self.segment_id + 1, old_position) game.add_agent(self.next_segment) game.state['score'] += self.segment_id + 1