Matrix.h

Go to the documentation of this file.
00001 
00011 #ifndef __MATRIX__H__
00012 #define __MATRIX__H__
00013 
00014 #include <list>
00015 #include <algorithm>
00016 #include <limits>
00017 
00018 #include "common.h"
00019 #include "objects/Object.h"
00020 #include "objects/ObjectFixed.h"
00021 #include "objects/ObjectTransferable.h"
00022 #include "objects/ObjectAgent.h"
00023 #include "objects/ObjectTrail.h"
00024 #include "configs/ConfigMatrix.h"
00025 
00034 class Matrix {
00035 public:
00039         typedef size_t SizeType;
00040 
00041 public:
00042         friend class iterator;
00043 
00048         class iterator {
00049         public:
00054                 typedef Matrix::SizeType SizeType;
00055 
00062                 iterator(const Matrix * matrix, SizeType xIndex = 0, SizeType yIndex = 0):
00063                         m(matrix), x(xIndex), y(yIndex) {}
00064 
00069                 iterator(const iterator &iter) {
00070                         *this = iter;
00071                 }
00072 
00076                 ~iterator() {}
00077 
00082                 Object & operator *();
00083 
00088                 Object * operator ->();
00089 
00093                 iterator & operator ++();
00094 
00100                 iterator operator ++(int);
00101 
00106                 iterator & operator =(const iterator & iter);
00107 
00115                 friend bool operator ==(const iterator & iter1, const iterator & iter2);
00116 
00124                 friend bool operator !=(const iterator & iter1, const iterator & iter2);
00125 
00126         private:
00128                 const Matrix * m;
00130                 SizeType x;
00132                 SizeType y;
00133         };
00134 
00135 public:
00140         explicit Matrix(const ConfigMatrix & config);
00141 
00145         ~Matrix();
00146 
00150         iterator begin();
00151 
00155         iterator end() {
00156                 return iterator(this, 0, height);
00157         }
00158 
00169         bool PutObject(Object * object, SizeType xIndex, SizeType yIndex);
00170 
00179         bool MoveObject(SizeType xFrom, SizeType yFrom, SizeType xTo, SizeType yTo);
00180 
00189         bool DestroyObject(SizeType xIndex, SizeType yIndex);
00190 
00199         bool IsThereObject(SizeType xIndex, SizeType yIndex) const;
00200 
00211         bool IsEditableByUser(SizeType xIndex, SizeType yIndex) const;
00212 
00216         void MakeStep();
00217 
00224         ConfigMatrix * GetConfigMatrix() const;
00225 
00226 private:
00232         void SendCollisions(Object * firstObject, Object * secondObject);
00233 
00239         void PerformActions();
00240 
00247         void PerformSpecificOperations();
00248 
00249 private:
00257         class SecondIndex {
00258         public:
00259                 friend class Matrix;
00260 
00265                 SecondIndex(Matrix * matrix): m(matrix) {}
00266 
00275                 Object & operator [](SizeType secondIndex);
00276 
00277         private:
00279                 Matrix * m;
00281                 SizeType x;
00282 
00283                 // Disable copy constructor
00284                 SecondIndex(const SecondIndex &);
00285                 // Disable assignment operator
00286                 SecondIndex & operator =(const SecondIndex &);
00287                 // User won't be able to destroy this object, so only Matrix can do it
00288                 ~SecondIndex() {}
00289         };
00290 
00291 public:
00298         SecondIndex & operator [](SizeType firstIndex);
00299 
00300 private:
00307         class CallSpecificMethods: public std::unary_function<Object *, void> {
00308         public:
00313                 void operator ()(Object * object) const {
00314                         object->ChooseNextAction();
00315                 }
00316         };
00317 
00324         class RemoveSpecificObjects: public std::unary_function<Object *, bool> {
00325         public:
00330                 bool operator ()(const Object * object) const {
00331                         return object->GetAction().GetAction() == Object::Action::EXPIRED_REMOVE;
00332                 }
00333         };
00334 
00338         class SaveObjectIntoConfig: public std::unary_function<Object *, void> {
00339         public:
00346                 explicit SaveObjectIntoConfig(ConfigMatrix * config,
00347                         SizeType xIndex, SizeType yIndex):
00348                         x(xIndex), y(yIndex), matrixConfig(config)
00349                 {}
00350 
00355                 void operator ()(const Object * object) const {
00356                         matrixConfig->AddConfigCell(new ConfigMatrix::ConfigCell(
00357                                 x, y, object->CreateObjectConfig()));
00358                 }
00359 
00360         private:
00362                 const SizeType x;
00364                 const SizeType y;
00366                 ConfigMatrix * const matrixConfig;
00367         };
00368 
00375         class Item {
00376         public:
00381                 typedef std::list<Object *> Container;
00382 
00387                 typedef Container::size_type SizeType;
00388 
00392                 Item() {}
00393 
00397                 ~Item() {
00398                         RemoveAllObjects(true);
00399                 }
00400 
00406                 Object * GetTopObject() const {
00407                         return (!container.empty() ? *container.begin() : 0);
00408                 }
00409 
00417                 void AddObject(Object *object);
00418 
00428                 bool RemoveObject(Object::Priority priority, bool freeMemory = true);
00429 
00435                 bool RemoveTopObject(bool freeMemory = true);
00436 
00441                 void RemoveAllObjects(bool freeMemory = true);
00442 
00446                 bool IsThereObject() const {
00447                         return !container.empty();
00448                 }
00449 
00455                 template <class Function>
00456                 void ApplyFunctionToEachObject(Function func, bool reversedPass = false) {
00457                         if (reversedPass) {
00458                                 std::for_each(container.rbegin(), container.rend(), func);
00459                         }
00460                         else {
00461                                 std::for_each(container.begin(), container.end(), func);
00462                         }
00463                 }
00464 
00469                 template <class Predicate>
00470                 void RemoveObjectsAccToPredicate(Predicate pred) {
00471                         Container::iterator i = container.begin();
00472                         while (i != container.end()) {
00473                                 if (pred(*i)) {
00474                                         delete *i;
00475                                         Container::iterator old = i;
00476                                         ++i;
00477                                         container.erase(old);
00478                                 }
00479                                 else {
00480                                         ++i;
00481                                 }
00482                         }
00483                 }
00484 
00485         private:
00487                 Container container;
00488         };
00489 
00490 public:
00492         SizeType GetWidth() const { return width; }
00493 
00495         SizeType GetHeight() const { return height; }
00496 
00498         static SizeType GetMinWidth() { return MIN_WIDTH; }
00499 
00501         static SizeType GetMinHeight() { return MIN_HEIGHT; }
00502 
00504         static SizeType GetDefaultWidth() { return DEFAULT_WIDTH; }
00505 
00507         static SizeType GetDefaultHeight() { return DEFAULT_HEIGHT; }
00508 
00510         static SizeType GetMaxWidth() { return MAX_WIDTH; }
00511 
00513         static SizeType GetMaxHeight() { return MAX_HEIGHT; }
00514 
00515 private:
00517         SizeType width;
00519         SizeType height;
00521         static const SizeType MIN_WIDTH;
00523         static const SizeType MIN_HEIGHT;
00525         static const SizeType DEFAULT_WIDTH;
00527         static const SizeType DEFAULT_HEIGHT;
00529         static const SizeType MAX_WIDTH;
00531         static const SizeType MAX_HEIGHT;
00533         static const SizeType WIDTH_INCREMENT;
00535         static const SizeType HEIGHT_INCREMENT;
00536 
00537 private:
00539         Item ** matrix;
00541         SecondIndex secIndex;
00543         Object::TicketSize ticketNumber;
00545         static const Object::TicketSize STARTING_TICKET_NUMBER = 0;
00546 
00547 private:
00555         void IncreaseMatrixSizeForBorders();
00556 
00562         void CreateEmptyMatrix();
00563 
00567         void CreateWallsAroundMatrix();
00568 
00573         void LoadObjectsFromConfig(const ConfigMatrix & config);
00574 
00578         void GenerateNextTicketNumber() {
00579                 ticketNumber++;
00580         }
00581 
00587         bool IsOutOfRange(SizeType xIndex, SizeType yIndex) const {
00588                 return (xIndex >= GetWidth() || yIndex >= GetHeight());
00589         }
00590 
00596         string CreateOutOfRangeMessage(SizeType xIndex, SizeType yIndex) const;
00597 
00603         bool IndexExists(SizeType xIndex, SizeType yIndex) const {
00604                 return (xIndex < GetWidth() && yIndex < GetHeight());
00605         }
00606 
00617         void GetIndexOfNextPlace(SizeType xFrom, SizeType yFrom, const Direction & direction,
00618                 SizeType & xTo, SizeType & yTo);
00619 
00634         bool GetIndexOfNextFreePlace(SizeType xFrom, SizeType yFrom,
00635                 SizeType & xTo, SizeType & yTo, Direction & direction);
00636 
00644         bool IsFreePlace(SizeType xIndex, SizeType yIndex) const {
00645                 return (!IsThereObject(xIndex, yIndex) ||
00646                         matrix[yIndex * GetWidth() + xIndex]->GetTopObject()->IsImaginary());
00647         }
00648 
00656         bool OnBorder(SizeType xIndex, SizeType yIndex) const {
00657                 return (xIndex == 0 || yIndex == 0 ||
00658                         xIndex == (GetWidth() - 1) || yIndex == (GetHeight() - 1));
00659         }
00660 
00669         bool CanBeAdded(const Object * object, SizeType xIndex, SizeType yIndex) const {
00670                 return (!IsOutOfRange(xIndex, yIndex) && !OnBorder(xIndex, yIndex) &&
00671                         (!IsThereObject(xIndex, yIndex) ||
00672                                 object->IsImaginary() ||
00673                                 matrix[yIndex * GetWidth() + xIndex]->GetTopObject()->IsImaginary()));
00674         }
00675 
00682         void InternalMoveObject(SizeType xFrom, SizeType yFrom, const Direction & direction);
00683 
00691         void InternalMoveObject(SizeType xFrom, SizeType yFrom, SizeType xTo, SizeType yTo);
00692 
00693 private:
00701         bool PerformActionTakeObject(Object * object, SizeType xIndex, SizeType yIndex);
00702 
00710         bool PerformActionDropObject(Object * object, SizeType xIndex, SizeType yIndex);
00711 
00719         bool PerformActionPutTrail(Object * object, SizeType xIndex, SizeType yIndex);
00720 };
00721 
00722 #endif /* #ifndef __MATRIX__H__ */
00723 
00724 /* End of file Matrix.h */

Generated on Sun Apr 29 11:46:10 2007 for IPP/ICP2007 by  doxygen 1.4.7