"""This is leftover from trying different scoring schemes"""
- # return self.score_exponential()
def get_my_on(self, idx, srcs=None):
+ """Find the number of ships I can land on idx"""
return find_number_on_available(self.pw, self.my_available, idx, self.max_turn,
def get_en_on(self, idx):
+ """Find the number of ships the enemy can land on idx"""
return find_number_on_available(self.pw, self.en_available, idx,
+ def find_neutrals(self, neutrals):
+ Find all the neutrals I can take.
- def find_neutrals(self, neutrals):
+ This is called with a list of all the planets that are neutral at
+ the end of the simulation.
+ Try to see if I can take it and earn back the ships before the
+ enemy can take it back.
+ The rest was hacked together, because I had a hard time with being
+ too aggressive or too passive.
+ Return a list of potential targets.
debug("looking at neutral: %d", idx)
rate = self.pw.planets[idx].growth_rate
- # BUG HERE ... sometimes takes neutrals too early.
for my_t in xrange(1,self.max_turn-1):
+ # never take on a turn that the enemy has a fleet landing.
if fleets[my_t] > 0: continue
if my_on[my_t] > future[my_t+1]:
needed = future[my_t+1]
- num = needed + 1
# TODO: account for sending more! my_on[my_t]
+ # cannot take
+ # Check if the enemy can take it, without me reinforcing.
+ # Find the first turn it could happen.
for en_t in xrange(my_t):
+ # enemy can land ships before me. so don't bother.
if en_on[en_t] > (en_t - my_t) * rate + 1:
+ # cost is confusing, but negative is good.
+ # -n means I have made n ships on the deal.
cost = num + (my_t - en_t) * rate
+ # find the first turn I can take. This is more useful
+ # in the enemy functions.
for t in xrange(self.max_turn):
# harder neutral. time to think through this a little more.
for earliest_enemy_landing in xrange(self.max_turn):
if en_on[earliest_enemy_landing] > 0:
- # Maybe only look at things we can beat the enemy to by
+ # only take if I am at least take_limit turns closer to the neutral
+ # than the enemy. Now that I am typing this after the finals have started,
+ # I realize this is why I am losing some games.
- delay = max(int(ceil(1.0 * needed / rate)), 1)
- # debug("delay is %d, needed %d, rate %d", delay, needed, rate)
for i in xrange(1, take_limit+1):
if my_t + i >= self.max_turn:
- debug("hard neutral: my_t: %d, diff: %d, take_turn %d, delay: %d, rate:%d",
- my_t, diff, my_t + i, delay, rate)
+ debug("hard neutral: my_t: %d, diff: %d, take_turn %d, rate:%d",
+ my_t, diff, my_t + i, rate)
- def find_defend_at_last_moment(self, mine):
- t = self.run_defend(idx)
def find_enemies(self, enemies, offset=0,all_in=True):
+ Calculate attacking planets that will be owned
+ by the enemy unless I do something about it.
+ # if not all_in, limit firing planets to the planets
+ # closest to the enemy. There is a magic number down here too...
+ # dict of src planets for each enemy.
srcs = dict([(en, None) for en in enemies])
mine = [p for p in self.pidx
if self.futures[p][-1] == 1 or
debug("enemies: %s", enemies)
+ # doh. This would be easier with the neighbors list.
tmp = [(m,find_closest(self.pw, m, enemies)) for m in mine]
tmp = [(m, d) for (m, (junk,d)) in tmp]
debug("closest: %s", closest)
+ # only fire from the closest of my planets, plus any other
+ # ones within a small radius. This was an attempt
+ # to prevent cross screen shots.
srcs[idx] = [m for m in mine
if self.pw.planets[m].dists[idx] < closest[m] + 5]
+ # Try to calculate for each enemy, accumulate the results.
t = self.run_enemy(idx,offset,srcs[idx])
def run_enemy(self, idx, offset, srcs):
+ Calculate if an enemy planet is a possible target, and
+ if so, how many to send.
+ Offset is the number of turns I get to move before the enemy. This
+ used to be useful. Basically, 0 considers that the enemy launches
+ a defense the same turn I attack. 1 means that they don't defend
debug("looking at enemy: %d", idx)
rate = self.pw.planets[idx].growth_rate
fleets = self.fleets[idx]
for turn in xrange(1, self.max_turn-1):
# don't consider when the enemy doesn't own it.
if future[turn+1] != 2: continue
+ if turn < offset: continue
- # assume they delay a turn to fire.
- # we will deal with possible launches later.
+ # need as many ships as the enemy could land here on turn - offset
+ needed = en_on[turn - offset]
- if turn < offset: continue
- needed = en_on[turn - offset]
+ # Enemy owns, so need to add the number of ships + 1
+ # this should never happen I guess...
+ # If I cannot take, keep looping.
if my_on[turn] < needed: continue
+ # If I can take, figure out how quickly I could take it.
while my_on[dist-1] >= needed:
if my_on[dist] >= needed:
+ # This is one of the things that worked well.
+ # If I already own the planet, go ahead and send now.
+ # If not, delay firing until the last second. This
+ # helps because I can avoid sending more than needed,.
# find the first turn to strike
# - never when the planet is neutral
# - the first time I own it
# - else when I can take it.
for first_turn in xrange(1, turn):
if future[first_turn] == 1:
+ Calculate the shots needed to attack target.
+ Target includes some information needed here:
+ - turn is the turn we want to land by
+ - first_turn is the first turn it is ok to land.
+ Loop through all the the planets from closest to farthest,
+ and make orders to launch from each planet on each turn
+ until the number needed has been launched. Mark
+ launched ships off from the available list.
debug("trying to attack: %s", target)
dists = [(d,p) for (d,p) in self.pw.planets[target["planet"]].neighbors
debug("planet: %d, distance: %d, av: %s", p, d, self.my_available[p])
first_turn = target["first_turn"]