class Cabinet:

    def __init__(self, filename):
        '''Create the arcade cabinet, and load up the file.'''
        self.input_buffer = list()
        self.output_buffer = list()
        self.intputer = Intputer(self.input_buffer, self.output_buffer)
        self.intputer.load_program(filename)
        self.tiles = dict()
    
    def run(self):
        '''Run the game'''
        while self.intputer.running:
            self.intputer.run(pause_for_input=True)
            while len(self.output_buffer) >= 3:
                self.process_tilebuffer()

    def process_tilebuffer(self):
        '''Pull the next 3 ints out of the output buffer and update the tiles.'''
        if len(self.output_buffer) < 3:
            raise RuntimeError('Not enough values in the buffer to process a tile.')
        col, row, tile = self.output_buffer[:3]
        self.output_buffer = self.output_buffer[3:]
        self.tiles[(row, col)] = tile
Example #2
0
    robot_location = (robot_location[0] + moves[robot_direction][0], 
                      robot_location[1] + moves[robot_direction][1])

def process_output():
    while output_buffer:
        paintPanel(robot_location, output_buffer.pop(0))
        rotate(output_buffer.pop(0))
        move()

def read_camera():
    input_buffer.append(readPanel(robot_location))

paintPanel((0,0), 1) # Second star - starting panel is white
read_camera()
while intputer.running:
    intputer.run(pause_for_input=True)
    process_output()
    if intputer.running:
        read_camera()

# How big is the resulting message?
min_row = min([pos[0] for pos in panels])
max_row = max([pos[0] for pos in panels])
min_col = min([pos[1] for pos in panels])
max_col = max([pos[1] for pos in panels])

print('Second star answer: ')
for i in range(max_row, min_row-1, -1):
    outline = []
    for j in range(min_col, max_col+1):
        outline.append('#' if panels.get((i,j),0) else ' ')
Example #3
0
class Droidmap:

    movemap = {
        'N': {"dircode": 1, "dirmove": (-1, 0)},
        'S': {"dircode": 2, "dirmove": ( 1, 0)},
        'W': {"dircode": 3, "dirmove": ( 0,-1)},
        'E': {"dircode": 4, "dirmove": ( 0, 1)}
    }

    directions = ('N', 'E', 'S', 'W')

    map_symbols = {
        None: ' ',
        0: '#',
        1: '.',
        2: '0'
    }

    def __init__(self, data):
        self.droid_loc = (0,0)
        self.last_move = 0
        self.map = {(0,0):1}
        self.input_buffer = list()
        self.output_buffer = list()
        self.intputer = Intputer(input_buffer=self.input_buffer, output_buffer=self.output_buffer, name="Droid")
        self.intputer.load_program(data)
        self.move_count = 1
        self.o2at = None
        self.current_direction = 0
    
    def rightside_explore(self):
        '''Traverse the entire map keeping the wall to our right.
        Assuming the maze is a closed space, we'll eventually loop
        back to the starting point after having explored the entire maze.'''
        while not (self.droid_loc == (0,0) and self.move_count > 20):
            # Try to move forward.
            result = self.one_move(self.directions[self.current_direction])
            # Blocked? Turn left.
            if not result:
                self.current_direction = (self.current_direction - 1) % 4
            # Free? Turn right.
            else:
                self.current_direction = (self.current_direction + 1) % 4
    
    def one_move(self, move):
        self.move_count += 1
        self.last_move = move
        self.input_buffer.append(self.movemap[move]["dircode"])
        self.intputer.run(pause_for_input=True)
        if self.output_buffer:
            result = self.handle_output()
            return result
        return None 

    def run_random(self):
        '''Not used - makes random moves until it finds the O2'''
        self.random_move()
        while self.intputer.running and self.move_count > 0:
            self.intputer.run(pause_for_input=True)
            if self.output_buffer:
                self.handle_output()
            if self.o2at:
                self.move_count -= 1
            else:
                self.move_count += 1
            self.random_move()
    
    def move_input(self):
        '''Not used. Originally for manual exploration of the map.'''
        move = input('Enter a move: N, S, E, W: ')
        move = move.upper()
        self.last_move = move
        self.input_buffer.append(self.movemap[move]["dircode"])
    
    def random_move(self):
        '''Not used, but this was a first method to test exploring the map.
        It works, but takes too long.'''
        move = random.choice(['N','S','E','W'])
        self.last_move = move
        self.input_buffer.append(self.movemap[move]["dircode"])

    def handle_output(self):
        while self.output_buffer:
            status = self.output_buffer.pop(0)
            newloc = (self.droid_loc[0] + self.movemap[self.last_move]["dirmove"][0],
                      self.droid_loc[1] + self.movemap[self.last_move]["dirmove"][1])
            if status == 0:
                self.map[newloc] = 0
            elif status == 1:
                self.map[newloc] = 1
                self.droid_loc = newloc
            elif status == 2:
                self.map[newloc] = 2
                self.droid_loc = newloc
                if not self.o2at:
                    self.o2at = newloc
                    print(f"OXYGEN FOUND AT LOCATION {newloc} on move {self.move_count}")
            else:
                raise RuntimeError(f"Unexpected status value encountered: {status}")
            return status

    def print_map(self):
        print('========')
        min_row, max_row, min_col, max_col = 0, 0, 0, 0
        for loc in self.map:
            min_row = min(loc[0], min_row)
            max_row = max(loc[0], max_row)
            min_col = min(loc[1], min_col)
            max_col = max(loc[1], max_col)
        for i in range(min_row, max_row+1):
            output_row = []
            for j in range(min_col, max_col+1):
                if (i, j) == self.droid_loc:
                    output_row.append('D')
                elif (i, j) == (0, 0):
                    output_row.append('X')
                else:
                    output_row.append(self.map_symbols[self.map.get((i,j), None)])
            print(''.join(output_row))
        print(f'Number of moves to explore maze: {self.move_count}')
    
    def possible_moves(self, loc):
        for move in self.movemap.values():
            tryloc = (loc[0] + move['dirmove'][0], loc[1] + move['dirmove'][1])
            if self.map.get(tryloc, 0):
                yield tryloc

    def minmoves_to_o2(self):
        shell_counts = 0
        move_shell = set([self.o2at])
        visited_locations = set([self.o2at])
        while move_shell:
            shell_counts += 1
            next_move_shell = set()
            for loc in move_shell:
                for tryloc in self.possible_moves(loc):
                    if tryloc not in visited_locations:
                        if tryloc == (0,0):
                            print(f'Path to (0,0) found in {shell_counts} moves')
                            return
                        next_move_shell.add(tryloc)
                        visited_locations.add(tryloc)
            move_shell = next_move_shell
        raise RuntimeError('Never found the origin.')
class Cabinet:

    tilemap = {0: ' ', 1: '#', 2: '@', 3: '=', 4: 'o'}

    def __init__(self, filename):
        '''Create the arcade cabinet, and load up the file.'''
        self.input_buffer = list()
        self.output_buffer = list()
        self.intputer = Intputer(self.input_buffer, self.output_buffer)
        self.intputer.load_program(filename)
        self.tiles = dict()
        self.score = 0

    def coindrop(self):
        self.intputer.memory[0] = 2

    def run(self):
        '''Run the game'''
        while self.intputer.running:
            self.intputer.run(pause_for_input=True)
            while len(self.output_buffer) >= 3:
                self.process_tilebuffer()
            self.make_move()
            # self.print_screen()

    def make_move(self):
        '''Figure out what move we should make, and make it.'''
        # Compare the columns of the ball and paddle
        ball_col = [pos for pos, tile in self.tiles.items() if tile == 4][0][1]
        paddle_col = [pos for pos, tile in self.tiles.items()
                      if tile == 3][0][1]
        move = 0
        if ball_col < paddle_col:
            move = -1
        elif ball_col > paddle_col:
            move = 1
        self.input_buffer.append(move)

    def process_tilebuffer(self):
        '''Pull the next 3 ints out of the output buffer and update the tiles.'''
        if len(self.output_buffer) < 3:
            raise RuntimeError(
                'Not enough values in the buffer to process a tile.')
        col = self.output_buffer.pop(0)
        row = self.output_buffer.pop(0)
        tile = self.output_buffer.pop(0)
        if col == -1 and row == 0:
            self.score = tile
        else:
            self.tiles[(row, col)] = tile

    def print_screen(self):
        '''Print out the screen memory'''
        print(f'Score: {self.score}')
        min_row = 0
        max_row = 0
        min_col = 0
        max_col = 0
        for loc in self.tiles:
            min_row = min(min_row, loc[0])
            max_row = max(max_row, loc[0])
            min_col = min(min_col, loc[1])
            max_col = max(max_col, loc[1])
        for row in range(min_row, max_row + 1):
            output_row = []
            for col in range(min_col, max_col + 1):
                tile = self.tiles.get((row, col), 0)
                output_row.append(self.tilemap[tile])
            print(''.join(output_row))
from intputer import Intputer

program = [
    109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99
]
program = [1102, 34915192, 34915192, 7, 4, 7, 99, 0]
program = [104, 1125899906842624, 99]
program = 'a09_input.txt'
input_buffer = [1]
output_buffer = []
intputer = Intputer(input_buffer=input_buffer, output_buffer=output_buffer)
# intputer = Intputer(output_buffer=output_buffer)
intputer.load_program(program)
intputer.run()
print(output_buffer)