From ab448a9eac4413df86c82e2610fe5e619e58beb1 Mon Sep 17 00:00:00 2001
From: bionic85 <144353436+bionic85@users.noreply.github.com>
Date: Tue, 26 Nov 2024 17:53:14 +0100
Subject: [PATCH] HashSet Implement

---
 PuzzlePlayer/Binary.cs | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/PuzzlePlayer/Binary.cs b/PuzzlePlayer/Binary.cs
index 8d9f878..7bc00fd 100644
--- a/PuzzlePlayer/Binary.cs
+++ b/PuzzlePlayer/Binary.cs
@@ -78,13 +78,13 @@ namespace PuzzlePlayer_Namespace
             int[,] startBoard = GetClearBoard(boardState.GetLength(0));
 
             // generate a board
-            int[,] generatedBoard = BackTrackAlgorithm(startBoard);
+            int[,] generatedBoard = BackTrackAlgorithm(startBoard, new HashSet<int[,]>());
 
             boardState = generatedBoard;
         }
 
         private static int recursionDepth = 0;
-        private static int maxDepth = 1000000; // 1 mil recursions are allowed
+        private static int maxDepth = 100000; // max recurtion depth that is allowed
 
         private static void PrintBoard(int[,] board)
         {
@@ -101,7 +101,7 @@ namespace PuzzlePlayer_Namespace
         // After searching online about what the best way is to make a random puzzle generator a lot of people pointed towards a backtracking algorithm
         // I found the information about what a backtracking algorithm is here: https://www.geeksforgeeks.org/introduction-to-backtracking-2/
         // But i wrote all the code myself
-        private static int[,] BackTrackAlgorithm(int[,] board)
+        private static int[,] BackTrackAlgorithm(int[,] board, HashSet<int[,]> alreadyCheckedBoards)
         {
             recursionDepth++;
             if (recursionDepth > maxDepth)
@@ -114,7 +114,11 @@ namespace PuzzlePlayer_Namespace
 
             // check if the board is complete. if so then we can return the result
             if (IsBoardCompletlyFilledIn(board))
+            {
+                recursionDepth--;
                 return board;
+            }
+
 
             // get all the possible choices and per choice do the backtrackAlgorithm
             List<Move> choices = GetChoices(board);
@@ -123,13 +127,16 @@ namespace PuzzlePlayer_Namespace
             // and because we already did a check if the board is completly filled-in, we know that we need to backtrack
             if (choices.Count == 0)
             {
-                //Debug.WriteLine("backtrack want count ==0");
+                recursionDepth--;
                 return null; // backtrack
             }
 
             // check if the current board is already imposible to complete even tho there are still choices left
             if (!BoardIsPosible(board, choices))
+            {
+                recursionDepth--;
                 return null;
+            }
 
             ///*
             // shuffle the choices in the list around to get different results every time
@@ -152,18 +159,31 @@ namespace PuzzlePlayer_Namespace
             {
                 int[,] newBoard = (int[,])board.Clone(); //create a shallow clone to avoid multiple paths refrencing the same object
 
-                newBoard[m.x,m.y] = m.changeTo;
+                newBoard[m.x, m.y] = m.changeTo;
+
+                if (alreadyCheckedBoards.Contains(newBoard))
+                {
+                    recursionDepth--;
+                    return null; //This point is never reached ????
+                }
+
+                alreadyCheckedBoards.Add(newBoard);
 
-                int[,] result = BackTrackAlgorithm(newBoard); // recursion for every move
+                int[,] result = BackTrackAlgorithm(newBoard, alreadyCheckedBoards); // recursion for every move
 
-                if(result != null)
+                if (result != null)
+                {
+                    recursionDepth--;
                     return result;
+                }
+  
             }
 
             recursionDepth--;
 
             // if all choices fail then we should also return null
             return null;
+
         }
 
         // checks if the board has a possible outcome to optimise the generating process
-- 
GitLab