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