File indexing completed on 2024-11-03 03:48:56
0001 /*************************************************************************** 0002 * Copyright 2007 Francesco Rossi <redsh@email.it> * 0003 * Copyright 2006-2007 Mick Kappenburg <ksudoku@kappendburg.net> * 0004 * Copyright 2006-2007 Johannes Bergmeier <johannes.bergmeier@gmx.net> * 0005 * Copyright 2015 Ian Wadham <iandw.au@gmail.com> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0021 ***************************************************************************/ 0022 0023 #include "puzzle.h" 0024 #include <cstdlib> 0025 0026 0027 #include "sudokuboard.h" 0028 #include "mathdokugenerator.h" 0029 0030 namespace ksudoku { 0031 0032 Puzzle::Puzzle(SKGraph *graph, bool withSolution) 0033 : m_withSolution(withSolution) 0034 , m_graph(graph) 0035 , m_initialized(false) 0036 { } 0037 0038 int Puzzle::value(int index) const { 0039 return ((index < m_puzzle.size()) ? m_puzzle.at(index) : 0); 0040 } 0041 0042 int Puzzle::solution(int index) const { 0043 return ((index < m_solution.size()) ? m_solution.at(index) : 0); 0044 } 0045 0046 int Puzzle::hintIndex(int moveNum) const { 0047 return ((moveNum >= m_hintList.count()) ? -1 : m_hintList.at(moveNum)); 0048 } 0049 0050 bool Puzzle::init() { 0051 if(m_initialized) return false; 0052 0053 if(m_withSolution) 0054 return false; 0055 0056 // Set up an empty puzzle. The user will enter his/her own puzzle. 0057 if(m_graph) { 0058 m_puzzle = m_graph->emptyBoard(); 0059 } 0060 return true; 0061 } 0062 0063 bool Puzzle::init(int difficulty, int symmetry) { 0064 if(m_initialized) return false; 0065 0066 auto * board = new SudokuBoard (m_graph); 0067 0068 // Generate a puzzle and its solution. 0069 bool success = board->generatePuzzle (m_puzzle, m_solution, 0070 (Difficulty) difficulty, (Symmetry) symmetry); 0071 if (success) { 0072 board->getMoveList (m_hintList); 0073 } 0074 // Too many tries at generating a puzzle that meets the user's reqs. 0075 else { 0076 m_puzzle.clear(); // Wipe the puzzle and its solution. 0077 m_solution.clear(); 0078 } 0079 delete board; 0080 return success; 0081 } 0082 0083 int Puzzle::init(const BoardContents & values) { 0084 if(m_initialized) return -1; 0085 int result = -1; 0086 SudokuType t = m_graph->specificType(); 0087 0088 // Save the puzzle values and solution (if any). 0089 m_puzzle = values; 0090 m_hintList.clear(); 0091 0092 if ((t != Mathdoku) && (t != KillerSudoku)) { 0093 auto * board = new SudokuBoard (m_graph); 0094 m_solution = board->solveBoard (m_puzzle); 0095 0096 // Get SudokuBoard to check the solution. 0097 result = board->checkPuzzle (m_puzzle); 0098 if (result != 0) { 0099 board->getMoveList (m_hintList); 0100 } 0101 if (result >= 0) { 0102 result = 1; // There is one solution. 0103 } 0104 else if (result == -1) { 0105 result = 0; // There is no solution. 0106 } 0107 else { 0108 result = 2; // There is more than one solution. 0109 } 0110 delete board; 0111 } 0112 else { 0113 MathdokuGenerator mg (m_graph); 0114 result = mg.solveMathdokuTypes (m_solution, &m_hintList); 0115 } 0116 return result; 0117 } 0118 0119 }