00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef EASYSOK_SOLVER_INC_GUARD_H
00022 #define EASYSOK_SOLVER_INC_GUARD_H
00023
00024
00025 #include <map>
00026 #include <utility>
00027 #include <vector>
00028
00029 #include "hash.h"
00030 #include "map.h"
00031 #include "move.h"
00032 #include "movements.h"
00033
00034
00035
00036
00046 class Solver
00047 {
00048
00049 public:
00050
00058 Solver(Map const & map, int cache_size);
00059
00060
00067 bool prepare();
00068
00069
00080 bool solve(int steps);
00081
00082
00087 int depth() const;
00088
00089
00094 int actMinDepth() const;
00095
00096
00101 int actMaxDepth() const;
00102
00103
00108 int maxDepthReached() const;
00109
00110
00115 int maxDepth() const;
00116
00117
00122 int nextMaxDepth() const;
00123
00124
00129 double percentageCompleted() const;
00130
00131
00136 Movements moves() const;
00137
00138
00143 Movements bestEffort() const;
00144
00145
00146 private:
00147
00155 bool doSingleStep();
00156
00157
00164 bool startSearch();
00165
00166
00171 bool collapse();
00172
00173
00178 void expand();
00179
00180
00187 bool processEndNodes();
00188
00189
00194 std::vector<int> const & validMoves() const;
00195
00196
00207 int movesForGem(int keeper_pos, int gem_pos, int goal_pos) const;
00208
00209
00218 bool isDeadlock(int position, bool ignore_on_goal = false) const;
00219
00220
00230 int minMovesForSolution(int moved_gem_pos) const;
00231
00232
00237 int assignmentSolver(std::vector<int> & matrix, int dim) const;
00238
00239
00251 int lowerBound(Hash const & hash, int moved_gem_pos, int depth);
00252
00253
00263 void updateCache(Hash const & hash, int moves_to_solve, int depth);
00264
00265
00276 void insertInCache(Hash const & hash, int moves_to_solve, int depth, bool calculated);
00277
00278
00283 void setupCache();
00284
00285
00292 std::vector<int> getGemPositions(Map const & map) const;
00293
00294
00299 void setupDistanceMap();
00300
00301
00306 void setupDeadlockPatterns();
00307
00308
00313 Movements getFullMoves() const;
00314
00315
00320 class CacheEntry
00321 {
00322
00323 public:
00324
00335 CacheEntry(int moves_to_solve, int depth, bool calculated);
00336
00337
00342 int movesToSolve() const;
00343
00344
00349 bool unsolvable() const;
00350
00351
00360 void setMovesToSolve(int moves_to_solve);
00361
00362
00367 int depth() const;
00368
00369
00376 void setDepth(int new_depth);
00377
00378
00383 bool wasCalculated() const;
00384
00385
00390 bool wasTouched() const;
00391
00392
00397 void touch();
00398
00399
00404 void untouch();
00405
00406
00407 private:
00408
00413 Q_UINT32 m_data;
00414 };
00415
00416
00421 Map m_map;
00422
00423
00428 Map m_start_map;
00429
00430
00435 Map m_empty_map;
00436
00437
00442 std::vector<int> m_pos;
00443
00444
00449 std::vector<int> m_move_lengths;
00450
00451
00456 std::vector<int> m_move_offsets;
00457
00458
00463 std::vector<int> m_min_solve_moves;
00464
00465
00470 std::vector<int> m_moves;
00471
00472
00477 std::vector<int> m_gem_positions;
00478
00479
00484 Movements m_solution_moves;
00485
00486
00491 Movements m_best_effort;
00492
00493
00498 int m_best_effort_max_depth;
00499
00500
00505 int m_best_effort_lower_bound;
00506
00507
00512 std::vector<int> m_possible_gem_positions;
00513
00514
00519 std::vector<int> m_goal_positions;
00520
00521
00526 std::vector<Hash> m_hashs;
00527
00528
00533 int m_goals;
00534
00535
00540 int m_depth;
00541
00542
00547 int m_act_min_depth;
00548
00549
00554 int m_act_max_depth;
00555
00556
00561 int m_max_depth_reached;
00562
00563
00568 int m_max_depth;
00569
00570
00575 int const m_width;
00576
00577
00582 int const m_height;
00583
00584
00589 int const m_size;
00590
00591
00596 int m_xy_offsets[4];
00597
00598
00603 int m_min_add_depth;
00604
00605
00610 bool m_solution_possible;
00611
00612
00617 std::map<Hash, CacheEntry> m_cache;
00618
00619
00624 int m_max_cache_size;
00625
00626
00631 int m_cache_size;
00632
00633
00638 std::vector<int> m_depth_counts;
00639
00640
00645 int m_max_depth_counts;
00646
00647
00652 std::vector<int> m_distance_map;
00653
00654
00659 std::vector<Q_UINT32> m_reachable_map;
00660
00661
00666 int m_reachable_map_gem;
00667
00668
00673 bool m_solve_finished;
00674
00675
00680 enum PatternType
00681 {
00682 KEEPER = 1 << 0,
00683 KEEPER_ON_GOAL = 1 << 1,
00684 GEM = 1 << 2,
00685 GEM_ON_GOAL = 1 << 3,
00686 EMPTY = 1 << 4,
00687 GOAL = 1 << 5,
00688 WALL = 1 << 6,
00689 OUTSIDE = 1 << 7
00690 };
00691
00692
00697 std::vector<int> m_deadlock_patterns;
00698
00699
00704 std::vector<int> m_deadlock_pattern_positions;
00705
00706
00711 std::vector<int> m_deadlock_pattern_lengths;
00712
00713
00718 static int const s_unsolvable;
00719 };
00720
00721
00722 #endif