main.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Example of world building, display, and successor computation for the artificial
  2. // intelligence path-finding lab
  3. //
  4. // Author: Didier LIME
  5. // Adapted by : Jovian HERSEMEULE
  6. // Date: 2018-10-03
  7. #include <iostream>
  8. #include <unistd.h>
  9. using namespace std;
  10. // Default parameters
  11. #define DEFAULT_LENGTH 6
  12. #define DEFAULT_HEIGHT 5
  13. #define DEFAULT_ANIMATION true
  14. #define DEFAULT_ANIMATION_DELAY 50000 // us
  15. #define DEFAULT_COLOR_ENABLE true
  16. // Tile codes
  17. #define FLOOR_TILE 0
  18. #define WALL_TILE 1
  19. #define TARGET_TILE 2
  20. #define HOLE_TILE 3
  21. // Typical cost
  22. #define FLOOR_COST 0.04f
  23. #define HOLE_COST -1.1f
  24. #define TARGET_COST 1.01f
  25. unsigned int identifyTile(unsigned int y, unsigned int x, unsigned int l) {
  26. return y * l + x;
  27. }
  28. void moveCursorUp(const unsigned int& h) {
  29. cout << "\033[" << h << 'A';
  30. }
  31. class World
  32. {
  33. private:
  34. // Number of columns
  35. unsigned int l;
  36. // Number of lines
  37. unsigned int h;
  38. // Size of the array
  39. const unsigned int size;
  40. // Unidimensional array for tiles
  41. int* board;
  42. // Unidimensional array of costs
  43. float* cost;
  44. // Number of empty tiles
  45. unsigned int tileQuantity;
  46. public:
  47. // Constructor
  48. World(unsigned int l_, unsigned int h_)
  49. :l(l_), h(h_), size(l_ * h_), tileQuantity(l_ * h_)
  50. {
  51. board = new int[size]();
  52. cost = new float[size]();
  53. // Clean
  54. for (unsigned int k(0); k < size; k++) {
  55. board[k] = FLOOR_TILE;
  56. cost[k] = FLOOR_COST;
  57. }
  58. // Add walls to the first and last columns
  59. for (unsigned int i = 0; i < h; i++)
  60. {
  61. board[i * l] = WALL_TILE;
  62. board[i * l + l - 1] = WALL_TILE;
  63. tileQuantity -= 2;
  64. }
  65. // Add walls to the first and last lines
  66. for (unsigned int j = 0; j < l; j++)
  67. {
  68. board[j] = WALL_TILE;
  69. board[(h - 1) * l + j] = WALL_TILE;
  70. tileQuantity -= 2;
  71. }
  72. // Add hardcoded elements
  73. board[identifyTile(2, 2, l)] = WALL_TILE;
  74. board[identifyTile(1, 4, l)] = TARGET_TILE;
  75. cost[identifyTile(1, 4, l)] = TARGET_COST;
  76. board[identifyTile(2, 4, l)] = HOLE_TILE;
  77. cost[identifyTile(2, 4, l)] = HOLE_COST;
  78. }
  79. // Copy constructor
  80. World(const World& other)
  81. :l(other.l), h(other.h), size(other.size), tileQuantity(other.tileQuantity)
  82. {
  83. board = new int[size]();
  84. cost = new float[size]();
  85. for (int k(0); k < size; k++) {
  86. board[k] = other.board[k];
  87. cost[k] = other.cost[k];
  88. }
  89. }
  90. // Display the costs
  91. void displayCosts() {
  92. int current;
  93. for (unsigned int i = 0; i < h; i++) {
  94. for (unsigned int j = 0; j < l; j++) {
  95. current = identifyTile(i, j, l);
  96. cout << '|';
  97. if (board[current] == WALL_TILE)
  98. cout << "- -";
  99. else
  100. cout << cost[current];
  101. }
  102. cout << '|' << endl;
  103. }
  104. }
  105. // Display the world
  106. void displayBoard()
  107. {
  108. for (unsigned int i = 0; i < h; i++)
  109. {
  110. for (unsigned int j = 0; j < l; j++)
  111. {
  112. switch (board[identifyTile(i, j, l)])
  113. {
  114. case FLOOR_TILE:
  115. cout << " ";
  116. break;
  117. case WALL_TILE:
  118. if (DEFAULT_COLOR_ENABLE) cout << "\033[0;43m";
  119. cout << "#";
  120. break;
  121. case HOLE_TILE:
  122. if (DEFAULT_COLOR_ENABLE) cout << "\033[1;35m";
  123. cout << "X";
  124. break;
  125. case TARGET_TILE:
  126. if (DEFAULT_COLOR_ENABLE) cout << "\033[1;36m";
  127. cout << "O";
  128. break;
  129. }
  130. if (DEFAULT_COLOR_ENABLE) cout << "\033[0;30m";
  131. }
  132. cout << endl;
  133. }
  134. }
  135. // compute the successors of tile number i in world w
  136. // we return the number n of valid successors
  137. // the actual list is in array r where only the first n
  138. // elements are significant
  139. unsigned int successors(unsigned int i, unsigned int r[4])
  140. {
  141. unsigned int n = 0;
  142. if (i >= 0 && i < size && board[i] != WALL_TILE)
  143. {
  144. // if i is a correct tile number (inside the array and not on a wall)
  145. // look in the four adjacent tiles and keep only those with no wall
  146. const unsigned int moves[] = { i - 1, i + 1, i - l, i + l};
  147. for (unsigned int k = 0; k < 4; k++)
  148. {
  149. if (board[moves[k]] != WALL_TILE)
  150. {
  151. r[n] = moves[k];
  152. n++;
  153. }
  154. }
  155. }
  156. return n;
  157. }
  158. // Mark a point in the world
  159. void markOne(unsigned int tile, int value = HOLE_TILE) {
  160. board[tile] = value;
  161. }
  162. void showProperties() {
  163. cout << "Length : " << l << endl;
  164. cout << "Height : " << h << endl;
  165. cout << "Number of floor tiles : " << tileQuantity << endl;
  166. }
  167. // Value iteration
  168. void valueIteration(float gamma, float epsilon) {
  169. unsigned int counter(0);
  170. unsigned int buffer[size];
  171. unsigned int succs[4];
  172. unsigned int succsCount;
  173. while (!isConverged(gamma, epsilon)) {
  174. for (unsigned int k(0); k < size; k ++) {
  175. succsCount = successors(k, succs);
  176. // todo
  177. }
  178. }
  179. }
  180. };
  181. int main()
  182. {
  183. // Create a world
  184. const unsigned int l(DEFAULT_LENGTH), h(DEFAULT_HEIGHT);
  185. World w(l, h);
  186. // Display it
  187. cout << endl << "Default world" << endl;
  188. w.showProperties();
  189. w.displayBoard();
  190. w.displayCosts();
  191. const bool animation(DEFAULT_ANIMATION);
  192. // 1
  193. cout << endl << "Value iteration" << endl;
  194. World w1(w);
  195. w1.displayBoard();
  196. w1.displayCosts();
  197. // 2
  198. cout << endl << "Policy iteration" << endl;
  199. World w2(w);
  200. w2.displayBoard();
  201. w2.displayCosts();
  202. // End
  203. return 0;
  204. }