Beispiel #1
0
class PaintingRobot(object):
    def __init__(self, program: List[int]) -> None:
        self.computer = IntcodeComputer(program)
        self.x: int = 0
        self.y: int = 0
        self.direction: int = 90

    def step(self, panel: DefaultDict[Tuple[int, int], int]) -> bool:

        current_panel_color = panel[(self.x, self.y)]

        color_to_paint = self.computer.run_and_halt(current_panel_color)
        if color_to_paint is None:
            return True

        direction_to_turn = self.computer.run_and_halt()
        if direction_to_turn is None:
            return True

        direction_to_turn = 90 if direction_to_turn == 0 else -90

        panel[(self.x, self.y)] = color_to_paint
        self.direction += direction_to_turn

        self.x = int(round(self.x + cos(radians(self.direction))))
        self.y = int(round(self.y + sin(radians(self.direction))))

        return False
Beispiel #2
0
def main_rendered(screen: Any, program: List[int]) -> None:
    '''
    Navigate through the maze to find the end and display progress on screen.
    '''
    curses.curs_set(0)

    # A dict, keyed on coordinates, with the number of times each direction has been traversed
    exploration_history: Dict[Tuple[int, int], int] = defaultdict(lambda: 0)

    # A dict, keyed on coordinates, with the character to render for that location
    maze_map: Dict[Tuple[int, int], str] = defaultdict(lambda: UNKNOWN)

    current_location: Tuple[int, int] = (0, 0)
    status: int = None  # used to store result of the last instruction
    exploration_history[current_location] += 1
    maze_map[current_location] = START

    robot = IntcodeComputer(program)

    steps = 0

    while True:

        render_scene(screen, current_location, maze_map)

        direction_to_move = get_next_direction(current_location,
                                               exploration_history)

        status = robot.run_until_input_required(direction_to_move)[0]

        if status == HIT_WALL:
            exploration_history[destination_coordinate(
                current_location, direction_to_move)] = LARGE_NUMBER
            maze_map[destination_coordinate(current_location,
                                            direction_to_move)] = WALL
        elif status == MOVED:
            current_location = destination_coordinate(current_location,
                                                      direction_to_move)
            exploration_history[current_location] += 1
            if maze_map[current_location] == UNKNOWN:
                maze_map[current_location] = PATH
        else:  # GOAL
            current_location = destination_coordinate(current_location,
                                                      direction_to_move)
            exploration_history[current_location] += 1
            maze_map[current_location] = GOAL

        steps += 1

        time.sleep(1 / REFRESH_RATE)

        if steps % 100 == 0 and is_exploration_complete(maze_map):
            break

    serialize_maze(maze_map, 'day15_maze_map.json')

    render_scene(screen, (0, 0), maze_map)
    screen.addstr(0, 0, ('{:^' + str(NX) + 's}').format('MAZE MAPPED!'))
    screen.getch()
Beispiel #3
0
 def __init__(self, screen: Any, program: List[int], free_play: bool=True) -> None:
     if free_play:
         tmp = program.copy()
         tmp[0] = 2 
     else:
         tmp = program.copy()
     self.score: int = 0
     self.paddle_x_position = -1
     self.ball_x_position = -1
     self.computer = IntcodeComputer(tmp)
     self.screen = screen
     initial_screen = self.computer.run_until_input_required()
     self.render_screen(initial_screen)
     curses.curs_set(0)
Beispiel #4
0
def run_amplifiers(program: List[int], input_value: int, phases: List[int]) -> int:

    amplifiers: List[IntcodeComputer] = [IntcodeComputer(program) for name in 'ABCDE']

    for phase, amp in zip(phases, amplifiers):
        output = amp.run(phase, input_value)[0]
        input_value = output

    return output
Beispiel #5
0
def run_amplifiers_with_feedback(program: List[int], input_value: int, phases: List[int]) -> int:

    amplifiers: List[IntcodeComputer] = [IntcodeComputer(program) for name in 'ABCDE']
    program_state: List[int] = [-1 for name in 'ABCDE']  # -1 for not initialized, 0 for executing, 1 for done

    while program_state[-1] <= 0:
        for i, amp in enumerate(amplifiers):
            if program_state[i] < 0:
                output = amp.run_and_halt(phases[i], input_value)
                program_state[i] = 0
            elif program_state[i] == 0:
                output = amp.run_and_halt(input_value)
            else:
                continue
                
            if output is not None:
                input_value = output
            else:
                program_state[i] = 1

    return input_value
Beispiel #6
0
class ArcadeCabinet(object):
    tile_rendering = {

        0: ' ',  # Blank
        1: '$',  # Wall
        2: '#',  # Block
        3: '-',  # Paddle
        4: 'o'   # Ball

    }
    
    def __init__(self, screen: Any, program: List[int], free_play: bool=True) -> None:
        if free_play:
            tmp = program.copy()
            tmp[0] = 2 
        else:
            tmp = program.copy()
        self.score: int = 0
        self.paddle_x_position = -1
        self.ball_x_position = -1
        self.computer = IntcodeComputer(tmp)
        self.screen = screen
        initial_screen = self.computer.run_until_input_required()
        self.render_screen(initial_screen)
        curses.curs_set(0)
        
    def render_screen(self, tiles: List[int]) -> None:

        for i in range(0, len(tiles), 3):

            if tiles[i] == -1 and tiles[i+1] == 0:
                new_score = tiles[i+2]
                if new_score > self.score:
                    self.score = new_score
                self.screen.addstr(0, 0, f'Score: {self.score:>10}')

            else:
                self.screen.addch(
                    tiles[i+1] + 1,
                    tiles[i],
                    self.tile_rendering[tiles[i+2]]
                )

                if tiles[i+2] == 3:
                    self.paddle_x_position = tiles[i]
                if tiles[i+2] == 4:
                    self.ball_x_position = tiles[i]

        self.screen.refresh()

    def game_loop(self, bot_player: bool=False) -> None:

        while True:
            if not bot_player:
                key = self.screen.getch()
                if key == curses.KEY_LEFT:
                    input_value = -1
                elif key == curses.KEY_RIGHT:
                    input_value = 1
                else:
                    input_value = 0
            else:
                diff = self.ball_x_position - self.paddle_x_position
                if diff > 0:
                    input_value = 1
                elif diff < 0:
                    input_value = -1
                else:
                    input_value = 0
                time.sleep(0.01)
            
            tiles = self.computer.run_until_input_required(input_value)

            if tiles is None:
                self.screen.addstr(18, 13, f'GAME OVER')
                self.screen.addstr(19, 13, f'SCORE: {self.score}')
                key = self.screen.getch()
                break
            else:
                self.render_screen(tiles)
Beispiel #7
0
            if tiles is None:
                self.screen.addstr(18, 13, f'GAME OVER')
                self.screen.addstr(19, 13, f'SCORE: {self.score}')
                key = self.screen.getch()
                break
            else:
                self.render_screen(tiles)
    

def main(screen: Any, bot_player: bool):

    program = read_program('./inputs/day13.txt')
    cabinet = ArcadeCabinet(screen, program)
    cabinet.game_loop(bot_player=bot_player)


if __name__ == '__main__':

    program = read_program('./inputs/day13.txt')
    computer = IntcodeComputer(program)
    output = computer.run()
    print(f"Number of block tiles: {sum([1 for i in range(2, len(output), 3) if output[i] == 2])}")

    if len(sys.argv) > 1:
        bot_player = int(sys.argv[1]) == 1
    else:
        bot_player = False

    curses.wrapper(main, bot_player)
    
Beispiel #8
0
 def __init__(self, program: List[int]) -> None:
     self.computer = IntcodeComputer(program)
     self.x: int = 0
     self.y: int = 0
     self.direction: int = 90
Beispiel #9
0
from day05 import IntcodeComputer, read_program

if __name__ == "__main__":
    test_program = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99]
    test_computer = IntcodeComputer(test_program)
    output = test_computer.run()
    assert len(output) == len(test_program)
    assert all(o == p for o, p in zip(output, test_program))


    test_program = [109, -1, 4, 1, 99]  # -1
    test_program = [109, -1, 104, 1, 99]  # 1
    test_program = [109, -1, 204, 1, 99]  # 109
    test_program = [109, 1, 9, 2, 204, -6, 99]  # 204
    test_program = [109, 1, 109, 9, 204, -6, 99]  # 204
    test_program = [109, 1, 209, -1, 204, -106, 99]  # 204
    test_computer = IntcodeComputer(test_program)
    output = test_computer.run()
    assert output[0] == 204
    test_program = [109, 1, 3, 3, 204, 2, 99]  # input
    test_program = [109, 1, 203, 2, 204, 2, 99]  # input
    test_computer = IntcodeComputer(test_program)
    output = test_computer.run(234)
    print(test_computer.memory)
    assert output[0] == 234

    test_program = [1102,34915192,34915192,7,4,7,99,0]
    test_computer = IntcodeComputer(test_program)
    output = test_computer.run()[0]
    assert len(str(output)) == 16