[gnome-nibbles/arnaudb/fix-level-25: 8/8] Add collision tests.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-nibbles/arnaudb/fix-level-25: 8/8] Add collision tests.
- Date: Mon, 29 Jun 2020 17:09:22 +0000 (UTC)
commit 04c24927a71967ee9da951bd2f366eb72c9f64cd
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Mon Jun 22 19:27:57 2020 +0200
Add collision tests.
Also allows to finish level 25
without the need to kill worm.
src/nibbles-game.vala | 56 +++++++++-----
src/nibbles-test.vala | 206 ++++++++++++++++++++++++++++++++++++++++++++++++--
src/worm.vala | 14 ----
3 files changed, 235 insertions(+), 41 deletions(-)
---
diff --git a/src/nibbles-game.vala b/src/nibbles-game.vala
index 368e574..a3f8e46 100644
--- a/src/nibbles-game.vala
+++ b/src/nibbles-game.vala
@@ -390,40 +390,56 @@ private class NibblesGame : Object
add_bonus (true);
var dead_worms = new Gee.LinkedList<Worm> ();
+
+ /* make AIs decide what they will do */
foreach (var worm in worms)
{
- if (worm.is_stopped)
- continue;
-
- if (worm.list.is_empty)
+ if (worm.is_stopped
+ || worm.list.is_empty)
continue;
if (!worm.is_human)
worm.ai_move (board, numworms, worms);
+ }
- 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;
- }
- }
+ /* kill worms which are hitting wall */
+ foreach (var worm in worms)
+ {
+ if (worm.is_stopped
+ || worm.list.is_empty)
+ continue;
if (!worm.can_move_to (board, numworms))
- {
dead_worms.add (worm);
+ }
+
+ /* move worms */
+ foreach (var worm in worms)
+ {
+ if (worm.is_stopped
+ || worm.list.is_empty)
continue;
- }
worm.move (board);
+
+ /* kill worms on heads collision */
+ 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);
+ }
+ }
}
+ /* remove dead worms */
foreach (var worm in dead_worms)
{
if (numworms > 1)
@@ -619,6 +635,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 */
}
diff --git a/src/worm.vala b/src/worm.vala
index 445b160..94b2c6d 100644
--- a/src/worm.vala
+++ b/src/worm.vala
@@ -291,20 +291,6 @@ private class Worm : Object
return true;
}
- internal bool will_collide_with_head (Worm other_worm)
- {
- if (!is_materialized || !other_worm.is_materialized)
- return false;
-
- var worm_pos = position_move ();
- var other_worm_pos = other_worm.position_move ();
-
- if (worm_pos == other_worm_pos)
- return true;
-
- return false;
- }
-
internal void spawn (int[,] board)
{
change = STARTING_LENGTH - 1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]