Beispiel #1
0
def task2(actions):
    ship_coords = (0, 0)
    wayp_coords = (10, 1)

    for action_str in actions:
        log(action_str, ship_coords, wayp_coords)
        action = action_str[0]
        value = int(action_str[1:])

        if action in ("N", "S", "E", "W"):
            if action == "N":
                move_dir = Direction.NORTH()
            elif action == "S":
                move_dir = Direction.SOUTH()
            elif action == "E":
                move_dir = Direction.EAST()
            elif action == "W":
                move_dir = Direction.WEST()

            for _ in range(value):
                wayp_coords = move_dir.move_grid_coordinates(wayp_coords)
        elif action == "F":
            ship_coords = (ship_coords[0] + value * wayp_coords[0], ship_coords[1] + value * wayp_coords[1])
        elif action == "L":
            wayp_coords = rotate_counterclockwise(wayp_coords, value, origin=(0,0))
        elif action == "R":
            wayp_coords = rotate_clockwise(wayp_coords, value, origin=(0,0))

        log(f"New coordinates {ship_coords} {wayp_coords}\n")

    return abs(int(ship_coords[0])) + abs(int(ship_coords[1]))
Beispiel #2
0
def task1(actions):
    coords = (0, 0)
    cur_dir = Direction.EAST()

    for action_str in actions:
        log(action_str, coords)
        action = action_str[0]
        value = int(action_str[1:])

        if action in ("N", "S", "E", "W", "F"):
            if action == "N":
                move_dir = Direction.NORTH()
            elif action == "S":
                move_dir = Direction.SOUTH()
            elif action == "E":
                move_dir = Direction.EAST()
            elif action == "W":
                move_dir = Direction.WEST()
            elif action == "F":
                move_dir = cur_dir

            for _ in range(value):
                coords = move_dir.move_grid_coordinates(coords)
        elif action == "L":
            cur_dir.rotate_counterclockwise(value)
        elif action == "R":
            cur_dir.rotate_clockwise(value)

        log(f"New coordinates {coords}\n")

    return abs(coords[0]) + abs(coords[1])
Beispiel #3
0
    def repair_level(node, neighbourhood, ring_level, neighbours):
        """Repair a ring at a certain level by inserting new neighbours.
        
        The new inserted nodes could be propagated to higher levels.
        """
        LOGGER.debug("[DBG] Repair level: " + str(ring_level) + " with " +
                     str(len(neighbours)) + " neighbours (" + str(neighbours) +
                     ")")

        ring = neighbourhood.get_ring(ring_level)
        # wrap_left = neighbourhood.can_wrap(Direction.LEFT)
        # wrap_right= neighbourhood.can_wrap(Direction.RIGHT)
        left = ring.get_side(Direction.LEFT)
        right = ring.get_side(Direction.RIGHT)

        added_left, added_right = False, False
        for new_node in neighbours:
            added_left |= left.add_neighbour(new_node)
            added_right |= right.add_neighbour(new_node)
            neighbourhood.update(new_node)

        sides = ((Direction.LEFT, added_left, left), (Direction.RIGHT,
                                                      added_right, right))
        for direction, added, half_ring in sides:
            LOGGER.log(
                logging.INFO, "[DBG] Added " + Direction.get_name(direction) +
                " : " + str(added))
            if (added):
                # Tell nodes that local node is one of their new neighbour.
                NeighbourhoodNet.ping_half_ring(node, half_ring, ring_level)

                # Fix the ring higher.
                route_msg = SNFixupHigher(node, ring_level, direction)
                node.route_internal(route_msg)
Beispiel #4
0
    def compute_cpe_and_data(self, message, side_join):
        """Compute the CPE of the joining node."""

        ln = self.__local_node
        side_local = Direction.get_opposite(side_join)

        # Create the CPE.
        data_store = ln.data_store
        [cut_dimension, cut_value, data_left,
         data_right] = data_store.get_partition_value(ln.cpe)

        # Create the CPE for the joining node.
        join_node = InternalNode(side_join, cut_dimension, cut_value)
        join_cpe = copy.deepcopy(ln.cpe)
        join_cpe.add_node(join_node)

        # Create the CPE for the local node.
        local_node = InternalNode(side_local, cut_dimension, cut_value)
        local_cpe = copy.deepcopy(ln.cpe)
        local_cpe.add_node(local_node)
        print("NEW CPE:: ", local_cpe)

        # Split the data.
        if (side_join == Direction.LEFT):
            join_value = data_left
            local_value = data_right
        else:
            assert side_join == Direction.RIGHT
            join_value = data_right
            local_value = data_left

        return join_cpe, join_value, local_cpe, local_value
Beispiel #5
0
    def repair_level(node, neighbourhood, ring_level, neighbours):
        """Repair a ring at a certain level by inserting new neighbours.
        
        The new inserted nodes could be propagated to higher levels.
        """
        LOGGER.debug( "[DBG] Repair level: " + str(ring_level) + " with " + str(len(neighbours)) + " neighbours (" + str(neighbours) + ")")

        ring = neighbourhood.get_ring(ring_level)
        # wrap_left = neighbourhood.can_wrap(Direction.LEFT)
        # wrap_right= neighbourhood.can_wrap(Direction.RIGHT)
        left = ring.get_side(Direction.LEFT)
        right = ring.get_side(Direction.RIGHT)

        added_left, added_right = False, False
        for new_node in neighbours:
            added_left |= left.add_neighbour(new_node) 
            added_right |= right.add_neighbour(new_node)
            neighbourhood.update(new_node)

        sides = ((Direction.LEFT, added_left, left), (Direction.RIGHT, added_right, right))
        for direction, added, half_ring in sides:
            LOGGER.log(logging.INFO, "[DBG] Added " + Direction.get_name(direction) + " : " + str(added))
            if(added):
                # Tell nodes that local node is one of their new neighbour.
                NeighbourhoodNet.ping_half_ring(node, half_ring, ring_level)

                # Fix the ring higher.
                route_msg = SNFixupHigher(node, ring_level, direction)
                node.route_internal(route_msg)
Beispiel #6
0
    def compute_cpe_and_data(self, message, side_join):
        """Compute the CPE of the joining node."""

        ln=self.__local_node
        side_local = Direction.get_opposite(side_join)
        
        # Create the CPE.
        data_store = ln.data_store
        [cut_dimension, cut_value, data_left, data_right] = data_store.get_partition_value(ln.cpe)

        # Create the CPE for the joining node.
        join_node = InternalNode(side_join, cut_dimension, cut_value)
        join_cpe = copy.deepcopy(ln.cpe)
        join_cpe.add_node(join_node)

        # Create the CPE for the local node.
        local_node = InternalNode(side_local, cut_dimension, cut_value)
        local_cpe = copy.deepcopy(ln.cpe)
        local_cpe.add_node(local_node)
        print("NEW CPE:: ", local_cpe)

        # Split the data.
        if(side_join == Direction.LEFT):
            join_value = data_left
            local_value = data_right
        else:
            assert side_join == Direction.RIGHT
            join_value = data_right
            local_value = data_left

        return join_cpe, join_value, local_cpe, local_value
Beispiel #7
0
    def which_side_space(self, space_part, forking=False):
        """ Indicates to which side of the node belongs the 'space_part'.
            'Left' means one of the internal nodes would have to be followed
            to the left instead so that the desired part is reached.
        """
        nb_here = 0
        here, left, right = False, False, False
        for inode in self.__internal_nodes:

            if(not space_part.exists(inode.dimension)):
                if (not forking):
                    raise CPEMissingDimension(
                        "Mandatory dimension %s isn't defined in %s"%
                        (repr(inode.dimension),repr(space_part)), inode.dimension)
                else:
                    # no clue, a split is required.
                    # - here? is still undefined: further inodes could invalidate it.
                    # - left? or right? will be set depending on our own direction
                    #   on the offending inode.
                    (l,r) = Direction.get_directions(Direction.get_opposite(inode.direction))
                    left |=l ; right |=r
                    nb_here+=1
            else:
                try:
                    m_range = space_part.get_component(inode.dimension)

                    if(inode.is_here(m_range)):
                        nb_here += 1
                        left |= inode.is_more_on_the_left(m_range)
                        right |= inode.is_more_on_the_right(m_range)
                        
                    else:
                        # The range is managed by the opposite side. @test1171706
                        # 0_0 opposite_side = Direction.get_opposite(inode.dimension.direction)
                        opposite_side = Direction.get_opposite(inode.direction)
                        left |= (opposite_side == Direction.LEFT)
                        right |= (opposite_side == Direction.RIGHT)
                        break
                    # you need all the dimensions to say 'it's here' so that it's actually here.
                except:
                    raise ValueError("Component %s of %s is of unknown type: %s"%(
                        repr(inode.dimension),repr(space_part),repr(m_range)))
        here |= (nb_here == len(self.__internal_nodes))
        assert True == left | here | right, "The request coudn't be oriented."

        return [left, here, right]
Beispiel #8
0
    def reset(self, being):
        super(BeingWidget, self).reset(being)

        for direc, widget in self.items.items():
            widget.reset(being)
            widget.setOpacity(0)

        direc = Direction.toViewed(self['direction'])
        self.setDirection(direc)
Beispiel #9
0
    def test_bare_bones(self):
        left, right = Direction.get_directions(Direction.LEFT)
        assert left, "Direction.get_directions(Direction.LEFT)"
        assert not right, "Direction.get_directions(Direction.LEFT)"

        left, right = Direction.get_directions(Direction.RIGHT)
        assert not left, "Direction.get_directions(R)"
        assert right, "Direction.get_directions(R)"

        assert Direction.get_opposite(Direction.LEFT) == Direction.RIGHT
        assert Direction.get_opposite(Direction.RIGHT) == Direction.LEFT

        assert RouterReflect.check_position_partition_tree(
            Direction.LEFT,None,.2,.7), "isn't it on the left ?"
        assert RouterReflect.check_position_partition_tree(
            Direction.RIGHT,None,.7,.2), "isn't it on the right ?"

        print("#0 : directions tests passed")
        return True
Beispiel #10
0
    def test_bare_bones(self):
        left, right = Direction.get_directions(Direction.LEFT)
        assert left, "Direction.get_directions(Direction.LEFT)"
        assert not right, "Direction.get_directions(Direction.LEFT)"

        left, right = Direction.get_directions(Direction.RIGHT)
        assert not left, "Direction.get_directions(R)"
        assert right, "Direction.get_directions(R)"

        assert Direction.get_opposite(Direction.LEFT) == Direction.RIGHT
        assert Direction.get_opposite(Direction.RIGHT) == Direction.LEFT

        assert RouterReflect.check_position_partition_tree(
            Direction.LEFT, None, .2, .7), "isn't it on the left ?"
        assert RouterReflect.check_position_partition_tree(
            Direction.RIGHT, None, .7, .2), "isn't it on the right ?"

        print("#0 : directions tests passed")
        return True
Beispiel #11
0
 def from_dict(cls, robot_description):
     """
     Return robot from JSON data received from server."
     """
     direction = Direction(robot_description["direction"])
     coordinates = tuple(robot_description["coordinates"])
     name = robot_description["name"]
     robot = cls(direction, coordinates, name)
     robot.lives = robot_description["lives"]
     robot.flags = robot_description["flags"]
     robot.damages = robot_description["damages"]
     robot.power_down = robot_description["power down"]
     robot.start_coordinates = robot_description["start coordinates"]
     return robot
Beispiel #12
0
    def __init__(self, parent, tile_width, use_svg, is_player):
        super(BeingWidget, self).__init__(parent, tile_width)
        ResetItem.__init__(self, tile_width)

        if use_svg and is_player:
            klass = ChibiDirectionWidget
        elif use_svg:
            klass = SvgSpeciesItem
        else:
            klass = CharItem

        self._current = None
        self.items = {}
        for direction in Direction.viewable(use_svg):
            self.items[direction] = klass(self, tile_width, direction)
            #FIXME figure out some other place to do this
            if not use_svg:
                self.items[direction].setBold()

        self.animation = BeingAnimation(self)
Beispiel #13
0
 def __repr__(self):
     return "<SNFixupHigher ((%i, %s from %s) #%i - RouteByPayload>"%(
         self.__ring_level, Direction.get_name(self.__direction),
         self.__src_node, self.__nb_hops)
Beispiel #14
0
    def test_ring(self):
        j=0
        nd=[]
        for n,i in (("g3",45),("jt",71),("na",53),("se",42),("sw",59),("xk",19)):
            nd+=[self.createNode(n,"127.0.0.1%i"%j)]
            nd[j].numeric_id=i     
            j=j+1
            
        import copy
        from equation import InternalNode
        from util import Direction
        
        import pdb; pdb.set_trace()
        cut_dim=("a","b","a","x","c")
        cut_val=("girl","soft","cute","c","face")
        
        from localevent import Router
        for i in (1, 0, 4, 2):
            nb = nd[3].neighbourhood
            side=Router.by_name_get_direction(nd[3].name_id,nd[i].name_id)
            nextn =  nb.get_neighbour(side,0)
            othern= nb.get_neighbour(not side,0)
            wrapf = nb.can_wrap(side)
            wrapb = nb.can_wrap(not side)
            
            assert(
                NodeID.lies_between_direction(side,nd[3].name_id,nd[i].name_id,nextn.name_id,wrapf)
                or
                NodeID.lies_between_direction(not side,nd[3].name_id,nd[i].name_id,othern.name_id,wrapb)
                )

            if (not NodeID.lies_between_direction(side,nd[3].name_id,nd[i].name_id,nextn.name_id, wrapf)):
                print("need to reverse side %s-%s-%s!"%(nd[3].name_id,nd[i].name_id,nextn.name_id))
                side=not side
                nextn=othern
                        
            print("next on %s is %s"%("LEFT" if side else "RIGHT",repr(nextn)))

            nb.add_neighbour(0,nd[i])
            if (nd[i].numeric_id>=32):
                nb.add_neighbour(1,nd[i])
            if (nd[i].numeric_id<48):
                nb.add_neighbour(2,nd[i])
            if (nd[i].numeric_id>40):
                nb.add_neighbour(3,nd[i])
            if (nd[i].numeric_id<44):
                nb.add_neighbour(4,nd[i])
            if (nd[i].numeric_id>=42):
                nb.add_neighbour(5,nd[i])

            new_side_join = side
            new_side_local= Direction.get_opposite(new_side_join)

            njnode=InternalNode(new_side_join,cut_dim[i],cut_val[i])
            njcpe =copy.deepcopy(nd[3].cpe)
            njcpe.add_node(njnode)
            print("%s gets CPE %s"%(nd[i].pname,njcpe))

            nlnode=InternalNode(new_side_local,cut_dim[i],cut_val[i])
            nlcpe =copy.deepcopy(nd[3].cpe)
            nlcpe.add_node(nlnode)
            print("%s gets CPE %s"%(nd[3].pname,nlcpe))
            nd[i].cpe=njcpe
            nd[3].cpe=nlcpe
Beispiel #15
0
    def test_ring(self):
        j = 0
        nd = []
        for n, i in (("g3", 45), ("jt", 71), ("na", 53), ("se", 42),
                     ("sw", 59), ("xk", 19)):
            nd += [self.createNode(n, "127.0.0.1%i" % j)]
            nd[j].numeric_id = i
            j = j + 1

        import copy
        from equation import InternalNode
        from util import Direction

        import pdb
        pdb.set_trace()
        cut_dim = ("a", "b", "a", "x", "c")
        cut_val = ("girl", "soft", "cute", "c", "face")

        from localevent import Router
        for i in (1, 0, 4, 2):
            nb = nd[3].neighbourhood
            side = Router.by_name_get_direction(nd[3].name_id, nd[i].name_id)
            nextn = nb.get_neighbour(side, 0)
            othern = nb.get_neighbour(not side, 0)
            wrapf = nb.can_wrap(side)
            wrapb = nb.can_wrap(not side)

            assert (NodeID.lies_between_direction(
                side, nd[3].name_id, nd[i].name_id, nextn.name_id, wrapf)
                    or NodeID.lies_between_direction(
                        not side, nd[3].name_id, nd[i].name_id, othern.name_id,
                        wrapb))

            if (not NodeID.lies_between_direction(
                    side, nd[3].name_id, nd[i].name_id, nextn.name_id, wrapf)):
                print("need to reverse side %s-%s-%s!" %
                      (nd[3].name_id, nd[i].name_id, nextn.name_id))
                side = not side
                nextn = othern

            print("next on %s is %s" %
                  ("LEFT" if side else "RIGHT", repr(nextn)))

            nb.add_neighbour(0, nd[i])
            if (nd[i].numeric_id >= 32):
                nb.add_neighbour(1, nd[i])
            if (nd[i].numeric_id < 48):
                nb.add_neighbour(2, nd[i])
            if (nd[i].numeric_id > 40):
                nb.add_neighbour(3, nd[i])
            if (nd[i].numeric_id < 44):
                nb.add_neighbour(4, nd[i])
            if (nd[i].numeric_id >= 42):
                nb.add_neighbour(5, nd[i])

            new_side_join = side
            new_side_local = Direction.get_opposite(new_side_join)

            njnode = InternalNode(new_side_join, cut_dim[i], cut_val[i])
            njcpe = copy.deepcopy(nd[3].cpe)
            njcpe.add_node(njnode)
            print("%s gets CPE %s" % (nd[i].pname, njcpe))

            nlnode = InternalNode(new_side_local, cut_dim[i], cut_val[i])
            nlcpe = copy.deepcopy(nd[3].cpe)
            nlcpe.add_node(nlnode)
            print("%s gets CPE %s" % (nd[3].pname, nlcpe))
            nd[i].cpe = njcpe
            nd[3].cpe = nlcpe
Beispiel #16
0
 def walk(self, old_tile, new_tile, level, direction):
     direc = Direction.toViewed(direction)
     self.setDirection(direc)
     self.animation.walk(old_tile, new_tile, level)
Beispiel #17
0
 def melee(self, tile, direc):
     direc = Direction.toViewed(direc)
     self.setDirection(direc)
     self.animation.melee(tile)
Beispiel #18
0
 def __repr__(self):
     return "<SNFixupHigher ((%i, %s from %s) #%i - RouteByPayload>" % (
         self.__ring_level, Direction.get_name(
             self.__direction), self.__src_node, self.__nb_hops)
Beispiel #19
0
 def _info(self):
     return "SNFixupHigher (%i, %s from %s) #%i - " % (
         self.__ring_level, Direction.get_name(
             self.__direction), self.__src_node, self.__nb_hops)
Beispiel #20
0
 def _info(self):
     return "SNFixupHigher (%i, %s from %s) #%i - "%(
         self.__ring_level, Direction.get_name(self.__direction),
         self.__src_node, self.__nb_hops)
Beispiel #21
0
    def by_cpe_get_next_hop_forking(self, lnode, message):
        self.__lastcall = ['bycpe+f']
        dest = []
        left, here, right = lnode.cpe.which_side_space(message.space_part,
                                                       True)
        if (here):
            # NOTE: it cannot be 'naked' message, but must be a clone with
            #   search range that has been 'constraint' to stick here.
            newmsg = copy.copy(message)
            newmsg.trace = copy.copy(message.trace)
            newmsg.limit = PidRange(lnode.partition_id, lnode.partition_id)
            dest.append((lnode, newmsg))

        # create 'directions', that identifies sub-rings to be scanned
        #   and the sub-range of PartitionID that should be taken into account.

        message.sign(
            "routing %s%s with %s" %
            ('L' if left else '', 'R' if right else '', repr(message.limit)))

        directions = list()
        if (left):
            r = message.limit.restrict(Direction.RIGHT, lnode.partition_id)
            directions.append((Direction.LEFT, r, 'L'))

        if (right):
            r = message.limit.restrict(Direction.LEFT, lnode.partition_id)
            directions.append((Direction.RIGHT, r, 'R'))

        self.__lastcall.append("scanning rings @%s: %s" %
                               (lnode.partition_id, repr(directions)))
        part = message.space_part
        neighbourhood = lnode.neighbourhood
        lastpid, lastngh = None, None

        # (point) routing guideline:
        #   for a message that must be sent in direction D, we look for
        #   the farthest neighbour that would not reverse the travelling
        #   direction.

        # (range) routing guideline:
        #   you send a copy to N[i] if region between N[i] and N[i+1] inter-
        #   sects the region you're searching for.

        for dirx, prange, pd in directions:
            for height in range(neighbourhood.nb_ring - 1, -1, -1):
                if height > 0 and neighbourhood.size(dirx, height) < 2:
                    continue  # this ring is empty or has a single node.
                ngh = neighbourhood.get_neighbour(dirx, height)
                pid = ngh.partition_id
                if lastngh != None and ngh.name_id == lastngh.name_id:
                    continue  # we just checked this neighbour
                lastngh = ngh
                self.__lastcall.append("%s (%i, %s)" %
                                       (ngh.pname, height, repr(dirx)))
                if (ngh.cpe.k == 0):
                    ngh.queue(message)
                    reply = RouteDirect(SNPingRequest(lnode, height), ngh)
                    self.__lastcall.append(
                        "requesting routing table complement at %s" % ngh)
                    return [(ngh, reply)]
                    # todo: rate-limit to avoid redundant PING requests.

                epid = prange.includes_pid(
                    pid)  # effective pid = pid+{-1,0,+1}
                if (epid != None):
                    left, here, right = ngh.cpe.which_side_space(part, True)
                    if (here or RouterReflect.__goes_forward(
                            dirx, left, right)):
                        self.__lastcall.append(
                            "%s is %s compared to %s" %
                            (part, 'here' if here else 'forw', repr(ngh.cpe)))
                        newmsg = copy.copy(message)
                        newmsg.sign("routed to %s at h=%i" %
                                    (ngh.pname, height))
                        newmsg.limit = prange.restrict(
                            Direction.get_opposite(dirx), epid)
                        dest.append((ngh, newmsg))
                    else:
                        self.__lastcall.append(
                            "ignored w/ %s, %s, %s - %s" %
                            (repr(left), repr(here), repr(right),
                             'L' if dirx == Direction.LEFT else 'R'))
                    lastpid = pid
                    prange = prange.restrict(dirx, epid)
                    # ^ messages that will be generated after this one will not be allowed
                    #   to forward beyond the 'current position'.
                    if (not RouterReflect.__goes_backward(dirx, left, right)):
                        break
                else:
                    self.__lastcall.append("%f out of partition range %s" %
                                           (pid, repr(prange)))
#        print("0_0 %s : %i"%(repr(message),len(dest)))
# ^it's a bad idea to do a per-message report to the MCP. Use your
#  'personal log' for that. Otherwise, you're forcing the MCP to do
#  a poll with period approaching msg_rate x buffer_size or your
#  own node will stall, waiting for room to appear in STDOUT buffer.
        return dest