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 #include "MoveSequence.h"
0021 #include "LevelMap.h"
0022 #include "Move.h"
0023 
0024 MoveSequence::MoveSequence (Move *_move, LevelMap *_map, bool _undo) {
0025   assert (_move->finished_);
0026 
0027   move_ = _move;
0028   map_ = _map;
0029   undo_ = _undo;
0030 
0031   if (undo_) {
0032     pos_ = move_->moveIndex_-2;
0033 
0034     xDest_ = x_ = move_->moves_[move_->moveIndex_-1]&0x7f;
0035     yDest_ = y_ = (move_->moves_[move_->moveIndex_-1]>>8)&0x7f;
0036   } else {
0037     pos_ = 1;
0038 
0039     xDest_ = x_ = move_->moves_[0]&0x7f;
0040     yDest_ = y_ = (move_->moves_[0]>>8)&0x7f;
0041   }
0042 
0043   newStep ();
0044 }
0045 
0046 bool
0047 MoveSequence::newStep () {
0048   if (pos_>=move_->moveIndex_ || pos_<0) return false;
0049 
0050   xDest_ = move_->moves_[pos_]&0x7f;
0051   yDest_ = (move_->moves_[pos_]>>8)&0x7f;
0052   if (undo_) push_ = (move_->moves_[pos_+1]&0x80)==0x80;
0053   else       push_ = (move_->moves_[pos_]&0x80)==0x80;
0054 
0055   xd_ = yd_ = 0;
0056   if (xDest_ < x_) xd_ = -1;
0057   if (xDest_ > x_) xd_ =  1;
0058   if (yDest_ < y_) yd_ = -1;
0059   if (yDest_ > y_) yd_ =  1;
0060 
0061   if (undo_) pos_--;
0062   else       pos_++;
0063 
0064   return true;
0065 }
0066 
0067 bool
0068 MoveSequence::next () {
0069   if (x_ == xDest_ && y_ == yDest_ && !newStep ()) return false;
0070 
0071   x_ += xd_;
0072   y_ += yd_;
0073 
0074   if (undo_) {
0075     if (push_) return map_->unpush (x_, y_);
0076     else return map_->unstep (x_, y_);
0077   } else {
0078     if (push_) return map_->push (x_, y_);
0079     else return map_->step (x_, y_);
0080   }
0081 }