[gnome-nibbles/arnaudb/fix-level-25] Add collision tests.



commit a53efb29932d340d02177f6af21f0baff86f4119
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Mon Jun 22 19:27:57 2020 +0200

    Add collision tests.
    
    Also improves a bit things
    for unfinishable level 25,
    but only for the 1st worm.

 src/nibbles-game.vala |  57 ++++++++++----
 src/nibbles-test.vala | 206 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 239 insertions(+), 24 deletions(-)
---
diff --git a/src/nibbles-game.vala b/src/nibbles-game.vala
index 368e574..aedcdd5 100644
--- a/src/nibbles-game.vala
+++ b/src/nibbles-game.vala
@@ -392,36 +392,59 @@ private class NibblesGame : Object
         var dead_worms = new Gee.LinkedList<Worm> ();
         foreach (var worm in worms)
         {
-            if (worm.is_stopped)
+            if (worm.is_stopped
+             || worm.list.is_empty
+             || worm.is_human)
                 continue;
 
-            if (worm.list.is_empty)
-                continue;
+            worm.ai_move (board, numworms, worms);
+        }
 
-            if (!worm.is_human)
-                worm.ai_move (board, numworms, worms);
+        foreach (var worm in worms)
+        {
+            if (worm.is_stopped
+             || worm.list.is_empty)
+                continue;
 
             foreach (var other_worm in worms)
             {
                 if (worm != other_worm
-                    && !other_worm.is_stopped
-                    && worm.will_collide_with_head (other_worm))
-                    {
-                        if (!dead_worms.contains (worm))
-                            dead_worms.add (worm);
-                        if (!dead_worms.contains (other_worm))
-                            dead_worms.add (other_worm);
-                        continue;
-                    }
+                 && !other_worm.is_stopped
+                 && !other_worm.list.is_empty
+                 && worm.will_collide_with_head (other_worm))
+                {
+                    if (!dead_worms.contains (worm))
+                        dead_worms.add (worm);
+                    if (!dead_worms.contains (other_worm))
+                        dead_worms.add (other_worm);
+                }
             }
 
             if (!worm.can_move_to (board, numworms))
-            {
                 dead_worms.add (worm);
+        }
+
+        foreach (var worm in worms)
+        {
+            if (worm.is_stopped
+             || worm.list.is_empty)
                 continue;
-            }
 
             worm.move (board);
+            foreach (var other_worm in worms)
+            {
+                if (worm != other_worm
+                 && !other_worm.is_stopped
+                 && !other_worm.list.is_empty
+                 && worm.head.x == other_worm.head.x
+                 && worm.head.y == other_worm.head.y)
+                {
+                    if (!dead_worms.contains (worm))
+                        dead_worms.add (worm);
+                    if (!dead_worms.contains (other_worm))
+                        dead_worms.add (other_worm);
+                }
+            }
         }
 
         foreach (var worm in dead_worms)
@@ -619,6 +642,8 @@ private class NibblesGame : Object
                 worms_left += 1;
             else if (worm.is_human && worm.lives <= 0)
                 return GameStatus.GAMEOVER;
+            else if (numhumans == 0 && worm.lives <= 0)
+                return GameStatus.GAMEOVER;
         }
 
         if (worms_left == 1 && numworms > 1)
diff --git a/src/nibbles-test.vala b/src/nibbles-test.vala
index d28445b..a006bc4 100644
--- a/src/nibbles-test.vala
+++ b/src/nibbles-test.vala
@@ -27,6 +27,8 @@ namespace NibblesTest
                                  test_tests);
         Test.add_func ("/Nibbles/test games",
                                  test_games);
+        Test.add_func ("/Nibbles/test heads",
+                                 test_heads);
         return Test.run ();
     }
 
@@ -49,11 +51,16 @@ namespace NibblesTest
 
         game.load_board (level_008, /* regular bonus = 8 + numworms */ 12);
 
+        ulong [] worms_handlers = new ulong [game.worms.size];
+        foreach (Worm worm in game.worms)
+            // FIXME we should not have to connect to anything 1/2
+            worms_handlers [worm.id] = worm.finish_added.connect (() => { worm.dematerialize (game.board, 
3); worm.is_stopped = false; });
+
         assert_true (game.numworms == 4);
         assert_true (game.worms.size == 4);
 
         uint8 applied_bonus = 0;
-        game.bonus_applied.connect ((bonus, worm) => { applied_bonus++; Test.message (@"worm $(worm.id) took 
bonus at [$(bonus.x), $(bonus.y)]"); });
+        ulong game_handler_1 = 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);
@@ -65,22 +72,27 @@ namespace NibblesTest
 
         // run until game is finished
         bool completed = false;
-        game.level_completed.connect (() => { completed = true; });
+        ulong game_handler_2 = game.level_completed.connect (() => { completed = true; });
         MainContext context = MainContext.@default ();
         while (!completed)
             context.iteration (/* may block */ false);
 
-        assert_true (applied_bonus == 17);
+        assert_true (applied_bonus == 15);
 
         assert_true (game.worms.@get (0).lives == 6);
-        assert_true (game.worms.@get (1).lives == 6);
+        assert_true (game.worms.@get (1).lives == 5);
         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);
+        assert_true (game.worms.@get (0).score ==  11);
+        assert_true (game.worms.@get (1).score ==  14);
+        assert_true (game.worms.@get (2).score == 119);
+        assert_true (game.worms.@get (3).score ==  19);
+
+        foreach (Worm worm in game.worms)
+            worm.disconnect (worms_handlers [worm.id]);
+        game.disconnect (game_handler_1);
+        game.disconnect (game_handler_2);
     }
 
     private const int level_008_width  = 92;
@@ -153,4 +165,182 @@ namespace NibblesTest
             "┃..........................................................................................┃",
             "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓........┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
         };
+
+    /*\
+    * * test heads
+    \*/
+
+    private static void test_heads ()
+    {
+        Test.message ("test heads 1");
+        _test_heads (test_heads_1, /* worm 0 */ 6, 4, /* worm 1 */ 11, 4, /* lives */ 6, 6);
+
+        Test.message ("test heads 2");
+        _test_heads (test_heads_2, /* worm 0 */ 6, 4, /* worm 1 */ 11, 4, /* lives */ 6, 5);
+
+        Test.message ("test heads 3");
+        _test_heads (test_heads_3, /* worm 0 */ 6, 4, /* worm 1 */ 10, 4, /* lives */ 6, 6);
+
+        Test.message ("test heads 4");
+        _test_heads (test_heads_4, /* worm 0 */ 6, 4, /* worm 1 */ 10, 4, /* lives */ 0, 0);
+
+        Test.message ("test heads 5");
+        _test_heads (test_heads_5, /* worm 0 */ 6, 1, /* worm 1 */  6, 4, /* lives */ 6, 6);
+
+        Test.message ("test heads 6");
+        _test_heads (test_heads_6, /* worm 0 */ 6, 1, /* worm 1 */  6, 4, /* lives */ 4, 6);
+
+        Test.message ("test heads 9");
+        _test_heads (test_heads_9, /* worm 0 */ 6, 1, /* worm 1 */  6, 4, /* lives */ 6, 5);
+
+        Test.message ("test heads 7");
+        _test_heads (test_heads_7, /* worm 0 */ 6, 2, /* worm 1 */  6, 4, /* lives */ 6, 6);
+
+        Test.message ("test heads 8");
+        _test_heads (test_heads_8, /* worm 0 */ 6, 2, /* worm 1 */  6, 4, /* lives */ 0, 0);
+
+        Test.message ("test heads 0");
+        _test_heads (test_heads_0, /* worm 0 */ 6, 2, /* worm 1 */  6, 4, /* lives */ 6, 6);
+    }
+
+    private static void _test_heads (string [] board,
+                                     int worm_0_x,
+                                     int worm_0_y,
+                                     int worm_1_x,
+                                     int worm_1_y,
+                                     int first_worm_lives,
+                                     int second_worm_lives)
+    {
+        NibblesGame game = new NibblesGame (/* start level */ 0, /* speed */ 0, /* fakes */ false, 
test_heads_width, test_heads_height, /* no random */ true);
+
+        game.numhumans = 0;
+        game.numai = 2;
+        game.create_worms ();
+
+        game.load_board (board, /* regular bonus */ 1);
+
+        ulong [] worms_handlers = new ulong [game.worms.size];
+        foreach (Worm worm in game.worms)
+            // FIXME we should not have to connect to anything 2/2
+            worms_handlers [worm.id] = worm.finish_added.connect (() => { worm.dematerialize (game.board, 
3); worm.is_stopped = false; });
+
+        assert_true (game.numworms == 2);
+        assert_true (game.worms.size == 2);
+
+        ulong game_handler_1 = game.bonus_applied.connect ((bonus, worm) => { Test.message (@"worm 
$(worm.id) took bonus at [$(bonus.x), $(bonus.y)]"); });
+
+        game.add_worms ();
+        game.start (/* add initial bonus */ true);
+
+        assert_true (game.worms.@get (0).lives == 6);
+        assert_true (game.worms.@get (1).lives == 6);
+
+        assert_true (game.worms.@get (0).score == 0);
+        assert_true (game.worms.@get (1).score == 0);
+
+        assert_true (game.worms.@get (0).head.x == worm_0_x && game.worms.@get (0).head.y == worm_0_y);
+        assert_true (game.worms.@get (1).head.x == worm_1_x && game.worms.@get (1).head.y == worm_1_y);
+
+        // run until game is finished
+        bool completed = false;
+        ulong game_handler_2 = game.level_completed.connect (() => { completed = true; });
+        MainContext context = MainContext.@default ();
+        do context.iteration (/* may block */ false);
+        while (!completed && (game.get_game_status () != GameStatus.GAMEOVER));
+
+        assert_true (game.worms.@get (0).lives == first_worm_lives);
+        assert_true (game.worms.@get (1).lives == second_worm_lives);
+
+        // FIXME looks like last bonus is not counted...
+        assert_true (game.worms.@get (0).score == 0);
+        assert_true (game.worms.@get (1).score == 0);
+
+        foreach (Worm worm in game.worms)
+            worm.disconnect (worms_handlers [worm.id]);
+        game.disconnect (game_handler_1);
+        game.disconnect (game_handler_2);
+    }
+
+    private const int test_heads_width = 18;
+    private const int test_heads_height = 6;
+    private const string [] test_heads_1 = {
+            "┏━━━━━━━━━━━━━━━━┓",
+            "┃................┃",
+            "┃................┃",
+            "┣━━━━━━━..━━━━━━━┫",
+            "┃▶..............◀┃",
+            "┗━━━━━━━━━━━━━━━━┛"
+        };  /* expected: 6, 6 */
+    private const string [] test_heads_2 = {
+            "┏━━━━━━━━━━━━━━━━┓",
+            "┃................┃",
+            "┃................┃",
+            "┣━━━━━━━.━━━━━━━━┫",
+            "┃▶..............◀┃",
+            "┗━━━━━━━━━━━━━━━━┛"
+        };  /* expected: 6, 5 */
+    private const string [] test_heads_3 = {
+            "┏━━━━━━━━━━━━━━━━┓",
+            "┃................┃",
+            "┃................┃",
+            "┣━━━━━━━..━━━━━━┳┫",
+            "┃▶.............◀┣┫",
+            "┗━━━━━━━━━━━━━━━┻┛"
+        };  /* expected: 6, 6 */
+    private const string [] test_heads_4 = {
+            "┏━━━━━━━━━━━━━━━━┓",
+            "┃................┃",
+            "┃................┃",
+            "┣━━━━━━━.━━━━━━━┳┫",
+            "┃▶.............◀┣┫",
+            "┗━━━━━━━━━━━━━━━┻┛"
+        };  /* expected: 0, 0 */
+    private const string [] test_heads_5 = {
+            "┏━━━━━━━┳━━━━━━━━┓",
+            "┃▶......┃........┃",
+            "┗━━━━━┓..........┃",
+            "┏━━━━━┛..........┃",
+            "┃▶......┃........┃",
+            "┗━━━━━━━┻━━━━━━━━┛"
+        };  /* expected: 6, 6 */
+    private const string [] test_heads_6 = {
+            "┏━━━━━━━┳━━━━━━━━┓",
+            "┃▶......┃........┃",
+            "┗━━━━━┓.┃........┃",
+            "┏━━━━━┛..........┃",
+            "┃▶......┃........┃",
+            "┗━━━━━━━┻━━━━━━━━┛"
+        };  /* expected: 4, 6 */
+    private const string [] test_heads_9 = {
+            "┏━━━━━━━┳━━━━━━━━┓",
+            "┃▶......┃........┃",
+            "┗━━━━━┓..........┃",
+            "┏━━━━━┛.┃........┃",
+            "┃▶......┃........┃",
+            "┗━━━━━━━┻━━━━━━━━┛"
+        };  /* expected: 6, 5 */
+    private const string [] test_heads_7 = {
+            "........┏━━━━━━━━┓",
+            "┏━━━━━━━┛........┃",
+            "┃▶...............┃",
+            "┣━━━━━━..........┃",
+            "┃▶......┃........┃",
+            "┗━━━━━━━┻━━━━━━━━┛"
+        };  /* expected: 6, 6 */
+    private const string [] test_heads_8 = {
+            "........┏━━━━━━━━┓",
+            "┏━━━━━━━┫........┃",
+            "┃▶......┃........┃",
+            "┣━━━━━━..........┃",
+            "┃▶......┃........┃",
+            "┗━━━━━━━┻━━━━━━━━┛"
+        };  /* expected: 0, 0 */
+    private const string [] test_heads_0 = {
+            "........┏━━━━━━━━┓",
+            "┏━━━━━━━┫........┃",
+            "┃▶......┃........┃",
+            "┣━━━━━━..........┃",
+            "┃▶...............┃",
+            "┗━━━━━━━━━━━━━━━━┛"
+        };  /* expected: 6, 6 */
 }


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