示例#1
0
    def think(self, dirt, food, enemyhill, enemyant, myhill, myant, mydead):
        '''Return a dict with the keys of myant mapped to lists of NESW=.'''
        # build a list of goals
        goaltime = DateTime.now()
        # active goals
        active = {}
        active.update({loc:self.ENEMYHILL for loc in enemyhill})
        if len(myant) > 1.35 * len(enemyant):
            active.update({loc:self.ENEMYANTBATTLE for loc in enemyant})
        else:
            active.update({loc:self.ENEMYANT for loc in enemyant})
        # log about active goals
        self.logfn('\nactive goals: {}'.format(active)) if self.logfn else None
        # passive goals
        passive = {}
        if len(myant) < 125:
            passive.update({loc:self.FOOD for loc in food})
            # increase age of passive goals; keep ages of old and visible ones
            self.age = {loc:age + 1 for loc, age in self.age.iteritems() \
                        if age > self.MAXAGE or loc in passive}
            # track age new passive goals
            new = {loc:0 for loc in passive}
            new.update(self.age)
            self.age = new
        # filter passive goals which are old
        passive = {loc:rad for loc, rad in passive.iteritems() \
                   if loc in self.age and self.age[loc] <= self.MAXAGE}
        # if there are enemies near a hill, protect the hill
        if any(any(antmath.nearest_unwrapped_loc(hill, self.size, e)[0] \
                   <= self.PERIMETER for e in enemyant) \
               for hill in myhill):
            passive.update({loc:self.MYHILL for loc in myhill})
        # log about passive goals
        self.logfn('\npassive goals: {}\nages: {}'.format(passive, self.age)
                   ) if self.logfn else None
        # combine goal lists, giving active goals priority
        passive.update(active)
        goals = passive
        # log about goal descision time
        self.logfn('goal time: {}ms'.format(
            (DateTime.now() - goaltime).total_seconds() * 1000.0)
            ) if self.logfn else None


        # assign moves to ants
        if goals:

            if len(goals) > 1:
                # divide ants by location into len(goals) groups
                clustime = DateTime.now()
                squads = self.cluster(1, goals.keys(), myant.keys())
                assert sum(map(len, squads.values())) == len(myant)
                self.logfn('cluster: {}ms'.format(
                    (DateTime.now() - clustime).total_seconds() * 1000.0)
                    ) if self.logfn else None
            else:
                # all ants are in one supercluster
                self.logfn('supercluster') if self.logfn else None
                rows, cols = zip(*myant.keys())
                r = float(sum(rows)) / len(myant)
                c = float(sum(cols)) / len(myant)
                squads = {(r, c): myant.keys()}

            # assign each squad the closest goal
            for sM, sA in squads.iteritems():
                dist, gloc = min([self.unwrapped_dir(sM, loc) for loc in goals])
                gradmin, gradmax = goals[self.wrap(gloc)]
                for aN in sA:
                    # make ants keep the right distance from goals
                    vect = antmath.naive_dir(aN, gloc)
                    dist = antmath.distance2(aN, gloc)
                    if dist > gradmax and dist < 7 * self.g['viewradius2']:
                        myant[aN] = vect
                        random.shuffle(myant[aN]) if gradmax != gradmin else None
                        myant[aN] += [antmath.reverse_dir(v) for v in vect]
                    elif dist < gradmin:
                        myant[aN] = [antmath.reverse_dir(v) for v in vect]
                        random.shuffle(myant[aN]) if gradmax != gradmin else None
                        myant[aN] += vect
                    else:
                        myant[aN] = self.v[:]
                        random.shuffle(myant[aN])

        else:

            # move each ant individually randomly
            self.logfn('brownian') if self.logfn else None
            for aN, (aI, aO) in myant.iteritems():
                random.shuffle(self.v)
                myant[aN] = self.v[:]

        return myant
示例#2
0
 def unwrap(self, a, b):
     if self.not_near_edge(a):
         return b
     else:
         d2, unwr = am.nearest_unwrapped_loc(a, self.size, b)
         return unwr