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