[hitori] Highlight all cells which break rule 2 instead of just the first



commit 5f8e7d8ad4e4d67ca95a1017263bd8c74803f257
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Oct 31 11:30:38 2010 +0000

    Highlight all cells which break rule 2 instead of just the first

 src/generator.c |    2 +-
 src/interface.c |    9 +++++++--
 src/main.c      |   11 -----------
 src/main.h      |    6 ++----
 src/rules.c     |   39 ++++++++++++++++++---------------------
 5 files changed, 28 insertions(+), 39 deletions(-)
---
diff --git a/src/generator.c b/src/generator.c
index c168dad..9cb4511 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -150,7 +150,7 @@ hitori_generate_board (Hitori *hitori, guint new_board_size, gint seed)
 				} while (total == 0);
 
 				hitori->board[iter.x][iter.y].num = total;
-				hitori->board[iter.x][iter.y].status &= ~CELL_PAINTED;
+				hitori->board[iter.x][iter.y].status &= (~CELL_PAINTED & ~CELL_ERROR);
 			}
 		}
 	}
diff --git a/src/interface.c b/src/interface.c
index 86549c6..47002c8 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -138,8 +138,7 @@ hitori_draw_cb (GtkWidget *drawing_area, cairo_t *cr, Hitori *hitori)
 				state = GTK_STATE_INSENSITIVE;
 
 			/* Draw the fill */
-			if (hitori->display_error == TRUE &&
-			    hitori->error_position.x == iter.x && hitori->error_position.y == iter.y)
+			if (hitori->board[iter.x][iter.y].status & CELL_ERROR)
 				cairo_set_source_rgb (cr, 0.678431373, 0.498039216, 0.658823529); /* Tango's lightest "plum" */
 			else
 				gdk_cairo_set_source_color (cr, &style->bg[state]);
@@ -407,6 +406,9 @@ hitori_undo_cb (GtkAction *action, Hitori *hitori)
 	if (hitori->undo_stack->undo == NULL || hitori->undo_stack->type == UNDO_NEW_GAME)
 		gtk_action_set_sensitive (hitori->undo_action, FALSE);
 
+	/* The player can't possibly have won, but we need to update the error highlighting */
+	hitori_check_win (hitori);
+
 	/* Redraw */
 	gtk_widget_queue_draw (hitori->drawing_area);
 }
@@ -440,6 +442,9 @@ hitori_redo_cb (GtkAction *action, Hitori *hitori)
 	if (hitori->undo_stack->redo == NULL)
 		gtk_action_set_sensitive (hitori->redo_action, FALSE);
 
+	/* The player can't possibly have won, but we need to update the error highlighting */
+	hitori_check_win (hitori);
+
 	/* Redraw */
 	gtk_widget_queue_draw (hitori->drawing_area);
 }
diff --git a/src/main.c b/src/main.c
index eacf7d1..d64e5f0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,7 +31,6 @@ void
 hitori_new_game (Hitori *hitori, guint board_size)
 {
 	hitori->made_a_move = FALSE;
-	hitori->display_error = FALSE;
 
 	hitori_generate_board (hitori, board_size, -1);
 	hitori_clear_undo_stack (hitori);
@@ -187,16 +186,6 @@ hitori_reset_timer (Hitori *hitori)
 }
 
 void
-hitori_set_error_position (Hitori *hitori, HitoriVector position)
-{
-	if (hitori->debug)
-		g_debug ("Setting error position as %u, %u", position.x, position.y);
-
-	hitori->error_position = position;
-	hitori->display_error = TRUE;
-}
-
-void
 hitori_quit (Hitori *hitori)
 {
 	static gboolean quitting = FALSE;
diff --git a/src/main.h b/src/main.h
index c60d827..c8fe02d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -51,7 +51,8 @@ typedef enum {
 	CELL_PAINTED = 1 << 1,
 	CELL_SHOULD_BE_PAINTED = 1 << 2,
 	CELL_TAG1 = 1 << 3,
-	CELL_TAG2 = 1 << 4
+	CELL_TAG2 = 1 << 4,
+	CELL_ERROR = 1 << 5
 } HitoriCellStatus;
 
 typedef struct {
@@ -83,9 +84,6 @@ typedef struct {
 	guint hint_status;
 	HitoriVector hint_position;
 
-	gboolean display_error;
-	HitoriVector error_position;
-
 	guint timer_value; /* seconds into the game */
 	GtkLabel *timer_label;
 	guint timeout_id;
diff --git a/src/rules.c b/src/rules.c
index b975dc6..96037b8 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -118,36 +118,33 @@ gboolean
 hitori_check_rule2 (Hitori *hitori)
 {
 	HitoriVector iter;
+	gboolean success = TRUE;
 
-	/*
-	 * Check the squares immediately below and to the right of the current one;
-	 * if they're painted in, the rule fails.
-	 */
-
+	/* Check the squares immediately next to the current one; if they're painted, the rule fails. */
 	for (iter.x = 0; iter.x < hitori->board_size; iter.x++) {
 		for (iter.y = 0; iter.y < hitori->board_size; iter.y++) {
-			if (hitori->board[iter.x][iter.y].status & CELL_PAINTED) {
-				if ((iter.x < hitori->board_size - 1 && hitori->board[iter.x+1][iter.y].status & CELL_PAINTED) ||
-				    (iter.y < hitori->board_size - 1 && hitori->board[iter.x][iter.y+1].status & CELL_PAINTED)) {
-					if (hitori->debug)
-						    g_debug ("Rule 2 failed");
-
-					/* Set the error position */
-					hitori_set_error_position (hitori, iter);
-
-					return FALSE;
-				}
+			if (hitori->board[iter.x][iter.y].status & CELL_PAINTED &&
+			    ((iter.x < hitori->board_size - 1 && hitori->board[iter.x+1][iter.y].status & CELL_PAINTED) ||
+			     (iter.y < hitori->board_size - 1 && hitori->board[iter.x][iter.y+1].status & CELL_PAINTED) ||
+			     (iter.x > 0 && hitori->board[iter.x - 1][iter.y].status & CELL_PAINTED) ||
+			     (iter.y > 0 && hitori->board[iter.x][iter.y - 1].status & CELL_PAINTED))) {
+				if (hitori->debug)
+					    g_debug ("Rule 2 failed");
+
+				/* Mark the cell as being erroneous and continue to the other cells so that they also get marked */
+				hitori->board[iter.x][iter.y].status |= CELL_ERROR;
+				success = FALSE;
+			} else {
+				/* Clear any error in the cell */
+				hitori->board[iter.x][iter.y].status &= ~CELL_ERROR;
 			}
 		}
 	}
 
-	if (hitori->debug)
+	if (hitori->debug && success)
 		g_debug ("Rule 2 OK");
 
-	/* Clear the error */
-	hitori->display_error = FALSE;
-
-	return TRUE;
+	return success;
 }
 
 /* Rule 3: all the unpainted cells must be joined together in one group. */



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