def genmoves(logfn, game):
    moves = {}
    past = {}
    lr = 0.4
    pf = 0.7
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, aO) in env.myid.iteritems():

            # weighted average of all previous moves
            if aI in past:
                aOr, aOc = aO
                pr, pc = past[aI]
                past[aI] = (aOr * lr + pr * (1.0 - lr),
                            aOc * lr + pc * (1.0 - lr))
            else:
                past[aI] = aO
            pr, pc = past[aI]

            # average of visible water
            water = env.digest('water', aN)
            wr = fsum(r for d2, (r, c) in water) / max(len(water), 1)
            wc = fsum(c for d2, (r, c) in water) / max(len(water), 1)

            # weighted average of water and move history
            target = (pr * pf + wr * (1.0 - pf),
                      pc * pf + wc * (1.0 - pf))
            c = choice(am.naive_dir(target, aN))
            if c != '=':
                moves[aI] = c
        moves = env.supplement(moves)
Example #2
0
def genmoves(logfn, game):
    battle = game['attackradius']
    holddist = (battle + 2) ** 2
    moves = {}
    rec = {}
    while True:
        env = yield moves
        moves = {}
        rec = {}

        for e in env.enemyant:
            mine = env.digest('myant', e)
            while mine:
                d2, m = mine.pop()
                aN = env.wrap(m)
                if d2 > holddist and env.ray(m, e):
                    if aN not in rec:
                        rec[aN] = []
                    v1, v2 = am.naive_dir(m, e)
                    rec[aN].append(v1 if random() < 0.65 else v2)

        for aI, (aN, _) in env.myid.iteritems():
            if aN in rec:
                moves[aI] = choice(rec[aN])

        moves = env.supplement(moves)
Example #3
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, _) in env.myid.iteritems():
            goals = env.digest('myant', aN)
            if goals:
                d2, gloc = goals[0]
                if 2 ** 2 < d2 < 4 ** 2 and env.ray(aN, gloc):
                    moves[aI] = am.naive_dir(aN, gloc)

        moves = env.supplement(moves)
Example #4
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, aO) in env.myid.iteritems():
            localfood = env.digest('food', aN)
            if env.food and not localfood:
                sumr = math.fsum(r for r, c in env.food)
                sumc = math.fsum(c for r, c in env.food)
                target = sumr / len(env.food), sumc / len(env.food)
                moves[aI] = random.choice(antmath.naive_dir(aN, target))

        moves = env.supplement(moves)
Example #5
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, _) in env.myid.iteritems():
            food = env.digest('food', aN)

            while food:
                d2, f = food.pop(0)
                if env.ray(aN, f):
                    v1, v2 = am.naive_dir(aN, f)
                    moves[aI] = v1 if random() < 0.75 else v2
                    break

        moves = env.supplement(moves)
Example #6
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, aO) in env.myid.iteritems():
            ants = [gloc for d2, gloc in \
                    env.digest('myant', aN) + env.digest('enemyant', aN) \
                    if d2 > 2.5 ** 2] # don't consider your clump
            if ants:
                sumr = fsum(r for r, c in ants)
                sumc = fsum(c for r, c in ants)
                target = sumr / len(ants), sumc / len(ants)
                v1, v2 = am.naive_dir(target, aN)
                moves[aI] = v1 if random() < 0.75 else v2

        moves = env.supplement(moves)
def genmoves(logfn, game):
    battle = game['attackradius']
    moveback = (battle + 2) ** 2
    moves = {} # id --> vect (ant ids to vector distributions)
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, _) in env.myid.iteritems():
            goals = env.digest('enemyant', aN)
            if goals:
                d2, target = goals[0]
                if d2 <= moveback and env.ray(aN, target):
                        v1, v2 = am.naive_dir(target, aN)
                        # favor an indirect retreat to retain ground
                        moves[aI] = v1 if random() < 0.25 else v2

        moves = env.supplement(moves)
Example #8
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for f in env.food.iterkeys():
            ants = env.digest('myant', f)

            while ants:
                d2, a = ants.pop(0)
                aN = env.wrap(a)
                aI, aO = env.myant[aN]
                if aI not in moves and env.ray(a, f):
                    v1, v2 = am.naive_dir(a, f)
                    moves[aI] = v1 if random() < 0.75 else v2
                    break

        moves = env.supplement(moves)
Example #9
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, _) in env.myid.iteritems():
            hill = env.digest('myhill', aN)
            enemy = env.digest('enemyant', aN)
            if hill and enemy:
                hill = hill[0][1]
                enemy = enemy[0][1]
                if env.ray(aN, enemy):
                    hr, hc = hill
                    er, ec = enemy
                    target = (hr + er) / 2.0, (hc + ec) / 2.0
                    if env.ray(aN, target):
                        v1, v2 = am.naive_dir(aN, target)
                        moves[aI] = v1 if random() < 0.75 else v2

        moves = env.supplement(moves)
Example #10
0
    def ray(self, origin, target):
        '''Is there a direct path from the origin to the target?'''
        origin = self.wrap(self.int(origin))
        target = self.unwrap(origin, self.int(target))

        # return a stored answer
        try:
            return self.rays[origin, target]
        except KeyError:
            pass

        # trivial
        if origin == target:
            return True

        # don't check long paths
        if self.dist2(origin, target) > self.rad2:
            return False

        # check path
        o = [origin]
        t = [target]
        # this loop has a bug and sometimes ran forever as a while loop
        # changed it to a for loop because the contest end was near!
        for _ in xrange(150):
            v, _ = am.naive_dir(o[-1], t[-1])
            o.append(self.wrap(am.displace_loc(v, o[-1])))
            t.append(self.unwrap(o[-1], t[-1]))
            if o[-1] == t[-1]:
                break

        # did the path pass through water?
        if self.water.viewkeys() & o:
            return False

        # remember the result
        for co, ct in itertools.izip(o[:-1], t[:-1]):
            self.rays[co, ct] = True

        return self.rays[origin, target]
Example #11
0
def genmoves(logfn, game):
    moves = {}
    arounds = {}
    while True:
        env = yield moves
        moves = {}

        if not arounds:
            for h in env.myhill:
                arounds[h] = set()
                for n in am.neighbors(h):
                    arounds[h] = arounds[h].union(am.eightsquare(n))
                arounds[h] = arounds[h].difference([h] + am.neighbors(h))

        for aI, (aN, _) in env.myid.iteritems():
            hills = env.digest('myhill', aN)
            if hills:
                d2, h = hills[0]
                if aN == h or aN in am.neighbors(h):
                    moves[aI] = choice('NESW')
                elif aN in arounds[h]:
                    moves[aI] = choice(am.naive_dir(h, aN))

        moves = env.supplement(moves)
Example #12
0
def genmoves(logfn, game):
    moves = {}
    while True:
        env = yield moves
        moves = {}

        for aI, (aN, _) in env.myid.iteritems():
            if aI not in moves:
                friends = env.digest('myant', aN)
                enemies = env.digest('enemyant', aN)
                if friends and enemies:
                    t2, target = enemies[0]
                    if env.ray(aN, target):
                        enemies = env.digest('enemyant', target)[1:]
                        myclump = [env.myant[f][0] for d2, f in friends \
                                   if d2 < 3 ** 2 and f in env.myant]
                        enclump = [e for d2, e in enemies \
                                   if d2 < 3 ** 2] + [target]
                        if len(myclump) > len(enclump):
                            v1, v2 = am.naive_dir(aN, target)
                            vect = v1 if random() < 0.75 else v2
                            for aI in myclump + [aI]:
                                moves[aI] = vect
        moves = env.supplement(moves)
Example #13
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