Patch for fifteen.c



  Hi,

  I spent some time fiddling with the fifteen applet today and came up with this
patch.  It allows the user to shift more than one tile at once (that is, you
can shift several that are in vertical or horizontal row) and modifies the
highlighting so that only tiles which can be moved are highlighted.  (one bug
which I introduced, if you click on a tile which doesn't move anything
while the tiles are in the completed configuration, it says "you win!".  Should
be easy to fix, I know how to fix it but I don't have time now :-( )

  Daniel
Index: fifteen.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/fifteen/fifteen.c,v
retrieving revision 1.13
diff -u -r1.13 fifteen.c
--- fifteen.c	1998/12/25 04:46:45	1.13
+++ fifteen.c	1999/01/19 23:54:41
@@ -58,13 +58,27 @@
 }
 
 static gint
+move_legal(GnomeCanvasItem **board,int x,int y)
+{
+	int i;
+	for(i=0; i<4; i++)
+	{
+		if(i!=x&&!board[y*4+i])
+			return TRUE;
+		else if(i!=y&&!board[i*4+x])
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static gint
 piece_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
 {
 	GnomeCanvas *canvas;
 	GnomeCanvasItem **board;
 	GnomeCanvasItem *text;
 	int num, pos, newpos;
-	int x, y;
+	int x, y, i, j, change;
 	double dx = 0.0, dy = 0.0;
 	int move;
 
@@ -76,50 +90,57 @@
 
 	switch (event->type) {
 	case GDK_ENTER_NOTIFY:
-		gnome_canvas_item_set (text,
-				       "fill_color", "white",
-				       NULL);
+		if(move_legal(board,pos&3,pos>>2))
+			gnome_canvas_item_set (text,
+					"fill_color", "white",
+				       	NULL);
 		break;
 
 	case GDK_LEAVE_NOTIFY:
-		gnome_canvas_item_set (text,
-				       "fill_color", "black",
-				       NULL);
+		if(move_legal(board,pos&3,pos>>2))
+			gnome_canvas_item_set (text,
+				       	"fill_color", "black",
+				       	NULL);
 		break;
 
 	case GDK_BUTTON_PRESS:
 		y = pos / 4;
 		x = pos % 4;
-
-		move = TRUE;
-
-		if ((y > 0) && (board[(y - 1) * 4 + x] == NULL)) {
-			dx = 0.0;
-			dy = -1.0;
-			y--;
-		} else if ((y < 3) && (board[(y + 1) * 4 + x] == NULL)) {
-			dx = 0.0;
-			dy = 1.0;
-			y++;
-		} else if ((x > 0) && (board[y * 4 + x - 1] == NULL)) {
-			dx = -1.0;
-			dy = 0.0;
-			x--;
-		} else if ((x < 3) && (board[y * 4 + x + 1] == NULL)) {
-			dx = 1.0;
-			dy = 0.0;
-			x++;
-		} else
-			move = FALSE;
-
-		if (move) {
-			newpos = y * 4 + x;
-			board[pos] = NULL;
-			board[newpos] = item;
-			gtk_object_set_data (GTK_OBJECT (item), "piece_pos", GINT_TO_POINTER (newpos));
-			gnome_canvas_item_move (item, dx * PIECE_SIZE, dy * PIECE_SIZE);
-			test_win (board);
+		
+		for( i=0; i<4; i++)
+		{
+			if( x!=i && !board[y*4+i] )
+			{
+				change=(i>x)?-1:1;
+				dx=(i>x)?1.0:-1.0;
+				for(j=i+change; j!=x+change; j+=change)
+				{
+					item=board[y*4+j];
+					board[y*4+(j-change)]=item;
+					gtk_object_set_data(GTK_OBJECT(item),"piece_pos",GINT_TO_POINTER(y*4+(j-change)));
+					gnome_canvas_item_move (item, dx * PIECE_SIZE, dy * PIECE_SIZE);
+				}
+				
+				board[y*4+(j-change)]=NULL;
+				break;
+			}
+			else if(y!=i && !board[i*4+x] )
+			{
+				change=(i>y)?-1:1;
+				dy=(i>y)?1.0:-1.0;
+				for(j=i+change; j!=y+change; j+=change)
+				{
+					item=board[j*4+x];
+					board[(j-change)*4+x]=item;
+					gtk_object_set_data(GTK_OBJECT(item),"piece_pos",GINT_TO_POINTER((j-change)*4+x));
+					gnome_canvas_item_move (item, dx * PIECE_SIZE, dy * PIECE_SIZE);
+				}
+				
+				board[(j-change)*4+x]=NULL;
+				break;
+			}
 		}
+		test_win(board);
 
 		break;
 


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