Complete.Org: Mailing Lists: Archives: freeciv-ai: January 2003:
[freeciv-ai] Re: AI diplomacy v5 (PR#2413)
Home

[freeciv-ai] Re: AI diplomacy v5 (PR#2413)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: per@xxxxxxxxxxx
Cc: freeciv-ai@xxxxxxxxxxx
Subject: [freeciv-ai] Re: AI diplomacy v5 (PR#2413)
From: "jorneg@xxxxxxxxxxx via RT" <rt@xxxxxxxxxxxxxx>
Date: Sun, 5 Jan 2003 08:17:22 -0800
Reply-to: rt@xxxxxxxxxxxxxx

En/na Per I. Mathisen via RT ha escrit:

>/********************************************************************** 
>NOTES ON THIS AI DIPLOMACY FILE:
> -> Be very careful with infinities - they can lead to overflows.
> -> Everything is measured in gold, even treaties. However, treaties
>    are meant to be broken, if that is measured profitable.
> -> Some players can be give attitudes (see aidata.h). These can
>    severely impair an ai's ability to pursue a diplomacy to its
>    own gain, but it is very good for modpacks and easy difficulties.
> -> We rely on omniscience here. Really.
>***********************************************************************/
>
>/********************************************************************** 
>  Evaluate gold worth of a single clause in a treaty. Note that it
>  sometimes matter a great deal who is giving what to whom, and
>  sometimes (such as with treaties) it does not matter at all.
>***********************************************************************/
>static int ai_goldequiv_clause(struct player *pplayer, 
>                               struct player *aplayer,
>                               struct Clause *pclause,
>                               struct ai_data *ai)
>{
>  int worth[MAX_NUM_PLAYERS]; /* worth of what X gives */
>  int i;
>  bool give = (pplayer == pclause->from);
>  int receiver, giver;
>
>  for (i = 0; i < MAX_NUM_PLAYERS; i++) {
>    worth[i] = 0;
>  }
>
>  giver = pclause->from->player_no;
>  if (give) {
>    receiver = aplayer->player_no;
>  } else {
>    receiver = pplayer->player_no;
>  }
>
>  switch (pclause->type) {
>  case CLAUSE_ADVANCE: {
>    int tech_cost;
>
>    if (give) {
>      tech_cost = ai_goldequiv_tech(aplayer, pclause->value);
>    } else {
>      tech_cost = ai_goldequiv_tech(pplayer, pclause->value);
>    }
>
>    /* Share and expect being shared brotherly between allies */
>    if (pplayers_allied(pplayer, aplayer)) {
>      tech_cost /= 10;
>    }
>
>    /* Calculate in tech leak to our enemies, guess 50% chance */
>    if (give) { 
>      players_iterate(eplayer) {
>        if (pplayers_allied(aplayer, eplayer) && aplayer != eplayer
>            && get_invention(eplayer, pclause->value) != TECH_KNOWN) {
>          worth[eplayer->player_no] -= 
>              ai_goldequiv_tech(eplayer, pclause->value) / 2;
>        }
>      } players_iterate_end;
>    }
>    worth[receiver] += tech_cost;
>    /* FIXME: We should calculate use of tech for allies too, but we
>       need to look just how the tech exchange code turns out 
>       first. - Per */
>  } break;
>
>  case CLAUSE_ALLIANCE:
>  case CLAUSE_PEACE:
>  case CLAUSE_CEASEFIRE: {
>    /* TODO: Note that right now most of this code is dead code because
>     * we set war_desire to zero for everyone but our no 1 target at
>     * another place in the code. - Per */
>    int war_desire = ai->diplomacy.other[aplayer->player_no].war_desire;
>
>    /* Attitude adjustment: Don't be too eager to get into a relationship
>     * that you can't stomach getting out of. */
>    if (ai_attitude(ai, DIP_BACKSTABBER)) {
>      war_desire /= 1.5;
>    }
>    if (ai_attitude(ai, DIP_TRUSTWORTHY)) {
>      war_desire *= 1.5;
>    }
>
>    /* Breaking treaties give us penalties on future diplomacy, so
>     * avoid flip-flopping treaty/war with our enemy. */
>    if (aplayer == ai->diplomacy.target 
>        && !ai_attitude(ai, DIP_BACKSTABBER)) {
>      war_desire *= 3;
>    }
>
>    /* No peace to our chosen victim if we are militarist */
>    if (aplayer == ai->diplomacy.target 
>        && ai_attitude(ai, DIP_MILITARIST)) {
>      worth[pplayer->player_no] = -FC_INFINITY;
>    }
>
>    /* We don't want treaties that obstruct our aims, but if war_desire
>       is negative then we want 'em this much. */
>    worth[pplayer->player_no] += -(war_desire * TRADE_WEIGHTING
>                                   * city_list_size(&aplayer->cities));
>    freelog(LOG_DIPL, "(%s ai diplo) Calculating pact with %s as 
> (%d*%d*%d=)%d",
>            pplayer->name, aplayer->name,
>            war_desire, TRADE_WEIGHTING, city_list_size(&aplayer->cities),
>            worth[pplayer->player_no]);
>
>    /* Modify for peace */
>    if (pclause->type == CLAUSE_PEACE) { 
>      if (!pplayers_non_attack(pplayer, aplayer)) {
>        diplo_notify(aplayer, TALK(%s) "Let us first cease hostilies, %s",
>                     pplayer->name, aplayer->name);
>        return -FC_INFINITY;
>      } else {
>        worth[pplayer->player_no] *= 1.5;
>      }
>    }
>
>    /* Modify for alliance */
>    if (pclause->type == CLAUSE_ALLIANCE) {
>      bool player_is_allied_with_ally = FALSE;
>      players_iterate(check_pl) {
>        /* We want to ally our ally's allies to prevent
>         * ugly wars between allies */
>        if (check_pl != pplayer && check_pl != aplayer
>            && pplayers_allied(pplayer, check_pl)
>            && pplayers_allied(aplayer, check_pl)) {
>          player_is_allied_with_ally = TRUE;
>        }
>      } players_iterate_end;
>      if (!pplayers_in_peace(pplayer, aplayer)) {
>        diplo_notify(aplayer, TALK(%s) "Let us first cease hostilies, %s",
>                     pplayer->name, aplayer->name);
>        return -FC_INFINITY;
>      } else if (!player_is_allied_with_ally) {
>        worth[pplayer->player_no] *= 3;
>      } else {
>        /* Let's all join hands! */
>        worth[pplayer->player_no] = 1;
>      }
>    }
>  
>
  would be better...
 diplo_notify(aplayer, TALK(%s) "Let us first make peace, %s",
                     pplayer->name, aplayer->name);



  case CLAUSE_CITY: {
    struct city *offer = city_list_find_id(&(pclause->from)->cities, 
                                           pclause->value);

    if (!offer || offer->owner != giver) {
      /* City destroyed or taken during negotiations */
      break;
    }

        I think that it's better to say to the user a message stating that the 
city cannot be transfered.


/********************************************************************** 
  Only ever called for AI players and never for barbarians.
***********************************************************************/
void ai_diplomacy_calculate(struct player *pplayer, struct ai_data *ai)
{
  int war_desire = 0;
  int war_fear = 0;
  struct player *target = NULL;
  struct city *palace = find_palace(pplayer);

  if (!pplayer->is_alive) {
    return; /* doh */
  }

  /* Stop war against a dead player */
  if (ai->diplomacy.target && !ai->diplomacy.target->is_alive) {
    freelog(LOG_DIPL, "(%s ai diplo) Target player %s is dead. Victory!",
            pplayer->name, ai->diplomacy.target->name);
    ai->diplomacy.timer = 0;
    ai->diplomacy.target = NULL;
    if (ai->diplomacy.strategy == WIN_CAPITAL) {
      ai->diplomacy.strategy = WIN_OPEN;
    }
  }

        Depending on compiler options this can crash the server. I would 
suggest:

  /* Stop war against a dead player */
  if (ai->diplomacy.target) 
        if ( !ai->diplomacy.target->is_alive) {







[Prev in Thread] Current Thread [Next in Thread]