File indexing completed on 2021-12-21 12:50:22

0001 /*
0002  *  ksokoban - a Sokoban game by KDE
0003  *  Copyright (C) 1998  Anders Widell  <d95-awi@nada.kth.se>
0004  *
0005  *  This program is free software; you can redistribute it and/or modify
0006  *  it under the terms of the GNU General Public License as published by
0007  *  the Free Software Foundation; either version 2 of the License, or
0008  *  (at your option) any later version.
0009  *
0010  *  This program is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  *  GNU General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU General Public License
0016  *  along with this program; if not, write to the Free Software
0017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018  */
0019 
0020 #ifndef MOVE_H
0021 #define MOVE_H
0022 
0023 #include <assert.h>
0024 #include <QString>
0025 
0026 #include "Map.h"
0027 class LevelMap;
0028 
0029 /**
0030  * Holds information about a move
0031  *
0032  * The move can consist of several atomic steps and pushes. An atomic
0033  * step/push is a step/push along a straight line. The reason why these are
0034  * grouped together in a Move object is that they belong to the same logical
0035  * move in the player's point of view. An undo/redo will undo/redo all the
0036  * atomic moves in one step.
0037  *
0038  * @short   Maintains game movement move
0039  * @author  Anders Widell <d95-awi@nada.kth.se>
0040  * @version 0.1
0041  * @see     History
0042  */
0043 
0044 class Move {
0045   friend class MoveSequence;
0046 private:
0047   unsigned short *moves_;
0048   int moveIndex_;
0049   bool finished_;
0050 
0051 #ifndef NDEBUG
0052   int lastX_, lastY_;
0053 #endif
0054 
0055 
0056 public:
0057   Move (int _startX, int _startY);
0058   ~Move ();
0059 
0060   /**
0061    * Add an atomic move.
0062    * NOTE: either (x != (previous x)) or (y != (previous y))
0063    * must be true (but not both).
0064    *
0065    * @see LevelMap#move
0066    *
0067    * @param x  x position of destination
0068    * @param y  y position of destination
0069    */
0070   void step (int _x, int _y) {
0071 #ifndef NDEBUG
0072     assert (!finished_);
0073     assert (_x>=0 && _x<=MAX_X && _y>=0 && _y<=MAX_Y);
0074     assert (moveIndex_ < 400);
0075     assert ((_x!=lastX_ && _y==lastY_) || (_x==lastX_ && _y!=lastY_));
0076     lastX_ = _x;
0077     lastY_ = _y;
0078 #endif
0079 
0080     moves_[moveIndex_++] = _x | (_y<<8);
0081   }
0082 
0083   /**
0084    * Same as move above, but used when an object is pushed.
0085    *
0086    * @see LevelMap#push
0087    */
0088   void push (int _x, int _y) {
0089 #ifndef NDEBUG
0090     assert (!finished_);
0091     assert (_x>=0 && _x<=MAX_X && _y>=0 && _y<=MAX_Y);
0092     assert (moveIndex_ < 400);
0093     assert ((_x!=lastX_ && _y==lastY_) || (_x==lastX_ && _y!=lastY_));
0094     lastX_ = _x;
0095     lastY_ = _y;
0096 #endif
0097 
0098     moves_[moveIndex_++] = _x | (_y<<8) | 0x80;
0099   }
0100 
0101   void finish ();
0102 
0103   int startX () const { return moves_[0]&0x7f; }
0104   int startY () const { return (moves_[0]>>8)&0x7f; }
0105   int finalX () const { return moves_[moveIndex_-1]&0x7f; }
0106   int finalY () const { return (moves_[moveIndex_-1]>>8)&0x7f; }
0107 
0108 
0109   void save (QString &_str);
0110   const char *load (const char *_str);
0111   bool redo (LevelMap *map);
0112   bool undo (LevelMap *map);
0113 };
0114 
0115 #endif  /* MOVE_H */