Пример #1
0
 def play(self, turn, pid, planets, fleets):
     my_planets, their_planets, _ = aggro_partition(pid, planets)
     destination = min(their_planets, key=get_ships)
     orders = []
     for planet in my_planets:
         orders.append(Order(planet, destination, planet.ships * 0.75))
     return orders
Пример #2
0
def strong_to_weak(turn, pid, planets, fleets, train):
    my_planets, their_planets, _ = aggro_partition(pid, planets)
    if len(my_planets) == 0 or len(their_planets) == 0:
        return []
    my_strongest = max(my_planets, key=get_ships)
    their_weakest = min(their_planets, key=get_ships)
    return [Order(my_strongest, their_weakest, my_strongest.ships * 0.75)]
Пример #3
0
    def play(self, turn, pid, planets, fleets):
        def mine(x):
            return x.owner == pid

        my_planets, other_planets = partition(mine, planets)
        source = random.choice(my_planets)
        destination = random.choice(other_planets)
        return [Order(source, destination, source.ships / 2)]
Пример #4
0
def all_to_weak(turn, pid, planets, fleets, train):
    my_planets, their_planets, _ = aggro_partition(pid, planets)
    if len(my_planets) == 0 or len(their_planets) == 0:
        return []
    destination = min(their_planets, key=get_ships)
    orders = []
    for planet in my_planets:
        orders.append(Order(planet, destination, planet.ships * 0.75))
    return orders
Пример #5
0
 def __call__(self, turn, pid, planets, fleets, train):
     def mine(x):
         return x.owner == pid
     my_planets, other_planets = partition(mine, planets)
     if len(my_planets) == 0 or len(other_planets) == 0:
       return []
     source = random.choice(my_planets)
     destination = random.choice(other_planets)
     return [Order(source, destination, source.ships / 2)]
Пример #6
0
    def play(self, turn, pid, planets, fleets):
        my_planets, their_planets, neutral_planets = aggro_partition(
            pid, planets)
        other_planets = their_planets + neutral_planets
        their_weakest = min(their_planets, key=get_ships)
        my_total = sum(map(get_ships, my_planets))
        destination = min(their_planets, key=get_ships)
        orders = []
        for planet in my_planets:
            if random.random() < 0.5:

                def dist_to(other_planet):
                    return turn_dist(planet, other_planet)

                closest = min(other_planets, key=dist_to)
                orders.append(Order(planet, closest, planet.ships * 0.75))
            else:
                orders.append(Order(planet, their_weakest,
                                    planet.ships * 0.75))
        return orders
Пример #7
0
def gships(pid, planet_data, cluster_data, t_dist, t_max, data, turn, train,
           planets, fleets, game_ratios):
    '''
    Calculates the number of ships the cluster needs to send in order to capture/help the planet
    @param pid: player id
    @type: int
    @param planet_data: the planet to send the ships to with data
                        e.g. planet_data['planet']  -  return the ImmutablePlanet object
    @type: {'planet' : p, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0}
    @param cluster_data: Combined data of all planets that belong to this cluster
                         e.g. cluster_data['cluster']  -  return the cluster of [ImmutablePlanet] objects
    @type: {'cluster' : cluster, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0}
    @param t_dist: turn distance between planet and cluster (approximation / take max)
    @type: int
    @param t_max: max turn distance on the map
    @type: int
    @param data: dictionary of all planets information. Each inner dictionary value is accesed using a planet as key
                 e.g.
                 data[key][planet.id][t_max]  -  key = 'value' | 'value_d'
                 data[key][planet.id]         -  key = 'influence_' + 'f' | 'e' | 'f_d' | 'e_d'
    @type: {'value' : {}, 'value_d' : {}, 'influence_f' : {}, 'influence_e' : {}, 'influence_f_d' : {}, 'influence_e_d' : {}}
    '''
    # input data sanity check
    assert isinstance(pid, int)
    assert isinstance(planet_data, dict)
    assert isinstance(cluster_data, dict)
    assert isinstance(t_dist, int)
    assert isinstance(t_max, int)
    assert isinstance(data, dict)
    # --------------------------------------------------------------------

    orders = []
    ships_needed_to_send = data['value'][planet_data['planet'].id][t_dist]
    all_ships = 0.0
    p_ships = {}
    for p in cluster_data['cluster']:
        all_ships += p.ships
        p_ships[p] = p.ships
    if all_ships < ships_needed_to_send:
        return orders

    percentage = ships_needed_to_send / all_ships

    for p in cluster_data['cluster']:
        orders.append(
            Order(p, planet_data['planet'],
                  round(p.ships * percentage) + 1))

    # we need to return an array of Order objects. The array can be empty.
    return orders
Пример #8
0
    def GetOrderToPointToRootStateObjects(self, order):
        src = des = None

        for ps in self.rootplanets:
            if order.source.id == ps.id:
                src = ps

        for pd in self.rootplanets:
            if order.destination.id == pd.id:
                des = pd

        assert src is not None and des is not None, "Can't find planet in GetOrderToPointToRootStateObjects()"

        #self.PrintRootUniverse()
        #print Order(src, des, order.ships)

        return Order(src, des, order.ships)
Пример #9
0
    def __call__(self, turn, pid, planets, fleets):
        self.pid = pid
        my_planets, other_planets = partition(lambda x: x.owner == pid,
                                              planets)

        sf = self.make_state_features(planets, fleets)
        self.last_state = [0] * (8 + 2 * DQN.buckets)

        if len(my_planets) == 0 or len(other_planets) == 0:
            return []

        if random.random() < self.eps or len(DQN.memory) < DQN.mem_size:
            src, dst = random.choice(my_planets), random.choice(planets)
        else:
            src, dst = self.make_smart_move(planets, fleets, sf)

        # if the state was not 'no source'
        self.last_state = self.make_features(src, dst, *sf)

        if src == dst:
            return []
        return [Order(src, dst, src.ships / 2)]
Пример #10
0
    def GetMoves(self):
        """ Get all possible moves from this state.
        """
        def mine(x):
            return x.owner == self.pid

        my_planets, other_planets = partition(mine, self.planets)

        res = []

        for src in my_planets:
            for dst in other_planets:
                if dst.ships < src.ships / 2:
                    res.append(Order(src, dst, src.ships / 2))

        if len(res) == 0 and len(my_planets) > 0 and len(other_planets) > 0:
            res.append(None)


##            src = max(my_planets, key=get_ships)
##            dst = min(other_planets, key=get_ships)
##            res.append(Order(src, dst, src.ships / 2))

        return res
Пример #11
0
def select_move(pid, planets, fleets):

    assert pid == 1 or pid == 2, "what?"

    my_planets, other_planets = partition(lambda x: x.owner == pid, planets)
    your_planets, neutral_planets = partition(lambda x: x.owner != 0,
                                              other_planets)

    if len(my_planets) == 0:
        return []


#  for i,p in enumerate(planets):
#    print "PLANET: ", i, p.id, "x=", p.x, "y=", p.y, p.owner, p.ships

# weights
    wv = [
        +3.0,  # src ships
        -1.25,  # dest ships
        +0.0,  # my ships total
        +0.0,  # your ships total
        +0.0,  # neutral ship total
        +0.0,  # my total growth
        +0.0,  # your total growth
        -6.0,  # distance , was -1.5
        +0.0,  # I own dest planet
        +30.0,  # opponent owns dest planet
        +5,  # neutral owns dest planet    
        -1.0,  # src growth
        +2.0,  # dest growth
    ]

    # incoming ship buckets
    buckets = 10

    weight_bucket = 2
    # src incoming ship buckets
    for i in range(buckets):
        wv.append(-(i + 1) * weight_bucket)
        #wv.append(weight_bucket/(1+i))
        #wv.append(-i*0.5)

    # dst incoming ship buckets
    for i in range(buckets):
        wv.append(-(i + 1) * weight_bucket)
        #wv.append(weight_bucket/(1+i))
        #wv.append(-i*0.5)

    my_ships_total = 0
    your_ships_total = 0
    neutral_ships_total = 0
    my_growth = 0
    your_growth = 0

    # tally ships and growth

    for p in planets:
        if p.id == 0:
            neutral_ships_total += p.ships
        elif p.id == pid:
            my_growth += p.growth
            my_ships_total += p.ships
        else:
            your_ships_total += p.ships
            your_growth += p.growth

    # compute maximal distance between planets

    max_dist = 0
    for src in planets:
        for dst in planets:
            d = dist(src, dst)
            if d > max_dist:
                max_dist = d

    # incoming ship bucket matrix
    # incoming friendly ships count 1, incoming enemy ships count -1
    # for each planet we tally incoming ship for time buckets 0..buckets-1
    # where buckets refers to the maximum distance on the map
    tally = numpy.zeros((len(planets), buckets))

    for f in fleets:
        # d = remaining distance
        d = dist(planets[f.source], planets[f.destination]) * \
            (f.remaining_turns/f.total_turns)
        b = d / max_dist * buckets
        if b >= buckets:
            b = buckets - 1
        tally[f.destination, b] += f.ships * (1 if f.owner == pid else -1)

    best_sum = float("-inf")
    best_orders = []

    for src in my_planets:
        for dst in planets:
            if src == dst:
                continue

            fv = []
            # planet totals
            fv.append(src.ships)
            fv.append(dst.ships)

            # ship total
            fv.append(my_ships_total)
            fv.append(your_ships_total)
            fv.append(neutral_ships_total)

            # growth
            fv.append(my_growth)
            fv.append(your_growth)

            # distance
            d = dist(src, dst)
            #print "PLANET DIST: ", src, dst
            #print "DIST: ", src.id, dst.id, d
            fv.append(d)

            # I own dst planet
            fv.append(1 if dst.id == pid else 0)
            # you own dst planet
            fv.append(1 if dst.id != 0 and dst.id != pid else 0)
            # neutral owns dst planet
            fv.append(1 if dst.id == 0 else 0)

            # growth
            fv.append(src.growth)
            fv.append(dst.growth)

            # incoming ship buckets (src)

            # print "incoming src", src.id, ": ",

            for i in range(buckets):
                fv.append(tally[src.id, i])
                # print i, tally[src.id, i],
            #print

            # incoming ship buckets (dst)
            # print "incoming dst", dst.id, ": ",

            for i in range(buckets):
                fv.append(tally[dst.id, i])
                #print tally[dst.id, i],
            #print

            assert len(fv) == len(wv), "lengths disagree " + str(
                len(fv)) + " " + str(len(wv))

            # compute value (weights * features)
            sum = 0
            for i, f in enumerate(fv):
                sum += f * wv[i]

            # print "Agent2: ", src.id, dst.id, sum

            # update best action (use tie-breaker?)
            if sum >= best_sum:
                if sum > best_sum:
                    best_orders = []
                best_sum = sum
                # best_orders.append(Order(src, dst, src.ships/2))
                best_orders.append(Order(src, dst, src.ships * 0.45))

    # print "#ORDERS: ", len(best_orders),
    best_order = random.choice(best_orders)

    #if best_order.source == best_order.destination:
    #  print "SAME PLANET!"
    #print
    # print "AgentTest2: ", best_order
    return [best_order]
Пример #12
0
def select_move(pid, planets, fleets):

  assert pid == 1 or pid == 2, "what?"

  my_planets, other_planets = partition(lambda x: x.owner == pid, planets)
  if len(my_planets) == 0 or len(other_planets) == 0:
    return []

  your_planets, neutral_planets = partition(lambda x: x.owner != 0, other_planets)

#  for i,p in enumerate(planets):
#    print "PLANET: ", i, p.id, "x=", p.x, "y=", p.y, p.owner, p.ships
  
  buckets = 10

  # evolved from manually tuned parameters (agenttest.py)
  # much better!
  wv = [0.86775324593161407, -1.9010099177760116, 0.70433224708478814,
   0.38139294338347268, 0.54156215783780215, -0.26850400844879657,
   0.036186433238020135, -2.4578285185718509, -0.22894880101333545,
   8.6048706141753843, 5.9310406603617754, -1.7418715081600573,
   1.7733665060956196, 0.75099526122482629, -0.24516344621926955,
   -0.58245534282527744, -1.9683307387551237, -4.5097072412766952,
   -3.3414734358820031, -1.6702149156291219, -2.8390520001774457,
   -5.380093894197751, -5.3042483457349077, -1.4015940841792449,
   -0.8879621041490966, -2.3146041377067901, -0.75674029604322557,
   -2.194825427869195, -2.7245477291943003, -3.5719201691901739,
   -3.9302814137729709, -3.6712154408545712, -5.9446914488922378]
  

  # Friday Morning:
  # wv = [0.87228527101416398, -0.79126636923666871,
  #       -0.34114544122826324, -1.2090512361564403, 1.4031361661285386,
  #       0.73674878406987754, -0.516640269495791, -3.1994083525469721,
  #       -0.5745394282397579, -0.22981889285018697, -1.417569495893277,
  #       -2.259612849650309, -1.417122273379628, 0.22398736570314653,
  #       1.1025017800623469, -2.3399564135382556, 0.46038305190135953,
  #       -0.19313043611744043, 0.83489567169438406, -0.52030771008719445,
  #       1.5391963665964257, -0.87786985834090447, 1.2020126747923154,
  #       0.72289829744304113, -1.2814151831330289, 1.3404938004129179,
  #       -0.58430476934010023, -2.2650232722412449, -0.47874802835808361,
  #       -1.0517218313694681, -0.1941961917394518, -1.110827613720589,
  #       -1.543892566692554]


  my_ships_total = 0
  your_ships_total = 0
  neutral_ships_total = 0
  my_growth = 0
  your_growth = 0

  # tally ships and growth
  
  for p in planets:
    if p.id == 0:
      neutral_ships_total += p.ships
    elif p.id == pid:
      my_growth += p.growth
      my_ships_total += p.ships
    else:
      your_ships_total += p.ships
      your_growth += p.growth

  # compute maximal distance between planets

  max_dist = 0
  for src in planets:
    for dst in planets:
      d = dist(src, dst)
      if d > max_dist:
        max_dist = d

  # incoming ship bucket matrix
  # incoming friendly ships count 1, incoming enemy ships count -1
  # for each planet we tally incoming ship for time buckets 0..buckets-1
  # where buckets refers to the maximum distance on the map
  tally = numpy.zeros((len(planets), buckets))

  for f in fleets:
    # d = remaining distance
    d = dist(planets[f.source], planets[f.destination]) * \
        (f.remaining_turns/f.total_turns)
    b = d/max_dist * buckets
    if b >= buckets:
      b = buckets-1
    tally[f.destination, b] += f.ships * (1 if f.owner == pid else -1)
  
  best_sum = float("-inf")
  best_orders = []
  
  for src in my_planets:
    for dst in planets:
      if src == dst:
        continue

      fv = []
      # planet totals
      fv.append(src.ships)
      fv.append(dst.ships)

      # ship total
      fv.append(my_ships_total)
      fv.append(your_ships_total)
      fv.append(neutral_ships_total)

      # growth
      fv.append(my_growth)
      fv.append(your_growth)

      # distance
      d = dist(src, dst)
      #print "PLANET DIST: ", src, dst
      #print "DIST: ", src.id, dst.id, d
      fv.append(d)

      # I own dst planet
      fv.append(1 if dst.id == pid else 0)
      # you own dst planet
      fv.append(1 if dst.id != 0 and dst.id != pid else 0)
      # neutral owns dst planet
      fv.append(1 if dst.id == 0 else 0)

      # growth
      fv.append(src.growth)
      fv.append(dst.growth)

      # incoming ship buckets (src)

      # print "incoming src", src.id, ": ", 

      for i in range(buckets):
        fv.append(tally[src.id, i])
        # print i, tally[src.id, i],
      #print
      
      # incoming ship buckets (dst)
      # print "incoming dst", dst.id, ": ", 

      for i in range(buckets):
        fv.append(tally[dst.id, i])
        #print tally[dst.id, i],
      #print
      
      assert len(fv) == len(wv), "lengths disagree " + str(len(fv)) + " " + str(len(wv))

      # compute value (weights * features)
      sum = 0
      for i,f in enumerate(fv):
        sum += f*wv[i]
      # print "Agent2: ", src.id, dst.id, sum

      # update best action (use tie-breaker?)
      if sum >= best_sum:
        if sum > best_sum:
          best_orders = []
        best_sum = sum
        best_orders.append(Order(src, dst, src.ships/2))

  # print "#ORDERS: ", len(best_orders),
  best_order = random.choice(best_orders)

  #if best_order.source == best_order.destination:
  #  print "SAME PLANET!"
  #print
  # print "AgentTest: ", best_order
  return [best_order]
Пример #13
0
 def play(self, turn, pid, planets, fleets):
     my_planets, their_planets, _ = aggro_partition(pid, planets)
     my_strongest = max(my_planets, key=get_ships)
     their_weakest = min(their_planets, key=get_ships)
     return [Order(my_strongest, their_weakest, my_strongest.ships * 0.75)]
Пример #14
0
    def __call__(self, turn, pid, planets, fleets):

        i = 1
        sumparams = 0
        while i < 11:
            sumparams += self.hotshot_params[i]
            i += 1
        if sumparams > 1 - self.hotshot_params[12]:
            #print "adapt params", sumparams, self.hotshot_params[12]
            factor = (1 - self.hotshot_params[12]) / sumparams
            i = 1
            while i < 11:
                self.hotshot_params[i] *= factor
                i += 1

        my_planets, their_planets, neutral_planets = aggro_partition(
            pid, planets)
        orders = []

        docked = 0
        flying = 0
        for planet in my_planets:
            docked += planet.ships
        for fleet in fleets:
            if fleet.owner == pid:
                flying += fleet.ships
        if flying + docked > 0:
            if float(flying) / float(flying +
                                     docked) > self.hotshot_params[11]:
                return []

        for planet in my_planets:
            if planet.ships < self.hotshot_params[0] * 100:
                continue

            def dist_to(other_planet):
                return turn_dist(planet, other_planet)

            def highgrowth_of(other_planet):
                return other_planet.growth * 1000 - turn_dist(
                    planet, other_planet)

            def lowgrowth_of(other_planet):
                return other_planet.growth * 1000 + turn_dist(
                    planet, other_planet)

            def ease_of(other_planet):
                return other_planet.ships * 1000 + turn_dist(
                    planet, other_planet)

            if len(neutral_planets) > 0:
                if self.hotshot_params[1] > 0:
                    closest = min(neutral_planets, key=dist_to)
                    orders.append(
                        Order(planet, closest,
                              planet.ships * self.hotshot_params[1]))
                if self.hotshot_params[2] > 0:
                    high_growth = max(neutral_planets, key=highgrowth_of)
                    orders.append(
                        Order(planet, high_growth,
                              planet.ships * self.hotshot_params[2]))
                if self.hotshot_params[3] > 0:
                    low_growth = min(neutral_planets, key=lowgrowth_of)
                    orders.append(
                        Order(planet, high_growth,
                              planet.ships * self.hotshot_params[3]))
                if self.hotshot_params[4] > 0:
                    any = neutral_planets[random.randint(
                        0,
                        len(neutral_planets) - 1)]
                    orders.append(
                        Order(planet, any,
                              planet.ships * self.hotshot_params[4]))
                if self.hotshot_params[5] > 0:
                    easy = min(neutral_planets, key=ease_of)
                    orders.append(
                        Order(planet, easy,
                              planet.ships * self.hotshot_params[5]))
            if len(their_planets) > 0:
                if self.hotshot_params[6] > 0:
                    closest = min(their_planets, key=dist_to)
                    orders.append(
                        Order(planet, closest,
                              planet.ships * self.hotshot_params[6]))
                if self.hotshot_params[7] > 0:
                    high_growth = max(their_planets, key=highgrowth_of)
                    orders.append(
                        Order(planet, high_growth,
                              planet.ships * self.hotshot_params[7]))
                if self.hotshot_params[8] > 0:
                    low_growth = min(their_planets, key=lowgrowth_of)
                    orders.append(
                        Order(planet, high_growth,
                              planet.ships * self.hotshot_params[8]))
                if self.hotshot_params[9] > 0:
                    any = their_planets[random.randint(0,
                                                       len(their_planets) - 1)]
                    orders.append(
                        Order(planet, any,
                              planet.ships * self.hotshot_params[9]))
                if self.hotshot_params[10] > 0:
                    easy = min(their_planets, key=ease_of)
                    orders.append(
                        Order(planet, easy,
                              planet.ships * self.hotshot_params[10]))

        return orders
Пример #15
0
def gships(pid, planet_data, clustr_data, t_dist, t_max, data, turn, train, planets, fleets, game_metrics):
    '''
    Calculates the number of ships the cluster needs to send in order to capture/help the planet
    @param pid: player id
    @type: int
    @param planet_data: the planet to send the ships to with data
    @type: {'planet' : p, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0}
    @param cluster_data: Combined data of all planets that belong to this cluster
    @type: {'cluster' : cluster, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0}
    @param t_dist: turn distance between planet and cluster (approximation / take max)
    @type: int
    @param t_max: max turn distance on the map
    @type: int
    @param data: dictionary of all planets information. Each inner dictionary value is accesed using a planet as key
                 e.g.
                 data[key][planet.id][t_max]  -  key = 'value' | 'value_d'
                 data[key][planet.id]         -  key = 'influence_' + 'f' | 'e' | 'f_d' | 'e_d'
    @type: {'value' : {}, 'value_d' : {}, 'influence_f' : {}, 'influence_e' : {}, 'influence_f_d' : {}, 'influence_e_d' : {}}
    '''
    # input data sanity check
    assert isinstance(pid, int)
    assert isinstance(planet_data, dict)
    assert isinstance(clustr_data, dict)
    assert isinstance(t_dist, int)
    assert isinstance(t_max, int)
    assert isinstance(data, dict)
    # -------------------------------------------------------------------- 
    # create relation value 1 / 0.5 / 0 depending of the planet is neutral / friendly / enemy
    cluster_planet_relationship = 0.0
    if pid == planet_data['planet'].owner:
        cluster_planet_relationship = 0.5
    elif planet_data['planet'].owner == 0:
        cluster_planet_relationship = 1



    # +1 to avoid division by 0
    # we send data as ratios (planet under cluster)
    # all values are between 0 and 1; except "owner" and "t_dist"
    input = [# cluster data
             clustr_data['ships'],
             clustr_data['growth'],
             clustr_data['value'],
             #clustr_data['value_d'],
             clustr_data['influence_f'],
             clustr_data['influence_e'],
             clustr_data['influence_f_m'],
             clustr_data['influence_e_m'],
             #clustr_data['influence_f_md'],
             #clustr_data['influence_e_md'],
             # planet data
             planet_data['ships'],
             planet_data['growth'],
             planet_data['value'],
             #planet_data['value_d'],
             planet_data['influence_f'],
             planet_data['influence_e'],
             planet_data['influence_f_m'],
             planet_data['influence_e_m'],
             #planet_data['influence_f_md'],
             #planet_data['influence_e_md'],
             game_metrics['growth_r'],       # overall growth ratio
             game_metrics['growth_er'],      # overall growth ratio enemy
             game_metrics['ships_r'],        # overall ship ratio
             cluster_planet_relationship,    # read above for details 
             t_dist / float(t_max)]
    
    assert not any(numpy.isnan(in_) or numpy.isinf(in_) for in_ in input)
    input_np = numpy.array(input, ndmin=2, dtype=config.floatX)

    # two output values. 
    # 1. The certainty of this attack / help
    # 2. the percentage og ships to send from the cluster
    out_np = NNetwork.gships.predict(input_np, batch_size = 1)
    out = out_np[0][0] # reformat the output data    

    assert not (numpy.isnan(out) or numpy.isinf(out))

    orders = []
    for p in clustr_data['cluster']:
        orders.append(Order(p, planet_data['planet'], int(p.ships / 2)))

    # if we are training, add pattern
    pattern = None
    if train:
        pattern = {
            'in' : input_np, 
            'out' : out_np,
            'reward' : 0.0,
            'in_' : None,
            'terminal' : False}       

    # we need to return an array of Order objects. The array can be empty.
    return (out, orders, pattern, t_dist, planet_data['value'])