diff options
Diffstat (limited to 'ksokoban/History.cpp')
-rw-r--r-- | ksokoban/History.cpp | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/ksokoban/History.cpp b/ksokoban/History.cpp new file mode 100644 index 00000000..4c73827d --- /dev/null +++ b/ksokoban/History.cpp @@ -0,0 +1,131 @@ +/* + * ksokoban - a Sokoban game for KDE + * Copyright (C) 1998 Anders Widell <awl@hem.passagen.se> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <qptrlist.h> + +#include "History.h" +#include "Move.h" +#include "MoveSequence.h" +#include "LevelMap.h" + +History::History() { + past_.setAutoDelete(true); + future_.setAutoDelete(true); +} + + +void +History::add(Move *_m) { + future_.clear(); + past_.append(_m); +} + +void +History::clear() { + past_.clear(); + future_.clear(); +} + +void +History::save(QString &_str) { + Move *m = past_.first(); + + while (m != 0) { + m->save(_str); + m = past_.next(); + } + _str += '-'; + + m = future_.first(); + while (m != 0) { + m->save(_str); + m = future_.next(); + } +} + +const char * +History::load(LevelMap *map, const char *_str) { + Move *m; + int x = map->xpos(); + int y = map->ypos(); + + clear(); + while (*_str != '\0' && *_str != '-') { + m = new Move(x, y); + _str = m->load(_str); + if (_str == 0) return 0; + x = m->finalX(); + y = m->finalY(); + past_.append(m); + if (!m->redo(map)) { + //printf("redo failed: %s\n", _str); + //abort(); + return 0; + } + } + if (*_str != '-') return 0; + + _str++; + while (*_str != '\0') { + m = new Move(x, y); + _str = m->load(_str); + if (_str == 0) return 0; + x = m->finalX(); + y = m->finalY(); + future_.append(m); + } + + return _str; +} + +bool +History::redo(LevelMap *map) { + if (future_.isEmpty()) return false; + + Move *m=future_.take(0); + past_.append(m); + return m->redo(map); +} + +MoveSequence * +History::deferRedo(LevelMap *map) { + if (future_.isEmpty()) return 0; + + Move *m=future_.take(0); + past_.append(m); + return new MoveSequence(m, map); +} + +bool +History::undo(LevelMap *map) { + if (past_.isEmpty()) return false; + + Move *m = past_.take(past_.count ()-1); + future_.insert(0, m); + return m->undo(map); +} + +MoveSequence * +History::deferUndo(LevelMap *map) { + if (past_.isEmpty()) return 0; + + Move *m = past_.take(past_.count()-1); + future_.insert(0, m); + return new MoveSequence(m, map, true); +} |