示例#1
0
    def fly_tick(self):
        " Iterate one flight tick "
        addx, addy = utils.components(self.speed * self.layout.dt, self.angle)
        self.x += addx
        self.y += addy
        # Check for out of bounds
        oob = False
        if self.x < 0:
            self.x = 0
            oob = True
        elif self.x > self.layout.xsize:
            self.x = self.layout.xsize
            oob = True
        if self.y < 0:
            self.y = 0
            oob = True
        elif self.y > self.layout.ysize:
            self.y = self.layout.ysize
            oob = True

        if oob:
            self.flying = False
            self.vspeed = 0
            self.speed = 0
            self.z = 0
            self.xland = self.x
            self.yland = self.y
        else:
            self.vspeed += -self.g * self.layout.dt
            self.z += self.vspeed * self.layout.dt
            if self.z <= 0.:
                self.flying = False
示例#2
0
    def fly_tick(self):
        " Iterate one flight tick "
        addx, addy = utils.components(self.speed*self.layout.dt,self.angle)
        self.x += addx
        self.y += addy
        # Check for out of bounds
        oob=False
        if self.x < 0:
            self.x = 0
            oob = True
        elif self.x > self.layout.xsize:
            self.x = self.layout.xsize
            oob = True
        if self.y < 0:
            self.y = 0
            oob = True
        elif self.y > self.layout.ysize:
            self.y = self.layout.ysize
            oob = True

        if oob:
            self.flying = False
            self.vspeed=0
            self.speed=0
            self.z=0
            self.xland=self.x
            self.yland=self.y
        else:
            self.vspeed += -self.g * self.layout.dt
            self.z += self.vspeed * self.layout.dt
            if self.z <= 0.:
                self.flying = False
示例#3
0
def makeislands(seq,gaplength):
    L = list(utils.components(seq,rel=lambda x,y: s_distance(x,y)<=gaplength))
    L.sort(key=lambda L: L[0].SSTART)
    for i,island in enumerate(L,1):
        suff = '_{}'.format(i)
        for hit in island: hit['SSEQID'] += suff
    return L
示例#4
0
 def prevent_friendly_collisions(self):
     """
     Ensure objective locations of same team players are spaced.
     """
     # Change objectives to pointing just in front of player, rather than
     # potentially a long way away.
     for p in self.players.values():
         angle = math.atan2(p.y_objective - p.y, p.x_objective - p.x)
         xadd, yadd = utils.components(p.top_speed * self.dt, angle)
         p.x_objective = p.x + xadd
         p.y_objective = p.y + yadd
     for thisP, thatP in itertools.combinations(self.players.values(), 2):
         if thisP.state == 0 or thatP.state == 0:
             continue  # Prone players don't count
         elif thisP.team != thatP.team:
             continue  # Different teams, probably WANT to collide...
         else:
             dist = np.sqrt( (thisP.x_objective-thatP.x_objective)**2 +\
                                 (thisP.y_objective-thatP.y_objective)**2 )\
                                 - thisP.size - thatP.size
             if dist < 0:
                 # We need to adjust the objectives.
                 # Find mid-point of current positions
                 cx = (thisP.x + thatP.x) / 2.
                 cy = (thisP.y + thatP.y) / 2.
                 # Find mid-point of objectives
                 ox = (thisP.x_objective + thatP.x_objective) / 2.
                 oy = (thisP.y_objective + thatP.y_objective) / 2.
                 # Find angle of line between two objectives.
                 hpi = 2 * math.atan(1.)
                 angle = math.atan2(cy - oy, cx - ox)
                 # Find angle of p.b. of this line
                 pb_angle = -1 / angle
                 # Project along the p.b. line enough to seperate the two objectives
                 pdist = -dist / 2.
                 thisx_delta, thisy_delta = utils.components(
                     pdist, pb_angle)
                 thatx_delta, thaty_delta = utils.components(
                     pdist, pb_angle + hpi)
                 thisP.x_objective += thisx_delta
                 thisP.y_objective += thisy_delta
                 thatP.x_objective += thatx_delta
                 thatP.y_objective += thaty_delta
示例#5
0
    def project_move(self, acc_angle):
        """
        Projects player one tick by applying max acceleration at the given angle.
        
        Returns
        -------
        Tuple of the projected phase (x,y, angle, speed) 
        """
        vx, vy = utils.components(self.current_speed, self.angle)
        ax, ay = utils.components(self.acc * self.layout.dt, acc_angle)
        vx_new, vy_new = (vx + ax, vy + ay)

        angle_new = math.atan2(vy_new, vx_new)
        speed_new = min(np.sqrt(vx_new ** 2 + vy_new ** 2), self.top_speed)

        # Speed limited components
        vx_new, vy_new = utils.components(speed_new, angle_new)

        return (self.x + vx_new * self.layout.dt, self.y + vy_new * self.layout.dt, angle_new, speed_new)
示例#6
0
    def project_move(self,acc_angle):
        """
        Projects player one tick by applying max acceleration at the given angle.
        
        Returns
        -------
        Tuple of the projected phase (x,y, angle, speed) 
        """
        vx, vy = utils.components(self.current_speed,self.angle)
        ax, ay =  utils.components(self.acc*self.layout.dt,acc_angle)
        vx_new, vy_new = (vx + ax,vy + ay)

        angle_new = math.atan2(vy_new,vx_new)
        speed_new = min(np.sqrt( vx_new**2 + vy_new**2),self.top_speed)
        
        # Speed limited components
        vx_new, vy_new = utils.components(speed_new,angle_new)

        return  (self.x + vx_new*self.layout.dt, self.y + vy_new*self.layout.dt, angle_new, speed_new)
示例#7
0
    def unproject_move(self, acc_angle):
        """
        Reverses the effect of a projection at the specified angle.
        
        Returns
        -------
        Tuple of the projected phase (x,y, angle, speed) 
        """
        hpi = 2 * math.atan(1.0)
        vx, vy = utils.components(self.current_speed, self.angle + hpi)
        ax, ay = utils.components(self.acc * self.layout.dt, acc_angle + hpi)
        vx_new, vy_new = (vx + ax, vy + ay)

        angle_new = math.atan2(vy_new, vx_new)
        speed_new = min(np.sqrt(vx_new ** 2 + vy_new ** 2), self.top_speed)

        # Speed limited components
        vx_new, vy_new = utils.components(speed_new, angle_new)

        return (self.x + vx_new, self.y + vy_new, angle_new, speed_new)
示例#8
0
    def unproject_move(self,acc_angle):
        """
        Reverses the effect of a projection at the specified angle.
        
        Returns
        -------
        Tuple of the projected phase (x,y, angle, speed) 
        """
        hpi = 2*math.atan(1.)
        vx, vy = utils.components(self.current_speed,self.angle+hpi)
        ax, ay =  utils.components(self.acc*self.layout.dt,acc_angle+hpi)
        vx_new, vy_new = (vx + ax,vy + ay)

        angle_new = math.atan2(vy_new,vx_new)
        speed_new = min(np.sqrt( vx_new**2 + vy_new**2),self.top_speed)
        
        # Speed limited components
        vx_new, vy_new = utils.components(speed_new,angle_new)

        return  (self.x + vx_new, self.y + vy_new, angle_new, speed_new)
示例#9
0
 def prevent_friendly_collisions(self):
     """
     Ensure objective locations of same team players are spaced.
     """
     # Change objectives to pointing just in front of player, rather than
     # potentially a long way away.
     for p in self.players.values():
         angle = math.atan2(p.y_objective-p.y,p.x_objective-p.x)
         xadd, yadd = utils.components(p.top_speed*self.dt,angle)
         p.x_objective = p.x + xadd
         p.y_objective = p.y + yadd
     for thisP, thatP in itertools.combinations(self.players.values(), 2):
         if thisP.state == 0 or thatP.state == 0:
             continue # Prone players don't count
         elif thisP.team != thatP.team:
             continue # Different teams, probably WANT to collide...
         else:
             dist = np.sqrt( (thisP.x_objective-thatP.x_objective)**2 +\
                                 (thisP.y_objective-thatP.y_objective)**2 )\
                                 - thisP.size - thatP.size
             if dist < 0:
                 # We need to adjust the objectives.
                 # Find mid-point of current positions
                 cx = (thisP.x + thatP.x)/2.
                 cy = (thisP.y + thatP.y)/2.
                 # Find mid-point of objectives
                 ox = (thisP.x_objective + thatP.x_objective)/2.
                 oy = (thisP.y_objective + thatP.y_objective)/2.
                 # Find angle of line between two objectives.
                 hpi=2*math.atan(1.)
                 angle = math.atan2(cy-oy,cx-ox)
                 # Find angle of p.b. of this line
                 pb_angle = -1/angle
                 # Project along the p.b. line enough to seperate the two objectives
                 pdist = -dist/2.
                 thisx_delta, thisy_delta =  utils.components(pdist,pb_angle)
                 thatx_delta, thaty_delta =  utils.components(pdist,pb_angle+hpi)
                 thisP.x_objective += thisx_delta
                 thisP.y_objective += thisy_delta
                 thatP.x_objective += thatx_delta
                 thatP.y_objective += thaty_delta
示例#10
0
 def launch(self,elv,power,target_x,target_y):
     """
     Initialise throw with given angle and power from current ball position.
     """
     self.carrier=0
     self.z=2. # Assume passes start 2m off the ground.
     self.angle = math.atan2(target_y-self.y,target_x-self.x)
     self.speed = power*math.cos(elv)
     self.vspeed = power*math.sin(elv)
     self.flying = True
     dist = power**2 * math.sin(2.*elv)/self.g
     dx, dy = utils.components(dist,self.angle)
     self.xland = self.x + dx
     self.yland = self.y + dy
示例#11
0
 def launch(self, elv, power, target_x, target_y):
     """
     Initialise throw with given angle and power from current ball position.
     """
     self.carrier = 0
     self.z = 2.  # Assume passes start 2m off the ground.
     self.angle = math.atan2(target_y - self.y, target_x - self.x)
     self.speed = power * math.cos(elv)
     self.vspeed = power * math.sin(elv)
     self.flying = True
     dist = power**2 * math.sin(2. * elv) / self.g
     dx, dy = utils.components(dist, self.angle)
     self.xland = self.x + dx
     self.yland = self.y + dy
示例#12
0
def classifyrecords(seq,overlap):
    '''Takes a sequence of blast hits; picks out as 'nests' sequences of
    adjacent hits that overlap with a neighbor. Returns a pair of lists:
    the first contains records that were not part of a nest, and the second
    contains nests, i.e.  lists of the resulting 'extracted' hits from that
    nest.
    
    This function does not stratify those nests - for use in the final
    algorithm, they must go through the function stratify().
    '''
    sings,nests = utils.bifilter(
                     utils.components(seq,lambda x,y: s_overlap(x,y)>=overlap),
                     key=lambda x: len(x)==1)
    return (map(_itemget(0),sings),nests)
        def featurize(self):
            features = [
            ]  # list of np.array[nfeatures, xsize, ysize] or np.array[xsize, ysize]
            feature_names = []  # list of strings

            deltas = (-1, 0, 1)
            neigh = np.zeros((len(deltas)**2, *self.in_image.shape),
                             dtype=np.int8)
            for ox, oy in product(*map(range, self.in_image.shape)):
                # absolute neighbourhood color
                for k, (i, j) in enumerate(product(*[deltas] * 2)):
                    x = (ox + i)  # % self.in_image.shape[0]
                    y = (oy + j)  # % self.in_image.shape[1]
                    if 0 <= x < self.in_image.shape[
                            0] and 0 <= y < self.in_image.shape[1]:
                        neigh[k, ox, oy] = self.in_image[x, y]
                    else:
                        neigh[k, ox, oy] = 0
                    k += 1
            features.append(neigh)
            feature_names.extend(
                ['Neigh{}'.format(i) for i in product(*[deltas] * 2)])

            # unique = np.zeros((3, *self.in_image.shape), dtype=np.int8) # 3 because row, column, neighborhood
            # unique_names = []
            # for ox, oy in product(*map(range, self.in_image.shape)):
            #     # absolute neighbourhood color
            #     unique[0, ox, oy] = len(np.unique(self.in_image[:, oy]))
            #     unique[1, ox, oy] = len(np.unique(self.in_image[ox, :]))
            #     unique[2, ox, oy] = len(np.unique(self.in_image[max(ox - 1, 0) : ox + 2,
            #                                                     max(oy - 1, 0) : oy + 2]))
            # features.append(unique)
            # feature_names.extend(['UniqueInRow', 'UniqueInCol', 'UniqueInNeigh'])

            if self.task_featurizer is None or self.task_featurizer.use_rot_90:
                rotations = (False, True)
            else:
                rotations = (False, )

            for use_rot in rotations:
                sym = np.zeros((4, *self.in_image.shape), dtype=np.int8)
                for ox, oy in product(*map(range, self.in_image.shape)):
                    for k, (i, j) in enumerate(product(*([[0, 1]] * 2))):
                        x, y = ox, oy
                        if i:
                            x = self.in_image.shape[0] - x - 1
                        if j:
                            y = self.in_image.shape[1] - y - 1
                        if use_rot:
                            if y >= self.in_image.shape[
                                    0] or x >= self.in_image.shape[1]:
                                sym[k, ox, oy] = -1
                            else:
                                sym[k, ox, oy] = self.in_image[y, x]
                        else:
                            sym[k, ox, oy] = self.in_image[x, y]
                features.append(sym)
                feature_names.extend(
                    f'SymRot90_{i}{j}' if use_rot else f'Sym_{i}{j}'
                    for i, j in product(*([[0, 1]] * 2)))

            deltas = [[1, 0], [-1, 0], [0, 1], [0, -1], [1, 1], [-1, -1],
                      [-1, 1], [1, -1]]
            for di, d in enumerate(deltas):
                col_opts = [0, None]
                targets = [raycast(self.in_image, d, col) for col in col_opts]
                for t1, col in zip(targets, col_opts):
                    cols, dists = Offset.get_cols_dists(t1, self.in_image)
                    features.extend([dists % 2, dists % 3])
                    dists = dists.astype(np.float32)
                    features.extend([cols, dists])
                    ray_type_label = 'Same' if col is None else 'Notbg'
                    feature_names.extend([
                        f'RayCol{ray_type_label}_{d}_mod2',
                        f'RayCol{ray_type_label}_{d}_mod3'
                    ])
                    feature_names.extend([
                        f'RayCol{ray_type_label}_{d}',
                        f'RayDist{ray_type_label}_{d}'
                    ])
                    for t2, col2 in zip(targets, col_opts):
                        off = Offset.compose(t1, t2)

                        cols2, dists2 = Offset.get_cols_dists(
                            off, self.in_image)
                        dists2 = dists2.astype(np.float32)
                        features.extend([cols2, dists2 - dists])
                        ray_type_label2 = 'Same' if col2 is None else 'Notbg'
                        feature_names.extend([
                            f'RayCol{ray_type_label}_{ray_type_label2}_{d}',
                            f'RayDist{ray_type_label}_{ray_type_label2}_{d}'
                        ])

            sizes, borders = components(self.in_image)
            sizes = sizes.astype(np.float32)
            border_exclusive = ((borders == borders.sum(2, keepdims=True)) *
                                np.arange(1, COLORS + 1)).sum(2) - 1
            features.extend([sizes, border_exclusive])
            feature_names.extend(['ComponentSize', 'ComponentBorderExclusive'])

            features = np.concatenate(
                list(
                    map(
                        lambda x: (x if len(x.shape) == 3 else x.reshape(
                            (-1, *x.shape))).astype(object), features)))
            features = features.reshape(
                (features.shape[0], -1)).transpose([1, 0])
            return pd.DataFrame(features, columns=feature_names)
示例#14
0
    def fly_tick(self):
        " Iterate one flight tick "
        # Check for potential catchers
        # Assume we can only catch if z <= 2 metres.
        # TODO: Player heights and jumping??

        addx, addy = utils.components(self.speed*self.layout.dt,self.angle)

        if self.z <= 2:
            # Ball at catchable height
            # Eqn of ball travelling line as ax + bx + c = 0
            x2 = self.x + addx
            y2 = self.y + addy
            a = self.y - y2
            b = x2 - self.x
            c = (self.x - x2)*self.y + (y2 - self.y)*self.x
            midx = (self.x + x2)/2.
            midy = (self.y + y2)/2.
            dflight = self.speed*self.layout.dt
            def catch_score(p):
                # Returns postion along flight path of ball for given player
                # Returns None if the player can't catch ball from their position
                if not p.want_to_catch: 
                    return None
                dist = abs(a*p.x + b* p.y + c)/np.sqrt(a**2 + b**2)
                if dist > p.size: 
                    return None
                # Check the position is bracketted in the flight delta
                elif np.sqrt( (midx-p.x)**2 + (midy-p.y)**2) > dflight/2. + p.size:
                    return None
                else:
                    return np.sqrt((p.x-self.x)**2 + (p.y-self.y)**2)
            # TODO: At the moment, first eligble catcher automatically catches. Need to implement skill
            # based chance, constested catches, etc.    
            best_score=1000.
            pcatch=None
            for p in self.layout.players.values():
                s = catch_score(p)
                if s != None:
                    if s < best_score:
                        best_score=s
                        pcatch=p
            if pcatch != None:
                # Player had made catch
                print("caught it",pcatch.pid)
                self.carrier=pcatch.pid
                self.flying=False
                self.x = pcatch.x
                self.y = pcatch.y
                return
        
        self.x += addx
        self.y += addy
        # Check for out of bounds
        oob=False
        if self.x < 0:
            self.x = 0
            oob = True
        elif self.x > self.layout.xsize:
            self.x = self.layout.xsize
            oob = True
        if self.y < 0:
            self.y = 0
            oob = True
        elif self.y > self.layout.ysize:
            self.y = self.layout.ysize
            oob = True

        if oob:
            self.flying = False
            self.vspeed=0
            self.speed=0
            self.z=0
            self.xland=self.x
            self.yland=self.y
        else:
            self.vspeed += -self.g * self.layout.dt
            self.z += self.vspeed * self.layout.dt
            if self.z <= 0.:
                self.flying = False
示例#15
0
    def fly_tick(self):
        " Iterate one flight tick "
        # Check for potential catchers
        # Assume we can only catch if z <= 2 metres.
        # TODO: Player heights and jumping??

        addx, addy = utils.components(self.speed * self.layout.dt, self.angle)

        if self.z <= 2:
            # Ball at catchable height
            # Eqn of ball travelling line as ax + bx + c = 0
            x2 = self.x + addx
            y2 = self.y + addy
            a = self.y - y2
            b = x2 - self.x
            c = (self.x - x2) * self.y + (y2 - self.y) * self.x
            midx = (self.x + x2) / 2.
            midy = (self.y + y2) / 2.
            dflight = self.speed * self.layout.dt

            def catch_score(p):
                # Returns postion along flight path of ball for given player
                # Returns None if the player can't catch ball from their position
                if not p.want_to_catch:
                    return None
                dist = abs(a * p.x + b * p.y + c) / np.sqrt(a**2 + b**2)
                if dist > p.size:
                    return None
                # Check the position is bracketted in the flight delta
                elif np.sqrt((midx - p.x)**2 +
                             (midy - p.y)**2) > dflight / 2. + p.size:
                    return None
                else:
                    return np.sqrt((p.x - self.x)**2 + (p.y - self.y)**2)

            # TODO: At the moment, first eligble catcher automatically catches. Need to implement skill
            # based chance, constested catches, etc.
            best_score = 1000.
            pcatch = None
            for p in self.layout.players.values():
                s = catch_score(p)
                if s != None:
                    if s < best_score:
                        best_score = s
                        pcatch = p
            if pcatch != None:
                # Player had made catch
                print("caught it", pcatch.pid)
                self.carrier = pcatch.pid
                self.flying = False
                self.x = pcatch.x
                self.y = pcatch.y
                return

        self.x += addx
        self.y += addy
        # Check for out of bounds
        oob = False
        if self.x < 0:
            self.x = 0
            oob = True
        elif self.x > self.layout.xsize:
            self.x = self.layout.xsize
            oob = True
        if self.y < 0:
            self.y = 0
            oob = True
        elif self.y > self.layout.ysize:
            self.y = self.layout.ysize
            oob = True

        if oob:
            self.flying = False
            self.vspeed = 0
            self.speed = 0
            self.z = 0
            self.xland = self.x
            self.yland = self.y
        else:
            self.vspeed += -self.g * self.layout.dt
            self.z += self.vspeed * self.layout.dt
            if self.z <= 0.:
                self.flying = False