[gnome-nibbles/arnaudb/modernize-code] Make game execution regular.



commit 3f7365136ab44dc0ccc2b82c361a1e61f171cd6c
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Fri May 29 12:44:34 2020 +0200

    Make game execution regular.
    
    Only use one main loop instead
    of two, avoiding races. Allows
    to test all faster and better.

 src/nibbles-game.vala | 48 +++++++++++-------------------------------------
 src/nibbles-test.vala | 18 +++++++++++++++---
 2 files changed, 26 insertions(+), 40 deletions(-)
---
diff --git a/src/nibbles-game.vala b/src/nibbles-game.vala
index 3c73133..06c204e 100644
--- a/src/nibbles-game.vala
+++ b/src/nibbles-game.vala
@@ -31,7 +31,6 @@ private class NibblesGame : Object
     internal const int MINIMUM_TILE_SIZE = 7;
 
     internal const int GAMEDELAY = 35;
-    private const int BONUSDELAY = 100;
 
     internal const int MAX_HUMANS = 4;
     internal const int MAX_AI = 5;
@@ -73,7 +72,6 @@ private class NibblesGame : Object
     internal bool is_paused     { internal get; private set; default = false; }
 
     private uint main_id = 0;
-    private uint add_bonus_id = 0;
 
     public bool fakes           { internal get; internal construct set; }
 
@@ -94,6 +92,7 @@ private class NibblesGame : Object
     * * Game controls
     \*/
 
+    private uint8 bonus_cycle = 0;
     internal void start (bool add_initial_bonus)
     {
         if (add_initial_bonus)
@@ -101,41 +100,23 @@ private class NibblesGame : Object
 
         is_running = true;
 
-        int worms_delay;
-        int bonus_delay;
-        switch (speed)
-        {
-            case 0: worms_delay = 7; bonus_delay = 20; break;  // used by tests
-            default:
-                if (speed > MAX_SPEED)
-                    assert_not_reached ();
-                worms_delay = GAMEDELAY * speed;
-                bonus_delay = BONUSDELAY * speed;
-                break;
-        }
-
-        main_id = Timeout.add (worms_delay, main_loop_cb);
+        main_id = Timeout.add (GAMEDELAY * speed, () => {
+                bonus_cycle = (bonus_cycle + 1) % 3;
+                if (bonus_cycle == 0)
+                    add_bonus (false);
+                return main_loop_cb ();
+            });
         Source.set_name_by_id (main_id, "[Nibbles] main_loop_cb");
-
-        add_bonus_id = Timeout.add (bonus_delay, add_bonus_cb);
-        Source.set_name_by_id (add_bonus_id, "[Nibbles] add_bonus_cb");
     }
 
     internal void stop ()
     {
         is_running = false;
 
-        if (main_id != 0)
-        {
-            Source.remove (main_id);
-            main_id = 0;
-        }
-
-        if (add_bonus_id != 0)
-        {
-            Source.remove (add_bonus_id);
-            add_bonus_id = 0;
-        }
+        if (main_id == 0)
+            return;
+        Source.remove (main_id);
+        main_id = 0;
     }
 
     internal void pause ()
@@ -442,13 +423,6 @@ private class NibblesGame : Object
         }
     }
 
-    private bool add_bonus_cb ()
-    {
-        add_bonus (false);
-
-        return Source.CONTINUE;
-    }
-
     private void bonus_found_cb (Worm worm)
     {
         var bonus = boni.get_bonus (board, worm.head.x, worm.head.y);
diff --git a/src/nibbles-test.vala b/src/nibbles-test.vala
index 67080c1..e1c148c 100644
--- a/src/nibbles-test.vala
+++ b/src/nibbles-test.vala
@@ -144,8 +144,8 @@ namespace NibblesTest
         assert_true (game.numworms == 4);
         assert_true (game.worms.size == 4);
 
-        // as there is no random, this output should be regular; it is not, surely because relying on two 
timeouts is racy
-        game.bonus_applied.connect ((bonus, worm) => { Test.message (@"worm $(worm.id) took bonus at 
[$(bonus.x), $(bonus.y)]"); });
+        uint8 applied_bonus = 0;
+        game.bonus_applied.connect ((bonus, worm) => { applied_bonus++; Test.message (@"worm $(worm.id) took 
bonus at [$(bonus.x), $(bonus.y)]"); });
 
         game.add_worms ();
         game.start (/* add initial bonus */ true);
@@ -155,12 +155,24 @@ namespace NibblesTest
         assert_true (game.worms.@get (2).head.x ==  9 && game.worms.@get (2).head.y == 39);
         assert_true (game.worms.@get (3).head.x == 51 && game.worms.@get (3).head.y == 45);
 
-        // run until game is finished; takes between 4 and 12 seconds on my computer, depending on worms 
motivation
+        // run until game is finished
         bool completed = false;
         game.level_completed.connect (() => { completed = true; });
         MainContext context = MainContext.@default ();
         while (!completed)
             context.iteration (/* may block */ false);
+
+        assert_true (applied_bonus == 17);
+
+        assert_true (game.worms.@get (0).lives == 6);
+        assert_true (game.worms.@get (1).lives == 6);
+        assert_true (game.worms.@get (2).lives == 6);
+        assert_true (game.worms.@get (3).lives == 6);
+
+        assert_true (game.worms.@get (0).score == 14);
+        assert_true (game.worms.@get (1).score == 21);
+        assert_true (game.worms.@get (2).score == 37);
+        assert_true (game.worms.@get (3).score == 16);
     }
 
     private const string level_008 = 
"fccccccccccccccccccccccccccccccccccccccce........dcccccccccccccccccccccccccccccccccccccccccg"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]