Пример #1
0
class Scanner(object):
    def __init__(self, size):
        self._board = Board(size, size, do_translate=False)
        self._program = load_program("dec19")
        self._x_given = False
        self._current_pos = None
        self._positions = [(x, y) for x in range(size) for y in range(size)]

    def _input(self):
        if self._current_pos is None:
            self._current_pos = self._positions.pop(0)
        if self._x_given:
            result = self._current_pos[1]
            self._x_given = False
            return result
        else:
            result = self._current_pos[0]
            self._x_given = True
            return result

    def _output(self, value):
        if value == 0:
            self._board.set(self._current_pos[0], self._current_pos[1], ".")
        elif value == 1:
            self._board.set(self._current_pos[0], self._current_pos[1], "#")
        else:
            raise ValueError("Invalid output value")
        self._current_pos = None

    def scan(self):
        while self._positions:
            intcode = IntCode(self._program)
            intcode.execute(self._input, self._output)
        self._board.print()
        return self._board.count("#")
Пример #2
0
class Robot(object):
    def __init__(self, program):
        self._intcode = IntCode(program)
        self._position = Position(0, 0)
        self._direction = Vector(0, 1)
        self._board = Board(1000, 1000)
        self._output_mode = OutputMode.COLOR
        self._paint_counter = {}

    def set_start_white(self):
        self._board.set(0, 0, Colors.WHITE.char)

    def input(self):
        char = self._board.get(self._position.x, self._position.y)
        return Colors.char2value(char)

    def output(self, value):
        if self._output_mode == OutputMode.COLOR:
            char = Colors.value2char(value)
            self._board.set(self._position.x, self._position.y, char)
            self._paint_counter[self._position] = 1
        elif self._output_mode == OutputMode.ROTATE:
            self._direction = self._direction.rotate(value)
            self._position += self._direction
        self._output_mode = OutputMode.alternate(self._output_mode)

    def run(self):
        self._intcode.execute(self.input, self.output)
        self._board.set(self._position.x, self._position.y,
                        self._direction.char())
        self._board.print()
        painted = sum(self._paint_counter.values())
        print("The robot painted {} panels".format(painted))
Пример #3
0
def load_map(lines):
    board = Board(len(lines[0]), len(lines), do_translate=False)
    asteroids = []
    for y, line in enumerate(lines):
        for x, c in enumerate(line.strip()):
            if c == "#":
                asteroid = Asteroid(x, y)
                asteroids.append(asteroid)
                board.set(x, y, asteroid)
    board.print()
    return asteroids, board
Пример #4
0
class Arcade(object):
    def __init__(self, program):
        self._board = Board(100, 100, flip=True)
        self._machine = IntCode(program)
        self._acc = []
        self._score = 0
        self._direction = 0
        self._ball_x = None
        self._paddle_x = None

    def play(self):
        self._machine.execute(input_func=self._joystick,
                              output_func=self._draw)
        self._board.print()
        return self._count(), self._score

    def _joystick(self):
        if self._ball_x and self._paddle_x:
            self._direction = self._ball_x - self._paddle_x
        return self._direction

    def _draw(self, value):
        self._acc.append(value)
        if len(self._acc) == 3:
            x, y, tile_value = self._acc
            if x == -1 and y == 0:
                self._score = tile_value
                print("New score: {}".format(self._score))
                self._board.print()
                print()
            else:
                tile = Tiles.from_value(tile_value)
                if tile == Tiles.BALL:
                    self._ball_x = x
                elif tile == Tiles.PADDLE:
                    self._paddle_x = x
                self._board.set(x, y, tile.char)
            self._acc = []

    def _count(self):
        return self._board.count(Tiles.BLOCK.char)
Пример #5
0
class Mapper(object):
    def __init__(self, intcode):
        self._board = Board(SIZE, SIZE)
        self._nodes = Board(SIZE,
                            SIZE,
                            fill_value=Node(0, NodeType.UNKNOWN, None, 9999),
                            dtype=np.object_)
        for y in range(SIZE):
            for x in range(SIZE):
                self._nodes.grid[y][x] = Node(0, NodeType.UNKNOWN, None, 9999)
        self._x = self._y = 0
        start_node = Node(1, NodeType.START, None, 0)
        self._nodes.set(self._x, self._y, start_node)
        self._board.set(self._x, self._y,
                        self._nodes.get(self._x, self._y).type.value)
        self._current_direction = Directions.NORTH
        self._current_node = start_node
        self._intcode = intcode
        self._counter = 0
        self._goal = None

    def map(self):
        try:
            self._intcode.execute(self._input, self._output)
        except Complete:
            self._draw_solved_map()
            return self._goal, self._nodes

    def _draw_solved_map(self):
        current = self._goal
        while current.type is not NodeType.START:
            c = self._board.get(current.x, current.y)
            self._board.set(current.x, current.y, Back.GREEN + c + Back.RESET)
            current = current.parent
        self._board.print()
        print("Distance to goal: {}".format(self._goal.distance))

    def is_map_complete(self):
        if self._goal is None:
            return False
        for row in self._nodes.grid:
            if all(node.type is NodeType.UNKNOWN for node in row):
                continue
            if any(0 < node.visits < 4 for node in row):
                return False
        return True

    def _input(self):
        best = None
        for direction in Directions:
            x, y = direction.move(self._x, self._y)
            candidate = self._nodes.get(x, y)
            if best is None or candidate.visits < best[0].visits:
                best = (candidate, direction)
        self._current_direction = best[1]
        return self._current_direction

    def _output(self, v):
        if v == Status.WALL:
            x, y = self._current_direction.move(self._x, self._y)
            node = Node(9999,
                        NodeType.WALL,
                        self._current_node,
                        9999,
                        x=x,
                        y=y)
            self._nodes.set(x, y, node)
            self._board.set(x, y, node.type.value)
        else:
            self._x, self._y = self._current_direction.move(self._x, self._y)
            prev_node, node = self._current_node, self._nodes.get(
                self._x, self._y)
            self._current_node = node
            node.x = self._x
            node.y = self._y
            node.visits += 1
            if node.distance > prev_node.distance:
                node.distance = prev_node.distance + 1
                node.parent = prev_node
            if v == Status.GOAL:
                node.type = NodeType.GOAL
                self._goal = node
            elif node.type != NodeType.START:
                node.type = NodeType.OPEN
            self._board.set(self._x, self._y, node.type.value)
        self._counter += 1
        if self._counter % 5 == 0:
            prev = self._board.set(
                self._x, self._y,
                Fore.RED + self._current_direction.char + Fore.RESET)
            self._board.print()
            self._board.set(self._x, self._y, prev)
        if self.is_map_complete():
            raise Complete()