class Game: def __init__(self, data, input): self.intcode = Intcode(data, input) self.screen = {} self.rounds = 0 def find_obj(self, obj): for coord in self.screen.keys(): if self.screen[coord] == obj: return coord def get_blocks(self): pieces = [] blocks = 0 for n in range(len(game.intcode.outputs)): if n % 3 == 2: pieces += [game.intcode.outputs[n]] for n in range(len(pieces)): if pieces[n] == 2: blocks += 1 return blocks def draw_screen(self): outputs = self.intcode.outputs self.intcode.outputs = [] index = 0 while index < len(outputs): x = outputs[index] y = outputs[index + 1] item = outputs[index + 2] index += 3 self.screen[(x, y)] = item screen = "" for y in range(25): for x in range(41): if (x, y) not in self.screen or self.screen[(x, y)] == 0: screen += ' ' elif self.screen[(x, y)] == 1: screen += 'w' elif self.screen[(x, y)] == 2: screen += 'b' elif self.screen[(x, y)] == 3: screen += 'p' elif self.screen[(x, y)] == 4: screen += 'o' screen += '\n' print(f"\n{screen}") def run_game(self, manual=False): game.intcode.data[0] = 2 last_move = ' ' score = 0 while self.intcode.is_running(): self.rounds += 1 self.intcode.run() self.draw_screen() ball = self.find_obj(4) paddle = self.find_obj(3) score = self.screen[(-1, 0)] if (-1, 0) in self.screen: print( f"score={score} rounds={self.rounds} ball={ball} paddle={paddle}" ) if manual: move_s = input("enter move[left=-1,,neutral=0,right=1.]: ") if len(move_s) == 0: move_s = last_move if move_s == ',': move = -1 elif move_s == '.': move = 1 elif move_s == ' ': move = 0 elif move_s == 's': name = f"day13-{self.rounds}" data = [self.intcode.data[n] for n in self.intcode.data] open(name, 'w').write(str(data)) print(f"wrote file {name}") continue else: continue last_move = move_s else: if ball[0] < paddle[0]: move = -1 elif ball[0] > paddle[0]: move = 1 else: move = 0 self.intcode.inputs = [move] return score
class HullPaintingRobot: def __init__(self, data, input): self.intcode = Intcode(data, input) self.dir = 0 self.dirs = ['up', 'right', 'down', 'left'] self.position = (0, 0) self.positions = {} def move(self, turn): assert turn in [0, 1] if turn == 0: self.dir = (self.dir - 1) % 4 elif turn == 1: self.dir = (self.dir + 1) % 4 x = self.position[0] y = self.position[1] if self.dir == 0: # up self.position = (x, y - 1) elif self.dir == 1: # right self.position = (x + 1, y) elif self.dir == 2: # down self.position = (x, y + 1) elif self.dir == 3: # left self.position = (x - 1, y) def run(self): while self.intcode.is_running(): self.intcode.run() assert self.intcode.inputs == [] assert len(self.intcode.outputs) == 2 color = self.intcode.outputs[0] turn = self.intcode.outputs[1] print(f"at {self.position} got color={color} turn={turn}") self.positions[self.position] = color self.move(turn) if self.position not in self.positions: current = 0 else: current = self.positions[self.position] self.intcode.outputs = [] self.intcode.inputs = [current] print("done") return len(self.positions) def show_message(self): first = list(self.positions.keys())[0] minx = first[0] miny = first[1] maxx = first[0] maxy = first[1] for position in self.positions: minx = min(minx, position[0]) miny = min(miny, position[1]) maxx = max(maxx, position[0]) maxy = max(maxy, position[1]) output = '' for y in range(miny, maxy + 1): for x in range(minx, maxx + 1): if (x, y) not in self.positions or self.positions[(x, y)] == 0: output += ' ' else: output += '#' output += '\n' return output
def run_two(self, inputs): intcode_a = Intcode(self.code[:], [inputs[0], 0], name='A') intcode_b = Intcode(self.code[:], [inputs[1]], name='B') intcode_c = Intcode(self.code[:], [inputs[2]], name='C') intcode_d = Intcode(self.code[:], [inputs[3]], name='D') intcode_e = Intcode(self.code[:], [inputs[4]], name='E') while intcode_a.is_running() and intcode_b.is_running( ) and intcode_c.is_running() and intcode_a.is_running( ) and intcode_d.is_running() and intcode_e.is_running(): intcode_a.run() if intcode_b.is_running() and len(intcode_a.outputs) > 0: intcode_b.inputs += intcode_a.outputs intcode_a.outputs = [] intcode_b.run() if intcode_c.is_running() and len(intcode_b.outputs) > 0: intcode_c.inputs += intcode_b.outputs intcode_b.outputs = [] intcode_c.run() if intcode_d.is_running() and len(intcode_c.outputs) > 0: intcode_d.inputs += intcode_c.outputs intcode_c.outputs = [] intcode_d.run() if intcode_e.is_running() and len(intcode_d.outputs) > 0: intcode_e.inputs += intcode_d.outputs intcode_d.outputs = [] intcode_e.run() if intcode_a.is_running() and len(intcode_e.outputs) > 0: intcode_a.inputs += intcode_e.outputs intcode_e.outputs = [] return intcode_e.outputs[0]