[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 I have updated your patch according to the preceeding discussions, as it seemed a much easier solution than having to muck about in the ai_fill_unit_param internals. I replaced the ignores zoc condition with a check for whether the unit is a military unit or not. This way all units that would have to cancel a treaty to move into peaceful borders do not try to do so, while units that can move freely in peaceful territory go ahead and explore it (e.g. explorers, workers, settlers, diplomats, etc.). Also, some minor style/comment/formatting fixes and a version for trunk. --- 一緒に未踏の地を探検しませんか。 diff --git a/ai/aiexplorer.c b/ai/aiexplorer.c index 3f7ffde..ac2ecb7 100644 --- a/ai/aiexplorer.c +++ b/ai/aiexplorer.c @@ -63,6 +63,63 @@ static int likely_ocean(struct tile *ptile, struct player *pplayer) } /** + Returns TRUE if a unit owned by the given player can safely explore the + given tile. This mainly takes care that military units do not try to + move into another player's territory in violation of a treaty. +**/ +static bool ai_may_explore(const struct tile *ptile, + const struct player *pplayer, + const bv_flags unit_flags) +{ + /* Don't allow military units to cross borders. */ + if (!BV_ISSET(unit_flags, F_CIVILIAN) + players_non_invade(tile_owner(ptile), pplayer)) { +return FALSE; + } + + /* Can't visit tiles with non-allied units. */ + if (is_non_allied_unit_tile(ptile, pplayer)) { +return FALSE; + } + + /* Non-allied cities are taboo even if no units are inside. */ + if (tile_city(ptile) !pplayers_allied(tile_owner(ptile), pplayer)) { +return FALSE; + } + + return TRUE; +} + +/*** + TB function used by ai_explorer_goto(). +***/ +static enum tile_behavior ai_explorer_tb(const struct tile *ptile, + enum known_type k, + const struct pf_parameter *param) +{ + if (!ai_may_explore(ptile, param-owner, param-unit_flags)) { +return TB_IGNORE; + } + return TB_NORMAL; +} + +/*** + Constrained goto using ai_may_explore(). +***/ +static bool ai_explorer_goto(struct unit *punit, struct tile *ptile) +{ + struct pf_parameter parameter; + struct ai_risk_cost risk_cost; + + ai_fill_unit_param(parameter, risk_cost, punit, ptile); + parameter.get_TB = ai_explorer_tb; + + UNIT_LOG(LOG_DEBUG, punit, ai_explorer_goto to %d,%d, + ptile-x, ptile-y); + return ai_unit_goto_constrained(punit, ptile, parameter); +} + +/** Return a value indicating how desirable it is to explore the given tile. In general, we want to discover unknown terrain of the opposite kind to our natural terrain, i.e. pedestrians like ocean and boats like land. @@ -114,12 +171,13 @@ static int explorer_desirable(struct tile *ptile, struct player *pplayer, int unknown = 0; /* First do some checks that would make a tile completely non-desirable. - * If there - * is a city on the tile, or if the tile is not accessible, or if the - * tile is on a different continent, or if we're a barbarian and - * the tile has a hut, don't go there. */ - if (tile_city(ptile) - || (is_barbarian(pplayer) tile_has_special(ptile, S_HUT))) { + * If we're a barbarian and the tile has a hut, don't go there. */ + if (is_barbarian(pplayer) tile_has_special(ptile, S_HUT)) { +return 0; + } + + /* Do no try to cross borders and break a treaty, etc. */ + if (!ai_may_explore(ptile, punit-owner, unit_type(punit)-flags)) { return 0; } @@ -298,7 +356,7 @@ enum unit_move_result ai_manage_explorer(struct unit *punit) if (best_tile != NULL) { /* 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_tile)) { +if (!ai_explorer_goto(punit, best_tile)) { /* Died? Strange... */ return MR_DEATH; } diff --git a/ai/aiexplorer.c b/ai/aiexplorer.c index 7f44a20..75fe158 100644 --- a/ai/aiexplorer.c +++ b/ai/aiexplorer.c @@ -108,6 +108,64 @@ static bool is_likely_trireme_loss(struct tile *ptile, struct player *pplayer, } /** + Returns TRUE if a unit owned by the given player can safely explore the + given tile. This mainly
Re: [Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 On Monday 24 November 2008, Madeline Book wrote: 1) it doesn't work for non_allied_unit_tiles that have only allied units on them I may be mistaken but, do you mean that the explorer can move to a tile in territory it cannot enter (by peace treaty) if there are allied units on that tile (and presumably the owner of those units is allowed to enter that territory)? As far as I know, allied units cannot be used in this way to sneak past borders (but a demonstrating savegame would convince me). You are right, below the situation I was observing - but notice that A's units are NonMil... A and B are at peace. A and C are allies without map sharing. B and C aren't at peace. C's unit - and only C's unit - is on one of B's tiles. At least A's Engineers and Settlers can access that tile. 2) fails for units that ignore controll zones (e.g. Diplomats) This confuses me, since zones of control (zoc) do not have anything to do with allowing units to enter a territory. Rather, they prevent non-ally units from moving into tiles in each others' zones of control (to summarise crudely). Maybe what you mean is that non-military units (unit flag NonMil) can enter peaceful territory, while military units cannot? So a unit with the non-military flag set to explore should consider peaceful territory allowed for the purpose of exploration? Actually Partisans aren't NonMil and still can enter peace tiles. Well, if the unit is a diplomat or spy, the other player could interpret the move as some kind of provocation, since they cannot see the 'X' showing that the unit is just there to explore. So I'm not sure that allowing the explorer AI to do that is such a good idea. I guess it is debatable, and I would accept a patch that has this behaviour. Atleast Explorer should be allowed to auto explore peace tiles. The really interresting case are diplomatic lanes - see the sea lane bug and substitute trimes with diplomats. 3) explorer_desirable doesn't check no_fights 4) explorer_desirable fails to handle allied cities Hmm, are you sure that explorer_desirable is called on tiles for which no_fights returns TB_IGNORE? I mean the tiles that are passed into explorer_desirable are read from the path finding map which uses no_fights already to prune away those tiles, it would seem to me. If so, this pruning was introduced after the 2.1.6 release (haven't checked). Well, in any case perhaps best is to make a new tb function structured specifically for explorers and put it in common/aicore/pf_tools.c. This function should be used in ai_fill_unit_param (instead of having to be set after the call and clobbering the existing get_TB pointer), and also in explorer_desirable (if indeed it is the case that it considers tiles that might have to be ignored) so that the checking code is not duplicated in more than one place. Yes. One problem with the no_fight change is what happens to ai units on a tile that just become a peace tile. Can they still move (2.1.6) or are they frosen? ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 [EMAIL PROTECTED] - Fri Nov 21 07:07:26 2008]: Your no_fights appoach is nice but insufficent. 1) it doesn't work for non_allied_unit_tiles that have only allied units on them I may be mistaken but, do you mean that the explorer can move to a tile in territory it cannot enter (by peace treaty) if there are allied units on that tile (and presumably the owner of those units is allowed to enter that territory)? As far as I know, allied units cannot be used in this way to sneak past borders (but a demonstrating savegame would convince me). 2) fails for units that ignore controll zones (e.g. Diplomats) This confuses me, since zones of control (zoc) do not have anything to do with allowing units to enter a territory. Rather, they prevent non-ally units from moving into tiles in each others' zones of control (to summarise crudely). Maybe what you mean is that non-military units (unit flag NonMil) can enter peaceful territory, while military units cannot? So a unit with the non-military flag set to explore should consider peaceful territory allowed for the purpose of exploration? Well, if the unit is a diplomat or spy, the other player could interpret the move as some kind of provocation, since they cannot see the 'X' showing that the unit is just there to explore. So I'm not sure that allowing the explorer AI to do that is such a good idea. I guess it is debatable, and I would accept a patch that has this behaviour. 3) explorer_desirable doesn't check no_fights 4) explorer_desirable fails to handle allied cities Hmm, are you sure that explorer_desirable is called on tiles for which no_fights returns TB_IGNORE? I mean the tiles that are passed into explorer_desirable are read from the path finding map which uses no_fights already to prune away those tiles, it would seem to me. Well, in any case perhaps best is to make a new tb function structured specifically for explorers and put it in common/aicore/pf_tools.c. This function should be used in ai_fill_unit_param (instead of having to be set after the call and clobbering the existing get_TB pointer), and also in explorer_desirable (if indeed it is the case that it considers tiles that might have to be ignored) so that the checking code is not duplicated in more than one place. --- はい。君の番です。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 On Friday 21 November 2008, Madeline Book wrote: I did some more investigating in the code and it would seem that there is a much simpler way to fix the problem. The attached patch makes a one line addition to the tile behaviour parameter function no_fights() to make it ignore tiles that are part of a territory the player cannot enter by treaty. As far as I can tell, this makes auto-explore work exactly the same as your patch. I will test it some more (as I hope you and others will too) to see if there are not any bad side-effects in the AI code, since no_fights is used for more than just exploring. Your no_fights appoach is nice but insufficent. 1) it doesn't work for non_allied_unit_tiles that have only allied units on them 2) fails for units that ignore controll zones (e.g. Diplomats) 3) explorer_desirable doesn't check no_fights 4) explorer_desirable fails to handle allied cities Sample for a pedestrian(? unknown, ~ water, = land, C allied city): ??? ~C~ === ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 [EMAIL PROTECTED] - Thu Nov 20 21:19:18 2008]: In the attached game the only Columbian unit - if set to auto explore - tries to violate the peace treaty. Thanks for the savegame. I have confirmed that making the unit auto-explore causes it to stop immediately because of the potential treaty violation, even though there are other tiles it could explore instead. The attached patch now handles cities (especially allied cities where the allies didn't trade maps/map access) correctly. I did some more investigating in the code and it would seem that there is a much simpler way to fix the problem. The attached patch makes a one line addition to the tile behaviour parameter function no_fights() to make it ignore tiles that are part of a territory the player cannot enter by treaty. As far as I can tell, this makes auto-explore work exactly the same as your patch. I will test it some more (as I hope you and others will too) to see if there are not any bad side-effects in the AI code, since no_fights is used for more than just exploring. --- 確かにそんなやり方で解決できるが。 diff --git a/common/aicore/pf_tools.c b/common/aicore/pf_tools.c index 17a095c..218306e 100644 --- a/common/aicore/pf_tools.c +++ b/common/aicore/pf_tools.c @@ -463,6 +463,7 @@ enum tile_behavior no_fights(const struct tile *ptile, enum known_type known, struct pf_parameter *param) { if (is_non_allied_unit_tile(ptile, param-owner) + || players_non_invade(tile_owner(ptile), param-owner) || is_non_allied_city_tile(ptile, param-owner)) { /* Can't attack */ return TB_IGNORE; ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 [EMAIL PROTECTED] - Wed Nov 19 07:45:23 2008]: Marine explorers stop if they try to travel to or trhough a marine tile who's owner is at peace with the unit's owner. As a consequence the units are stoped and require player interaction even though there are still unexplored reacheable tiles. It would be helpful if you could post the savegame where this behaviour occurs. This will also help others to test whether your patch fixes it. The attached patch should fixe this issue in the vast majority of cases. Only if ai_manage_explorer's best_title isn't reacheable does the explorer stop, even if there are still other unexplored reachable tiles. The code in the patch seems alright, but the style could be improved. Please follow the coding style guidelines at: http://freeciv.wikia.com/wiki/Coding_Style Basically, just make your code look like the rest of the source code. In particular: - Make a comment header for every new function. - Do not put a space between the pointer star '*' and the function argument name. - Line up multi-line function arguments to one column past the '(' after the function name, using spaces. - Put a space after the 'if' keyword. - Put a space after the the closing parenthesis of an 'if' condition. - Do not put a space after the '!' operator. - Do not use c++ style comments. - Be sure to use an indentation width of 2 spaces in the code that you add. I realize this is a lot for such a small patch, but most of the time nobody wants to have to reformat other people's code just so that they can put it in the repository. And were it to happen that anybody could use their own style anytime they felt like it, the source tree would become much harder to maintain over time. --- お役所仕事は、いただきます〜 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
URL: http://bugs.freeciv.org/Ticket/Display.html?id=40570 Marine explorers stop if they try to travel to or trhough a marine tile who's owner is at peace with the unit's owner. As a consequence the units are stoped and require player interaction even though there are still unexplored reacheable tiles. The attached patch should fixe this issue in the vast majority of cases. Only if ai_manage_explorer's best_title isn't reacheable does the explorer stop, even if there are still other unexplored reachable tiles. diff -ur freeciv-2.1.6/ai/aiexplorer.c freeciv-2.1.6-marine-explorer/ai/aiexplorer.c --- freeciv-2.1.6/ai/aiexplorer.c 2008-08-10 14:56:15.0 +0200 +++ freeciv-2.1.6-marine-explorer/ai/aiexplorer.c 2008-11-18 14:30:08.0 +0100 @@ -107,6 +107,51 @@ } } +/* + * Explorers shouldn't try to break a peace treaty and thus cause + * player interaction. + */ +static bool ai_may_explore(const struct tile * ptile, +const struct player * pplayer, const bv_flags unit_flags) +{ + if(! BV_ISSET(unit_flags, F_IGZOC)){ +// don't invade unless there are only allied troops on the tile +if(players_non_invade(ptile-owner, pplayer)){ + if(!is_allied_unit_tile(ptile, pplayer)){ +return FALSE; + } +} + } + + // don't attack + if(is_non_allied_unit_tile(ptile, pplayer)){ +return FALSE; + } + + return TRUE; +} + +enum tile_behavior ai_explorer_tb(const struct tile *ptile, enum known_type k, +struct pf_parameter * param) +{ + if(!ai_may_explore(ptile, param-owner, param-unit_flags)){ +return TB_IGNORE; + } + return TB_NORMAL; +} + +static bool ai_explorer_goto(struct unit *punit, struct tile *ptile) +{ + struct pf_parameter parameter; + struct ai_risk_cost risk_cost; + + ai_fill_unit_param(parameter, risk_cost, punit, ptile); + parameter.get_TB = ai_explorer_tb; + + UNIT_LOG(LOG_DEBUG, punit, ai_explorer_goto to %d,%d, ptile-x, ptile-y); + return ai_unit_goto_constrained(punit, ptile, parameter); +} + /** Return a value indicating how desirable it is to explore the given tile. In general, we want to discover unknown terrain of the opposite kind to @@ -170,6 +215,11 @@ return 0; } + /* Enforce diplomatic realtions. */ + if(! ai_may_explore(ptile, punit-owner, unit_type(punit)-flags)){ + return 0; + } + /* What value we assign to the number of land and water tiles * depends on if we're a land or water unit. */ if (is_ground_unit(punit)) { @@ -345,7 +395,7 @@ if (best_tile != NULL) { /* 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_tile)) { +if (!ai_explorer_goto(punit, best_tile)) { /* Died? Strange... */ return MR_DEATH; } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev