Ejemplo n.º 1
0
class EHPR():
    def __init__(self, program):
        self.painted = defaultdict(int)
        self.position = Position(0,0)
        self.direction = Direction.Up
        self.computer = IntcodeComputer(program, [], "Emergency Hull Painting Robot", 0)

    def set_start_color(self, color):
        self.painted[self.position] = color

    def move(self, command):
        new_direction = (Direction(((self.direction.value + 1) % 4)) if command
                            else Direction(((self.direction.value - 1) % 4)))
        new_position = Position(*(sum(x) for x in zip(self.position, movement[new_direction])))
        self.direction = new_direction
        self.position = new_position

    def paint_square(self, color):
        self.painted[self.position] = color

    def execute_step(self):
        self.computer.add_input(self.painted[self.position])
        self.computer.run_program()
        output = self.computer.get_output()
        color, command = output[-2:]
        self.paint_square(color)
        self.move(command)
Ejemplo n.º 2
0
class ArcadeCabinet():
    def __init__(self, program, free_play=False, auto=False, display=True):
        if free_play:
            program = program[:]
            program[0] = 2
        self.computer = IntcodeComputer(program, [], "Arcade Cabinet")
        self.gamestate = dict()
        self.ball, self.tile = None, None
        self.auto = auto
        self.display = display

    def draw_screen(self):
        max_x = max(x for x, y in self.gamestate.keys())
        max_y = max(y for x, y in self.gamestate.keys())
        score = self.gamestate[(-1, 0)] if (-1, 0) in self.gamestate else 0
        printstr = "\tSCORE:\t %i\n" % score
        for y in range(max_y + 1):
            for x in range(max_x + 1):
                printstr = printstr + "%s" % tiles[self.gamestate[(x, y)]]
            printstr = printstr + "\n"
        sys.stdout.write(printstr)

    def parse_instruction(self, instruction):
        x, y, tile = instruction
        self.gamestate[(x, y)] = tile
        if tile == 4:
            self.ball = x
        elif tile == 3:
            self.tile = x

    def joystick(self, key='n'):
        if keyboard.is_pressed('a') or key == 'a':
            self.computer.add_input(-1)
        elif keyboard.is_pressed('d') or key == 'd':
            self.computer.add_input(1)
        elif keyboard.is_pressed('s') or key == 's':
            self.computer.add_input(0)

    def self_play(self):
        if self.tile > self.ball:
            return 'a'
        elif self.tile < self.ball:
            return 'd'
        else:
            return 's'

    def score_counter(self):
        score = self.gamestate[(-1, 0)] if (-1, 0) in self.gamestate else 0
        sys.stdout.write("\r")
        sys.stdout.flush()
        sys.stdout.write("Score: %i" % score)

    def run_game(self):
        while not self.computer.has_stopped():
            output = self.computer.run_program()
            for instruction in chunks(output, 3):
                self.parse_instruction(instruction)
            if self.display:
                self.draw_screen()
                time.sleep(0.07)
            else:
                self.score_counter()
            self.computer.input_l.clear()
            key = self.self_play() if self.auto else None
            self.joystick(key)
        sys.stdout.write('\n')
        self.draw_screen()
Ejemplo n.º 3
0
class RepairDroid():
    def __init__(self, program, visualize=0):
        self.computer = IntcodeComputer(program, [], "Arcade Cabinet")
        self.areamap = dict()
        self.visualize = visualize
        self.startpos = Position(0,0)
        self.areamap[self.startpos] = Field(self.startpos, 1, -1)
        self.currentpos = self.startpos

    def move_droid(self, direction):
        move = movement[direction]
        new_pos = Position(self.currentpos.x + move[0], self.currentpos.y + move[1])
        self.computer.add_input(direction.value)
        output = self.computer.run_program()
        if new_pos not in self.areamap:
            new_field = Field(new_pos, output[-1], self.areamap[self.currentpos].dist)
            self.areamap[new_pos] = new_field
            if new_field.type == FieldType.WALL:
                return False
            else:
                self.currentpos = new_pos
                return True
        elif self.areamap[new_pos].type != FieldType.WALL:
            if self.areamap[new_pos].dist < self.areamap[self.currentpos].dist-1:
                # we found a shorter path to the current position
                self.areamap[self.currentpos].update_dist(self.areamap[new_pos].dist+1)
            self.currentpos = new_pos
            return False
        else:
            return False

    def draw_map(self):
        min_x = min(x for x,y in self.areamap.keys())
        max_x = max(x for x,y in self.areamap.keys())
        min_y = min(y for x,y in self.areamap.keys())
        max_y = max(y for x,y in self.areamap.keys())
        x_range = max_x - min_x
        y_range = max_y - min_y
        full_map = ""
        for y in range(y_range+1):
            for x in range(x_range+1):
                position = Position(x+min_x, y+min_y)
                if position == self.currentpos:
                    full_map = full_map + "D"
                elif position not in self.areamap:
                    full_map = full_map + "#"
                elif self.areamap[position].type == FieldType.FIELD:
                    full_map = full_map + " "
                elif self.areamap[position].type == FieldType.WALL:
                    full_map = full_map + "|"
                elif self.areamap[position].type == FieldType.OSYS:
                    full_map = full_map + "X"
                elif self.areamap[position].type == FieldType.OXY:
                    full_map = full_map + "O"
            full_map = full_map + "\n"
        full_map = full_map + "\n"
        print(full_map)

    def traverse_grid(self):
        directions = [Direction.EAST, Direction.SOUTH, Direction.NORTH, Direction.WEST]
        steps = deque(directions)
        i = 0
        while steps:
            i+=1
            next_move = steps.popleft()
            if self.visualize:
                time.sleep(0.2)
                print("Step: %i" % i)
                self.draw_map()
            if self.move_droid(next_move):
                prev = opposite[next_move]
                steps.appendleft(prev)
                move_order = directions[:]
                move_order.remove(prev)
                for entry in reversed(move_order):
                    steps.appendleft(entry)
            else:
                continue
        self.draw_map()