[freeciv-ai] Re: AI diplomacy v5 (PR#2413)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
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) {
- [freeciv-ai] AI diplomacy v5 (PR#2413), Per I. Mathisen via RT, 2003/01/03
- Message not available
- Message not available
- [freeciv-ai] Re: AI diplomacy v5 (PR#2413),
jorneg@xxxxxxxxxxx via RT <=
|
|