? explore.txt ? data/mono ? data/mono.tilespec ? data/oldciv ? data/oldciv.tilespec ? data/oldciv_shields.tilespec ? data/tinydent ? data/tinydent.tilespec Index: ai/aiunit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v retrieving revision 1.229 diff -u -3 -p -r1.229 aiunit.c --- ai/aiunit.c 2002/11/14 09:14:50 1.229 +++ ai/aiunit.c 2002/11/14 19:56:02 @@ -256,6 +256,71 @@ static bool tile_is_accessible(struct un } /************************************************************************** + Determine if a tile is likely to be water, given information that + the player actually has. Return the certainty that it's water + (0x80 = certain, 0x40 = no idea, 0 = certainly not). +**************************************************************************/ +int likely_ocean(int x, int y, struct player *pplayer) +{ + int sum = 0; + + if(map_get_known(x,y,pplayer)) + { + /* we've seen the tile already. */ + if(map_get_terrain(x,y) == T_OCEAN) + return 128; + else + return 0; + } + + /* without the bounds checks we get segfaults */ + if(((x-1 >= 0) && map_get_known(x-1,y,pplayer) && + map_get_terrain(x-1,y) == T_OCEAN) || + ((x+1 < map.xsize) && map_get_known(x+1,y,pplayer) && + map_get_terrain(x+1,y) == T_OCEAN) || + ((y-1 >= 0) && map_get_known(x,y-1,pplayer) && + map_get_terrain(x,y-1) == T_OCEAN) || + ((y+1 < map.ysize) && map_get_known(x,y+1,pplayer) && + (map_get_terrain(x,y+1) == T_OCEAN))) + { + /* we can tell by the border if there's land there. */ + if(map_get_terrain(x,y) == T_OCEAN) + return 0x80; + else + return 0; + } + + sum = 0x40; + /* average the adjacent 8 tiles */ + square_iterate(x, y, 1, x1, y1) { + if((y1<0) || (y1>map.ysize)) + continue; + + if(map_get_known(x1,y1, pplayer)) + { + /* this nearby tile is water */ + + if((x != x1) && (y != y1)) + { + /* diagonals count for less. */ + if(map_get_terrain(x1,y1) == T_OCEAN) + sum += 2; + else + sum -= 2; + } + else + { + if(map_get_terrain(x1,y1) == T_OCEAN) + sum += 4; + else + sum -= 4; + } + } + } square_iterate_end; + return sum; +} + +/************************************************************************** Handle eXplore mode of a unit (explorers are always in eXplore mode for AI) - explores unknown territory, finds huts. @@ -378,21 +443,69 @@ bool ai_manage_explorer(struct unit *pun while (punit->moves_left > 0) { /* Best (highest) number of unknown tiles adjacent (in vision range) */ int most_unknown = 0; + + /* most desirable tile, given adjacent water */ + int most_desirable = 0; + + /* relative value of exploring ocean and land */ + int landscore = 5; + int oceanscore = 60; + + /* relative value of staying near known ocean and land */ + int klandscore = 2; + int koceanscore = 25; + /* Desired destination */ int best_x = -1, best_y = -1; + if(is_sailing_unit(punit)) + { + /* for sailing explorer, reverse desirable tiles */ + int temp; + + temp = landscore; + landscore = oceanscore; + oceanscore = temp; + + temp = klandscore; + klandscore = koceanscore; + koceanscore = temp; + } + /* Evaluate all adjacent tiles. */ square_iterate(x, y, 1, x1, y1) { /* Number of unknown tiles in vision range around this tile */ int unknown = 0; + int desirable = 0; + int ocean = 0; + square_iterate(x1, y1, range, x2, y2) { + ocean = likely_ocean(x2,y2, pplayer); if (!map_get_known(x2, y2, pplayer)) - unknown++; + { + unknown++; + /* if it's a tile we don't know, weight the value of + * exploring it by if it's likely to be ocean or not. + */ + if(ocean > 0x40) + desirable += oceanscore; + else if(ocean < 0x40) + desirable += landscore; + } + else + { + if(ocean > 0x40) + desirable += koceanscore; + else if(ocean < 0x40) + desirable += klandscore; + } } square_iterate_end; - if (unknown > most_unknown) { + /* regardless how desirable a tile is, if we don't discover + * any new territory, don't go there. */ + if (unknown && (desirable > most_desirable)) { if (unit_flag(punit, F_TRIREME) && trireme_loss_pct(pplayer, x1, y1) != 0) continue; @@ -414,7 +527,10 @@ bool ai_manage_explorer(struct unit *pun if (is_barbarian(pplayer) && map_has_special(x1, y1, S_HUT)) continue; + if(unknown > most_unknown) + most_unknown = unknown; most_unknown = unknown; + most_desirable = desirable; best_x = x1; best_y = y1; } @@ -444,7 +560,7 @@ bool ai_manage_explorer(struct unit *pun if (broken) { break; } /* a move failed, so danger of endless loop */ } else { - /* Everything is already explored. */ + /* Everything is already explored. */ break; } }