Mon 02 Apr 2012 12:30:30 AM UTC, SVN revision 53751: Refactoring move_unit(), making the algorithm more robust.
(Some obscure cases had weird results; patch #3133 )
(Browse SVN revision 53751 )
Fri 30 Mar 2012 10:41:28 PM UTC, comment #13: No, it was used just nowhere.
And afaik no, the leaders in the status tables are visible (or not) based upon the side settings (shroud,fog,hidden), independently from the game's progress.
Fri 30 Mar 2012 08:39:33 AM UTC, comment #12: could this be related to the status table which shows oposit teams ?
IIRC the oposit leader isn't filled until you see the opposite team (maybe the opposite leader, not sure)
Fri 30 Mar 2012 02:18:49 AM UTC, comment #11: Well, I had figured the team::seen_ stuff had to do with something I read a while ago dealing with music and multiplayer. My main concern was to keep it working at least as well as it had been previously, and I could look at it more later.
Let me see... I don't know if this is exactly where I saw it before, but searching the bugs turned up bug #4609 and bug #4617 . Back in 2005, the last player in a fogged multiplayer game had an advantage in that the music would let him know which factions the other players were using before his first turn. Maybe team::seen_ was used to randomize the music until the opponents' factions were known (though seeing their units).
However, 'grep -r "has_seen"' shows only one occurrence, and that is where the function is defined in team.hpp. (Plus seen_ is not used by team outside see()/has_seen().) So it's not used? I guess there is something else solving the music issue? (No longer playing other sides' themes during their movement? I have not played multiplayer to find out.) Looks like team::seen_ might be something that has outlived its usefulness.
(No, I do not know why I would have seen such old bug reports before; those are from well before I discovered the game. Possibly I had done an unrelated search and just stumbled upon them.)
Thu 29 Mar 2012 11:17:38 PM UTC, comment #10: Ok, well. I think I at least grasp the problem case you describe, why the original algorithm causes it and yours doesn't. The VC debugger goes through your code without complaints which generally means you ain't doing bad stuff with iterators. I find it easier to understand with your modifications since you divide it more apart into parts. And yes I think you understand it probably better than me and I feel comfortable about you becoming a dev, since I think that you know what you're doing (that is the important question always).
So, I'd say the patch is save to apply.
And btw; this team::seen_ variable an related functions seem unused (you seem to have put a comment about it). I know of no such functionality (teams knowing about which other teams they know - all teams always know all other teams).
Wed 28 Mar 2012 08:48:50 PM UTC, comment #9: Crab: I'm taking ownership of this patch while discussing it's relation to patch https://gna.org/patch/?3186
If you still want to handle it specifically, ping me on IRC
jamit : see my comment on the other patch
Thu 22 Mar 2012 10:41:28 AM UTC, comment #8: brilliand:
I thought about adding a "movethrough" event myself, but decided to fix the algorithm before adding complexities to it. On the other hand, if adding complexities fixes the algorithm as a side-effect, that might be a more efficient course of action. Let me see what you have done...
I see your patch takes the "trailing pointer" approach. I had considered that, but I found it insufficient in at least one case. Since I was going to end up essentially going through the route twice anyway, I opted for an approach I consider easier to follow when reading the code.
Your patch appears to not handle that one case correctly, and I think there are some other oddball cases that it also falls short on. I'll run some tests to confirm, and if it does fall short, I can give you some test scenarios to work with. Or we can leave it as a question of which is more pressing -- adding your "movethrough" event or making movement work correctly in obscure cases.
So what is this case that made me drop the trailing pointer approach? It can get complicated in "typical" situations just because of all the factors that can be involved, so I'll push it to an extreme, yet simple, version. Suppose you are in a scenario with fog, and your quick lancer is in the middle of flat terrain surrounded by friendly heavy infantrymen. Really surrounded, as in every hex the lancer could move to this turn is occupied. If you click the lancer, then click an unoccupied hex (setting up a multi-turn move), there should be no effect because of the infantry. However, if you move the infantryman who is where the lancer wanted to end this turn, then repeat clicking the lancer and the multi-turn destination hex, the lancer should now move to the just-vacated hex, and clear fog from every hex along the first leg of that multi-turn route.
Here is the problem: how do you know which hexes to clear of fog before you know if you have a hex you can move to? (If you clear fog before determining if the lancer can actually move, you allow the lancer to scout in all directions before committing to any actual movement.) My approach is to first see where the lancer can go based on known information, then iterate through the route a second time to handle discoveries, such as clearing fog.
Wed 21 Mar 2012 02:29:33 PM UTC, comment #7: I think my patch #3186 is a competitor to this patch. It revises move_unit() with a different purpose in mind (adding [event]name=movethrough), but it happens to fix the particular problem mentioned in the first comment to this patch.
Thu 23 Feb 2012 05:51:37 PM UTC, comment #6: Sure, this happens all the time, Linux-devs breaking compilation on other systems. And vice versa, but me no longer since I use a recent MinGw compiler to countercheck (which didn't complain here.)
Yes, that works.
Sat 18 Feb 2012 10:45:46 PM UTC, comment #5: I hope it's apparent, but I'll say it anyway: I did not get that error when I compiled it (gcc 4.4.3, Ubuntu 10.04). The relevance of which is that I cannot be sure that any particular change will eliminate that error.
However, I do have a theory. Two lines above that, sight_it is declared as
If you change the iterator to a const iterator
does the error go away? That would fit because the only two changes to the lines throwing the error are that I put seen_units into a structure and the code itself got put into a function. The former should not cause an error, but I did flag the relevant function parameter as "const", so iterators into it should be const. I'll fix that, and if it clears up that error, I'll upload a new .diff. (If it does not clear the error, I'll look for other suspects before uploading a new .diff.)
Now that I am looking at it though, it seems odd that gcc does not throw at least a warning for me. (It should, as that is a non-const iterator into a const container.) Is there a flag missing in the make file? Or maybe it's a bug in gcc? (Or maybe a bug in old gcc?)
Sat 18 Feb 2012 09:41:55 PM UTC, comment #4: movement-split.diff doesn't compile in MSVC,
in the
// Fire sighted event here
for (sight_it = stops.seen_units.begin();
sight_it != stops.seen_units.end(); ++sight_it)
part it can't make the sight_it = stops.seen_units.begin() assignment due to missing operator (error C2679); movement-split-improved.diff improved however compiles and this is supposedly what you want to get applied.
Sat 18 Feb 2012 04:55:19 AM UTC, comment #3: OK, I divided the function into more manageable pieces, and the patch into two parts. The first part is just splitting the current function into its parts, while the second also converts those parts to my new algorithm.
(file #15164 , file #15165 )
Thu 16 Feb 2012 08:22:13 PM UTC, comment #2: Smaller functions? I could do that. (In fact, I would prefer that. It just seemed as though the existing style had a preference for monolithic functions, so I went with what was there.)
Yes, same name from the forums.
Yes, this is "dangerous" in the sense you mean. Then again, the timing for such a change seems good as a new development cycle has just begun, so there is about as much time as possible for people to find any bugs before it gets released. (Not that I think there are any bugs, just agreement that such changes have to be assumed to be likely to introduce some.) Plus, I do believe that making the foundation more robust can reduce the number of bugs introduced in the future (so this would sort of be an investment in future growth for Wesnoth).
Well, and I guess I went for something like this because I know just how good I am, even though there is no reason for anyone in the project to know that (nor to believe me just because I said so). I do tend to go for the harder problems, and scepticism of what I offer is understandable. I just ask for a chance to be considered "not a crackpot".
Thu 16 Feb 2012 03:55:34 PM UTC, comment #1: Hello, you are the user with the same name from the forums ?
You should be aware that both the patches you submitted are hard refactoring, and such are always likely to introduce bugs, because neither the submitter nor the committer tend to be aware of all the corner cases. I mean, I wouldn't have chosen "this" as my first time patches due to needing to take responsibility for all the problems they may cause later on. (In fact, I think I never committed something so dangerous so far...)
That being said, I wouldn't be surprised if that ~500 lines function is responsible for some current problems. I would try to break it apart in smaller functions.
Thu 16 Feb 2012 12:16:42 AM UTC, original submission: I was looking through some of Wesnoth's code when I noticed some errors in the algorithm used for calculating movement. Nothing major, though, as the errors only occur in somewhat obscure cases. I thought it might be easier to fix up the code than to document all the oddball cases, so here is a patch with a corrected algorithm for move_unit() in actions.cpp.
So that I am not asking for blind trust that problems exist, I did take screenshots of one of the least obscure problem cases. The attached images show the "before" and "after" of a mouse click. The salient points are the following.
1) The unit's planned movement for the current turn ends in an enemy's ZoC.
2) The unit's planned movement for the current turn ends on a friendly unit.
3) The unit did actually move after clicking.
I would expect the unit's remaining movement to be decreased by the cost of the hexes it entered (so decreased to 8 in the example case). Instead, movement is set to the cost to enter the hexes it planned to enter this turn but did not (so was set to 1 for the second image).