1 /***************************************************************************
2 * Copyright 2006-2007 Johannes Bergmeier <johannes.bergmeier@gmx.net> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
19 #include "history.h"
20
21 namespace ksudoku {
22
HistoryEvent()23 HistoryEvent::HistoryEvent()
24 : m_cellsIndex(), m_cellsBefore(), m_cellsAfter()
25 {
26 }
27
HistoryEvent(int index,const CellInfo & changeCell)28 HistoryEvent::HistoryEvent(int index, const CellInfo& changeCell)
29 : m_cellsIndex(1, index), m_cellsBefore(), m_cellsAfter(1, changeCell)
30 {
31 }
32
HistoryEvent(const PuzzleState & puzzleChange)33 HistoryEvent::HistoryEvent(const PuzzleState& puzzleChange)
34 : m_cellsIndex(puzzleChange.size()), m_cellsBefore(), m_cellsAfter(puzzleChange.size())
35 {
36 for(int i = 0; i < puzzleChange.size(); i++) {
37 m_cellsIndex[i] = i;
38 m_cellsAfter[i] = getPuzzleCell(puzzleChange, i);
39 }
40 }
41
setPuzzleCell(PuzzleState & puzzle,int index,const CellInfo & cell) const42 void HistoryEvent::setPuzzleCell(PuzzleState& puzzle, int index, const CellInfo& cell) const {
43 switch(cell.state()) {
44 case GivenValue:
45 puzzle.setGiven(index, true);
46 puzzle.resetMarkers(index);
47 puzzle.setValue(index, cell.value());
48 break;
49 case ObviouslyWrong:
50 case WrongValue:
51 case CorrectValue:
52 puzzle.setGiven(index, false);
53 puzzle.resetMarkers(index);
54 puzzle.setValue(index, cell.value());
55 break;
56 case Marker:
57 puzzle.setGiven(index, false);
58 puzzle.setValue(index, 0);
59 puzzle.setMarkers(index, cell.markers());
60 break;
61 }
62 }
63
getPuzzleCell(const PuzzleState & puzzle,int index) const64 CellInfo HistoryEvent::getPuzzleCell(const PuzzleState& puzzle, int index) const {
65 if(puzzle.given(index)) {
66 return CellInfo(GivenValue, puzzle.value(index));
67 } else if(puzzle.value(index) == 0) {
68 return CellInfo(puzzle.markers(index));
69 } else {
70 return CellInfo(CorrectValue, puzzle.value(index));
71 }
72 }
73
74
applyTo(PuzzleState & puzzle)75 bool HistoryEvent::applyTo(PuzzleState& puzzle) {
76 if(m_cellsBefore.size() != 0 || m_cellsIndex.size() == 0)
77 return false;
78
79 m_cellsBefore = QVector<CellInfo>(m_cellsIndex.count());
80 for(int i = 0; i < m_cellsIndex.count(); ++i) {
81 m_cellsBefore[i] = getPuzzleCell(puzzle, m_cellsIndex[i]);
82 setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsAfter[i]);
83 }
84 return true;
85 }
86
undoOn(PuzzleState & puzzle) const87 bool HistoryEvent::undoOn(PuzzleState& puzzle) const {
88 if(m_cellsBefore.isEmpty() || m_cellsBefore.size() != m_cellsIndex.size())
89 return false;
90
91 for(int i = 0; i < m_cellsIndex.count(); ++i) {
92 setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsBefore[i]);
93 }
94 return true;
95 }
96
redoOn(PuzzleState & puzzle) const97 bool HistoryEvent::redoOn(PuzzleState& puzzle) const {
98 if(m_cellsBefore.isEmpty() || m_cellsBefore.size() != m_cellsIndex.size())
99 return false;
100
101 for(int i = 0; i < m_cellsIndex.count(); ++i) {
102 setPuzzleCell(puzzle, m_cellsIndex[i], m_cellsAfter[i]);
103 }
104 return true;
105 }
106
107 }
108