From 82b8146f8723e1dc65e8ecbc80dc4740c4cdde6d Mon Sep 17 00:00:00 2001
From: bionic85 <144353436+bionic85@users.noreply.github.com>
Date: Wed, 27 Nov 2024 20:09:32 +0100
Subject: [PATCH] Binary Generator is done kinda type shit

---
 PuzzlePlayer/Binary.cs       | 47 +++++++++++++++++++++++++++++-------
 PuzzlePlayer/Board.cs        | 27 +++------------------
 PuzzlePlayer/PuzzleForm.cs   |  2 +-
 PuzzlePlayer/PuzzlePlayer.cs |  2 +-
 4 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/PuzzlePlayer/Binary.cs b/PuzzlePlayer/Binary.cs
index e87269a..cd9d37e 100644
--- a/PuzzlePlayer/Binary.cs
+++ b/PuzzlePlayer/Binary.cs
@@ -4,6 +4,7 @@ using System.Diagnostics;
 using System.Drawing;
 using System.Linq;
 using System.Runtime.CompilerServices;
+using System.Windows.Forms;
 
 namespace PuzzlePlayer_Namespace
 { 
@@ -74,13 +75,41 @@ namespace PuzzlePlayer_Namespace
         // generates a random solvable board
         public override void Generate()
         {
-            // start with a clear board
-            int[,] startBoard = GetClearBoard(boardState.GetLength(0));
+            // generate a board with a brute force methode
+            // this methode works fine for boards with a size of 6x6 or less. But takes exponential more time if the board size is bigger
+            int counter = 1;
+            int[,] generatedBoard;
 
-            // generate a board
-            int[,] generatedBoard = BackTrackAlgorithm(startBoard, new HashSet<string>());
+            //generates a board starting with an empty board and a empty HashSet
+            while ((generatedBoard = BackTrackAlgorithm(GetClearBoard(boardState.GetLength(0)), new HashSet<string>())) == null)
+            {
+                counter++;
+                Debug.WriteLine($"board is null....trying for  the {counter} time");
+            }
+            MessageBox.Show($"Found board in {counter} tries");
+
+            boardState = (int[,])generatedBoard.Clone();
+            
+
+            Random rnd = new Random();
+            //remove spaces until the board is unsolvable, then go one step back
+            while (true)
+            {
+                int[,] copy = (int[,])boardState.Clone();
+                int x = rnd.Next(boardState.GetLength(0));
+                int y = rnd.Next(boardState.GetLength(1));
 
-            boardState = generatedBoard;
+                if (boardState[x,y] != emptySpace)
+                    boardState[x,y] = emptySpace;
+
+                if(Solve(true) == SOLUTIONS.NONE)
+                {
+                    boardState = (int[,])copy.Clone();
+                    break;
+                }
+            }
+            // save the generated board for testing the users solution and the use of a reset button
+            lastGeneratedBoard = (int[,])boardState.Clone();
         }
 
         
@@ -136,6 +165,7 @@ namespace PuzzlePlayer_Namespace
 
         private static int recursionDepth = 0;
         private static int maxDepth = 100000; // max recurtion depth that is allowed
+        private static int maxBoardsInHashSet = 40000;
 
         // generates a random board with a backtracking algorithm
         // After searching online about what the best way is to make a random puzzle generator a lot of people pointed towards a backtracking algorithm
@@ -145,11 +175,10 @@ namespace PuzzlePlayer_Namespace
         // It uses a HashSet to blablalblalbllablalblablablal
         private static int[,] BackTrackAlgorithm(int[,] board, HashSet<string> alreadyCheckedBoards)
         {
-            recursionDepth++;
-            if (recursionDepth > maxDepth)
+            //recursionDepth++;
+            if (recursionDepth > maxDepth || alreadyCheckedBoards.Count > maxBoardsInHashSet)
             {
-                Debug.WriteLine("Max recursion depth reached.");
-                return board;
+                return null;
             }
             // print board for debugging
             //PrintBoard(board);
diff --git a/PuzzlePlayer/Board.cs b/PuzzlePlayer/Board.cs
index cd4170a..edc10d8 100644
--- a/PuzzlePlayer/Board.cs
+++ b/PuzzlePlayer/Board.cs
@@ -40,31 +40,10 @@ namespace PuzzlePlayer_Namespace
         protected const int emptySpace = -1; // for every puzzle -1 represents a empty space
         public string description;
 
-        // a property for getting and setting the boardsstate. The boardstate should only be setted if the imputed int[,] is valid.
+        // variables to keep track of the board state and the last generated board
         public int[,] boardState;
+        public int[,] lastGeneratedBoard;
 
-        /*
-        public int[,] BoardState
-        {
-            get { return boardState; }
-        }
-        */
-
-        /*
-        // checks if the board is valid and solvable before setting the variable.
-        public bool setBoardState(int[,] newState)
-        {
-            int[,] copy = boardState;
-            boardState = newState;
-            if (IsBoardValid(newState) && Solve(true) == SOLUTIONS.UNIQUE) //HIER GAAT HET FOUT
-                return true;
-            else
-            {
-                boardState = copy;
-                return false;
-            }
-        }
-        */
         public abstract void Draw(Graphics gr, Point p, Size s);
 
         // a methode for solving the whole board. It uses the private SolveStep methode untill the whole board is solved
@@ -72,7 +51,7 @@ namespace PuzzlePlayer_Namespace
         public SOLUTIONS Solve(bool CheckOnly)
         {
             // two variables for storing the result and the next solveStep
-            int[,] result = boardState;
+            int[,] result = (int[,])boardState.Clone();
             List<Move> possibleMoves;
 
             // keep looping until the SolveStep returns an empty list
diff --git a/PuzzlePlayer/PuzzleForm.cs b/PuzzlePlayer/PuzzleForm.cs
index 74d1d0f..6a2d6c6 100644
--- a/PuzzlePlayer/PuzzleForm.cs
+++ b/PuzzlePlayer/PuzzleForm.cs
@@ -47,7 +47,7 @@ namespace PuzzlePlayer_Namespace
             };
 
             // example board: https://imgur.com/spyYaPl
-            ///*
+            /*
             int[,] test = Binary.GetClearBoard(Board.boardState.GetLength(0));
 
             test[0, 0] = 1;
diff --git a/PuzzlePlayer/PuzzlePlayer.cs b/PuzzlePlayer/PuzzlePlayer.cs
index 7d94311..b7b74b7 100644
--- a/PuzzlePlayer/PuzzlePlayer.cs
+++ b/PuzzlePlayer/PuzzlePlayer.cs
@@ -9,7 +9,7 @@ namespace PuzzlePlayer_Namespace
     {
         internal static void Main(string[] args)
         {
-            Application.Run(new PuzzleForm(new Binary()));
+            Application.Run(new PuzzleForm(new Binary(6)));
         }
     }
 
-- 
GitLab