? civscore.log ? rand_pos.diff ? title.diff ? diff ? tinydent-1.11.4.tar.gz ? null_flags1.diff ? map_iterate.diff ? map_iterate2.diff ? mapgen1.diff ? log ? base_real_map_distance.diff ? map_distance_vector1.diff ? data/tinydent ? data/tinydent.tilespec ? data/tinydent.mod ? data/tinydent1.diff Index: server/gotohand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v retrieving revision 1.122 diff -u -r1.122 gotohand.c --- server/gotohand.c 2001/10/08 12:11:17 1.122 +++ server/gotohand.c 2001/11/11 18:31:52 @@ -1329,8 +1329,8 @@ turn_index = fc_malloc((map.xsize*map.ysize)*sizeof(unsigned int)); } - freelog(LOG_DEBUG, "unit @(%d, %d) fuel=%d, moves_left=%d\n", - punit->x, punit->y, punit->fuel, punit->moves_left); + freelog(LOG_DEBUG, "unit (id=%d) @(%d, %d) fuel=%d, moves_left=%d\n", + punit->id, punit->x, punit->y, punit->fuel, punit->moves_left); init_refuel(&start, punit->x, punit->y, FUEL_START, 0, punit->moves_left/3); if (punit->fuel > 1) start.moves_left += (punit->fuel-1) * fullmoves; @@ -1429,8 +1429,9 @@ } /************************************************************************** - Returns #moves left when player playerid is moving a unit from src_x,src_y to - dest_x,dest_y in moves moves. [Kero] + Returns #moves left when the given player is moving a unit from + (src_x,src_y) to (dest_x,dest_y) in moves moves. + If there was no way to move between returns -1. The function has 3 stages: @@ -1442,79 +1443,66 @@ int air_can_move_between(int moves, int src_x, int src_y, int dest_x, int dest_y, struct player *pplayer) { - int x, y, go_x, go_y, i, movescount; - struct tile *ptile; - freelog(LOG_DEBUG, "naive_air_can_move_between %i,%i -> %i,%i, moves: %i", - src_x, src_y, dest_x, dest_y, moves); + int x, y, movescount; + + freelog(LOG_DEBUG, + "air_can_move_between(moves=%d, src=(%i,%i), dest=(%i,%i))", + moves, src_x, src_y, dest_x, dest_y); /* O(1) */ if (real_map_distance(src_x, src_y, dest_x, dest_y) > moves) return -1; if (real_map_distance(src_x, src_y, dest_x, dest_y) == 0) return moves; /* O(moves). Try to go to the destination in a ``straight'' line. */ - x = src_x; y = src_y; + x = src_x; + y = src_y; movescount = moves; while (real_map_distance(x, y, dest_x, dest_y) > 1) { - if (movescount <= 1) - goto TRYFULL; + int preferred_dir, preferred_dir_dx, preferred_dir_dy; + int best_dir = -1, best = -1; - go_x = (x > dest_x ? - (x-dest_x < map.xsize/2 ? -1 : 1) : - (dest_x-x < map.xsize/2 ? 1 : -1)); - go_y = (dest_y > y ? 1 : -1); - - freelog(LOG_DEBUG, "%i,%i to %i,%i. go_x: %i, go_y:%i", - x, y, dest_x, dest_y, go_x, go_y); - if (x == dest_x) { - for (i = x-1 ; i <= x+1; i++) - if ((ptile = map_get_tile(i, y+go_y)) - /* && is_real_tile(i, y+go_y) */ - && ! is_non_allied_unit_tile(ptile, pplayer)) { - x = i; - y += go_y; - goto NEXTCYCLE; - } + if (movescount <= 1) { goto TRYFULL; - } else if (y == dest_y) { - for (i = y-1 ; i <= y+1; i++) - if ((ptile = map_get_tile(x+go_x, i)) - && is_real_tile(x+go_x, i) - && ! is_non_allied_unit_tile(ptile, pplayer)) { - x += go_x; - y = i; - goto NEXTCYCLE; - } - goto TRYFULL; } - /* (x+go_x, y+go_y) is always real, given (x, y) is real */ - ptile = map_get_tile(x+go_x, y+go_y); - if (! is_non_allied_unit_tile(ptile, pplayer)) { - x += go_x; - y += go_y; - goto NEXTCYCLE; - } + preferred_dir = straightest_direction(x, y, dest_x, dest_y); - /* (x+go_x, y) is always real, given (x, y) is real */ - ptile = map_get_tile(x+go_x, y); - if (! is_non_allied_unit_tile(ptile, pplayer)) { - x += go_x; - goto NEXTCYCLE; - } + DIRSTEP(preferred_dir_dx, preferred_dir_dy, preferred_dir); - /* (x, y+go_y) is always real, given (x, y) is real */ - ptile = map_get_tile(x, y+go_y); - if (! is_non_allied_unit_tile(ptile, pplayer)) { - y += go_y; - goto NEXTCYCLE; - } + freelog(LOG_DEBUG, " current=(%i,%i) dest=(%i,%i)", x, y, dest_x, + dest_y); + adjc_dir_iterate(x, y, nx, ny, dir) { + int value, dir_dx, dir_dy; - /* we didn't advance.*/ - goto TRYFULL; + if (!dir_ok(x, y, dest_x, dest_y, dir)) { + continue; + } + if (is_non_allied_unit_tile(map_get_tile(nx, ny), pplayer)) { + continue; + } + + DIRSTEP(dir_dx, dir_dy, dir); + value = preferred_dir_dx * dir_dx + preferred_dir_dy * dir_dy; + + if (value > best) { + best = value; + best_dir = dir; + } + } adjc_dir_iterate_end; - NEXTCYCLE: + if (best_dir == -1) { + goto TRYFULL; + } else { + int nx, ny, is_real; + + is_real = MAPSTEP(nx, ny, x, y, best_dir); + assert(is_real); + x = nx; + y = ny; + } movescount--; } + /* if this loop stopped we made it! We found a way! */ freelog(LOG_DEBUG, "end of loop; success"); return movescount-1; @@ -1541,8 +1529,7 @@ continue; /* No need for all the calculations */ if (warmap.cost[x1][y1] == MAXCOST) { - ptile = map_get_tile(x1, y1); - penemy = is_non_allied_unit_tile(ptile, pplayer); + penemy = is_non_allied_unit_tile(map_get_tile(x1, y1), pplayer); if (!penemy || (x1 == dest_x && y1 == dest_y)) { /* allow attack goto's */ cost = warmap.cost[x1][y1] = warmap.cost[x][y] + 1;