/// <summary> /// Sets the size of the sub grid /// </summary> /// <param name="pSubGridSize">The raw entry from the puzzle file for the sub grid size</param> private void GetSubGridSize(string pSubGridSize) { //Checks to ensure it is in the correct format if (pSubGridSize.Length == 3) { //Parses the size string m_SubGridSize = GridSize.Parse(pSubGridSize); //Checks to ensure the sub grid rows and columns multiplies is the size of the full puzzle if (m_SubGridSize.rowCount * m_SubGridSize.columnCount != m_PuzzleSize) { throw new Exception(String.Format("File read error - Sub grid values must multiply ({0}) to equal the length of the symbol set ({1}) (Puzzle size)", m_SubGridSize.rowCount * m_SubGridSize.columnCount, m_PuzzleSize)); } } else { throw new Exception("File read error - There must only be 1 sub grid size of rows followed by collumns eg. 3x3"); } }
/// <summary> /// Used to clone a puzzle /// </summary> /// <param name="pPuzzle">The puzzle to be cloned</param> private Puzzle(Puzzle pPuzzle) { m_PuzzleSize = pPuzzle.m_PuzzleSize; m_SubGridSize = pPuzzle.m_SubGridSize; m_Rows = new ObservableCollection <ObservableCollection <Cell> >(); m_CurrentSymbolSet = pPuzzle.m_CurrentSymbolSet; Symbol.SetSymbols(m_CurrentSymbolSet); foreach (ObservableCollection <Cell> row in pPuzzle.m_Rows) { ObservableCollection <Cell> column = new ObservableCollection <Cell>(); foreach (Cell cell in row) { Cell currentCell = cell.Clone(); column.Add(currentCell); } m_Rows.Add(column); } SetCellRelations(); SetCellPossibleValues(); }
public Puzzle GeneratePuzzle(int pPuzzleSize, GridSize pSubGridSize) { m_PuzzleSize = pPuzzleSize; m_SubGridSize = pSubGridSize; int[,] puzzle = new int[m_PuzzleSize, m_PuzzleSize]; m_BruteForce = new BruteForce(); int numberOfCellsEntered = 0; bool puzzleFound = false; while (!puzzleFound) { int row = RNG.RANDOM.Next(0, m_PuzzleSize); int col = RNG.RANDOM.Next(0, m_PuzzleSize); while (puzzle[row, col] != 0) { row = RNG.RANDOM.Next(0, m_PuzzleSize); col = RNG.RANDOM.Next(0, m_PuzzleSize); } int[] possibles = PossibleValues(puzzle, row, col); if (possibles.Length > 0) { puzzle[row, col] = possibles[RNG.RANDOM.Next(possibles.Length)]; numberOfCellsEntered++; } else { numberOfCellsEntered = 0; puzzle = new int[m_PuzzleSize, m_PuzzleSize]; continue; } if (numberOfCellsEntered > (m_PuzzleSize * m_PuzzleSize) / (m_PuzzleSize / 2)) { m_BruteForce = new BruteForce(); var task = Task.Run(() => m_BruteForce.Solve(puzzle, m_PuzzleSize, m_SubGridSize)); if (!task.Wait(TimeSpan.FromSeconds(1))) { m_BruteForce = new BruteForce(); numberOfCellsEntered = 0; puzzle = new int[m_PuzzleSize, m_PuzzleSize]; continue; } if (m_BruteForce.numberOfSolutions > 0) { puzzleFound = true; continue; } else { m_BruteForce = new BruteForce(); numberOfCellsEntered = 0; puzzle = new int[m_PuzzleSize, m_PuzzleSize]; } } } m_BruteForce = new BruteForce(); int numberOfHints = (m_PuzzleSize * m_PuzzleSize) / (m_PuzzleSize / 2) + ((m_PuzzleSize * m_PuzzleSize) / 4); int currentNumberOfHints = m_PuzzleSize * m_PuzzleSize; int tries = 0; int lowestNumber = int.MaxValue; int[,] currentPuzzle = Clone(puzzle); int[,] previousPuzzle = Clone(puzzle); while (true) { int row = RNG.RANDOM.Next(0, m_PuzzleSize); int col = RNG.RANDOM.Next(0, m_PuzzleSize); while (currentPuzzle[row, col] == 0) { row = RNG.RANDOM.Next(0, m_PuzzleSize); col = RNG.RANDOM.Next(0, m_PuzzleSize); } currentPuzzle[row, col] = 0; currentNumberOfHints--; m_BruteForce = new BruteForce(); m_BruteForce.Solve(Clone(currentPuzzle), m_PuzzleSize, m_SubGridSize); if (m_BruteForce.numberOfSolutions == 1) { if (currentNumberOfHints < lowestNumber) { lowestNumber = currentNumberOfHints; previousPuzzle = Clone(currentPuzzle); } continue; } else { if (currentNumberOfHints <= numberOfHints || tries == 10) { puzzle = previousPuzzle; break; } else { tries++; currentPuzzle = Clone(puzzle); m_BruteForce = new BruteForce(); currentNumberOfHints = m_PuzzleSize * m_PuzzleSize; } } } return(new Puzzle(puzzle, m_PuzzleSize, m_SubGridSize)); }