00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef EASYSOK_MAP_INC_GUARD_H
00022 #define EASYSOK_MAP_INC_GUARD_H
00023
00024
00025 #include <vector.h>
00026
00027 #include <qglobal.h>
00028 #include <qpoint.h>
00029 #include <qregexp.h>
00030 #include <qstring.h>
00031
00032 #include "movements.h"
00033
00034
00035 class CompressedMap;
00036 class Move;
00037 class QDataStream;
00038 class QStringList;
00039
00040
00041
00042
00055 class Map
00056 {
00057
00058 public:
00059
00060
00065 enum Piece
00066 {
00071 KEEPER = 0,
00072
00073
00078 KEEPER_ON_GOAL = 1,
00079
00080
00085 GEM = 2,
00086
00087
00092 GEM_ON_GOAL = 3,
00093
00094
00099 EMPTY = 4,
00100
00101
00106 GOAL = 5,
00107
00108
00113 WALL = 6,
00114
00115
00120 OUTSIDE = 7
00121 };
00122
00123
00128 enum MapValidity
00129 {
00134 IS_VALID,
00135
00136
00141 NO_KEEPER,
00142
00143
00149 TOO_MANY_KEEPERS,
00150
00151
00156 NO_GEMS,
00157
00158
00163 MORE_GEMS_THAN_GOALS,
00164
00165
00170 MORE_GOALS_THAN_GEMS,
00171
00172
00177 MAP_LEAKS,
00178
00179
00184 MAP_SOLVED,
00185
00186
00191 MAP_INVALID
00192 };
00193
00194
00203 Map(int width, int height, std::vector<int> const & pieces);
00204
00205
00212 Map(QDataStream & stream);
00213
00214
00225 Map(QStringList & lines);
00226
00227
00234 Map(CompressedMap const & compressed_map);
00235
00236
00243 void writeToStream(QDataStream & stream);
00244
00245
00250 int width() const;
00251
00252
00257 int height() const;
00258
00259
00264 std::vector<int> const & pieces() const;
00265
00266
00271 bool isValid() const;
00272
00273
00281 MapValidity validity() const;
00282
00283
00288 bool isSolved() const;
00289
00290
00295 int numberOfEmptyGoals() const;
00296
00297
00304 int getIndex(QPoint position) const;
00305
00306
00313 QPoint getPoint(int index) const;
00314
00315
00322 bool isValidPosition(QPoint position) const;
00323
00324
00331 bool isValidIndex(int index) const;
00332
00333
00340 Piece getPiece(QPoint position) const;
00341
00342
00347 Piece getPiece(int index) const;
00348
00349
00359 void setPiece(QPoint position, int piece);
00360
00361
00366 void setPiece(int index, int piece);
00367
00368
00373 void mirrorVertically();
00374
00375
00380 void mirrorHorizontally();
00381
00382
00389 void rotateLeft();
00390
00391
00396 void rotateRight();
00397
00398
00403 bool isCrossed(QPoint position) const;
00404
00405
00410 bool isCrossed(int index) const;
00411
00412
00417 void uncrossAll();
00418
00419
00426 bool isReachable(QPoint position) const;
00427
00428
00433 bool isReachable(int index) const;
00434
00435
00442 void calcReachable() const;
00443
00444
00451 void calcReachable(QPoint position) const;
00452
00453
00458 void calcReachable(int index) const;
00459
00460
00465 void clearReachable() const;
00466
00467
00474 bool isDeadlock(QPoint position) const;
00475
00476
00481 bool isDeadlock(int index) const;
00482
00483
00488 void clearDeadlocks() const;
00489
00490
00495 void calcDeadlocks() const;
00496
00497
00502 void crossDeadlocks() const;
00503
00504
00509 QPoint keeper() const;
00510
00511
00522 void setKeeper(QPoint position);
00523
00524
00529 void setKeeper(int index);
00530
00531
00536 void setKeeperToFirstReachable();
00537
00538
00546 void moveGem(QPoint from, QPoint to);
00547
00548
00553 void moveGem(int from, int to);
00554
00555
00562 bool containsKeeper(QPoint position) const;
00563
00564
00569 bool containsKeeper(int index) const;
00570
00571
00578 bool containsGem(QPoint position) const;
00579
00580
00585 bool containsGem(int index) const;
00586
00587
00594 bool containsGoal(QPoint position) const;
00595
00596
00601 bool containsGoal(int index) const;
00602
00603
00612 bool canDropKeeper(QPoint position) const;
00613
00614
00619 bool canDropKeeper(int index) const;
00620
00621
00628 bool canDropGem(QPoint position) const;
00629
00630
00635 bool canDropGem(int index) const;
00636
00637
00645 void doMove(Move const & move, bool retro_mode);
00646
00647
00657 void doUndoMove(Move const & move, bool retro_mode);
00658
00659
00667 bool isValidMove(Move const & move, bool retro_mode) const;
00668
00669
00676 bool isValidNonPushMove(Move const & move) const;
00677
00678
00686 bool isValidPushMove(Move const & move, bool retro_mode) const;
00687
00688
00696 bool isValidAtomicPushMove(Move const & move, bool retro_mode) const;
00697
00698
00708 Movements getShortestPath(QPoint from, QPoint to) const;
00709
00710
00723 Movements getShortestPathForGem(QPoint from, QPoint to, bool retro) const;
00724
00725
00739 std::vector<int> getDistanceMap(QPoint const & position, int unsolvable, bool retro_mode = false) const;
00740
00741
00746 std::vector<int> getDistanceMap(int index, int unsolvable, bool retro_mode = false) const;
00747
00748
00758 Movements expandMove(Move const & move, bool retro_mode) const;
00759
00760
00769 Movements expandUndoMove(Move const & move) const;
00770
00771
00781 Movements expandMoves(Movements moves, bool retro_mode) const;
00782
00783
00795 Movements collapseMoves(Movements moves) const;
00796
00797
00806 bool areValidMoves(Movements const & moves) const;
00807
00808
00819 bool areValidSolutionMoves(Movements const & moves, int & number_of_pushes, int & number_of_moves) const;
00820
00821
00826 Map adjustSize() const;
00827
00828
00833 Map fillEdges() const;
00834
00835
00843 Map simplify() const;
00844
00845
00850 QString toText() const;
00851
00852
00857 QString toServerFormat() const;
00858
00859
00866 static bool isMapLine(QString const & line);
00867
00868
00875 static bool pieceContainsKeeper(int piece);
00876
00877
00884 static bool pieceContainsGem(int piece);
00885
00886
00893 static bool pieceContainsGoal(int piece);
00894
00895
00902 static bool canDropKeeperOnPiece(int piece);
00903
00904
00913 static bool canDropGemOnPiece(int piece);
00914
00915
00916 private:
00917
00931 bool areValidSolutionMovesImpl(Movements const & moves, bool & is_solution,
00932 int & number_of_pushes, int & number_of_moves) const;
00933
00934
00939 enum PieceFlags
00940 {
00945 CROSSED = 8,
00946
00947
00952 REACHABLE = 16,
00953
00954
00959 DEADLOCK = 32
00960 };
00961
00962
00967 enum Mask
00968 {
00973 PIECE = 7,
00974
00975
00980 ALL = PIECE + CROSSED + REACHABLE + DEADLOCK,
00981
00982
00987 CLEAR_PIECE = ALL - PIECE,
00988
00989
00994 CLEAR_CROSSED = ALL - CROSSED,
00995
00996
01001 CLEAR_REACHABLE = ALL - REACHABLE,
01002
01003
01008 CLEAR_DEADLOCK = ALL - DEADLOCK
01009 };
01010
01011
01016 void calcTrivialDeadlocks() const;
01017
01018
01027 bool isPossibleDeadlock(int index) const;
01028
01029
01034 void setupOffsets();
01035
01036
01041 void setupNumberOfEmptyGoals() const;
01042
01043
01048 void setupKeeperAndEmptyGoals();
01049
01050
01055 void createOutsidePieces();
01056
01057
01062 void createOutsidePiecesHelper(int x, int y);
01063
01064
01069 int m_width;
01070
01071
01076 int m_height;
01077
01078
01083 int m_size;
01084
01085
01091 QPoint m_keeper;
01092
01093
01098 mutable MapValidity m_validity;
01099
01100
01105 mutable int m_empty_goals;
01106
01107
01112 mutable bool m_deadlocks_valid;
01113
01114
01119 mutable bool m_reachable_valid;
01120
01121
01126 mutable bool m_empty_goals_valid;
01127
01128
01133 mutable bool m_validity_valid;
01134
01135
01140 mutable std::vector<int> m_pieces;
01141
01142
01147 int m_xy_offsets[4];
01148
01149
01154 static char const s_piece_to_text[8];
01155
01156
01161 static bool const s_piece_contains_gem[8];
01162
01163
01168 static bool const s_piece_contains_goal[8];
01169
01170
01175 static bool const s_can_drop_keeper[24];
01176
01177
01182 static bool const s_can_drop_gem[8];
01183
01184
01189 static QRegExp s_map_regexp;
01190 };
01191
01192
01193 #endif