File indexing completed on 2024-04-28 04:04:47

0001 /***************************************************************************
0002  *   Copyright 2006-2007 Johannes Bergmeier <johannes.bergmeier@gmx.net>   *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0018  ***************************************************************************/
0019 #include "history.h"
0020 
0021 namespace ksudoku {
0022 
0023 HistoryEvent::HistoryEvent()
0024     : m_cellsIndex(), m_cellsBefore(), m_cellsAfter()
0025 {
0026 }
0027 
0028 HistoryEvent::HistoryEvent(int index, const CellInfo& changeCell) 
0029     : m_cellsIndex(1, index), m_cellsBefore(), m_cellsAfter(1, changeCell)
0030 {
0031 }
0032 
0033 HistoryEvent::HistoryEvent(const PuzzleState& puzzleChange)
0034     : m_cellsIndex(puzzleChange.size()), m_cellsBefore(), m_cellsAfter(puzzleChange.size())
0035 {
0036     for(int i = 0; i < puzzleChange.size(); i++) {
0037         m_cellsIndex[i] = i;
0038         m_cellsAfter[i] = getPuzzleCell(puzzleChange, i);
0039     }
0040 }
0041 
0042 void HistoryEvent::setPuzzleCell(PuzzleState& puzzle, int index, const CellInfo& cell) const {
0043     switch(cell.state()) {
0044         case GivenValue:
0045             puzzle.setGiven(index, true);
0046             puzzle.resetMarkers(index);
0047             puzzle.setValue(index, cell.value());
0048             break;
0049         case ObviouslyWrong:
0050         case WrongValue:
0051         case CorrectValue:
0052             puzzle.setGiven(index, false);
0053             puzzle.resetMarkers(index);
0054             puzzle.setValue(index, cell.value());
0055             break;
0056         case Marker:
0057             puzzle.setGiven(index, false);
0058             puzzle.setValue(index, 0);
0059             puzzle.setMarkers(index, cell.markers());
0060             break;
0061     }
0062 }
0063 
0064 CellInfo HistoryEvent::getPuzzleCell(const PuzzleState& puzzle, int index) const {
0065     if(puzzle.given(index)) {
0066         return CellInfo(GivenValue, puzzle.value(index));
0067     } else if(puzzle.value(index) == 0) {
0068         return CellInfo(puzzle.markers(index));
0069     } else {
0070         return CellInfo(CorrectValue, puzzle.value(index));
0071     }
0072 }
0073 
0074 
0075 bool HistoryEvent::applyTo(PuzzleState& puzzle) {
0076     if(m_cellsBefore.size() != 0 || m_cellsIndex.size() == 0)
0077         return false;
0078     
0079     m_cellsBefore = QList<CellInfo>(m_cellsIndex.count());
0080     for(int i = 0; i < m_cellsIndex.count(); ++i) {
0081         m_cellsBefore[i] = getPuzzleCell(puzzle, m_cellsIndex[i]);
0082         setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsAfter[i]);
0083     }
0084     return true;
0085 }
0086 
0087 bool HistoryEvent::undoOn(PuzzleState& puzzle) const {
0088         if(m_cellsBefore.isEmpty() || m_cellsBefore.size() != m_cellsIndex.size())
0089         return false;
0090     
0091     for(int i = 0; i < m_cellsIndex.count(); ++i) {
0092         setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsBefore[i]);
0093     }
0094     return true;
0095 }
0096 
0097 bool HistoryEvent::redoOn(PuzzleState& puzzle) const {
0098         if(m_cellsBefore.isEmpty() || m_cellsBefore.size() != m_cellsIndex.size())
0099         return false;
0100     
0101     for(int i = 0; i < m_cellsIndex.count(); ++i) {
0102         setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsAfter[i]);
0103     }
0104     return true;
0105 }
0106 
0107 }