main.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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.0f
  24. #define TARGET_COST 1.0f
  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. }
  88. }
  89. // Display the world
  90. void display()
  91. {
  92. for (unsigned int i = 0; i < h; i++)
  93. {
  94. for (unsigned int j = 0; j < l; j++)
  95. {
  96. switch (board[identifyTile(i, j, l)])
  97. {
  98. case FLOOR_TILE:
  99. cout << " ";
  100. break;
  101. case WALL_TILE:
  102. if (DEFAULT_COLOR_ENABLE) cout << "\033[0;43m";
  103. cout << "#";
  104. break;
  105. case HOLE_TILE:
  106. if (DEFAULT_COLOR_ENABLE) cout << "\033[1;35m";
  107. cout << "X";
  108. break;
  109. case TARGET_TILE:
  110. if (DEFAULT_COLOR_ENABLE) cout << "\033[1;36m";
  111. cout << "O";
  112. break;
  113. }
  114. if (DEFAULT_COLOR_ENABLE) cout << "\033[0;30m";
  115. }
  116. cout << endl;
  117. }
  118. }
  119. // compute the successors of tile number i in world w
  120. // we return the number n of valid successors
  121. // the actual list is in array r where only the first n
  122. // elements are significant
  123. unsigned int successors(unsigned int i, unsigned int r[4])
  124. {
  125. unsigned int n = 0;
  126. if (i >= 0 && i < size && board[i] != WALL_TILE)
  127. {
  128. // if i is a correct tile number (inside the array and not on a wall)
  129. // look in the four adjacent tiles and keep only those with no wall
  130. const unsigned int moves[] = { i - 1, i + 1, i - l, i + l};
  131. for (unsigned int k = 0; k < 4; k++)
  132. {
  133. if (board[moves[k]] != WALL_TILE)
  134. {
  135. r[n] = moves[k];
  136. n++;
  137. }
  138. }
  139. }
  140. return n;
  141. }
  142. // Mark a point in the world
  143. void markOne(unsigned int tile, int value = HOLE_TILE) {
  144. board[tile] = value;
  145. }
  146. void showProperties() {
  147. cout << "Length : " << l << endl;
  148. cout << "Height : " << h << endl;
  149. cout << "Number of floor tiles : " << tileQuantity << endl;
  150. }
  151. };
  152. int main()
  153. {
  154. // Create a world
  155. const unsigned int l(DEFAULT_LENGTH), h(DEFAULT_HEIGHT);
  156. World w(l, h);
  157. // Display it
  158. cout << endl << "Default world" << endl;
  159. w.showProperties();
  160. w.display();
  161. const bool animation(DEFAULT_ANIMATION);
  162. // 1
  163. cout << endl << "Value iteration" << endl;
  164. World w1(w);
  165. w1.display();
  166. // 2
  167. cout << endl << "Policy iteration" << endl;
  168. World w2(w);
  169. w2.display();
  170. // End
  171. return 0;
  172. }