gnome-games r7585 - trunk/gnibbles



Author: andreasr
Date: Mon Apr  7 21:58:55 2008
New Revision: 7585
URL: http://svn.gnome.org/viewvc/gnome-games?rev=7585&view=rev

Log:
Patch fixing collision detection of worms heads (bug #400395).


Modified:
   trunk/gnibbles/ChangeLog
   trunk/gnibbles/gnibbles.c
   trunk/gnibbles/worm.c
   trunk/gnibbles/worm.h

Modified: trunk/gnibbles/gnibbles.c
==============================================================================
--- trunk/gnibbles/gnibbles.c	(original)
+++ trunk/gnibbles/gnibbles.c	Mon Apr  7 21:58:55 2008
@@ -487,23 +487,25 @@
     status &= !dead[i];
   }
 
+  for (i = 0; i < properties->numworms; i++)
+    if (!dead[i] && worms[i]->lives > 0)
+      gnibbles_worm_move_tail (worms[i]);
+
+  for (i = 0; i < properties->numworms; i++)
+    if (!dead[i] && worms[i]->lives > 0)
+      gnibbles_worm_draw_head (worms[i]);
+
+
   /* If one worm has died, me must make sure that an earlier worm was not
    * supposed to die as well. */
 
-  if (!status)
-    for (i = 0; i < properties->numworms; i++)
-      if (!dead[i])
-	for (j = 0; j < properties->numworms; j++) {
-	  if (i != j
-	      && worms[i]->xhead == worms[j]->xhead
-	      && worms[i]->yhead == worms[j]->yhead)
-	    dead[i] = TRUE;
-	  gnibbles_draw_pixmap (BLANKPIXMAP,
-				worms[i]->xtail, worms[i]->ytail);
-	  gnibbles_draw_pixmap
-	    (properties->wormprops[i]->color,
-	     worms[i]->xhead, worms[i]->yhead);
-	}
+  for (i = 0; i < properties->numworms; i++)
+    for (j = 0; j < properties->numworms; j++) {
+      if (i != j
+          && worms[i]->xhead == worms[j]->xhead
+	  && worms[i]->yhead == worms[j]->yhead)
+	dead[i] = TRUE;
+    }
 
   for (i = 0; i < properties->numworms; i++)
     if (dead[i]) {
@@ -517,19 +519,11 @@
 				 worms[i]->ystart,
 				 worms[i]->direction_start);
 	games_sound_play ("crash");
-	return (CONTINUE);
+	/* Don't return here.  May need to reset more worms. */
 	}
 
     }
 
-  for (i = 0; i < properties->numworms; i++)
-    if (worms[i]->lives > 0)
-      gnibbles_worm_move_tail (worms[i]);
-
-  for (i = 0; i < properties->numworms; i++)
-    if (worms[i]->lives > 0)
-      gnibbles_worm_draw_head (worms[i]);
-
   if (status & GAMEOVER) {
     games_sound_play ("crash");
     games_sound_play ("gameover");

Modified: trunk/gnibbles/worm.c
==============================================================================
--- trunk/gnibbles/worm.c	(original)
+++ trunk/gnibbles/worm.c	Mon Apr  7 21:58:55 2008
@@ -358,40 +358,56 @@
 }
 
 gint
-gnibbles_worm_test_move_head (GnibblesWorm * worm)
+gnibbles_worm_can_move_to (GnibblesWorm * worm, gint x, gint y)
 {
-  int x, y;
+  if (worm->xhead == x)
+    return worm->yhead - 1 == y || worm->yhead + 1 == y;
+  if (worm->yhead == y)
+    return worm->xhead - 1 == x || worm->xhead + 1 == x;
+  return (FALSE);
+}
 
-  x = worm->xhead;
-  y = worm->yhead;
+void
+gnibbles_worm_position_move_head (GnibblesWorm * worm, gint *x, gint *y)
+{
+  *x = worm->xhead;
+  *y = worm->yhead;
 
   switch (worm->direction) {
   case WORMUP:
-    y = worm->yhead - 1;
+    *y = worm->yhead - 1;
     break;
   case WORMDOWN:
-    y = worm->yhead + 1;
+    *y = worm->yhead + 1;
     break;
   case WORMLEFT:
-    x = worm->xhead - 1;
+    *x = worm->xhead - 1;
     break;
   case WORMRIGHT:
-    x = worm->xhead + 1;
+    *x = worm->xhead + 1;
     break;
   }
 
-  if (x == BOARDWIDTH) {
-    x = 0;
+  if (*x == BOARDWIDTH) {
+    *x = 0;
   }
-  if (x < 0) {
-    x = BOARDWIDTH - 1;
+  if (*x < 0) {
+    *x = BOARDWIDTH - 1;
   }
-  if (y == BOARDHEIGHT) {
-    y = 0;
+  if (*y == BOARDHEIGHT) {
+    *y = 0;
   }
-  if (y < 0) {
-    y = BOARDHEIGHT - 1;
+  if (*y < 0) {
+    *y = BOARDHEIGHT - 1;
   }
+}
+
+gint
+gnibbles_worm_test_move_head (GnibblesWorm * worm)
+{
+  int x, y;
+
+  gnibbles_worm_position_move_head(worm, &x, &y);
 
   if (board[x][y] > EMPTYCHAR && board[x][y] < 'z' + properties->numworms)
     return (FALSE);
@@ -399,6 +415,23 @@
   return (TRUE);
 }
 
+gint
+gnibbles_worm_is_move_safe (GnibblesWorm * worm)
+{
+  int x, y, i;
+
+  gnibbles_worm_position_move_head(worm, &x, &y);
+
+  for (i = 0; i < properties->numworms; i++) {
+    if (i != worm->number) {
+      if (gnibbles_worm_can_move_to (worms[i], x, y))
+        return (FALSE);
+    }
+  }
+
+  return (TRUE);
+}
+
 void
 gnibbles_worm_erase_tail (GnibblesWorm * worm)
 {
@@ -635,7 +668,18 @@
     }
   }
  
-  /* Avoid walls */
+  /* Avoid walls and the heads of other snakes. */
+  for (dir = 1; dir <= 4; dir++) {
+    if (dir == opposite) continue;
+    if (!gnibbles_worm_test_move_head (worm)
+        || !gnibbles_worm_is_move_safe (worm)) {
+      worm->direction = dir;
+    } else {
+      continue;
+    }
+  }
+  /* Make sure we are at least avoiding walls.
+   * Mostly other snakes should avoid our head. */
   for (dir = 1; dir <= 4; dir++) {
     if (dir == opposite) continue;
     if (!gnibbles_worm_test_move_head (worm)) {

Modified: trunk/gnibbles/worm.h
==============================================================================
--- trunk/gnibbles/worm.h	(original)
+++ trunk/gnibbles/worm.h	Mon Apr  7 21:58:55 2008
@@ -60,8 +60,14 @@
 
 gint gnibbles_worm_handle_keypress (GnibblesWorm * worm, guint keyval);
 
+void gnibbles_worm_position_move_head (GnibblesWorm * worm, gint *x, gint *y);
+
 gint gnibbles_worm_test_move_head (GnibblesWorm * worm);
 
+gint gnibbles_worm_can_move_to (GnibblesWorm * worm, gint x, gint y);
+
+gint gnibbles_worm_is_move_safe (GnibblesWorm * worm);
+
 void gnibbles_worm_move_tail (GnibblesWorm * worm);
 
 void gnibbles_worm_undraw_nth (GnibblesWorm * worm, gint offset);



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