[Freeciv-Dev] Re: (PR#6364) exploring tririemes suck
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Thu, 2 Oct 2003, Gregory Berkolaiko wrote:
>
> On Wed, 1 Oct 2003, Jason Short wrote:
>
> > If you put a tririeme on explore, it will never leave the coast. With
> > three moves per turn, it is quite safe for it to cross danger positions
> > and return to a non-dangerous one. But the tririeme will never do this
> > (it may cross a dangerous position en route to a non-dangerous one, but
> > will never venture into a dangerous position with plans to return).
>
> Oh, lay off!!!
>
> It's better to suck than to sink!
>
> I am working on it, but PF just doesn't return dangerous positions as a
> possible destination...
Here is a quick hack and a savegame to test it. Focus on the exploring
trireme and hit enter, you will see it venture into the open for one step.
What it will not do is to count the total number of unknowns uncovered by
a given path and select the better path basing on it. This is beyond PFs
abilities.
It will also not stop in the middle of the path and try to re-evaluate the
direction it is going in. It is possible to do that, but it will make
ai_explorer too heavy I am afraid.
The patch is a quick hack, a proof of concept and must be done properly,
eventualy.
G.
? ggg.gz
? mmm.gz
? ttt.gz
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.92
diff -u -r1.92 aitools.c
--- ai/aitools.c 2003/09/28 01:04:59 1.92
+++ ai/aitools.c 2003/10/02 10:58:45
@@ -100,9 +100,12 @@
We use ai_unit_attack which means "move if target unoccupied, attack
otherwise" and also brings our bodyguard along.
*************************************************************************/
-bool ai_unit_execute_path(struct unit *punit, struct pf_path *path)
+bool ai_unit_execute_path(struct unit *punit, struct pf_path *path,
+ bool attack)
{
int i;
+ enum unit_activity activity = punit->activity;
+ handle_unit_activity_request(punit, ACTIVITY_GOTO);
/* We start with i = 1 for i = 0 is our present position */
for (i = 1; i < path->length; i++) {
@@ -114,7 +117,7 @@
* of the way so that we abort if unexpected opposition
* shows up. Any enemy on the target tile is expected to
* be our target and any attack there intentional. */
- if (i == path->length - 1) {
+ if (i == path->length - 1 && attack) {
result = ai_unit_attack(punit, x, y);
} else {
ai_unit_move(punit, x, y);
@@ -127,10 +130,12 @@
if (!same_pos(punit->x, punit->y, x, y)) {
/* Stopped (or maybe fought) */
+ handle_unit_activity_request(punit, activity);
return TRUE;
}
}
+ handle_unit_activity_request(punit, activity);
return TRUE;
}
@@ -335,7 +340,7 @@
bool alive;
CHECK_UNIT(punit);
- assert(unit_owner(punit)->ai.control);
+ // assert(unit_owner(punit)->ai.control);
assert(is_normal_map_pos(x, y));
assert(is_tiles_adjacent(punit->x, punit->y, x, y));
@@ -372,7 +377,7 @@
struct tile *ptile = map_get_tile(x,y);
CHECK_UNIT(punit);
- assert(unit_owner(punit)->ai.control);
+ // assert(unit_owner(punit)->ai.control);
assert(is_normal_map_pos(x, y));
assert(is_tiles_adjacent(punit->x, punit->y, x, y));
Index: ai/aitools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.h,v
retrieving revision 1.39
diff -u -r1.39 aitools.h
--- ai/aitools.h 2003/09/27 11:22:40 1.39
+++ ai/aitools.h 2003/10/02 10:58:45
@@ -42,7 +42,8 @@
int value, int delay, int build_cost);
int stack_cost(struct unit *pdef);
-bool ai_unit_execute_path(struct unit *punit, struct pf_path *path);
+bool ai_unit_execute_path(struct unit *punit, struct pf_path *path,
+ bool attack);
bool ai_unit_gothere(struct unit *punit);
bool ai_unit_goto(struct unit *punit, int x, int y);
void ai_unit_new_role(struct unit *punit, enum ai_unit_task task, int x, int
y);
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.297
diff -u -r1.297 aiunit.c
--- ai/aiunit.c 2003/09/28 09:33:21 1.297
+++ ai/aiunit.c 2003/10/02 10:58:46
@@ -522,6 +522,23 @@
return desirable;
}
+/****************************************************************************
+ Extra cost to encourage paths to go near unknown terrain
+****************************************************************************/
+static int explorer_EC(int x, int y, enum known_type known,
+ struct pf_parameter *param)
+{
+ int unknowns = 0;
+
+ square_iterate(x, y, 1, x1, y1) {
+ if (!map_is_known(x1, y1, param->owner)) {
+ unknowns++;
+ }
+ } square_iterate_end;
+
+ return 0 - unknowns*81;
+}
+
/**************************************************************************
Handle eXplore mode of a unit (explorers are always in eXplore mode
for AI) - explores unknown territory, finds huts.
@@ -543,13 +560,10 @@
* order to be better than the current most_desirable tile. */
int max_dist = FC_INFINITY;
- /* Coordinates of most desirable tile. Initialized to make
- * compiler happy. */
- int best_x = -1, best_y = -1;
-
/* Path-finding stuff */
struct pf_map *map;
struct pf_parameter parameter;
+ struct pf_path *path = NULL;
#define DIST_FACTOR 0.6
@@ -558,6 +572,7 @@
parameter.get_TB = no_fights_or_unknown;
/* When exploring, even AI should pretend to not cheat. */
parameter.omniscience = FALSE;
+ parameter.get_EC = explorer_EC;
map = pf_create_map(¶meter);
while (pf_next(map)) {
@@ -567,9 +582,10 @@
pf_next_get_position(map, &pos);
/* Our callback should insure this. */
- assert(map_is_known(pos.x, pos.y, pplayer));
+ // assert(map_is_known(pos.x, pos.y, pplayer));
desirable = explorer_desirable(pos.x, pos.y, pplayer, punit);
+ desirable += MAX(0, -pos.total_EC);
if (desirable == 0) {
/* Totally non-desirable tile. No need to continue. */
continue;
@@ -578,8 +594,10 @@
if (desirable > most_desirable) {
most_desirable = desirable;
- best_x = pos.x;
- best_y = pos.y;
+ if (path) {
+ free(path);
+ }
+ path = pf_next_get_path(map);
/* We want to break when
* most_desirable > BEST_POSSIBLE_SCORE * DIST_FACTOR^dist
* which is equivalent to
@@ -597,13 +615,15 @@
pf_destroy_map(map);
/* Go to the best tile found. */
- if (most_desirable > 0) {
+ if (path) {
/* TODO: read the path off the map we made. Then we can make a path
* which goes beside the unknown, with a good EC callback... */
- if (!ai_unit_goto(punit, best_x, best_y)) {
+ if (!ai_unit_execute_path(punit, path, FALSE)) {
/* Died? Strange... */
+ free(path);
return FALSE;
}
+ free(path);
if (punit->moves_left > 0) {
/* We can still move on... */
if (!same_pos(punit->x, punit->y, x, y)) {
@@ -1096,7 +1116,7 @@
while (count-- > 0 && punit->moves_left > 0
&& (path = find_rampage_target(punit, thresh_adj, thresh_move))) {
- if (!ai_unit_execute_path(punit, path)) {
+ if (!ai_unit_execute_path(punit, path, TRUE)) {
/* Died */
count = -1;
}
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.8
diff -u -r1.8 pf_tools.c
--- common/aicore/pf_tools.c 2003/09/21 09:06:43 1.8
+++ common/aicore/pf_tools.c 2003/10/02 10:58:46
@@ -361,7 +361,7 @@
|| is_non_allied_unit_tile(ptile, param->owner)
|| is_non_allied_city_tile(ptile, param->owner)) {
/* Can't attack */
- return TB_IGNORE;
+ return TB_DONT_LEAVE;
}
return TB_NORMAL;
}
ggg.gz
Description: ggg.gz
|
|