[gnome-tetravex] Ensure the puzzle is unsolved at start.



commit bbc65a9d20dc04208a9f81ad00c5bac52973083c
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Wed Sep 18 01:34:00 2019 +0200

    Ensure the puzzle is unsolved at start.
    
    Granted, it was only a problem
    for two by two boards. Anyway.

 src/puzzle.vala | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)
---
diff --git a/src/puzzle.vala b/src/puzzle.vala
index 05f9f0c..9ebee1e 100644
--- a/src/puzzle.vala
+++ b/src/puzzle.vala
@@ -94,6 +94,13 @@ private class Puzzle : Object
     }
 
     construct
+    {
+        do { init_board (size, out board); }
+        while (solved_on_right ());
+
+        start_clock ();
+    }
+    private static inline void init_board (uint8 size, out Tile? [,] board)
     {
         board = new Tile? [size * 2, size];
         for (uint8 x = 0; x < size; x++)
@@ -136,18 +143,40 @@ private class Puzzle : Object
         }
 
         /* ...and place then randomly on the right hand side */
+        int32 length = (int32) tiles.length ();
         for (uint8 x = 0; x < size; x++)
         {
             for (uint8 y = 0; y < size; y++)
             {
-                int32 n = Random.int_range (0, (int32) tiles.length ());
+                int32 n = Random.int_range (0, length);
                 Tile tile = tiles.nth_data ((uint) n);
                 board [x + size, y] = tile;
                 tiles.remove (tile);
+                length--;
             }
         }
-
-        start_clock ();
+    }
+    private inline bool solved_on_right ()
+    {
+        for (uint8 x = size; x < 2 * size; x++)
+        {
+            for (uint8 y = 0; y < size; y++)
+            {
+                Tile? tile = board [x, y];
+                if (tile == null)
+                    return false;
+
+                if (x > 0        && board [x - 1, y] != null && ((!) board [x - 1, y]).east  != ((!) 
tile).west)
+                    return false;
+                if (x < size - 1 && board [x + 1, y] != null && ((!) board [x + 1, y]).west  != ((!) 
tile).east)
+                    return false;
+                if (y > 0        && board [x, y - 1] != null && ((!) board [x, y - 1]).south != ((!) 
tile).north)
+                    return false;
+                if (y < size - 1 && board [x, y + 1] != null && ((!) board [x, y + 1]).north != ((!) 
tile).south)
+                    return false;
+            }
+        }
+        return true;
     }
 
     internal Tile? get_tile (uint8 x, uint8 y)


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