Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2005:
[Freeciv-Dev] Re: (PR#12339) Manual Turn Done in AI Mode no Longer Works
Home

[Freeciv-Dev] Re: (PR#12339) Manual Turn Done in AI Mode no Longer Works

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: badamson@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#12339) Manual Turn Done in AI Mode no Longer Works
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Feb 2005 16:47:17 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12339 >

Benedict Adamson wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=12339 >
> 
> I've noticed this with a modified version of Freeciv, based on the 
> current development version.
> 
> Previously, your could have timeout set to 0, 'take' an AI player and 
> watch the AI through the client, with turns ending only when you clicked 
> on the 'Turn Done' button.
> 
> Now, the server runs without stopping. This makes testing the AI difficult.
> 
> The code was OK on 2005-02-20. I notice there have been changes to 
> srv_main.c since then.

Argh.  This is a result of PR#576.  It is symptomatic of a larger 
problem, which is rather annoying.

Originally, we would have one sniff_packets() loop per turn.  This loop 
not only waited for network packets but also read command-line input. 
Unless the timeout was set to -1 (a special-case for autogames) it would 
not advance until "all players" press turn-done.  When a player presses 
turn-done the check_for_full_turn_done function is called, which sets 
force_end_of_sniff if necessary to advance to the next turn (more than a 
little ugly but there it is).  check_for_full_turn_done *will* set 
force_end_of_sniff if the game has only AI players, but it is not called 
until/unless someone presses turn-done (again, ugly).

One bug of the old solution is that if you have two AI players, both 
with clients connected to them, if either client presses turn-done then 
the turn will advance.  Ironically, if turnblock is disabled then this 
bug won't show up.  (This is based on the code, I haven't tested it.)

In the new model, a turn may have one or more phases.  Each phase 
doesn't end until the player or players press turn-done.  The difference 
is that even in human games some phases may have only AI players, and 
these phases must not block.  So now we have to call 
check_for_full_turn_done for all phases, without waiting for a turn-done 
packet from the client (srv_main.c:1536).  And this means the old 
check_for_full_turn_done doesn't work at all.  We need exact conditions 
for when the game should advance and when it shouldn't.

So there are basically two problems here.  The problem you're seeing is 
the easier one, which is the result of the old bug in 
check_for_full_turn_done.  The other problem may not be a problem at all 
(maybe it's a feature?), but can be dealt with (I think) by aborting the 
check if there are no connected players.  This patch does both.

(In an earlier version of the PR#576 patch I had the connected-player 
check added.  This was lost somehow in the later versions.  However this 
still wouldn't fix the manual-turn-done problem which is the result of 
an old bug.)

-jason

Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.229
diff -u -r1.229 srv_main.c
--- server/srv_main.c   23 Feb 2005 19:24:53 -0000      1.229
+++ server/srv_main.c   24 Feb 2005 00:46:05 -0000
@@ -1016,22 +1016,37 @@
 **************************************************************************/
 void check_for_full_turn_done(void)
 {
+  bool connected = FALSE;
+
   /* fixedlength is only applicable if we have a timeout set */
   if (game.fixedlength && game.timeout != 0) {
     return;
   }
 
+  /* If there are no connected players, don't automatically advance.  This is
+   * a hack to prevent all-AI games from running rampant.  Note that if
+   * timeout is set to -1 this function call is skipped entirely and the
+   * server will run rampant. */
+  players_iterate(pplayer) {
+    if (pplayer->is_connected) {
+      connected = TRUE;
+      break;
+    }
+  } players_iterate_end;
+  if (!connected) {
+    return;
+  }
+
   phase_players_iterate(pplayer) {
-    if (game.turnblock) {
-      if (!pplayer->ai.control && pplayer->is_alive
-         && !pplayer->phase_done) {
-        return;
-      }
-    } else {
-      if (pplayer->is_connected && pplayer->is_alive
-         && !pplayer->phase_done) {
-        return;
-      }
+    if (game.turnblock && !pplayer->ai.control && pplayer->is_alive
+       && !pplayer->phase_done) {
+      /* If turnblock is enabled check for human players, connected
+       * or not. */
+      return;
+    } else if (pplayer->is_connected && pplayer->is_alive
+              && !pplayer->phase_done) {
+      /* In all cases, we wait for any connected players. */
+      return;
     }
   } phase_players_iterate_end;
 

[Prev in Thread] Current Thread [Next in Thread]