def get_moves( self, position: Point2D, direction: part_a.Instruction.Direction ) -> Iterable[Tuple[Optional[Point2D], part_a.Instruction.Direction]]: """ >>> list(InstructionExtended( ... InstructionExtended.Turn.Left, 10).get_moves( ... Point2D(2, 3), InstructionExtended.Direction.Up)) [(Point2D(x=1, y=3), Direction.Left), (Point2D(x=0, y=3), Direction.Left), ..., (Point2D(x=-7, y=3), Direction.Left), (Point2D(x=-8, y=3), Direction.Left)] >>> list(InstructionExtended( ... InstructionExtended.Turn.Left, 10).get_moves( ... Point2D(2, 3), InstructionExtended.Direction.Down)) [(Point2D(x=3, y=3), Direction.Right), (Point2D(x=4, y=3), Direction.Right), ..., (Point2D(x=11, y=3), Direction.Right), (Point2D(x=12, y=3), Direction.Right)] >>> list(InstructionExtended( ... InstructionExtended.Turn.Right, 10).get_moves( ... Point2D(2, 3), InstructionExtended.Direction.Left)) [(Point2D(x=2, y=2), Direction.Up), (Point2D(x=2, y=1), Direction.Up), ..., (Point2D(x=2, y=-6), Direction.Up), (Point2D(x=2, y=-7), Direction.Up)] >>> list(InstructionExtended( ... InstructionExtended.Turn.Right, 10).get_moves( ... Point2D(2, 3), InstructionExtended.Direction.Right)) [(Point2D(x=2, y=4), Direction.Down), (Point2D(x=2, y=5), Direction.Down), ..., (Point2D(x=2, y=12), Direction.Down), (Point2D(x=2, y=13), Direction.Down)] >>> list(InstructionExtended( ... InstructionExtended.Turn.Right, 0).get_moves( ... Point2D(2, 5), InstructionExtended.Direction.Down)) [(None, Direction.Left)] """ direction_index = self.LEFT_ROTATION.index(direction) if self.turn == self.Turn.Left: direction_index += 1 else: direction_index -= 1 final_direction = \ self.LEFT_ROTATION[direction_index % len(self.LEFT_ROTATION)] if not self.move_amount: yield None, final_direction else: for move_amount in range(1, self.move_amount + 1): position = position.offset(self.OFFSETS[final_direction]) yield position, final_direction
def move_in_direction(self, position: Point2D, direction: Direction, positions: Iterable[Point2D]) -> Point2D: """ >>> # noinspection PyUnresolvedReferences >>> positions_9 = { ... Point2D(x, y) for x in range(0, 3) for y in range(0, 3)} >>> InstructionLine([]).move_in_direction( ... Point2D(1, 1), InstructionLine.Direction.Up, positions_9) Point2D(x=1, y=0) >>> InstructionLine([]).move_in_direction( ... Point2D(1, 0), InstructionLine.Direction.Up, positions_9) Point2D(x=1, y=0) >>> InstructionLine([]).move_in_direction( ... Point2D(1, 1), InstructionLine.Direction.Down, positions_9) Point2D(x=1, y=2) >>> InstructionLine([]).move_in_direction( ... Point2D(1, 2), InstructionLine.Direction.Down, positions_9) Point2D(x=1, y=2) >>> InstructionLine([]).move_in_direction( ... Point2D(1, 1), InstructionLine.Direction.Left, positions_9) Point2D(x=0, y=1) >>> InstructionLine([]).move_in_direction( ... Point2D(0, 1), InstructionLine.Direction.Left, positions_9) Point2D(x=0, y=1) >>> InstructionLine([]).move_in_direction( ... Point2D(1, 1), InstructionLine.Direction.Right, positions_9) Point2D(x=2, y=1) >>> InstructionLine([]).move_in_direction( ... Point2D(2, 1), InstructionLine.Direction.Right, positions_9) Point2D(x=2, y=1) """ new_position = position.offset(self.DIRECTION_OFFSETS[direction]) if new_position not in positions: return position return new_position
def get_neighbourhood(self, point: Point2D) -> Neighbourhood: return cast(Neighbourhood, tuple( self[point.offset(neighbour_offset)] for neighbour_offset in self.NEIGHBOURHOOD_OFFSETS ))