123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // Example of world building, display, and successor computation for the artificial
- // intelligence path-finding lab
- //
- // Author: Didier LIME
- // Adapted by : Jovian HERSEMEULE
- // Date: 2018-10-03
- #include <iostream>
- #include <unistd.h>
- using namespace std;
- // Default parameters
- #define DEFAULT_LENGTH 6
- #define DEFAULT_HEIGHT 5
- #define DEFAULT_ANIMATION true
- #define DEFAULT_ANIMATION_DELAY 50000 // us
- #define DEFAULT_COLOR_ENABLE true
- // Tile codes
- #define FLOOR_TILE 0
- #define WALL_TILE 1
- #define TARGET_TILE 2
- #define HOLE_TILE 3
- // Typical cost
- #define FLOOR_COST 0.04f
- #define HOLE_COST -1.1f
- #define TARGET_COST 1.01f
- unsigned int identifyTile(unsigned int y, unsigned int x, unsigned int l) {
- return y * l + x;
- }
- void moveCursorUp(const unsigned int& h) {
- cout << "\033[" << h << 'A';
- }
- class World
- {
- private:
- // Number of columns
- unsigned int l;
- // Number of lines
- unsigned int h;
- // Size of the array
- const unsigned int size;
- // Unidimensional array for tiles
- int* board;
- // Unidimensional array of costs
- float* cost;
- // Number of empty tiles
- unsigned int tileQuantity;
- public:
- // Constructor
- World(unsigned int l_, unsigned int h_)
- :l(l_), h(h_), size(l_ * h_), tileQuantity(l_ * h_)
- {
- board = new int[size]();
- cost = new float[size]();
- // Clean
- for (unsigned int k(0); k < size; k++) {
- board[k] = FLOOR_TILE;
- cost[k] = FLOOR_COST;
- }
- // Add walls to the first and last columns
- for (unsigned int i = 0; i < h; i++)
- {
- board[i * l] = WALL_TILE;
- board[i * l + l - 1] = WALL_TILE;
- tileQuantity -= 2;
- }
- // Add walls to the first and last lines
- for (unsigned int j = 0; j < l; j++)
- {
- board[j] = WALL_TILE;
- board[(h - 1) * l + j] = WALL_TILE;
- tileQuantity -= 2;
- }
- // Add hardcoded elements
- board[identifyTile(2, 2, l)] = WALL_TILE;
- board[identifyTile(1, 4, l)] = TARGET_TILE;
- cost[identifyTile(1, 4, l)] = TARGET_COST;
- board[identifyTile(2, 4, l)] = HOLE_TILE;
- cost[identifyTile(2, 4, l)] = HOLE_COST;
- }
- // Copy constructor
- World(const World& other)
- :l(other.l), h(other.h), size(other.size), tileQuantity(other.tileQuantity)
- {
- board = new int[size]();
- cost = new float[size]();
- for (int k(0); k < size; k++) {
- board[k] = other.board[k];
- cost[k] = other.cost[k];
- }
- }
- // Display the costs
- void displayCosts() {
- int current;
- for (unsigned int i = 0; i < h; i++) {
- for (unsigned int j = 0; j < l; j++) {
- current = identifyTile(i, j, l);
- cout << '|';
- if (board[current] == WALL_TILE)
- cout << "- -";
- else
- cout << cost[current];
- }
- cout << '|' << endl;
- }
- }
- // Display the world
- void displayBoard()
- {
- for (unsigned int i = 0; i < h; i++)
- {
- for (unsigned int j = 0; j < l; j++)
- {
- switch (board[identifyTile(i, j, l)])
- {
- case FLOOR_TILE:
- cout << " ";
- break;
- case WALL_TILE:
- if (DEFAULT_COLOR_ENABLE) cout << "\033[0;43m";
- cout << "#";
- break;
- case HOLE_TILE:
- if (DEFAULT_COLOR_ENABLE) cout << "\033[1;35m";
- cout << "X";
- break;
- case TARGET_TILE:
- if (DEFAULT_COLOR_ENABLE) cout << "\033[1;36m";
- cout << "O";
- break;
- }
- if (DEFAULT_COLOR_ENABLE) cout << "\033[0;30m";
- }
- cout << endl;
- }
- }
- // compute the successors of tile number i in world w
- // we return the number n of valid successors
- // the actual list is in array r where only the first n
- // elements are significant
- unsigned int successors(unsigned int i, unsigned int r[4])
- {
- unsigned int n = 0;
- if (i >= 0 && i < size && board[i] != WALL_TILE)
- {
- // if i is a correct tile number (inside the array and not on a wall)
- // look in the four adjacent tiles and keep only those with no 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_TILE)
- {
- r[n] = moves[k];
- n++;
- }
- }
- }
- return n;
- }
- // Mark a point in the world
- void markOne(unsigned int tile, int value = HOLE_TILE) {
- board[tile] = value;
- }
- void showProperties() {
- cout << "Length : " << l << endl;
- cout << "Height : " << h << endl;
- cout << "Number of floor tiles : " << tileQuantity << endl;
- }
- // Value iteration
- void valueIteration(float gamma, float epsilon) {
- unsigned int counter(0);
- unsigned int buffer[size];
- unsigned int succs[4];
- unsigned int succsCount;
- while (!isConverged(gamma, epsilon)) {
- for (unsigned int k(0); k < size; k ++) {
- succsCount = successors(k, succs);
- // todo
- }
- }
- }
- };
- int main()
- {
- // Create a world
- const unsigned int l(DEFAULT_LENGTH), h(DEFAULT_HEIGHT);
- World w(l, h);
- // Display it
- cout << endl << "Default world" << endl;
- w.showProperties();
- w.displayBoard();
- w.displayCosts();
- const bool animation(DEFAULT_ANIMATION);
- // 1
- cout << endl << "Value iteration" << endl;
- World w1(w);
- w1.displayBoard();
- w1.displayCosts();
- // 2
- cout << endl << "Policy iteration" << endl;
- World w2(w);
- w2.displayBoard();
- w2.displayCosts();
- // End
- return 0;
- }
|