File indexing completed on 2024-04-21 04:05:04

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 }