Ejemplo n.º 1
0
 def attacked_prob(self, province, nation, force, bias, adjacent_units):
     ''' How likely the province is to be attacked by an enemy of the nation,
         with at least the indicated force.
     '''#'''
     result = 0
     if nation != self.power:
         entering = False
         supports = []
         for unit in self.friends(province, adjacent_units):
             order = self.unit_orders.get_order(unit)
             if order.is_moving():
                 if order.destination.province.key == province.key:
                     entering = True
             elif (order.is_supporting()
                     and order.destination.province.key == province.key
                     and order.supported.location.province.key != province.key):
                 supports.append(1 - self.success_prob(order, bias, adjacent_units))
         if force == 1: result = entering and 1 or 0
         elif len(supports) >= force - 1:
             # Will my supports work?
             result = 1 - (bias and min or max)([reduce(mul, sl, 1)
                     for sl in sublists(supports) if len(sl) == force - 1])
     
     if bias:
         # Allow mutual enemies to help out
         enemies = self.enemies(province, nation, adjacent_units)
         # Todo: Consider whether they cooperate, ever
         if len(enemies) >= force: result = 1
     return result
Ejemplo n.º 2
0
 def generate_move_combos(self):
     adj_provs = defaultdict(list)
     for unit in self.power.units:
         for key in unit.location.borders_out:
             dest = self.map.locs[key]
             if not any(other.nation == self.power
                     for other in dest.province.units):
                 adj_provs[key[1]].append(MoveOrder(unit, dest))
     return [OrderCombo(self, combo)
         for value in adj_provs.values()
         for combo in sublists(value)
         if combo]
Ejemplo n.º 3
0
 def get_children(self, new_orders):
     # Support functions
     def valid(order_list):
         ''' Checks for multiple orders to a single unit, or empty lists.
             Todo: Check for convoy matching.
         '''#'''
         if not order_list: return False
         keys_seen = []
         for order in order_list:
             key = order.unit.key
             if key in keys_seen: return False
             keys_seen.append(key)
         return True
     def attackers(province, friendly=self.player.power.key,
             spaces=self.player.map.spaces):
         ''' Compiles a list of enemy units that can enter the province.'''
         bordering = [spaces[prov].units for prov in province.borders_in]
         return [u for u in sum(bordering, [])
             if u and u.nation != friendly and u.can_move_to(province)]
     def occupied(province, friendly=self.player.power.key):
         ''' Determines whether an enemy is in a space.'''
         return any(unit.nation != friendly for unit in province.units)
     
     # Determine who can still be ordered
     unordered = [u for u in self.player.power.units
         if not self.unit_orders.get_order(u)]
     holding = [order.unit for order in self.unit_orders
         if order.is_holding()]
     if not (unordered or holding): return []
     
     # Collect orders related to the new orders
     sub_orders = []
     enter_provs = []
     for order in new_orders:
         if order.is_moving():
             if (occupied(order.destination.province)
                     or len(attackers(order.destination.province)) > 0):
                 # Try to support the move
                 sub_orders.extend([
                     SupportMoveOrder(u, order.unit, order.destination)
                     for u in unordered + holding
                     if u.can_move_to(order.destination.province)])
             # Try to enter the vacated space
             enter_provs.append(order.unit.location.province.key)
         else:
             enemies = attackers(order.unit.location.province)
             if (len(enemies) > 1):
                 # Try to support the stationary unit
                 sub_orders.extend([SupportHoldOrder(u, order.unit)
                     for u in unordered + holding
                     if u.can_move_to(order.unit.location.province)])
                 # Try to cut support for attacks
                 enter_provs.extend([u.location.province.key for u in enemies])
             if (order.is_supporting()
                     and order.supported.location != order.destination
                     and occupied(order.destination.province)):
                 # Try to cut support to the attacked unit
                 enter_provs.extend([u.location.province.key
                         for u in attackers(order.destination.province)])
                 # Todo: Try to block retreats
     
     # Try to enter indicated provinces
     sub_orders.extend([MoveOrder(u, self.player.map.locs[key])
             for u in unordered for key in u.location.borders_out
             if key[1] in enter_provs])
     # Try to convoy to the indicated provinces
     sub_orders.extend(self.convoys_to(enter_provs, unordered, holding))
     
     # Run all possible combinations of the related orders
     return [OrderCombo(self, order_list)
         for order_list in sublists(sub_orders)
         if valid(order_list)]