Advertisement
Guest User

Untitled

a guest
Dec 13th, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.39 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5.  
  6. const char WALL = '*';
  7. const char WORKER = 'w';
  8. const char WDEST = 'W';
  9. const char BOX = 'b';
  10. const char BDEST = 'B';
  11. const char EMPTY = ' ';
  12. const char DEST = '.';
  13. typedef char Cell;
  14. typedef vector<vector<Cell>> Puzzle;
  15.  
  16. struct Candidate
  17. {
  18.     Puzzle candidate;
  19.     int parent_candidate;
  20. };
  21.  
  22. struct Pos
  23. {
  24.     int col, row;
  25. };
  26.  
  27. struct Step
  28. {
  29.     Pos from,to;
  30. } ;
  31.  
  32.  
  33. int size( vector<Cell>& data )
  34. {
  35.     return static_cast<int>(data.size());
  36. }
  37.  
  38. int size( Puzzle& data )
  39. {
  40.     return static_cast<int>(data.size());
  41. }
  42.  
  43. int size(vector<Candidate>& data)
  44. {
  45.     return static_cast<int>(data.size());
  46. }
  47.  
  48.  
  49. bool is_south_of_box(Puzzle& puzzle, Pos worker_pos)
  50. {
  51.      //Pre:
  52.     assert(worker_pos.col > 0 && worker_pos.row > 0);
  53.     //Post:
  54.     //This function will be true if the worker is directly south of a box.
  55.  
  56.     int r = worker_pos.row;
  57.     int c = worker_pos.col;
  58.     if(puzzle[c-1][r] == BOX || puzzle[c-1][r] == BDEST )
  59.     {
  60.         return true;
  61.     }
  62.     return false;
  63. }
  64.  
  65. bool is_north_of_box(Puzzle& puzzle, Pos worker_pos)
  66. {
  67.      //Pre:
  68.     assert(worker_pos.col > 0 && worker_pos.row > 0);
  69.     //Post:
  70.     //This function will be true if the worker is directly north of a box.
  71.  
  72.     int r = worker_pos.row;
  73.     int c = worker_pos.col;
  74.     if(puzzle[c+1][r] == BOX || puzzle[c+1][r] == BDEST )
  75.     {
  76.         return true;
  77.     }
  78.     return false;
  79. }
  80.  
  81. bool is_east_of_box(Puzzle& puzzle, Pos worker_pos)
  82. {
  83.      //Pre:
  84.     assert(worker_pos.col > 0 && worker_pos.row > 0);
  85.     //Post:
  86.     //This function will be true if the worker is directly east of a box.
  87.  
  88.  
  89.     int r = worker_pos.row;
  90.     int c = worker_pos.col;
  91.     if(puzzle[c][r-1] == BOX || puzzle[c][r-1] == BDEST )
  92.     {
  93.         return true;
  94.     }
  95.     return false;
  96. }
  97.  
  98. bool is_west_of_box(Puzzle& puzzle, Pos worker_pos)
  99. {
  100.      //Pre:
  101.     assert(worker_pos.col > 0 && worker_pos.row > 0);
  102.     //Post:
  103.     //This function will be true if the worker is directly west of a box.
  104.  
  105.  
  106.     int r = worker_pos.row;
  107.     int c = worker_pos.col;
  108.     if(puzzle[c][r+1] == BOX || puzzle[c][r+1] == BDEST )
  109.     {
  110.         return true;
  111.     }
  112.     return false;
  113. }
  114.  
  115.  
  116. Pos find_worker(Puzzle& room)
  117. {
  118.     //Pre:
  119.     assert(true);
  120.     //Post:
  121.     //This function will give the position of the worker
  122.  
  123.     for(int r = 0; r < size(room); r++)
  124.         for(int c = 0; c < size(room[0]); c++)
  125.             if(room[r][c] == 'w' || room[r][c] == 'W')
  126.                 return {r,c};
  127. }
  128.  
  129. void move_box_west(Puzzle& puzzle)
  130. {
  131.      //Pre:
  132.     assert(true);
  133.     //Post:
  134.     //After this function is called, the box directly west of the worker
  135.     //will be one spot to the west. The spot where the box was will either
  136.     //be an empty cell or a destination cell
  137.  
  138.     Pos wpos = find_worker(puzzle);
  139.  
  140.  
  141.     if(puzzle[wpos.col][wpos.row - 2] == EMPTY)
  142.         puzzle[wpos.col][wpos.row - 2] = BOX;
  143.     else
  144.         puzzle[wpos.col][wpos.row - 2] = BDEST;
  145.  
  146.     if(puzzle[wpos.col][wpos.row - 1] == BOX)
  147.         puzzle[wpos.col][wpos.row - 1] = EMPTY;
  148.     else
  149.         puzzle[wpos.col][wpos.row - 1] = DEST;
  150. }
  151.  
  152. void move_box_east(Puzzle& puzzle)
  153. {
  154.      //Pre:
  155.     assert(true);
  156.     //Post:
  157.     //After this function is called, the box directly east of the worker
  158.     //will be one spot to the east. The spot where the box was will either
  159.     //be an empty cell or a destination cell
  160.  
  161.     Pos wpos = find_worker(puzzle);
  162.  
  163.  
  164.     if(puzzle[wpos.col][wpos.row + 2] == EMPTY)
  165.         puzzle[wpos.col][wpos.row + 2] = BOX;
  166.     else
  167.         puzzle[wpos.col][wpos.row + 2] = BDEST;
  168.  
  169.     if(puzzle[wpos.col][wpos.row + 1] == BOX)
  170.         puzzle[wpos.col][wpos.row + 1] = EMPTY;
  171.     else
  172.         puzzle[wpos.col][wpos.row + 1] = DEST;
  173. }
  174.  
  175. void move_box_south(Puzzle& puzzle)
  176. {
  177.     //Pre:
  178.     assert(true);
  179.     //Post:
  180.     //After this function is called, the box directly south of the worker
  181.     //will be one spot to the south. The spot where the box was will either
  182.     //be an empty cell or a destination cell
  183.  
  184.     Pos wpos = find_worker(puzzle);
  185.  
  186.     if(puzzle[wpos.col + 2][wpos.row] == EMPTY)
  187.         puzzle[wpos.col + 2][wpos.row] = BOX;
  188.     else
  189.         puzzle[wpos.col + 2][wpos.row] = BDEST;
  190.  
  191.     if(puzzle[wpos.col + 1][wpos.row] == BOX)
  192.         puzzle[wpos.col + 1][wpos.row] = EMPTY;
  193.     else
  194.         puzzle[wpos.col + 1][wpos.row] = DEST;
  195. }
  196.  
  197.  
  198. void move_box_north(Puzzle& puzzle)
  199. {
  200.     //Pre:
  201.     assert(true);
  202.     //Post:
  203.     //After this function is called, the box directly north of the worker
  204.     //will be one spot to the north. The spot where the box was will either
  205.     //be an empty cell or a destination cell
  206.  
  207.  
  208.     Pos wpos = find_worker(puzzle);
  209.  
  210.  
  211.     if(puzzle[wpos.col - 2][wpos.row] == EMPTY)
  212.         puzzle[wpos.col - 2][wpos.row] = BOX;
  213.     else
  214.         puzzle[wpos.col - 2][wpos.row] = BDEST;
  215.  
  216.     if(puzzle[wpos.col - 1][wpos.row] == BOX)
  217.         puzzle[wpos.col - 1][wpos.row] = EMPTY;
  218.     else
  219.         puzzle[wpos.col - 1][wpos.row] = DEST;
  220. }
  221.  
  222.  
  223. void move_worker_west(Puzzle& puzzle)
  224. {
  225.     //Pre:
  226.     assert(true);
  227.     //Post:
  228.     //After this function is called, the worker will be moved one spot
  229.     //to the west.  The spot where the worker was will either
  230.     //be an empty cell or a destination cell
  231.  
  232.     Pos wpos = find_worker(puzzle);
  233.  
  234.     if(puzzle[wpos.col][wpos.row - 1] == EMPTY)
  235.         puzzle[wpos.col][wpos.row - 1] = WORKER;
  236.     else
  237.         puzzle[wpos.col][wpos.row - 1] = WDEST;
  238.  
  239.     if(puzzle[wpos.col][wpos.row] == WORKER)
  240.         puzzle[wpos.col][wpos.row] = EMPTY;
  241.     else
  242.         puzzle[wpos.col][wpos.row] = DEST;
  243. }
  244.  
  245. void move_worker_east(Puzzle& puzzle)
  246. {
  247.     //Pre:
  248.     assert(true);
  249.     //Post:
  250.     //After this function is called, the worker will be moved one spot
  251.     //to the east.  The spot where the worker was will either
  252.     //be an empty cell or a destination cell
  253.  
  254.     Pos wpos = find_worker(puzzle);
  255.  
  256.     if(puzzle[wpos.col][wpos.row + 1] == EMPTY)
  257.         puzzle[wpos.col][wpos.row + 1] = WORKER;
  258.     else
  259.         puzzle[wpos.col][wpos.row + 1] = WDEST;
  260.  
  261.     if(puzzle[wpos.col][wpos.row] == WORKER)
  262.         puzzle[wpos.col][wpos.row] = EMPTY;
  263.     else
  264.         puzzle[wpos.col][wpos.row] = DEST;
  265. }
  266.  
  267. void move_worker_north(Puzzle& puzzle)
  268. {
  269.     //Pre:
  270.     assert(true);
  271.     //Post:
  272.     //After this function is called, the worker will be moved one spot
  273.     //to the north.  The spot where the worker was will either
  274.     //be an empty cell or a destination cell
  275.  
  276.     Pos wpos = find_worker(puzzle);
  277.  
  278.     if(puzzle[wpos.col - 1][wpos.row] == EMPTY)
  279.         puzzle[wpos.col - 1][wpos.row] = WORKER;
  280.     else
  281.         puzzle[wpos.col - 1][wpos.row] = WDEST;
  282.  
  283.     if(puzzle[wpos.col][wpos.row] == WORKER)
  284.         puzzle[wpos.col][wpos.row] = EMPTY;
  285.     else
  286.         puzzle[wpos.col][wpos.row] = DEST;
  287. }
  288.  
  289. void move_worker_south(Puzzle& puzzle)
  290. {
  291.     //Pre:
  292.     assert(true);
  293.     //Post:
  294.     //After this function is called, the worker will be moved one spot
  295.     //to the south.  The spot where the worker was will either
  296.     //be an empty cell or a destination cell
  297.  
  298.     Pos wpos = find_worker(puzzle);
  299.  
  300.     if(puzzle[wpos.col + 1][wpos.row] == EMPTY)
  301.         puzzle[wpos.col + 1][wpos.row] = WORKER;
  302.     else
  303.         puzzle[wpos.col + 1][wpos.row] = WDEST;
  304.  
  305.     if(puzzle[wpos.col][wpos.row] == WORKER)
  306.         puzzle[wpos.col][wpos.row] = EMPTY;
  307.     else
  308.         puzzle[wpos.col][wpos.row] = DEST;
  309. }
  310.  
  311. void go_north(Puzzle& puzzle)
  312. {
  313.     //Pre:
  314.     assert(true);
  315.     //Post:
  316.     //After this function is called, the worker will be moved one spot
  317.     //to the north, and if there is a box north of the worker, it will
  318.     //be moved also. The spot where the worker was will either be an empty
  319.     //spot or a destination.
  320.  
  321.     //find the worker
  322.     Pos worker_pos = find_worker(puzzle);
  323.  
  324.     //check if the worker is south of a box
  325.     if (is_south_of_box(puzzle, worker_pos))
  326.         move_box_north(puzzle);
  327.  
  328.     move_worker_north(puzzle);
  329. }
  330.  
  331. void go_south(Puzzle& puzzle)
  332. {
  333.     //Pre:
  334.     assert(true);
  335.     //Post:
  336.     //After this function is called, the worker will be moved one spot
  337.     //to the south, and if there is a box south of the worker, it will
  338.     //be moved also. The spot where the worker was will either be an empty
  339.     //spot or a destination.
  340.  
  341.     //find the worker
  342.     Pos worker_pos = find_worker(puzzle);
  343.  
  344.     //check if the worker is south of a box
  345.     if (is_north_of_box(puzzle, worker_pos))
  346.         move_box_south(puzzle);
  347.  
  348.     move_worker_south(puzzle);
  349. }
  350.  
  351. void go_east(Puzzle& puzzle)
  352. {
  353.     //Pre:
  354.     assert(true);
  355.     //Post:
  356.     //After this function is called, the worker will be moved one spot
  357.     //to the east, and if there is a box east of the worker, it will
  358.     //be moved also. The spot where the worker was will either be an empty
  359.     //spot or a destination.
  360.  
  361.     //find the worker
  362.     Pos worker_pos = find_worker(puzzle);
  363.  
  364.     //check if the worker is south of a box
  365.     if (is_west_of_box(puzzle, worker_pos))
  366.  
  367.         move_box_east(puzzle);
  368.  
  369.  
  370.     move_worker_east(puzzle);
  371. }
  372.  
  373. void go_west(Puzzle& puzzle)
  374. {
  375.     //Pre:
  376.     assert(true);
  377.     //Post:
  378.     //After this function is called, the worker will be moved one spot
  379.     //to the west, and if there is a box west of the worker, it will
  380.     //be moved also. The spot where the worker was will either be an empty
  381.     //spot or a destination.
  382.     //find the worker
  383.     Pos worker_pos = find_worker(puzzle);
  384.  
  385.     //check if the worker is south of a box
  386.     if (is_east_of_box(puzzle, worker_pos))
  387.         move_box_west(puzzle);
  388.  
  389.     move_worker_west(puzzle);
  390. }
  391.  
  392. bool can_go_north(Puzzle& puzzle)
  393. {
  394.     //Pre:
  395.     assert(true);
  396.     //Post:
  397.     //If the worker is able to go north (when there is no wall in the way,
  398.     //with or without box) it will have returned true.
  399.     Pos p = find_worker(puzzle);
  400.     char tocell = puzzle[p.row][p.col];
  401.     if(tocell == WALL)
  402.         return false;
  403.     if(tocell == EMPTY || tocell == DEST)
  404.         return true;
  405.     if((tocell == BOX  || tocell == BDEST) && (puzzle[p.row - 1][p.col] == EMPTY || puzzle[p.row - 1][p.col] == DEST))
  406.         return true;
  407. }
  408.  
  409.  
  410. bool can_go_south(Puzzle& puzzle)
  411. {
  412.     //Pre:
  413.     assert(true);
  414.     //Post:
  415.     //If the worker is able to go south (when there is no wall in the way,
  416.     //with or without box) it will have returned true.
  417.  
  418.     Pos p = find_worker(puzzle);
  419.     char tocell = puzzle[p.row][p.col];
  420.     if(tocell == WALL)
  421.         return false;
  422.     if(tocell == EMPTY || tocell == DEST)
  423.         return true;
  424.     if((tocell == BOX || tocell == BDEST) && (puzzle[p.row + 1][p.col] == EMPTY|| puzzle[p.row + 1][p.col] == DEST))
  425.         return true;
  426. }
  427.  
  428.  
  429. bool can_go_west(Puzzle& puzzle)
  430. {
  431.     //Pre:
  432.     assert(true);
  433.     //Post:
  434.     //If the worker is able to go west (when there is no wall in the way,
  435.     //with or without box) it will have returned true.
  436.  
  437.     Pos p = find_worker(puzzle);
  438.     char tocell = puzzle[p.row][p.col];
  439.     if(tocell == WALL)
  440.         return false;
  441.     if(tocell == EMPTY || tocell == DEST)
  442.         return true;
  443.     if((tocell == BOX || tocell == BDEST) && (puzzle[p.row][p.col - 1] == EMPTY || puzzle[p.row][p.col - 1] == DEST))
  444.         return true;
  445. }
  446.  
  447. bool can_go_east(Puzzle& puzzle)
  448. {
  449.     //Pre:
  450.     assert(true);
  451.     //Post:
  452.     //If the worker is able to go east (when there is no wall in the way,
  453.     //with or without box) it will have returned true.
  454.  
  455.     Pos p = find_worker(puzzle);
  456.     char tocell = puzzle[p.row][p.col];
  457.     if(tocell == WALL)
  458.         return false;
  459.     if(tocell == EMPTY || tocell == DEST)
  460.         return true;
  461.     if((tocell == BOX || tocell == BDEST) && (puzzle[p.row][p.col + 1] == EMPTY || puzzle[p.row][p.col + 1] == DEST))
  462.         return true;
  463. }
  464.  
  465.  
  466. void print_puzzle(Puzzle& room)
  467. {
  468.     //Pre:
  469.     assert(true);
  470.     //Post:
  471.     //This function will print the puzzle.
  472.     for(int r = 0; r < size(room); r++)
  473.     {
  474.         for(int c = 0; c < size(room[0]); c++)
  475.         {
  476.             cout << room[r][c];
  477.         }
  478.         cout << endl;
  479.     }
  480.     cout << endl;
  481. }
  482.  
  483.  
  484. bool puzzle_present(vector<Candidate> c, int i, Puzzle newp)
  485. {
  486.     //Pre:
  487.     assert(i > 0);
  488.     //Post:
  489.     //This function will return true if the new configuration has already
  490.     //been considered
  491.  
  492.     while(i >= 0)
  493.     {
  494.         if(c[i].candidate == newp)
  495.             return true;
  496.         i = c[i].parent_candidate;
  497.     }
  498.     return false;
  499. }
  500.  
  501. bool puzzle_ready(Puzzle p)
  502. {
  503.     //Pre:
  504.     assert(true);
  505.     //Post:
  506.     //This function will return true if the puzzle is completed; ie if there
  507.     //are no empty destination cells
  508.     for(int r = 0; r < size(p); r++)
  509.         for(int c = 0; c < size(p[0]); c++)
  510.             if(p[r][c] == '.')
  511.                 return false;
  512.     return true;
  513. }
  514.  
  515. void show_path(vector<Candidate>& c, int i)
  516. {
  517.     //Pre:
  518.     assert(true);
  519.     //Post:
  520.     //This function will recursively print the path we took to complete
  521.     //the puzzle
  522.     if(i < 0)
  523.         print_puzzle(c[i].candidate);
  524.     else
  525.     {
  526.         print_puzzle(c[i].candidate);
  527.         show_path(c, c[i].parent_candidate);
  528.     }
  529. }
  530.  
  531. void solve_breadth_first(Puzzle& start)
  532. {
  533.     //Pre:
  534.     assert(true);
  535.     //post:
  536.     //This function will use a breadth first search algorythm to find
  537.     //a solution for the puzzle and if it exists it will print all the steps
  538.     //needed to solve it.
  539.     vector<Candidate> c = {{start, -1}};
  540.     int i = 0;
  541.     while(i < size(c) && !puzzle_ready(c[i].candidate))
  542.     {
  543.         Puzzle p = c[i].candidate;
  544.         if(can_go_north(p))
  545.         {
  546.             //go north, and save to new puzzle
  547.             Puzzle newp = p;
  548.             go_north(newp);
  549.             //check if new puzzle is really new
  550.             if(!puzzle_present(c, i, newp))
  551.             {
  552.                 Candidate newc = {newp, i};
  553.                 //save new puzzle to puzzle
  554.                 c.push_back(newc);
  555.             }
  556.  
  557.         }
  558. /*
  559.         if(can_go_south(p))
  560.         {
  561.             Puzzle newp = p;
  562.             go_south(newp);
  563.             if(!puzzle_present(c, i, newp))
  564.                 Candidate newc = {newp, i};
  565.                 c.push_back(newc);
  566.  
  567.         }
  568.  
  569.         if(can_go_west(p))
  570.         {
  571.             Puzzle newp = p;
  572.             go_west(newp);
  573.             if(!puzzle_present(c, i, newp))
  574.                 Candidate newc = {newp, i};
  575.                 c.push_back(newc);
  576.         }
  577.  
  578.         if(can_go_east(p))
  579.         {
  580.             Puzzle newp = p;
  581.             go_south(newp);
  582.             if(!puzzle_present(c, i, newp))
  583.                 Candidate newc = {newp, i};
  584.                 c.push_back(newc);
  585.         }
  586. */
  587.         i++;
  588.     }
  589.     if(i<size(c)) show_path(c, i);
  590. }
  591.  
  592.  
  593. int main()
  594. {
  595.     Puzzle room =               {   {'*','*','*','*','*','*','*','*',' ','*'} ,
  596.                                     {'*',' ',' ',' ',' ',' ',' ','b','B','*'} ,
  597.                                     {'*','B',' ',' ',' ',' ',' ','B','W','*'} ,
  598.                                     {'*',' ',' ','*','*','*','*','.',' ','*'} ,
  599.                                     {'*','*','*','*','*','*','*','*',' ','*'} };
  600.     print_puzzle(room);
  601.     go_north(room);
  602.     print_puzzle(room);
  603.     go_west(room);
  604.     print_puzzle(room);
  605.     go_south(room);
  606.     print_puzzle(room);
  607.     go_east(room);
  608.     print_puzzle(room);
  609.  
  610.  
  611.  
  612.  
  613.  
  614.     return 0;
  615.  
  616.  
  617.  
  618. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement