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

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 <unistd.h>
0021 #include <stdlib.h>
0022 #include <ctype.h>
0023 #include <assert.h>
0024 #include <stdio.h>
0025 #include <string.h>
0026 
0027 #include <KConfig>
0028 
0029 #include <zlib.h>
0030 
0031 #include "LevelMap.h"
0032 #include "LevelCollection.h"
0033 
0034 #define BUFSIZE (128*1024)
0035 
0036 const QString &
0037 LevelMap::collectionName() {
0038   return collection_->name();
0039 }
0040 
0041 LevelMap::LevelMap () : collection_(nullptr), totalMoves_(0), totalPushes_(0),
0042             goodLevel_(false) {
0043 }
0044 
0045 LevelMap::~LevelMap () {
0046 }
0047 
0048 void
0049 LevelMap::changeCollection (LevelCollection *_collection)
0050 {
0051   collection_ = _collection;
0052   goodLevel_ = collection_->loadLevel(this);
0053   totalMoves_ = totalPushes_ = 0;
0054 }
0055 
0056 int
0057 LevelMap::level () const {
0058   if (collection_ == nullptr) return 0;
0059   return collection_->level();
0060 }
0061 
0062 void
0063 LevelMap::level (int _level) {
0064   assert(collection_ != nullptr);
0065 
0066   collection_->level(_level);
0067   goodLevel_ = collection_->loadLevel(this);
0068 
0069   totalMoves_ = totalPushes_ = 0;
0070 }
0071 
0072 int
0073 LevelMap::noOfLevels () const {
0074   assert(collection_ != nullptr);
0075   return collection_->noOfLevels();
0076 }
0077 
0078 int
0079 LevelMap::completedLevels () const{
0080   assert(collection_ != nullptr);
0081   return collection_->completedLevels();
0082 }
0083 
0084 int
0085 LevelMap::distance (int x1, int y1, int x2, int y2) {
0086   int d;
0087 
0088   if (x2 > x1) d = x2-x1;
0089   else d = x1-x2;
0090 
0091   if (y2 > y1) d += y2-y1;
0092   else d += y1-y2;
0093 
0094   return d;
0095 }
0096 
0097 bool
0098 LevelMap::step (int _x, int _y) {
0099   int oldX=xpos_, oldY=ypos_;
0100 
0101   bool success = Map::step (_x, _y);
0102 
0103   totalMoves_ += distance (oldX, oldY, xpos_, ypos_);
0104 
0105   return success;
0106 }
0107 
0108 bool
0109 LevelMap::push (int _x, int _y) {
0110   int oldX=xpos_, oldY=ypos_;
0111 
0112   bool success = Map::push (_x, _y);
0113 
0114   int d = distance (oldX, oldY, xpos_, ypos_);
0115   totalMoves_ += d;
0116   totalPushes_ += d;
0117 
0118   if (completed ()) collection_->levelCompleted();
0119 
0120   return success;
0121 }
0122 
0123 bool
0124 LevelMap::unstep (int _x, int _y) {
0125   int oldX=xpos_, oldY=ypos_;
0126 
0127   bool success = Map::unstep (_x, _y);
0128 
0129   totalMoves_ -= distance (oldX, oldY, xpos_, ypos_);
0130 
0131   return success;
0132 }
0133 
0134 bool
0135 LevelMap::unpush (int _x, int _y) {
0136   int oldX=xpos_, oldY=ypos_;
0137 
0138   bool success = Map::unpush (_x, _y);
0139 
0140   int d = distance (oldX, oldY, xpos_, ypos_);
0141   totalMoves_ -= d;
0142   totalPushes_ -= d;
0143 
0144   return success;
0145 }
0146 
0147 #if 0
0148 void
0149 LevelMap::random (void) {
0150   printf ("start!\n");
0151 
0152   minX_ = 0;
0153   minY_ = 0;
0154   maxX_ = MAX_X;
0155   maxY_ = MAX_Y;
0156   totalMoves_ = totalPushes_ = 0;
0157   clearMap ();
0158 
0159   xpos_ = 13;
0160   ypos_ = 9;
0161 
0162   KRandomSequence random(0);
0163 
0164   for (int i=0; i<200; i++) {
0165     map (xpos_, ypos_, FLOOR);
0166 
0167     switch (random.getLong(4)) {
0168     case 0:
0169       if (ypos_ > 1) ypos_--; else i--;
0170       break;
0171 
0172     case 1:
0173       if (ypos_ < MAX_Y-1) ypos_++; else i--;
0174       break;
0175 
0176     case 2:
0177       if (xpos_ > 1) xpos_--; else i--;
0178       break;
0179 
0180     case 3:
0181       if (xpos_ < MAX_X-1) xpos_++; else i--;
0182       break;
0183     }
0184   }
0185 
0186   for (int y=1; y<MAX_Y; y++) {
0187     for (int x=1; x<MAX_X; x++) {
0188       if (map (x, y) & FLOOR) {
0189     if (!(map (x, y-1) & FLOOR)) map (x, y-1, WALL);
0190     if (!(map (x, y+1) & FLOOR)) map (x, y+1, WALL);
0191     if (!(map (x-1, y) & FLOOR)) map (x-1, y, WALL);
0192     if (!(map (x+1, y) & FLOOR)) map (x+1, y, WALL);
0193       }
0194     }
0195   }
0196 
0197   printf ("klar!\n");
0198   printMap ();
0199 }
0200 #endif