123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #include <iostream>
- #include <list>
- #include <cstdlib>
- #include <ctime>
- #include <stack>
- using namespace std;
- #define FREE 0
- #define WALL 1
- #define ORIGIN 2
- #define TARGET 3
- #define DISCOVERED 4
- #define TRACE 5
- unsigned int identifyTile(unsigned int y, unsigned int x, unsigned int l) {
- return y * l + x;
- }
- class World
- {
- private:
-
- unsigned int l;
-
- unsigned int h;
-
- const unsigned int size;
-
- int* board;
- public:
-
- World(unsigned int l_, unsigned int h_, double p)
- :l(l_), h(h_), size(l_ * h_)
- {
- board = new int[size]();
-
- for (unsigned int i = 0; i < h; i++)
- {
- board[i * l] = WALL;
- board[i * l + l - 1] = WALL;
- }
-
- for (unsigned int j = 0; j < l; j++)
- {
- board[j] = WALL;
- board[(h - 1) * l + j] = WALL;
- }
- for (unsigned int i = 0; i < h; i++)
- {
- for (unsigned int j = 0; j < l; j++)
- {
-
-
- if ((double) rand() / RAND_MAX < p && !(i == 1 && j == 1) && !(i == h - 2 && j == l - 2))
- {
- board[i * l + j] = WALL;
- }
- }
- }
- }
-
- void display()
- {
- for (unsigned int i = 0; i < h; i++)
- {
- for (unsigned int j = 0; j < l; j++)
- {
- switch (board[identifyTile(i, j, l)])
- {
- case FREE:
- cout << " ";
- break;
- case WALL:
- cout << "#";
- break;
- case ORIGIN:
- cout << "o";
- break;
- case TARGET:
- cout << "T";
- break;
- case DISCOVERED:
- cout << ":";
- break;
- case TRACE:
- cout << "+";
- break;
- }
- }
- cout << endl;
- }
- }
-
-
-
-
- unsigned int successors(unsigned int i, unsigned int r[4])
- {
- unsigned int n = 0;
- if (i >= 0 && i < size && board[i] != WALL)
- {
-
-
- const unsigned int moves[] = { i - 1, i + 1, i - l, i + l};
- for (unsigned int k = 0; k < 4; k++)
- {
- if (board[moves[k]] != WALL)
- {
- r[n] = moves[k];
- n++;
- }
- }
- }
- return n;
- }
-
- void markAll(const list<unsigned int>& path, int value = TRACE) {
- for (auto tile : path) {
- markOne(tile, value);
- }
- }
-
- void markOne(unsigned int tile, int value = ORIGIN) {
- board[tile] = value;
- }
-
-
-
-
- const bool dfs(unsigned int origin, unsigned int target, list<unsigned int>& path, list<unsigned int>& discovered)
- {
- bool targetIsReached = false;
- bool explored[size];
- unsigned int previous[size];
- for (unsigned int k(0); k < size; k ++) {
- explored[k] = false;
- previous[k] = k;
- }
- explored[origin] = true;
- stack<unsigned int> open;
- open.push(origin);
- int current;
- int neighbour;
- unsigned int succs[4];
- unsigned int nbSuccs;
- do {
- current = open.top();
- open.pop();
- nbSuccs = successors(current, succs);
- for (unsigned int i(0); i < nbSuccs; i++) {
- neighbour = succs[i];
- if (!explored[neighbour]) {
- open.push(neighbour);
- previous[neighbour] = current;
- }
- }
-
- explored[current] = true;
- discovered.push_back(current);
-
- targetIsReached = (current == target);
- } while (!targetIsReached && !open.empty());
-
- if (targetIsReached) {
- do {
- path.push_back(current);
- current = previous[current];
- } while (current != origin);
- }
- return targetIsReached;
- }
- };
- int main()
- {
-
- srand(time(0));
-
- const unsigned int l(50), h(15);
- const double wallProbability(0.2);
- World w(l, h, wallProbability);
- unsigned int start(identifyTile(1, 1, l));
- unsigned int end(identifyTile(h - 2, l - 2, l));
-
- cout << endl << "Generated world" << endl;
- w.markOne(start, ORIGIN);
- w.markOne(end, TARGET);
- w.display();
-
- list<unsigned int> dfsPath;
- list<unsigned int> dfsDiscovered;
- bool exitFound = w.dfs(start, end, dfsPath, dfsDiscovered);
-
- cout << endl << "Depth-First Search" << endl;
- w.markAll(dfsDiscovered, DISCOVERED);
- w.markAll(dfsPath, TRACE);
- w.markOne(start, ORIGIN);
- w.markOne(end, TARGET);
- w.display();
-
- if (exitFound)
- cout << "SUCCESS !" << endl;
- else
- cout << "FAILURE ..." << endl;
- cout << dfsDiscovered.size() << " tiles discovered;" << endl;
- cout << dfsPath.size() << " path length.";
-
- return 0;
- }
|