Example #1
0
    def _recursive_wire_replace(self, old_wire_coords, new_wire):
        """Recursively flood through a wire and replace it with a new
        wire.

        TODO: How does caching fit into this?

        Returns : set
          Set of all the SimNodes which will need to have their IO updated.

        """
        # Replace the current wire
        self.set_basic(old_wire_coords, new_wire)

        dirty_simnodes = {}

        # In the list of all wire neighbours which aren't the new wire...
        for nd in util.neighbour_deltas():
            nc = util.add(old_wire_coords, nd)
            _, nc, n = self.into(nc, nd)
            if isinstance(n, Wire) and n != new_wire:
                # Replace them, too!
                dirty_simnodes.update(
                    self._recursive_wire_replace(nc, new_wire))
            elif n is not None:
                dirty_simnodes[nc] = n
        return dirty_simnodes
Example #2
0
    def editor_loop(self):
        while True:
            # Just render the first board for now
            self.render(self.world.boards[0])

            # Get input
            inp = self.t.inkey()
            logger.debug('Key Input: ' + repr(inp))

            ui_event = self.key_to_event(inp)
            if ui_event is None:
                continue

            move_delta = ui_event.get('move')
            quit = ui_event.get('quit')
            write_board = ui_event.get('write_board')

            if move_delta:
                new_pos = util.add(self.cursor_pos, move_delta)
                if min(new_pos) >= 0:
                    self.cursor_pos = new_pos
            elif quit:
                return
            elif write_board:
                index = write_board['index']
                self.write_board_to_disk(self.world.boards[index],
                                         write_board['filepath'])

            else:
                # Pass it along to the world message queue
                self.world.submit(ui_event)
                self.world.process_queue()
Example #3
0
 def get(self, q_board, my_coords, q_coord_delta):
     new_coords = util.add(my_coords, q_coord_delta)
     new_node = q_board.get(new_coords)
     try:
         return new_node.get(q_board, new_coords, q_coord_delta)
     except AttributeError:
         return (q_board, my_coords, None)
Example #4
0
    def _surround_bridge_with_wires(self):
        # Place wire around the bridge
        new_wires = [util.add(self.bridge_coords, nc)
                     for nc in util.neighbour_deltas()]
        for w in new_wires:
            self.board.set(w, Wire())

        self.board.tick()
Example #5
0
 def neighbour_objs_into(self, coords):
     """Returns the neighbouring nodes through portals (No `None`s)"""
     n_objs = []
     for nd in util.neighbour_deltas():
         nc = util.add(coords, nd)
         _, nc, n = self.into(nc, nd)
         if n is not None:
             n_objs.append(n)
     return n_objs
Example #6
0
    def _grid_local_wire_break(self, coords, broken_wire: Wire):
        """Break a wire into multiple bits if required

        Parameters
        ----------

        coords : (x, y)
          Coordinates of where the wire group was broken.
        broken_wire : Wire
          The wire object which was broken.
        """

        current_obj = self.get(coords)
        assert (not isinstance(current_obj, Wire))

        # Note: This can work even if there are no wires... Just marks all the
        #       neighbours as dirty.
        new_wires = set()
        dirty_simnodes = {}  # coord -> obj
        for nd in util.neighbour_deltas():
            nc = util.add(coords, nd)
            # Use coords to avoid mutating what we are iterating over
            _, nc, n = self.into(nc, nd)
            if n is broken_wire:
                new_wire = Wire()
                dirty_simnodes.update(
                    self._recursive_wire_replace(nc, new_wire))
                # Update this later - Can't do here because we need to wait for
                # dirty simnodes to refresh
                new_wires.add(new_wire)
            elif n is not None:
                dirty_simnodes[nc] = n

        # Update IO for all dirty_simnodes
        for coord, n in dirty_simnodes.items():
            n.recalculate_io(coord, self)
        # Make sure the new wires immediately show the correct value
        for wire in new_wires:
            wire.calculate_next_output()
            wire.tick()
Example #7
0
    def recalculate_io(self, my_coord, board):
        # Reset inputs as empty, then slowly repopulate
        self.inputs = set()
        # Need to keep track of outputs so we don't immediately remove
        # ourselves again if many neighbour tiles are the same input AND
        # output object (eg, in the case of a simple 1-tick nand clock)
        outputs = set()
        deltas = util.neighbour_deltas()

        for i, delta in enumerate(deltas):
            nc = util.add(delta, my_coord)
            _, nc, n = board.into(nc, delta)

            if n is not None:
                if i == self.facing:
                    n.input_add(self, util.invert(delta))
                    outputs.add(n)
                else:
                    if n not in outputs:
                        n.input_remove(self)
                    if n.outputs_to(util.invert(delta)):
                        self.inputs.add(n)