Ejemplo n.º 1
0
/**********************************************************************
  Find something to bomb
  Air-units specific victim search
  Returns the want for the best target.  The targets are stored in the
  path and pptile arguments if not NULL.
  TODO: take counterattack dangers into account
  TODO: make separate handicaps for air units seeing targets
        IMO should be more restrictive than general H_MAP, H_FOG
*********************************************************************/
static int find_something_to_bomb(struct ai_type *ait, struct unit *punit,
                                  struct pf_path **path, struct tile **pptile)
{
  struct player *pplayer = unit_owner(punit);
  struct pf_parameter parameter;
  struct pf_map *pfm;
  struct tile *best_tile = NULL;
  int best = 0;

  pft_fill_unit_parameter(&parameter, punit);
  pfm = pf_map_new(&parameter);

  /* Let's find something to bomb */
  pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
    if (move_cost >= punit->moves_left) {
      /* Too far! */
      break;
    }

    if (ai_handicap(pplayer, H_MAP) && !map_is_known(ptile, pplayer)) {
      /* The target tile is unknown */
      continue;
    }

    if (ai_handicap(pplayer, H_FOG) 
        && !map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
      /* The tile is fogged */
      continue;
    }

    if (is_enemy_unit_tile(ptile, pplayer)
        && dai_should_we_air_attack_tile(ait, punit, ptile)
        && can_unit_attack_tile(punit, ptile)) {
      int new_best = dai_evaluate_tile_for_air_attack(punit, ptile);

      if (new_best > best) {
        best_tile = ptile;
        best = new_best;
        log_debug("%s wants to attack tile (%d, %d)", 
                  unit_rule_name(punit), TILE_XY(ptile));
      }
    }
  } pf_map_positions_iterate_end;

  /* Return the best values. */
  if (pptile) {
    *pptile = best_tile;
  }
  if (path) {
    *path = best_tile ? pf_map_path(pfm, best_tile) : NULL;
  }

  pf_map_destroy(pfm);
  return best;
} 
Ejemplo n.º 2
0
/*******************************************************************
  Chooses the best available and usable air unit and records it in 
  choice, if it's better than previous choice
  The interface is somewhat different from other ai_choose, but
  that's what it should be like, I believe -- GB
******************************************************************/
bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer,
                             struct city *pcity, struct adv_choice *choice)
{
  bool want_something = FALSE;

  /* This AI doesn't know to build planes */
  if (ai_handicap(pplayer, H_NOPLANES)) {
    return FALSE;
  }

  /* military_advisor_choose_build does something idiotic, 
   * this function should not be called if there is danger... */
  if (choice->want >= 100 && choice->type != CT_ATTACKER) {
    return FALSE;
  }

  if (!player_knows_techs_with_flag(pplayer, TF_BUILD_AIRBORNE)) {
    return FALSE;
  }

  unit_type_iterate(punittype) {
    struct unit_class *pclass = utype_class(punittype);

    if (pclass->adv.land_move == MOVE_NONE
        || pclass->adv.sea_move == MOVE_NONE
        || uclass_has_flag(pclass, UCF_TERRAIN_SPEED)
        || unit_type_is_losing_hp(pplayer, punittype)) {
      /* We don't consider this a plane */
      continue;
    }
    if (can_city_build_unit_now(pcity, punittype)) {
      struct unit *virtual_unit = 
	unit_virtual_create(pplayer, pcity, punittype,
                            do_make_unit_veteran(pcity, punittype));
      int profit = find_something_to_bomb(ait, virtual_unit, NULL, NULL);

      if (profit > choice->want){
        /* Update choice */
        choice->want = profit;
        choice->value.utype = punittype;
        choice->type = CT_ATTACKER;
        choice->need_boat = FALSE;
        want_something = TRUE;
        log_debug("%s wants to build %s (want=%d)",
                  city_name(pcity), utype_rule_name(punittype), profit);
      } else {
        log_debug("%s doesn't want to build %s (want=%d)",
                  city_name(pcity), utype_rule_name(punittype), profit);
      }
      unit_virtual_destroy(virtual_unit);
    }
  } unit_type_iterate_end;

  return want_something;
}
Ejemplo n.º 3
0
/*****************************************************************************
  Find best tile the paratrooper should jump to.
*****************************************************************************/
static struct tile *find_best_tile_to_paradrop_to(struct ai_type *ait,
                                                  struct unit *punit)
{
  int best = 0;
  int val;
  struct tile* best_tile = NULL;
  int range = unit_type(punit)->paratroopers_range;
  struct city* acity;
  struct player* pplayer = unit_owner(punit);

  /* First, we search for undefended cities in danger */
  square_iterate(unit_tile(punit), range, ptile) {
    if (!map_is_known(ptile, pplayer)) {
      continue;
    }
  
    acity = tile_city(ptile);
    if (acity && city_owner(acity) == unit_owner(punit)
        && unit_list_size(ptile->units) == 0) {
      val = city_size_get(acity) * def_ai_city_data(acity, ait)->urgency;
      if (val > best) {
	best = val;
	best_tile = ptile;
      }
    }
  } square_iterate_end;
  
  if (best_tile != NULL) {
    acity = tile_city(best_tile);
    UNIT_LOG(LOGLEVEL_PARATROOPER, punit, 
             "Choose to jump in order to protect allied city %s (%d %d). "
	     "Benefit: %d",
	     city_name(acity), TILE_XY(best_tile), best);
    return best_tile;
  }

  /* Second, we search for undefended enemy cities */
  square_iterate(unit_tile(punit), range, ptile) {
    acity = tile_city(ptile);
    if (acity && pplayers_at_war(unit_owner(punit), city_owner(acity)) &&
        (unit_list_size(ptile->units) == 0)) {
      if (!map_is_known_and_seen(ptile, pplayer, V_MAIN)
          && ai_handicap(pplayer, H_FOG)) {
        continue;
      }
      /* Prefer big cities on other continents */
      val = city_size_get(acity)
            + (tile_continent(unit_tile(punit)) != tile_continent(ptile));
      if (val > best) {
        best = val;
	best_tile = ptile;
      }
    }
  } square_iterate_end;