Advertisement
Guest User

RubiksCube solver (1st face only)

a guest
Jan 21st, 2020
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.26 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <vector>
  3. #include <iostream>
  4. #include <memory>
  5. #include <string>
  6. #include <algorithm>
  7. #include <ctime>
  8. #include <random>
  9.  
  10.  
  11.  
  12. enum Colors {
  13.     white = 0,
  14.     yellow = 1,
  15.     red = 2,
  16.     green = 3,
  17.     orange = 4,
  18.     blue = 5
  19. };
  20.  
  21. enum Directions {
  22.     x = 0,
  23.     y = 1,
  24.     z = 2
  25. };
  26.  
  27. enum Movements {
  28.     R = 0,
  29.     Rp = 1,
  30.     L = 2,
  31.     Lp = 3,
  32.     U = 4,
  33.     Up = 5,
  34.     D = 6,
  35.     Dp = 7,
  36.     F = 8,
  37.     Fp = 9,
  38.     B = 10,
  39.     Bp = 11
  40. };
  41.  
  42.  
  43. class Piece {
  44.    
  45.     protected:
  46.    
  47.    
  48.    
  49.     public:
  50.    
  51.     virtual std::shared_ptr<Piece> copy() {}
  52.     virtual int getColor() {}
  53.     virtual int getColor(int i) {}
  54.     virtual std::ostream& getStream(std::ostream& stream) {return stream;}
  55.     virtual void rotate() {}
  56.     virtual void rotate(int unchangedDirection) {}
  57.     virtual std::vector<int> getAllColors() {}
  58.    
  59. };
  60.  
  61. class Corner : public Piece {
  62.    
  63.     private:
  64.     int m_xColor;
  65.     int m_yColor;
  66.     int m_zColor;
  67.    
  68.     public:
  69.    
  70.     Corner(int xColor, int yColor, int zColor);
  71.     virtual std::shared_ptr<Piece> copy();
  72.     virtual int getColor(int i);
  73.     virtual std::ostream& getStream(std::ostream& stream) override;
  74.     virtual void rotate(int unchangedDirection);
  75.     virtual std::vector<int> getAllColors();
  76. };
  77.  
  78. class Edge : public Piece {
  79.    
  80.     private:
  81.     int m_color1;
  82.     int m_color2;
  83.  
  84.     public:
  85.    
  86.     // color1 is the color oriented to the white side or the yellow side.
  87.     // If there is not, this is the color oriented to the red or the orange side.
  88.     // color2 is the other color
  89.     Edge(int color1, int color2);
  90.     virtual std::shared_ptr<Piece> copy();
  91.     virtual int getColor(int i);
  92.     virtual std::ostream& getStream(std::ostream& stream) override;
  93.     virtual void rotate();
  94.     virtual std::vector<int> getAllColors();
  95. };
  96.  
  97. class Center : public Piece {
  98.    
  99.     private:
  100.     int m_color;
  101.    
  102.     public:
  103.    
  104.     Center(int color);
  105.     virtual std::shared_ptr<Piece> copy();
  106.     virtual int getColor();
  107.     virtual std::ostream& getStream(std::ostream& stream) override;
  108.     virtual std::vector<int> getAllColors();
  109. };
  110.  
  111. typedef std::vector<std::vector<std::shared_ptr<Piece>>> vectorOfPieces;
  112.  
  113. class Sequence {
  114.    
  115. };
  116.  
  117. class RubiksCube {
  118.    
  119.     private:
  120.     vectorOfPieces m_possibility;
  121.     void move(int corners[4][2], int edges[4][2], bool prime, bool doEdgesRotate, int cornerUnchangedDirection);
  122.     void moveInterior(int edges[4][2], int centers[4][2], bool prime);
  123.     bool isPieceWellPlaced(vectorOfPieces objective, std::shared_ptr<Piece> piece);
  124.     std::vector<int> findPlaceOfPiece(std::shared_ptr<Piece> piece, vectorOfPieces possibility);
  125.     // RESOLUTION
  126.     // FIRST CROSS (WHITE FACE)
  127.     void solveFirstCross(vectorOfPieces objective);
  128.     void putEdgeDown(std::shared_ptr<Piece> edge);
  129.     void placeEdge(vectorOfPieces objective, std::shared_ptr<Piece> edge);
  130.     // 1st FACE (WHITE) = CORNERS
  131.     void finishFirstFace(vectorOfPieces objective);
  132.     void putCornerDown(std::shared_ptr<Piece> corner);
  133.     void placeCorner(vectorOfPieces objective, std::shared_ptr<Piece> corner);
  134.     void silentMovex();
  135.     void silentMovexp();
  136.     void silentMovey();
  137.     void silentMoveyp();
  138.     void silentMovez();
  139.     void silentMovezp();
  140.    
  141.  
  142.     public:
  143.     static RubiksCube askForCube();
  144.     static RubiksCube makeRandomCube();
  145.     static RubiksCube makeRandomCube(vectorOfPieces possibility);
  146.     static RubiksCube makeRandomCube(vectorOfPieces possibility, int seed);
  147.     RubiksCube(vectorOfPieces possibility);
  148.     void moveR();
  149.     void moveRp();
  150.     void moveL();
  151.     void moveLp();
  152.     void moveU();
  153.     void moveUp();
  154.     void moveD();
  155.     void moveDp();
  156.     void moveF();
  157.     void moveFp();
  158.     void moveB();
  159.     void moveBp();
  160.     void moveM();
  161.     void movem();
  162.     void moveE();
  163.     void movee();
  164.     void moveS();
  165.     void moves();
  166.     void movex();
  167.     void movexp();
  168.     void movey();
  169.     void moveyp();
  170.     void movez();
  171.     void movezp();
  172.     int getFaceColor();
  173.     std::shared_ptr<Piece> getPiece(int ring, int i);
  174.     Sequence goTo(vectorOfPieces objective);
  175.     void getStats();
  176.     void test();
  177. };
  178.  
  179.  
  180.  
  181.  
  182. // CONSTANTS
  183.  
  184. vectorOfPieces RUBIKS_CUBE_FINISHED = {
  185.     {
  186.         std::shared_ptr<Piece>(new Center(Colors::white)),
  187.         std::shared_ptr<Piece>(new Corner(Colors::green, Colors::white, Colors::red)),
  188.         std::shared_ptr<Piece>(new Edge(Colors::white, Colors::green)),
  189.         std::shared_ptr<Piece>(new Corner(Colors::green, Colors::white, Colors::orange)),
  190.         std::shared_ptr<Piece>(new Edge(Colors::white, Colors::orange)),
  191.         std::shared_ptr<Piece>(new Corner(Colors::blue, Colors::white, Colors::orange)),
  192.         std::shared_ptr<Piece>(new Edge(Colors::white, Colors::blue)),
  193.         std::shared_ptr<Piece>(new Corner(Colors::blue, Colors::white, Colors::red)),
  194.         std::shared_ptr<Piece>(new Edge(Colors::white, Colors::red))
  195.     },
  196.     {
  197.         std::shared_ptr<Piece>(new Edge(Colors::red, Colors::green)),
  198.         std::shared_ptr<Piece>(new Center(Colors::green)),
  199.         std::shared_ptr<Piece>(new Edge(Colors::orange, Colors::green)),
  200.         std::shared_ptr<Piece>(new Center(Colors::orange)),
  201.         std::shared_ptr<Piece>(new Edge(Colors::orange, Colors::blue)),
  202.         std::shared_ptr<Piece>(new Center(Colors::blue)),
  203.         std::shared_ptr<Piece>(new Edge(Colors::red, Colors::blue)),
  204.         std::shared_ptr<Piece>(new Center(Colors::red))
  205.     },
  206.     {
  207.         std::shared_ptr<Piece>(new Center(Colors::yellow)),
  208.         std::shared_ptr<Piece>(new Corner(Colors::green, Colors::yellow, Colors::red)),
  209.         std::shared_ptr<Piece>(new Edge(Colors::yellow, Colors::green)),
  210.         std::shared_ptr<Piece>(new Corner(Colors::green, Colors::yellow, Colors::orange)),
  211.         std::shared_ptr<Piece>(new Edge(Colors::yellow, Colors::orange)),
  212.         std::shared_ptr<Piece>(new Corner(Colors::blue, Colors::yellow, Colors::orange)),
  213.         std::shared_ptr<Piece>(new Edge(Colors::yellow, Colors::blue)),
  214.         std::shared_ptr<Piece>(new Corner(Colors::blue, Colors::yellow, Colors::red)),
  215.         std::shared_ptr<Piece>(new Edge(Colors::yellow, Colors::red))
  216.     }
  217. };
  218.  
  219.  
  220.  
  221.  
  222. std::ostream& Corner::getStream(std::ostream& stream) {
  223.     stream << "Corner(";
  224.     int color;
  225.     for (int i = 0; i < 3; i++) {
  226.         stream << "Colors::";
  227.         color = getColor(i);
  228.         switch (color) {
  229.             case Colors::white : stream << "white" ; break;
  230.             case Colors::yellow : stream << "yellow" ; break;
  231.             case Colors::red : stream << "red" ; break;
  232.             case Colors::green : stream << "green" ; break;
  233.             case Colors::orange : stream << "orange" ; break;
  234.             case Colors::blue : stream << "blue" ; break;
  235.         }
  236.         stream << ", ";
  237.     }
  238.     stream << ")";
  239.     return stream;
  240. }
  241.  
  242. std::ostream& Edge::getStream(std::ostream& stream) {
  243.     stream << "Edge(";
  244.     int color;
  245.     for (int i = 0; i < 2; i++) {
  246.         stream << "Colors::";
  247.         color = getColor(i);
  248.         switch (color) {
  249.             case Colors::white : stream << "white" ; break;
  250.             case Colors::yellow : stream << "yellow" ; break;
  251.             case Colors::red : stream << "red" ; break;
  252.             case Colors::green : stream << "green" ; break;
  253.             case Colors::orange : stream << "orange" ; break;
  254.             case Colors::blue : stream << "blue" ; break;
  255.         }
  256.         stream << ", ";
  257.     }
  258.     stream << ")";
  259.     return stream;
  260. }
  261.  
  262. std::ostream& Center::getStream(std::ostream& stream) {
  263.     stream << "Center(";
  264.     stream << "Colors::";
  265.     int color = getColor();
  266.     switch (color) {
  267.         case Colors::white : stream << "white" ; break;
  268.         case Colors::yellow : stream << "yellow" ; break;
  269.         case Colors::red : stream << "red" ; break;
  270.         case Colors::green : stream << "green" ; break;
  271.         case Colors::orange : stream << "orange" ; break;
  272.         case Colors::blue : stream << "blue" ; break;
  273.         default: stream << "oullalala la ya un pb la... color=" << color << std::endl;
  274.     }
  275.     stream << ", ";
  276.     stream << ")";
  277.     return stream;
  278. }
  279.  
  280. std::ostream& operator<<(std::ostream& sortie, std::shared_ptr<Piece> piece) {
  281.     return piece->getStream(sortie);
  282. }
  283.  
  284. std::ostream& operator<<(std::ostream& stream, RubiksCube cube) {
  285.     stream << "{" << std::endl;
  286.     stream << "\t{" << std::endl;
  287.     for (int i = 0; i < 9; i++) {
  288.         stream << "\t\t" << cube.getPiece(0, i) << "," << std::endl;
  289.     }
  290.     stream << "\t}," << std::endl;
  291.     stream << "\t{" << std::endl;
  292.     for (int i = 0; i < 8; i++) {
  293.         stream << "\t\t" << cube.getPiece(1, i) << "," << std::endl;
  294.     }
  295.     stream << "\t}," << std::endl;
  296.     stream << "\t{" << std::endl;
  297.     for (int i = 0; i < 9; i++) {
  298.         stream << "\t\t" << cube.getPiece(2, i) << "," << std::endl;
  299.     }
  300.     stream << "\t}" << std::endl;
  301.     stream << "}" << std::endl;
  302.     return stream;
  303. }
  304.  
  305. bool operator==(std::shared_ptr<Piece> piece1, std::shared_ptr<Piece> piece2) {
  306.     std::vector<int> piece1Colors = piece1->getAllColors();
  307.     std::vector<int> piece2Colors = piece2->getAllColors();
  308.     if (piece1Colors.size() != piece2Colors.size()) return false;
  309.     for (int i = 0; i < piece2Colors.size(); i++) {
  310.         if (piece1Colors[i] != piece2Colors[i]) return false;
  311.     } return true;
  312. }
  313.  
  314. bool operator!=(std::shared_ptr<Piece> piece1, std::shared_ptr<Piece> piece2) {
  315.     std::vector<int> piece1Colors = piece1->getAllColors();
  316.     std::vector<int> piece2Colors = piece2->getAllColors();
  317.     if (piece1Colors.size() != piece2Colors.size()) return true;
  318.     for (int i = 0; i < piece2Colors.size(); i++) {
  319.         if (std::find(piece1Colors.begin(), piece1Colors.end(), piece2Colors[i]) == piece1Colors.end()) {
  320.             return true;
  321.         }
  322.     } return false;
  323. }
  324.  
  325. Corner::Corner(int xColor, int yColor, int zColor) :
  326. m_xColor(xColor),
  327. m_yColor(yColor),
  328. m_zColor(zColor) {}
  329.  
  330. Edge::Edge(int color1, int color2) :
  331. m_color1(color1),
  332. m_color2(color2) {}
  333.  
  334. Center::Center(int color) :
  335. m_color(color) {}
  336.  
  337. std::shared_ptr<Piece> Corner::copy() {
  338.     return std::shared_ptr<Piece> (new Corner(m_xColor, m_yColor, m_zColor));
  339. }
  340.  
  341. std::shared_ptr<Piece> Edge::copy() {
  342.     return std::shared_ptr<Piece> (new Edge(m_color1, m_color2));
  343. }
  344.  
  345. std::shared_ptr<Piece> Center::copy() {
  346.     return std::shared_ptr<Piece> (new Center(m_color));
  347. }
  348.  
  349. int Corner::getColor(int color) {
  350.     switch (color) {
  351.         case 0: return m_xColor;
  352.         case 1: return m_yColor;
  353.         case 2: return m_zColor;
  354.     }
  355. }
  356.  
  357. int Edge::getColor(int color) {
  358.     switch (color) {
  359.         case 0: return m_color1;
  360.         case 1: return m_color2;
  361.     }
  362. }
  363.  
  364. int Center::getColor() {
  365.     return m_color;
  366. }
  367.  
  368. std::vector<int> Corner::getAllColors() {
  369.     std::vector<int> colors = {m_xColor, m_yColor, m_zColor};
  370.     return colors;
  371. }
  372.  
  373. std::vector<int> Edge::getAllColors() {
  374.     std::vector<int> colors = {m_color1, m_color2};
  375.     return colors;
  376. }
  377.  
  378. std::vector<int> Center::getAllColors() {
  379.     std::vector<int> colors = {m_color};
  380.     return colors;
  381. }
  382.  
  383. void Corner::rotate(int unchangedDirection) {
  384.     int directionsToChange[2];
  385.     if (unchangedDirection == Directions::x) {
  386.         int color = m_yColor;
  387.         m_yColor = m_zColor;
  388.         m_zColor = color;
  389.     }
  390.     if (unchangedDirection == Directions::y) {
  391.         int color = m_xColor;
  392.         m_xColor = m_zColor;
  393.         m_zColor = color;
  394.     }
  395.     if (unchangedDirection == Directions::z) {
  396.         int color = m_xColor;
  397.         m_xColor = m_yColor;
  398.         m_yColor = color;
  399.     }
  400.    
  401. }
  402.  
  403. void Edge::rotate() {
  404.     int color1 = m_color1;
  405.     m_color1 = m_color2;
  406.     m_color2 = color1;
  407. }
  408.  
  409. RubiksCube::RubiksCube(vectorOfPieces possibility) :
  410. m_possibility(possibility) {}
  411.  
  412. std::shared_ptr<Piece> RubiksCube::getPiece(int ring, int i) {
  413.     return m_possibility[ring][i];
  414. }
  415.  
  416. int RubiksCube::getFaceColor() {
  417.     return m_possibility[1][7]->getColor();
  418. }
  419.  
  420.  
  421. void RubiksCube::move(int corners[4][2], int edges[4][2], bool prime, bool doEdgesRotate, int cornerUnchangedDirection) {
  422.     std::vector<std::shared_ptr<Piece>> cornersVector = {
  423.         m_possibility[corners[0][0]][corners[0][1]],
  424.         m_possibility[corners[1][0]][corners[1][1]],
  425.         m_possibility[corners[2][0]][corners[2][1]],
  426.         m_possibility[corners[3][0]][corners[3][1]]
  427.     };
  428.     std::vector<std::shared_ptr<Piece>> edgesVector = {
  429.         m_possibility[edges[0][0]][edges[0][1]],
  430.         m_possibility[edges[1][0]][edges[1][1]],
  431.         m_possibility[edges[2][0]][edges[2][1]],
  432.         m_possibility[edges[3][0]][edges[3][1]]
  433.     };
  434.     if (!prime) {
  435.         m_possibility[corners[0][0]][corners[0][1]] = cornersVector[3];
  436.         m_possibility[corners[1][0]][corners[1][1]] = cornersVector[0];
  437.         m_possibility[corners[2][0]][corners[2][1]] = cornersVector[1];
  438.         m_possibility[corners[3][0]][corners[3][1]] = cornersVector[2];
  439.         m_possibility[edges[0][0]][edges[0][1]] = edgesVector[3];
  440.         m_possibility[edges[1][0]][edges[1][1]] = edgesVector[0];
  441.         m_possibility[edges[2][0]][edges[2][1]] = edgesVector[1];
  442.         m_possibility[edges[3][0]][edges[3][1]] = edgesVector[2];
  443.     } else {
  444.         m_possibility[corners[0][0]][corners[0][1]] = cornersVector[1];
  445.         m_possibility[corners[1][0]][corners[1][1]] = cornersVector[2];
  446.         m_possibility[corners[2][0]][corners[2][1]] = cornersVector[3];
  447.         m_possibility[corners[3][0]][corners[3][1]] = cornersVector[0];
  448.         m_possibility[edges[0][0]][edges[0][1]] = edgesVector[1];
  449.         m_possibility[edges[1][0]][edges[1][1]] = edgesVector[2];
  450.         m_possibility[edges[2][0]][edges[2][1]] = edgesVector[3];
  451.         m_possibility[edges[3][0]][edges[3][1]] = edgesVector[0];
  452.     }
  453.     if (doEdgesRotate) {
  454.         for (int i = 0; i < 4; i++) {
  455.             m_possibility[edges[i][0]][edges[i][1]]->rotate();
  456.         }
  457.     }
  458.     for (int i = 0; i < 4; i++) {
  459.         m_possibility[corners[i][0]][corners[i][1]]->rotate(cornerUnchangedDirection);
  460.     }
  461. }
  462.  
  463. void RubiksCube::moveInterior(int edges[4][2], int centers[4][2], bool prime) {
  464.     std::vector<std::shared_ptr<Piece>> edgesVector = {
  465.         m_possibility[edges[0][0]][edges[0][1]],
  466.         m_possibility[edges[1][0]][edges[1][1]],
  467.         m_possibility[edges[2][0]][edges[2][1]],
  468.         m_possibility[edges[3][0]][edges[3][1]]
  469.     };
  470.     std::vector<std::shared_ptr<Piece>> centersVector = {
  471.         m_possibility[centers[0][0]][centers[0][1]],
  472.         m_possibility[centers[1][0]][centers[1][1]],
  473.         m_possibility[centers[2][0]][centers[2][1]],
  474.         m_possibility[centers[3][0]][centers[3][1]]
  475.     };
  476.     if (!prime) {
  477.         m_possibility[edges[0][0]][edges[0][1]] = edgesVector[3];
  478.         m_possibility[edges[1][0]][edges[1][1]] = edgesVector[0];
  479.         m_possibility[edges[2][0]][edges[2][1]] = edgesVector[1];
  480.         m_possibility[edges[3][0]][edges[3][1]] = edgesVector[2];
  481.         m_possibility[centers[0][0]][centers[0][1]] = centersVector[3];
  482.         m_possibility[centers[1][0]][centers[1][1]] = centersVector[0];
  483.         m_possibility[centers[2][0]][centers[2][1]] = centersVector[1];
  484.         m_possibility[centers[3][0]][centers[3][1]] = centersVector[2];
  485.     } else {
  486.         m_possibility[edges[0][0]][edges[0][1]] = edgesVector[1];
  487.         m_possibility[edges[1][0]][edges[1][1]] = edgesVector[2];
  488.         m_possibility[edges[2][0]][edges[2][1]] = edgesVector[3];
  489.         m_possibility[edges[3][0]][edges[3][1]] = edgesVector[0];
  490.         m_possibility[centers[0][0]][centers[0][1]] = centersVector[1];
  491.         m_possibility[centers[1][0]][centers[1][1]] = centersVector[2];
  492.         m_possibility[centers[2][0]][centers[2][1]] = centersVector[3];
  493.         m_possibility[centers[3][0]][centers[3][1]] = centersVector[0];
  494.     }
  495.     for (int i = 0; i < 4; i++) {
  496.         m_possibility[edges[i][0]][edges[i][1]]->rotate();
  497.     }
  498. }
  499.  
  500. void RubiksCube::moveR() {
  501.     int corners[4][2] = {{0,7}, {0,5}, {2,5}, {2,7}};
  502.     int edges[4][2] = {{0,6}, {1,4}, {2,6}, {1,6}};
  503.     int doEdgesRotate = getFaceColor() == Colors::blue || getFaceColor() == Colors::green;
  504.     move(corners, edges, false, doEdgesRotate, Directions::x);
  505. }
  506.  
  507. void RubiksCube::moveRp() {
  508.     int corners[4][2] = {{0,7}, {0,5}, {2,5}, {2,7}};
  509.     int edges[4][2] = {{0,6}, {1,4}, {2,6}, {1,6}};
  510.     int doEdgesRotate = getFaceColor() == Colors::blue || getFaceColor() == Colors::green;
  511.     move(corners, edges, true, doEdgesRotate, Directions::x);
  512. }
  513.  
  514.  
  515. void RubiksCube::moveL() {
  516.     int corners[4][2] = {{0,3}, {0,1}, {2,1}, {2,3}};
  517.     int edges[4][2] = {{0,2}, {1,0}, {2,2}, {1,2}};
  518.     int doEdgesRotate = getFaceColor() == Colors::blue || getFaceColor() == Colors::green;
  519.     move(corners, edges, false, doEdgesRotate, Directions::x);
  520. }
  521.  
  522. void RubiksCube::moveLp() {
  523.     int corners[4][2] = {{0,3}, {0,1}, {2,1}, {2,3}};
  524.     int edges[4][2] = {{0,2}, {1,0}, {2,2}, {1,2}};
  525.     int doEdgesRotate = getFaceColor() == Colors::blue || getFaceColor() == Colors::green;
  526.     move(corners, edges, true, doEdgesRotate, Directions::x);
  527. }
  528.  
  529. void RubiksCube::moveU() {
  530.     int corners[4][2] = {{0,1}, {0,3}, {0,5}, {0,7}};
  531.     int edges[4][2] = {{0,2}, {0,4}, {0,6}, {0,8}};
  532.     int doEdgesRotate = getFaceColor() == Colors::white || getFaceColor() == Colors::yellow;
  533.     move(corners, edges, false, doEdgesRotate, Directions::y);
  534. }
  535.  
  536. void RubiksCube::moveUp() {
  537.     int corners[4][2] = {{0,1}, {0,3}, {0,5}, {0,7}};
  538.     int edges[4][2] = {{0,2}, {0,4}, {0,6}, {0,8}};
  539.     int doEdgesRotate = getFaceColor() == Colors::white || getFaceColor() == Colors::yellow;
  540.     move(corners, edges, true, false, Directions::y);
  541. }
  542.  
  543. void RubiksCube::moveD() {
  544.     int corners[4][2] = {{2,7}, {2,5}, {2,3}, {2,1}};
  545.     int edges[4][2] = {{2,8}, {2,6}, {2,4}, {2,2}};
  546.     int doEdgesRotate = getFaceColor() == Colors::white || getFaceColor() == Colors::yellow;
  547.     move(corners, edges, false, false, Directions::y);
  548. }
  549.  
  550. void RubiksCube::moveDp() {
  551.     int corners[4][2] = {{2,7}, {2,5}, {2,3}, {2,1}};
  552.     int edges[4][2] = {{2,8}, {2,6}, {2,4}, {2,2}};
  553.     int doEdgesRotate = getFaceColor() == Colors::white || getFaceColor() == Colors::yellow;
  554.     move(corners, edges, true, false, Directions::y);
  555. }
  556.  
  557. void RubiksCube::moveF() {
  558.     int corners[4][2] = {{0,1}, {0,7}, {2,7}, {2,1}};
  559.     int edges[4][2] = {{0,8}, {1,6}, {2,8}, {1,0}};
  560.     int doEdgesRotate = getFaceColor() == Colors::red || getFaceColor() == Colors::red;
  561.     move(corners, edges, false, doEdgesRotate, Directions::z);
  562. }
  563.  
  564. void RubiksCube::moveFp() {
  565.     int corners[4][2] = {{0,1}, {0,7}, {2,7}, {2,1}};
  566.     int edges[4][2] = {{0,8}, {1,6}, {2,8}, {1,0}};
  567.     int doEdgesRotate = getFaceColor() == Colors::red || getFaceColor() == Colors::orange;
  568.     move(corners, edges, true, doEdgesRotate, Directions::z);
  569. }
  570.  
  571. void RubiksCube::moveB() {
  572.     int corners[4][2] = {{0,3}, {2,3}, {2,5}, {0,5}};
  573.     int edges[4][2] = {{0,4}, {1,2}, {2,4}, {1,4}};
  574.     int doEdgesRotate = getFaceColor() == Colors::red || getFaceColor() == Colors::orange;
  575.     move(corners, edges, false, doEdgesRotate, Directions::z);
  576. }
  577.  
  578. void RubiksCube::moveBp() {
  579.     int corners[4][2] = {{0,3}, {2,3}, {2,5}, {0,5}};
  580.     int edges[4][2] = {{0,4}, {1,2}, {2,4}, {1,4}};
  581.     int doEdgesRotate = getFaceColor() == Colors::red || getFaceColor() == Colors::orange;
  582.     move(corners, edges, true, doEdgesRotate, Directions::z);
  583. }
  584.  
  585. void RubiksCube::moveM() {
  586.     int edges[4][2] = {{0,8}, {2,8}, {2,4}, {0,4}};
  587.     int centers[4][2] = {{0,0}, {1,7}, {2,0}, {1,3}};
  588.     moveInterior(edges, centers, false);
  589. }
  590.  
  591. void RubiksCube::movem() {
  592.     int edges[4][2] = {{0,8}, {2,8}, {2,4}, {0,4}};
  593.     int centers[4][2] = {{0,0}, {1,7}, {2,0}, {1,3}};
  594.     moveInterior(edges, centers, true);
  595. }
  596.  
  597. void RubiksCube::moveE() {
  598.     int edges[4][2] = {{1,0}, {1,2}, {1,4}, {1,6}};
  599.     int centers[4][2] = {{1,7}, {1,1}, {1,3}, {1,5}};
  600.     moveInterior(edges, centers, false);
  601. }
  602.  
  603. void RubiksCube::movee() {
  604.     int edges[4][2] = {{1,0}, {1,2}, {1,4}, {1,6}};
  605.     int centers[4][2] = {{1,7}, {1,1}, {1,3}, {1,5}};
  606.     moveInterior(edges, centers, true);
  607. }
  608.  
  609. void RubiksCube::moveS() {
  610.     int edges[4][2] = {{0,6}, {2,6}, {2,2}, {0,2}};
  611.     int centers[4][2] = {{0,0}, {1,5}, {2,0}, {1,1}};
  612.     moveInterior(edges, centers, false);
  613. }
  614.  
  615. void RubiksCube::moves() {
  616.     int edges[4][2] = {{0,6}, {2,6}, {2,2}, {0,2}};
  617.     int centers[4][2] = {{0,0}, {1,5}, {2,0}, {1,1}};
  618.     moveInterior(edges, centers, true);
  619. }
  620.  
  621. void RubiksCube::movex() {
  622.     moveR();
  623.     movem();
  624.     moveLp();
  625. }
  626.  
  627. void RubiksCube::movexp() {
  628.     moveRp();
  629.     moveM();
  630.     moveL();
  631. }
  632.  
  633. void RubiksCube::movey() {
  634.     moveU();
  635.     moveE();
  636.     moveDp();
  637. }
  638.  
  639. void RubiksCube::moveyp() {
  640.     moveUp();
  641.     movee();
  642.     moveD();
  643. }
  644.  
  645. void RubiksCube::movez() {
  646.     moveF();
  647.     moveS();
  648.     moveBp();
  649. }
  650.  
  651.  
  652. void RubiksCube::movezp() {
  653.     moveFp();
  654.     moveS();
  655.     moveB();
  656. }
  657.  
  658. void RubiksCube::silentMovex() {
  659.     moveR();
  660.     movem();
  661.     moveLp();
  662. }
  663.  
  664. void RubiksCube::silentMovexp() {
  665.     moveRp();
  666.     moveM();
  667.     moveL();
  668. }
  669.  
  670. void RubiksCube::silentMovey() {
  671.     moveU();
  672.     moveE();
  673.     moveDp();
  674. }
  675.  
  676. void RubiksCube::silentMoveyp() {
  677.     moveUp();
  678.     movee();
  679.     moveD();
  680. }
  681.  
  682. void RubiksCube::silentMovez() {
  683.     moveF();
  684.     moveS();
  685.     moveBp();
  686. }
  687.  
  688. void RubiksCube::silentMovezp() {
  689.     moveFp();
  690.     moveS();
  691.     moveB();
  692. }
  693.  
  694. RubiksCube RubiksCube::askForCube() {
  695.     int faces[6][9];
  696.     std::cout << "Les couleurs"
  697.     << std::endl << "\t- Blanc : 0"
  698.     << std::endl << "\t- Jaune : 1"
  699.     << std::endl << "\t- Rouge : 2"
  700.     << std::endl << "\t- Vert : 3"
  701.     << std::endl << "\t- Orange : 4"
  702.     << std::endl << "\t- Bleu : 5" << std::endl;
  703.     std::string facesNames[6] = {"blanche", "jaune", "rouge", "verte", "orange", "bleue"};
  704.     for (int face = 0; face < 6; face++) {
  705.         std::cout << "Entrez la face " << facesNames[face] << " : (centre en premier)" << std::endl;
  706.         for (int i = 0; i < 9; i++) {
  707.             std::cout << "\t> ";
  708.             std::cin >> faces[face][i];
  709.         }
  710.     }
  711.     vectorOfPieces possibility = {
  712.         {
  713.             std::shared_ptr<Piece>(new Center(faces[0][0])),
  714.             std::shared_ptr<Piece>(new Corner(faces[3][5], faces[0][1], faces[2][3])),
  715.             std::shared_ptr<Piece>(new Edge(faces[0][2], faces[3][4])),
  716.             std::shared_ptr<Piece>(new Corner(faces[3][3], faces[0][3], faces[4][5])),
  717.             std::shared_ptr<Piece>(new Edge(faces[0][4], faces[4][4])),
  718.             std::shared_ptr<Piece>(new Corner(faces[5][5], faces[0][5], faces[4][3])),
  719.             std::shared_ptr<Piece>(new Edge(faces[0][6], faces[5][4])),
  720.             std::shared_ptr<Piece>(new Corner(faces[5][3], faces[0][7], faces[2][5])),
  721.             std::shared_ptr<Piece>(new Edge(faces[0][8], faces[2][4])),
  722.         },
  723.         {
  724.             std::shared_ptr<Piece>(new Edge(faces[2][2], faces[3][6])),
  725.             std::shared_ptr<Piece>(new Center(faces[3][0])),
  726.             std::shared_ptr<Piece>(new Edge(faces[4][6], faces[3][2])),
  727.             std::shared_ptr<Piece>(new Center(faces[4][0])),
  728.             std::shared_ptr<Piece>(new Edge(faces[4][2], faces[5][6])),
  729.             std::shared_ptr<Piece>(new Center(faces[5][0])),
  730.             std::shared_ptr<Piece>(new Edge(faces[2][6], faces[5][2])),
  731.             std::shared_ptr<Piece>(new Center(faces[2][0])),
  732.         },
  733.         {
  734.             std::shared_ptr<Piece>(new Center(faces[1][0])),
  735.             std::shared_ptr<Piece>(new Corner(faces[3][7], faces[1][3], faces[2][1])),
  736.             std::shared_ptr<Piece>(new Edge(faces[1][2], faces[3][8])),
  737.             std::shared_ptr<Piece>(new Corner(faces[3][1], faces[1][1], faces[4][7])),
  738.             std::shared_ptr<Piece>(new Edge(faces[1][8], faces[4][8])),
  739.             std::shared_ptr<Piece>(new Corner(faces[5][7], faces[1][7], faces[4][1])),
  740.             std::shared_ptr<Piece>(new Edge(faces[1][6], faces[5][8])),
  741.             std::shared_ptr<Piece>(new Corner(faces[5][1], faces[1][5], faces[2][7])),
  742.             std::shared_ptr<Piece>(new Edge(faces[1][4], faces[2][8])),
  743.         }
  744.     };
  745.     RubiksCube cube(possibility);
  746.     return cube;
  747. }
  748.  
  749. RubiksCube RubiksCube::makeRandomCube(vectorOfPieces possibility, int seed) {
  750.     for (int i = 0; i < 9; i++) {
  751.         possibility[0][i] = possibility[0][i]->copy();
  752.     }
  753.     for (int i = 0; i < 8; i++) {
  754.         possibility[1][i] = possibility[1][i]->copy();
  755.     }
  756.     for (int i = 0; i < 9; i++) {
  757.         possibility[2][i] = possibility[2][i]->copy();
  758.     }
  759.     srand(seed);
  760.     RubiksCube cube(possibility);
  761.     for (int i = 0; i < 100; i++) {
  762.         switch(rand() % 11) {
  763.             case Movements::R: cube.moveR();break;
  764.             case Movements::Rp: cube.moveRp();break;
  765.             case Movements::L: cube.moveL();break;
  766.             case Movements::Lp: cube.moveLp();break;
  767.             case Movements::U: cube.moveU();break;
  768.             case Movements::Up: cube.moveUp();break;
  769.             case Movements::D: cube.moveD();break;
  770.             case Movements::Dp: cube.moveDp();break;
  771.             case Movements::F: cube.moveF();break;
  772.             case Movements::Fp: cube.moveFp();break;
  773.             case Movements::B: cube.moveB();break;
  774.             case Movements::Bp: cube.moveBp();break;
  775.         }
  776.     } return cube;
  777. }
  778.  
  779. RubiksCube RubiksCube::makeRandomCube(vectorOfPieces possibility) {
  780.     return makeRandomCube(possibility, time(NULL));
  781. }
  782.  
  783. RubiksCube RubiksCube::makeRandomCube() {
  784.     return makeRandomCube(RUBIKS_CUBE_FINISHED, time(NULL));
  785. }
  786.  
  787. std::vector<int> RubiksCube::findPlaceOfPiece(std::shared_ptr<Piece> piece, vectorOfPieces possibility) {
  788.     for (int i = 0; i < 9; i++) {
  789.         if (!(possibility[0][i] != piece)) return std::vector<int> {0, i};
  790.     }
  791.     for (int i = 0; i < 8; i++) {
  792.         if (!(possibility[1][i] != piece)) return std::vector<int> {1, i};
  793.     }
  794.     for (int i = 0; i < 9; i++) {
  795.         if (!(possibility[2][i] != piece)) return std::vector<int> {2, i};
  796.     }
  797.     std::cout << "ERROR : Piece not found " << piece << std::endl;
  798.     return std::vector<int> {-1, -1};
  799. }
  800.  
  801. bool RubiksCube::isPieceWellPlaced(vectorOfPieces objective, std::shared_ptr<Piece> piece) {
  802.     std::vector<int> movements;
  803.     if (m_possibility[1][1]->getColor() == Colors::white || m_possibility[1][5]->getColor() == Colors::white) {
  804.         silentMovex();
  805.         movements.push_back(Directions::x);
  806.     }
  807.     while (m_possibility[0][0]->getColor() != Colors::white) {
  808.         silentMovex();
  809.         movements.push_back(Directions::x);
  810.     }
  811.     while (m_possibility[1][7]->getColor() != Colors::red) {
  812.         silentMovey();
  813.         movements.push_back(Directions::y);
  814.     }
  815.     std::vector<int> placeOnObjective = findPlaceOfPiece(piece, objective);
  816.     std::vector<int> placeOnPossibility =  findPlaceOfPiece(piece, m_possibility);
  817.     bool response = placeOnObjective == placeOnPossibility;
  818.     for (int i = movements.size() - 1; i >= 0; i--) {
  819.         switch (movements[i]) {
  820.             case Directions::x: silentMovexp();break;
  821.             case Directions::y: silentMoveyp();break;
  822.             case Directions::z: silentMovezp();break;
  823.         }
  824.     }
  825.     return response;
  826. }
  827.  
  828. Sequence RubiksCube::goTo(vectorOfPieces objective) {
  829.     solveFirstCross(objective);
  830.     finishFirstFace(objective);
  831.     Sequence s;
  832.     return s;
  833. }
  834.  
  835. void RubiksCube::solveFirstCross(vectorOfPieces objective) {
  836.     std::vector<std::shared_ptr<Piece>> edges = {
  837.         objective[0][2],
  838.         objective[0][4],
  839.         objective[0][6],
  840.         objective[0][8]
  841.     };
  842.     for (int i = 0; i < 4; i++) {
  843.         moveyp();
  844.         if (!isPieceWellPlaced(objective, edges[i])) {
  845.             putEdgeDown(edges[i]);
  846.             placeEdge(objective, edges[i]);
  847.         }
  848.     }
  849. }
  850.  
  851. void RubiksCube::putEdgeDown(std::shared_ptr<Piece> edge) {
  852.     std::vector<int> pos = findPlaceOfPiece(edge, m_possibility);
  853.     for (int i = 0; i < pos[1] / 2; i++) {
  854.         moveyp();
  855.     }
  856.     if (pos[0] == 0) {
  857.         moveM();
  858.         moveDp();
  859.         movem();
  860.         moveD();
  861.     } else if (pos[0] == 1) {
  862.         moveL();
  863.         moveD();
  864.         moveLp();
  865.     }
  866.     for (int i = 0; i < pos[1] / 2; i++) {
  867.         movey();
  868.         moveD();
  869.     }
  870. }
  871.  
  872. void RubiksCube::placeEdge(vectorOfPieces objective, std::shared_ptr<Piece> edge) {
  873.     if (m_possibility[2][8]->getColor(1) == objective[0][findPlaceOfPiece(edge, objective)[1]]->getColor(0)) {   // GOOD ORIENTATION
  874.         moveDp();
  875.         moveM();
  876.         moveD();
  877.         movem();
  878.     } else {    // BAD ORIENTATION
  879.         moveM();
  880.         moveD();
  881.         moveD();
  882.         movem();
  883.     }
  884. }
  885.  
  886.  
  887. void RubiksCube::finishFirstFace(vectorOfPieces objective) {
  888.     std::vector<std::shared_ptr<Piece>> corners = {
  889.         objective[0][1],
  890.         objective[0][3],
  891.         objective[0][5],
  892.         objective[0][7]
  893.     };
  894.     for (int i = 0; i < 4; i++) {
  895.         moveyp();
  896.         if (!isPieceWellPlaced(objective, corners[i])) {
  897.             putCornerDown(corners[i]);
  898.             placeCorner(objective, corners[i]);
  899.         }
  900.     }
  901. }
  902.  
  903. void RubiksCube::putCornerDown(std::shared_ptr<Piece> corner) {
  904.     std::vector<int> pos = findPlaceOfPiece(corner, m_possibility);
  905.     for (int i = 0; i < (pos[1] + 1) / 2; i++) {
  906.         moveyp();
  907.     }
  908.     if (pos[0] == 0) {
  909.         moveRp();
  910.         moveDp();
  911.         moveR();
  912.         moveD();
  913.     }
  914.     for (int i = 0; i < (pos[1] + 1) / 2; i++) {
  915.         movey();
  916.         moveD();
  917.     }
  918. }
  919.  
  920.  
  921.  
  922.  
  923. void RubiksCube::placeCorner(vectorOfPieces objective, std::shared_ptr<Piece> corner) {
  924.     int color = objective[0][findPlaceOfPiece(corner, objective)[1]]->getColor(1);      // COLOR OF WHITE FACE
  925.     //std::cout << objective << std::endl;
  926.     //std::cout << color << findPlaceOfPiece(corner, objective)[0] << findPlaceOfPiece(corner, objective)[1];
  927.     //std::cout << m_possibility[2][7] << std::endl;
  928.     if (m_possibility[2][7]->getColor(0) == color) {
  929.         moveRp();
  930.         moveDp();
  931.         moveR();
  932.     } else if (m_possibility[2][7]->getColor(1) == color) {
  933.         moveRp();
  934.         moveD();
  935.         moveD();
  936.         moveR();
  937.         moveD();
  938.         moveRp();
  939.         moveDp();
  940.         moveR();
  941.     } else if (m_possibility[2][7]->getColor(2) == color) {
  942.         moveDp();
  943.         moveRp();
  944.         moveD();
  945.         moveR();
  946.     }
  947. }
  948.  
  949. void RubiksCube::test() {
  950.     std::cout << m_possibility.size() << m_possibility[0].size() << m_possibility[1].size() << m_possibility[2].size();
  951. }
  952.  
  953. void getStats(bool debug) {
  954.     std::vector<std::vector<int>> TO_VERIFY {
  955.         {0, 0},
  956.         {0, 1},
  957.         {0, 2},
  958.         {0, 3},
  959.         {0, 4},
  960.         {0, 5},
  961.         {0, 6},
  962.         {0, 7},
  963.         {0, 8},
  964.     };
  965.     srand(time(NULL));
  966.     int rights = 0;
  967.     int tests = 1000;
  968.     double startTime = time(NULL);
  969.     for (int i = 0; i < tests; i++) {
  970.         int seed = rand();
  971.         RubiksCube cube = RubiksCube::makeRandomCube(RUBIKS_CUBE_FINISHED, seed);
  972.         cube.goTo(RUBIKS_CUBE_FINISHED);
  973.         bool error = false;
  974.         for (int j = 0; j < TO_VERIFY.size(); j++) {
  975.             if (cube.getPiece(TO_VERIFY[j][0], TO_VERIFY[j][1]) != RUBIKS_CUBE_FINISHED[TO_VERIFY[j][0]][TO_VERIFY[j][1]]) {
  976.                 error = true;
  977.             }
  978.         }
  979.         if (!error) {
  980.             rights += 1;
  981.         } else if (debug) {
  982.             std::cout << "FAILURE WITH SEED : " << seed << std::endl;
  983.         }
  984.         if (tests / 100 != 0 && i % (tests/100) == 0) {
  985.             std::cout << i / (tests/100) << "% made" << std::endl;
  986.         }
  987.     }
  988.     double endTime = time(NULL);
  989.     std::cout << std::endl << std::endl;
  990.     std::cout << "\t- Number of tests : " << tests << std::endl;
  991.     std::cout << "\t- " << (((double)rights)/tests) * 100 << "% tests successfull (" << tests - rights << " failed)" << std::endl;
  992.     std::cout << "\t- Execution time : " << endTime - startTime << "s" << std::endl;
  993.     std::cout << "\t- " << (endTime - startTime) / tests << " s/test" << std::endl;
  994.     std::cout << "\t- " << tests / (endTime - startTime) << " tests/s" << std::endl;
  995. }
  996.  
  997.  
  998.  
  999. int main() {
  1000.     //RubiksCube cube = RubiksCube::makeRandomCube();
  1001.     //cube.goTo(RUBIKS_CUBE_FINISHED);
  1002.     //std::cout << cube;
  1003.     getStats(false);
  1004.     return 0;
  1005. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement