Пример #1
0
    def add(self, node: Machine):

        if verbose: node.toggle_verbose()

        new_addr = len(self.__nodes)
        node.run(new_addr)

        self.__nodes.append({'machine': node, 'message_queue': deque()})
Пример #2
0
class Bot:
    NORTH = 'north'
    SOUTH = 'south'
    WEST = 'west'
    EAST = 'east'

    def __init__(self, m):
        self.__m = m
        self.__cpu = Machine(self.__m[:])
        self.__history = []

        self.__move_count = 0
        self.__safe_items = {
            'asterisk', 'polygon', 'tambourine', 'mug', 'cake', 'jam',
            'easter egg', 'klein bottle'
        }

        if verbose: self.__cpu.toggle_verbose()

    def map(self, _display=True):

        history = self.__history
        p = 0
        move = self.NORTH
        tries = {}
        inventory = set()
        seen_items = set()
        safe_items = self.__safe_items
        checkpoint_map = []
        disable_pickups = False

        self.__cpu.run()
        o = ''.join(list(map(chr, self.__cpu.dump_output(clear=True))))

        print('MAIN OUTPUT:', o)

        while True and not self.__cpu.halted():
            sleep(0.2)
            '''
      here, we will use (D)epth (F)irst (S)earch algo to traverse
      the entire map, collect all items and find our way to the checkpoint.

      '''
            p = self.location(o)

            if p not in tries:
                tries[p] = set(self.moves(o))

            if tries[p]:
                print(f'AVAILABLE TRIES FOR [ {p.upper()} ]:', tries[p])
                backtrack = False

                prev = move
                move = tries[p].pop()

                if tries[p] and prev == self.reverse(move):
                    prev = move
                    move = tries[p].pop()
                    tries[p].add(prev)

            else:
                backtrack = True

                if not history:
                    '''
            no where to backtrack to. this will happen when we've explored 
            every other path and are forced to backtrack all the back to the beginning.

            END PROGRAM
            '''
                    print('NO HISTORY')

                    if checkpoint_map and len(seen_items) == len(safe_items):
                        print('ALL SET: NAVIGATE TO CHECKPOINT')
                        print('SEEN ITEMS:', seen_items)
                        print('Hit enter to continue >_')

                        sys.stdin.readline()

                        path = checkpoint_map[::-1]

                        while path:
                            self.instruct(path.pop())

                        move = self.EAST

                    else:
                        print('MISSING ITEMS OR NO CHECKPOINT PATH')
                        print('PATH:', checkpoint_map)
                        print('SEEN ITEMS:', seen_items)
                        break

                else:
                    move = self.reverse(history.pop())

            o = self.instruct(move)

            for item in self.items(o):
                if item not in 'molten lava escape pod giant electromagnet photons infinite loop' and (
                        not disable_pickups or item not in seen_items):
                    self.instruct(f'take {item}')
                    inventory.add(item)
                    seen_items.add(item)

                else:
                    pass  # print('SKIPPED:', item)

            if 'checkpoint' in o:
                print('CHECKPOINT')
                '''
        Save path to checkpoint for later
        '''
                checkpoint_map = history.copy()
                ''' 
        Make sure ALL safe items are collected before 
        initiating brute force.
        '''
                if len(seen_items) != len(safe_items):
                    continue

                else:
                    print('============ ALL SET ================')
                    self.instruct('inv')
                    print('=====================================')
                    print('Hit enter to continue >_')

                    sys.stdin.readline()

                    self.brute()
                    break

            if "You can't go that way" not in o:

                if not backtrack:
                    history.append(move)

    def brute(self):
        '''
    try all possible combinations of items at the checkpoint.
    '''

        for i in range(3, 6):
            print(f'TRYING SETS OF {i}')
            print('-------------------------------------')
            print('Hit enter to continue >_')
            sys.stdin.readline()

            item_combinations = set(combinations(self.__safe_items, i))

            while item_combinations:
                current_set = item_combinations.pop()
                print('TRYING WITH FOLLOWING INVENTORY:', current_set)

                _o = self.items(self.instruct('inv', silent=True))

                for item in [x for x in _o if x not in current_set]:
                    self.instruct(f'drop {item}', silent=True)

                for item in [x for x in current_set if x not in _o]:
                    self.instruct(f'take {item}', silent=True)

                _o = self.instruct('inv')
                ''' TRY '''
                _o = self.instruct('east')

                if not re.search(r'(heavier|lighter) than', _o):
                    print('YAYYYY (?):', _o)
                    return

                sleep(0.2)

        print('SECURITY BREACH FAILED. TRY AGAIN.')

    def instruct(self, command: str, join: bool = True, silent: bool = False):
        '''
    - convert text command to ASCII and feed to computer.
    - return output
    '''

        if not silent:
            print('INSTR:', command)

        cpu = self.__cpu

        for c in map(ord, command):
            cpu.run(c)

        cpu.run(10)  # return

        o = list(map(chr, cpu.dump_output(clear=True)))

        if not silent:
            print('OUTPUT:', ''.join(o))

        return ''.join(o) if join else o

    def moves(self, o):
        '''
    extract available moves from output
    '''

        res = re.findall(r'- (north|south|east|west)', ''.join(o))

        if res:
            pass  # print('MOVES:', res)

        return res

    def items(self, o):
        '''
    extract items from output
    '''

        res = re.findall(r'- ([ a-z]+)', o)

        if res:
            res = [
                x for x in res if x not in {'north', 'south', 'east', 'west'}
            ]
            # if res: print('ITEMS:', res)

        return res

    def location(self, o):
        '''
    extract location from output
    '''

        res = re.findall(r'== ([ a-z]+) ==', o.lower())

        return res[0]

    def reverse(self, direction=None):
        if direction == None: direction = self.__history[-1]

        return {
            self.NORTH: self.SOUTH,
            self.SOUTH: self.NORTH,
            self.WEST: self.EAST,
            self.EAST: self.WEST
        }[direction]
Пример #3
0
class Arcade9000Turbo:
    def __init__(self, m):
        self.__cpu = Machine(m)
        self.__minx = self.__miny = self.__maxx = self.__maxy = 0
        '''
    we only need to track (x)
    '''
        self.__player_x = 0
        self.__ball_x = 0
        self.__canvas = defaultdict(lambda: ' ')
        self.__scores = 0
        self.__tiles = {0: ' ', 1: '|', 2: '⬜', 3: '➖', 4: '⚪'}

        if verbose: self.__cpu.toggle_verbose()

    def play(self, auto: bool = False):
        self.__cpu.run()

        while not self.__cpu.halted() or self.__cpu.has_output():
            x = self.__cpu.output()
            y = self.__cpu.output()

            if x == -1 and y == 0:
                '''
        player's current score

        '''
                self.__scores = self.__cpu.output()
                self.display()

            elif x != None and y != None:
                '''
        draw a tile to the screen

        '''
                self.draw(x, y, self.__cpu.output())
                self.display()

            elif auto and self.__cpu.waiting():
                m = 0
                if self.__ball_x > self.__player_x:
                    m = 1
                    print('_/_ >')

                elif self.__ball_x < self.__player_x:
                    m = -1
                    print('_\\_ >')
                else:
                    print('_|_ >')

                self.__cpu.run(m)

            elif self.__cpu.waiting():
                print('_|_ >')
                self.input()

    def input(self):
        try:
            self.__cpu.run(int(sys.stdin.readline()))
        except ValueError:
            print('Invalid input (hint: enter -1, 0, or 1 ):')
            self.input()

    def display(self):
        grid = [[' '] * (self.__maxx + 1) for _ in range(self.__maxy + 1)]

        count = 0
        for (x, y), v in self.__canvas.items():
            if x < 0 or y < 0: break
            if v == self.__tiles[2]: count += 1
            grid[y][x] = v

        subprocess.call("clear")
        for l in grid:
            print(''.join(l))

        print('\n')
        print('.' * (self.__maxx + 1))

        print('Score: {0}, Blocks: {1}'.format(self.__scores, count))

    def draw(self, x, y, tile_id):
        self.__canvas[(x, y)] = self.__tiles[tile_id]

        self.__minx = min(self.__minx, x)
        self.__maxx = max(self.__maxx, x)
        self.__miny = min(self.__miny, y)
        self.__maxy = max(self.__maxy, y)

        if tile_id == 4:
            '''
      track ball displacement
      '''
            self.__ball_x = x
        elif tile_id == 3:
            '''
      track player position
      '''
            self.__player_x = x
Пример #4
0
class Robot:
  def __init__(self, m):
    self.__cpu = Machine(m)

    '''
    {current, min, max}

    '''
    self.__x, self.__y = (0, 0, 0), (0, 0, 0)
    self.__panels = defaultdict(lambda: '.')
    self.__color = 0

    '''
    < : 0
    ^ : 1
    > : 2
    v : 3

    '''
    self.__direction = 1

    if verbose: self.__cpu.toggle_verbose()


  def start(self, start_color):
    if start_color: self.__panels[(0, 0)] = '#'

    while not self.__cpu.halted():

      self.__cpu.run(1 if self.__panels[(self.__x[0], self.__y[0])] == '#' else 0)

      self.paint(self.__cpu.output())

      self.turn(self.__cpu.output())
      self.move()


  def display(self):
    _, minx, maxx = self.__x
    _, miny, maxy = self.__y


    grid = [[' ']*(maxx+1) for _ in range(maxy+1)]

    for (x, y), v in self.__panels.items():
      if x < 0 or y < 0: break

      if v == '#': grid[y][x] = v

    for l in grid: print(''.join(l))
    
    print('\n', '--------------------------------------\n', 'COUNT', len(self.__panels), '\n\n')

  def turn(self, lr):
    if verbose: print('FROM ', ['<', '^', '>', 'v'][self.__direction]*4, lr)
    if lr == 0: self.left()
    else: self.right()

    if verbose: print('TURNED ', ['<', '^', '>', 'v'][self.__direction]*4)


  def left(self):
    self.__direction += (3 if self.__direction == 0 else -1)

    return self.__direction

  def right(self):
    self.__direction += (-3 if self.__direction == 3 else 1)

    return self.__direction

  def move(self):
    x, minx, maxx = self.__x
    y, miny, maxy = self.__y

    # <- left
    if self.__direction == 0: 
      if verbose: print('MOV <----', x)
      x -= 1
      minx = min(minx, x)

      if verbose: print('x:', x)

    # -> right
    elif self.__direction == 2: 
      if verbose: print('MOV ---->', x)
      x += 1
      maxx = max(maxx, x)

      if verbose: print('x:', x)

    # -> up
    elif self.__direction == 1: 
      if verbose: print('MOV ^^^^^^', y)
      y -= 1
      miny = min(miny, y)

      if verbose:  print('y:', y)

    # -> down
    elif self.__direction == 3: 
      if verbose: print('MOV vvvvvv', y)
      y += 1
      maxy = max(maxy, y)
        
      if verbose: print('y:', y)

    self.__x, self.__y = (x, minx, maxx), (y, miny, maxy)
      

  def paint(self, color = None):
    if color != None: self.__color = color
  

    self.__panels[(self.__x[0], self.__y[0])] = ('.' if self.__color == 0 else '#')