[freeciv-ai] Re: (PR#2477) Improved Auto-Explore
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Tue, Dec 03, 2002 at 05:19:38AM -0800, Guest via RT wrote:
>
> [rfalke - Tue Dec 3 07:35:06 2002]:
>
> > Please remove some unneeded ().
>
> OK, I think I removed them all. I like to put in "unneeded ()" because I
> once programmed a DSP with a programming language that was almost
> indistinguishable from C; the only difference was '||' bound more
> closely than '&&'. Since then I've been a bit free with the brackets.
> Here I left some in to prevent a warning from gcc.
Mhh I wasn't thinking about the () around && and || but about the x<0
term.
> > Can't 0x80 and co be replaced with an enum?
>
> Probably. I want it to return a "fuzzy" value, so code that uses it
> could make decisions based on how certain they are that the value is
> ocean. I'm not sure how to do this using enum. How about
>
> #define OCEAN_CERTAIN_IS 0x80
> #define OCEAN_UNKNOWN 0x40
> #define OCEAN_CERTAIN_NOT 0x00
>
> ? I you think that's a good idea I'll add it in the next revision.
> Index: ai/aiunit.c
> ===================================================================
> RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
> retrieving revision 1.231
> diff -u -3 -p -r1.231 aiunit.c
> --- ai/aiunit.c 2002/12/02 22:48:13 1.231
> +++ ai/aiunit.c 2002/12/03 13:14:32
> @@ -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 0x80;
> + } 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. */
Please use adjc_iterate and DIR_IS_CARDINAL.
> + if(map_get_terrain(x,y) == T_OCEAN) {
> + return 0x80;
> + } else {
> + return 0;
> + }
> + }
It looks like you referring in this construct here to the kludge we
use in the client to draw correctly the ocean squares.
> + sum = 0x40;
> + /* average the adjacent 8 tiles */
> + square_iterate(x, y, 1, x1, y1) {
> + if(y1 < 0 || y1 > map.ysize) {
> + continue;
> + }
Please use adjc_iterate.
> + 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;
How did you calibrated these values? 64 + 4*4+4*2 = 88 and 64 -
(4*4+4*2) = 40. Shouldn't these values be nearer 0 and 128?
Can you scale them to 100 and call them percent?
> + return sum;
> +}
> +
> +/**************************************************************************
> Handle eXplore mode of a unit (explorers are always in eXplore mode for AI) -
> explores unknown territory, finds huts.
>
> @@ -369,21 +434,67 @@ 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;
What is k?
> + 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;
> + }
Please make a set of values and then assign in if
(sailing){...}else{...} the final values. This temp usage is just
ugly.
> 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) {
> - if (!map_get_known(x2, y2, pplayer))
> - unknown++;
> + ocean = likely_ocean(x2,y2, pplayer);
> + if (!map_get_known(x2, y2, pplayer)) {
> + 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)) {
unknon > 0
> if (unit_flag(punit, F_TRIREME)
> && trireme_loss_pct(pplayer, x1, y1) != 0)
> continue;
> @@ -405,7 +516,10 @@ bool ai_manage_explorer(struct unit *pun
> if (is_barbarian(pplayer) && map_has_special(x1, y1, S_HUT))
> continue;
>
> - most_unknown = unknown;
> + if(unknown > most_unknown) {
> + most_unknown = unknown;
> + }
> + most_desirable = desirable;
> best_x = x1;
> best_y = y1;
> }
I take my request for enums back. The code however should be changed
that likely_ocean is more a ocean_probability with a result range of
0<=x<=100.
Raimar
--
email: rf13@xxxxxxxxxxxxxxxxx
"The primary purpose of the DATA statement is to give names to
constants; instead of referring to pi as 3.141592653589793 at every
appearance, the variable PI can be given that value with a DATA
statement and used instead of the longer form of the constant. This
also simplifies modifying the program, should the value of pi
change."
-- FORTRAN manual for Xerox Computers
[freeciv-ai] (PR#2477) Improved Auto-Explore, Guest via RT, 2002/12/03
[freeciv-ai] (PR#2477) Improved Auto-Explore, Guest via RT, 2002/12/15
|
|