[gnome-nibbles] Fix corner-case handling of tail teleportation
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-nibbles] Fix corner-case handling of tail teleportation
- Date: Tue, 19 Aug 2014 00:46:04 +0000 (UTC)
commit 9f819cdaedd4a23f52ebc27ea0ec0267ffc5b461
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sun Jul 20 17:03:33 2014 -0500
Fix corner-case handling of tail teleportation
What we do here is really insane. After our tail moves into the
teleporter, we erase it from the text board and remove its clutter
actor, but then intentionally leave the tail pointer stationary,
trusting to the gnibbles_worm_get_tail_direction function to position it
properly on the next turn, then warping and moving the tail pointer an
extra time on that turn. This kind of works because
gnibbles_worm_get_tail_direction() operates on the clutter actors, which
are stored in a linked list and do know their position. But it's also
super fragile if we do anything interesting with the teleporters (e.g.
teleport immediately on the next move, because we came at a teleporter
from a particular direction). So instead of this
don't-move-then-move-twice nonsense, assume that if we ever do not know
which direction to move in it's because we're at a teleporter, and try
to use it.
Also, add a couple sensible assertions to make sure this assumption
always holds.
https://bugzilla.gnome.org/show_bug.cgi?id=654072
src/warpmanager.c | 26 ++++++++++++++++++--------
src/worm.c | 22 +++-------------------
2 files changed, 21 insertions(+), 27 deletions(-)
---
diff --git a/src/warpmanager.c b/src/warpmanager.c
index ed8b4af..4244be2 100644
--- a/src/warpmanager.c
+++ b/src/warpmanager.c
@@ -148,8 +148,21 @@ gnibbles_warpmanager_worm_change_pos (GnibblesWarpManager * warpmanager,
worm->xhead = x;
worm->yhead = y;
+
+ return;
}
}
+
+ g_assert_not_reached ();
+}
+
+static gboolean
+is_adjacent_to_warp (gint x, gint y, GnibblesWarp * warp)
+{
+ return abs (warp->x - x) <= 1 && abs (warp->y - y) <= 1
+ || abs (warp->x + 1 - x) <= 1 && abs (warp->y - y) <= 1
+ || abs (warp->x - x) <= 1 && abs (warp->y + 1 -y) <= 1
+ || abs (warp->x + 1 - x) <= 1 && abs (warp->y + 1 - y) <= 1;
}
void
@@ -159,14 +172,7 @@ gnibbles_warpmanager_worm_change_tail_pos (GnibblesWarpManager * warpmanager,
int i, x, y, good;
for (i = 0; i < warpmanager->numwarps; i++) {
- if ((worm->xtail == warpmanager->warps[i]->x &&
- worm->ytail == warpmanager->warps[i]->y) ||
- (worm->xtail == warpmanager->warps[i]->x + 1 &&
- worm->ytail == warpmanager->warps[i]->y) ||
- (worm->xtail == warpmanager->warps[i]->x &&
- worm->ytail == warpmanager->warps[i]->y + 1) ||
- (worm->xtail == warpmanager->warps[i]->x + 1 &&
- worm->ytail == warpmanager->warps[i]->y + 1)) {
+ if (is_adjacent_to_warp (worm->xtail, worm->ytail, warpmanager->warps[i])) {
x = warpmanager->warps[i]->wx;
y = warpmanager->warps[i]->wy;
@@ -185,8 +191,12 @@ gnibbles_warpmanager_worm_change_tail_pos (GnibblesWarpManager * warpmanager,
worm->xtail = x;
worm->ytail = y;
+
+ return;
}
}
+
+ g_assert_not_reached ();
}
void
diff --git a/src/worm.c b/src/worm.c
index 0a576f6..6546e8c 100644
--- a/src/worm.c
+++ b/src/worm.c
@@ -429,29 +429,13 @@ gnibbles_worm_move_tail_pointer (GnibblesWorm *worm)
worm->ytail = BOARDHEIGHT - 1;
break;
default:
+ /* OK, we're teleporting */
break;
}
- if (board->walls[worm->xtail][worm->ytail] == WARPLETTER) {
+ if (tail_dir == -1) {
gnibbles_warpmanager_worm_change_tail_pos (warpmanager, worm);
- tail_dir = gnibbles_worm_get_tail_direction (worm);
- board->walls[worm->xtail][worm->ytail] = EMPTYCHAR;
- switch (tail_dir) {
- case WORMRIGHT:
- worm->xtail++;
- break;
- case WORMDOWN:
- worm->ytail++;
- break;
- case WORMLEFT:
- worm->xtail--;
- break;
- case WORMUP:
- worm->ytail--;
- break;
- default:
- break;
- }
+ board->walls[worm->xtail][worm->ytail] = worm->number + WORMCHAR;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]