Advertisement
brilliant_moves

RubiksCube.java

Nov 13th, 2012
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 38.34 KB | None | 0 0
  1. import java.awt.*;      // for Frame
  2. import java.awt.event.*;    // for Buttons and Menu Items
  3. import java.util.*;     // for date/time and Random functions
  4. import javax.swing.*;       // for pop-up help message, JFrame
  5.  
  6. public class RubiksCube {
  7.  
  8.     public static void main(String[] args) {
  9.         RubiksCubeJFrame frame = new RubiksCubeJFrame();
  10.         frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
  11.         frame.setVisible(true);
  12.     }
  13. }
  14.  
  15. class RubiksCubeJFrame extends JFrame implements ActionListener {
  16.  
  17.     /**
  18.     *   Program:    RubiksCube.java
  19.     *   Purpose:    Solve Rubik's Cube in 2-D or glorious 3-D. Very addictive!
  20.     *   Creator:    Chris Clarke
  21.     *   Created:    31.01.2010 to 08.02.2010
  22.     *   Modified:   09.04.2010 Timer added
  23.     *   Modified:   13.11.2012 (converted Frame to JFrame)
  24.     */
  25.                 // make clockwise moves ("Minus" implies anti-clockwise)   
  26.     private Button      btnLeft, btnLeftMinus, btnRight, btnRightMinus;
  27.     private Button      btnFront, btnFrontMinus, btnUpper, btnUpperMinus;
  28.     private Button      btnLower, btnLowerMinus;
  29.     private Button      btnLeftMiddle, btnLeftMiddleMinus;
  30.     private Button      btnFrontMiddle, btnFrontMiddleMinus;
  31.     private Button      btnMiddle, btnMiddleMinus;
  32.                 // turn whole cube's orientation
  33.     private Button      btnRotateFront2Upper, btnRotateUpper2Front;
  34.     private Button      btnRotateLeft2Front, btnRotateFront2Left;
  35.     private Button      btnJumble;          // to jumble cube up
  36.                 // Function/Formula buttons
  37.     private Button      btnEnableFunctions;
  38.     private Button      btnF1a, btnF1b, btnF2a, btnF2b, btnF3a, btnF3b;
  39.  
  40.     MenuItem        resetMI, exitMI, TwoDMI, ThreeDMI, helpMI;
  41.  
  42.     public int[][][]    square=new int[6][3][3];
  43.     public static final int START_X=200;
  44.     public static final int START_Y=200;
  45.     public static final int SQUARE_SIZE=40;
  46.     public static final int SQUARE_SIZE_3D=(int) (SQUARE_SIZE*1.5);
  47.     public int      moveCount=0;    // counts no. of moves to solve cube
  48.     public int      moveNum_F;  // Function/Formula number of moves
  49.     public int      F_index;    //  "   "   move index
  50.     public boolean      done=false; // true when in middle of a function
  51.     public static boolean   jumble;     // to jumble upon startup or not?
  52.     public boolean      jumbled=false;  // false until user jumbles it up
  53.     public String       display="3D";   // 2-Dimensional or 3-Dimensional
  54.                 // record time when cube jumbled up
  55.     public int      startYear=0, startMonth=0, startDay=0;
  56.     public int      startHour=0, startMinute=0, startSecond=0;
  57.  
  58.     //  Function F1a
  59.     //  left/upper/front2/upper2/front2/upper2/front2/upper/leftMinus
  60.     public static final String SWAPTOPLEFTEDGEWITHFRONTRIGHTEDGE = "LUFFUUFFUUFFUl";
  61.  
  62.  
  63.     //  Function F1b
  64.     //  rightMinus/upper/front2/upper2/front2/upper2/front2/upper/right
  65.     public static final String SWAPTOPRIGHTEDGEWITHFRONTLEFTEDGE = "rUFFUUFFUUFFUR";
  66.  
  67.  
  68.     //  Function F2a
  69.     //  leftMiddleMinus/frontMiddleMinus/base/frontMiddle/base/base/
  70.     //      leftMiddle/base
  71.     public static final String SWAP2TOPEDGEPIECES = "xyBYBBXB";
  72.  
  73.  
  74.     //  Function F2b
  75.     //  right/middleMinus/right/middleMinus/right/middleMinus/right/middleMinus
  76.     public static final String ROTATETOPEDGEPIECE = "RzRzRzRz";
  77.  
  78.  
  79.     //  Function F3a
  80.     //  left/front/rightMinus/frontMinus/leftMinus/front/right/frontMinus
  81.     public static final String SWAP3CORNERSANTICLOCKWISE = "LFrflFRf";
  82.  
  83.  
  84.     /*  Function F3b
  85.         left/front/rightMinus/frontMinus/leftMinus/front/right/frontMinus
  86.         rotateLeft2Front
  87.         front/right/frontMinus/left/front/rightMinus/frontMinus/leftMinus
  88.         rotateFront2Left
  89.     */
  90.     public static final String ROTATECORNERS1CLOCKWISE1ANTICLOCKWISE="LFrflFRf" +"HFRfLFrflh";
  91.  
  92.  
  93.     RubiksCubeJFrame() {
  94.         setTitle("Rubik\'s Cube by Chris Clarke");
  95.         MenuBar mbar = new MenuBar();
  96.         Menu fileMenu = new Menu("File");
  97.         resetMI = new MenuItem("Reset");
  98.         resetMI.addActionListener(this);
  99.         fileMenu.add(resetMI);
  100.         exitMI = new MenuItem("Exit");
  101.         exitMI.addActionListener(this);
  102.         fileMenu.add(exitMI);
  103.         mbar.add(fileMenu);
  104.         Menu viewMenu = new Menu("View");
  105.         TwoDMI = new MenuItem("2-D");
  106.         TwoDMI.addActionListener(this);
  107.         viewMenu.add(TwoDMI);
  108.         ThreeDMI = new MenuItem("3-D");
  109.         ThreeDMI.addActionListener(this);
  110.         viewMenu.add(ThreeDMI);
  111.         mbar.add(viewMenu);
  112.         Menu helpMenu = new Menu("Help");
  113.         helpMI = new MenuItem("Help");
  114.         helpMI.addActionListener(this);
  115.         helpMenu.add(helpMI);
  116.         mbar.add(helpMenu);
  117.         setMenuBar(mbar);
  118.  
  119.         // Build control panel.
  120.         Panel panel = new Panel();
  121.         btnLeft = new Button("Left");
  122.         btnLeft.addActionListener(this);
  123.         panel.add(btnLeft);
  124.         btnLeftMinus = new Button("Left-1");
  125.         btnLeftMinus.addActionListener(this);
  126.         panel.add(btnLeftMinus);
  127.         btnLeftMiddle = new Button("Left Mid Col");
  128.         btnLeftMiddle.addActionListener(this);
  129.         panel.add(btnLeftMiddle);
  130.         btnLeftMiddleMinus = new Button("Left Mid-1");
  131.         btnLeftMiddleMinus.addActionListener(this);
  132.         panel.add(btnLeftMiddleMinus);
  133.  
  134.         btnFront = new Button("Front");
  135.         btnFront.addActionListener(this);
  136.         panel.add(btnFront);
  137.         btnFrontMinus = new Button("Front-1");
  138.         btnFrontMinus.addActionListener(this);
  139.         panel.add(btnFrontMinus);
  140.         btnFrontMiddle = new Button("Front Mid Col");
  141.         btnFrontMiddle.addActionListener(this);
  142.         panel.add(btnFrontMiddle);
  143.         btnFrontMiddleMinus = new Button("Front Mid-1");
  144.         btnFrontMiddleMinus.addActionListener(this);
  145.         panel.add(btnFrontMiddleMinus);
  146.  
  147.         btnRight = new Button("Right");
  148.         btnRight.addActionListener(this);
  149.         panel.add(btnRight);
  150.         btnRightMinus = new Button("Right-1");
  151.         btnRightMinus.addActionListener(this);
  152.         panel.add(btnRightMinus);
  153.  
  154.         btnUpper = new Button("Upper");
  155.         btnUpper.addActionListener(this);
  156.         panel.add(btnUpper);
  157.         btnUpperMinus = new Button("Upper-1");
  158.         btnUpperMinus.addActionListener(this);
  159.         panel.add(btnUpperMinus);
  160.         btnLower = new Button("Lower");
  161.         btnLower.addActionListener(this);
  162.         panel.add(btnLower);
  163.         btnLowerMinus = new Button("Lower-1");
  164.         btnLowerMinus.addActionListener(this);
  165.         panel.add(btnLowerMinus);
  166.         btnMiddle = new Button("Middle");
  167.         btnMiddle.addActionListener(this);
  168.         panel.add(btnMiddle);
  169.         btnMiddleMinus = new Button("Middle-1");
  170.         btnMiddleMinus.addActionListener(this);
  171.         panel.add(btnMiddleMinus);
  172.  
  173.         add(panel, BorderLayout.NORTH);
  174.  
  175.         // Build control panel2.
  176.         Panel panel2 = new Panel();
  177.         Label lblTurnCube=new Label("Turn cube");
  178.         panel2.add(lblTurnCube);
  179.         btnRotateFront2Upper = new Button("Front Up");
  180.         btnRotateFront2Upper.addActionListener(this);
  181.         panel2.add(btnRotateFront2Upper);
  182.         btnRotateUpper2Front = new Button("Front Down");
  183.         btnRotateUpper2Front.addActionListener(this);
  184.         panel2.add(btnRotateUpper2Front);
  185.  
  186.         btnRotateLeft2Front = new Button("Front to Right");
  187.         btnRotateLeft2Front.addActionListener(this);
  188.         panel2.add(btnRotateLeft2Front);
  189.         btnRotateFront2Left = new Button("Front to Left");
  190.         btnRotateFront2Left.addActionListener(this);
  191.         panel2.add(btnRotateFront2Left);
  192.         Label lblSpc1=new Label("   "); // spacer
  193.         panel2.add(lblSpc1);
  194.         btnJumble=new Button("Jumble up cube!");
  195.         btnJumble.addActionListener(this);
  196.         panel2.add(btnJumble);
  197.         Label lblSpc2=new Label("   "); // spacer
  198.         panel2.add(lblSpc2);
  199.         btnEnableFunctions = new Button("Enable Formulae");
  200.         btnEnableFunctions.addActionListener(this);
  201.         panel2.add(btnEnableFunctions);
  202.         // Function/Formula buttons
  203.         btnF1a=new Button("F1a");
  204.         btnF1a.addActionListener(this);
  205.         panel2.add(btnF1a);
  206.         btnF1b=new Button("F1b");
  207.         btnF1b.addActionListener(this);
  208.         panel2.add(btnF1b);
  209.         btnF2a=new Button("F2a");
  210.         btnF2a.addActionListener(this);
  211.         panel2.add(btnF2a);
  212.         btnF2b=new Button("F2b");
  213.         btnF2b.addActionListener(this);
  214.         panel2.add(btnF2b);
  215.         btnF3a=new Button("F3a");
  216.         btnF3a.addActionListener(this);
  217.         panel2.add(btnF3a);
  218.         btnF3b=new Button("F3b");
  219.         btnF3b.addActionListener(this);
  220.         panel2.add(btnF3b);
  221.         add(panel2, BorderLayout.SOUTH);
  222.  
  223.         reset();
  224.         // Set to a reasonable size.
  225.         setSize(1024, 768);
  226.     }
  227.  
  228.     public void reset() {
  229.         // set cube to start position
  230.         for (int face=0; face<6; face++)
  231.             for (int row=0; row<3; row++)
  232.                 for (int col=0; col<3; col++)
  233.                     square[face][row][col]=face;
  234.         moveCount=0;
  235.         jumbled=false;
  236.         enableFunctionButtons();
  237.     }
  238.  
  239.     public void setColour(Graphics g, int c) {
  240.         switch(c) {
  241.             case 0: g.setColor(Color.RED); break;
  242.             case 1: g.setColor(Color.YELLOW); break;
  243.             case 2: g.setColor(Color.BLUE); break;
  244.             case 3: g.setColor(Color.GREEN); break;
  245.             case 4: g.setColor(Color.WHITE); break;
  246.             case 5: g.setColor(new Color(230, 120, 0)); // orange
  247.         }
  248.     }
  249.  
  250.     public void labelTheFaces(Graphics g) {
  251.         g.drawString("upper", START_X+(3*SQUARE_SIZE), START_Y-10);
  252.         g.drawString("left", START_X-30, START_Y+(3*SQUARE_SIZE)+10);
  253.         g.drawString("front", START_X+(3*SQUARE_SIZE)+2, START_Y+(3*SQUARE_SIZE)+10);
  254.         g.drawString("right", START_X+(6*SQUARE_SIZE)+2, START_Y+(3*SQUARE_SIZE)+10);
  255.         g.drawString("back", START_X+(12*SQUARE_SIZE)+10, START_Y+(3*SQUARE_SIZE)+10);
  256.         g.drawString("lower", START_X+(3*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE)+20);
  257.     }
  258.  
  259.     public void drawBlackLines(Graphics g) {
  260.         // horizontals
  261.         for (int y=START_Y; y<=START_Y+9*SQUARE_SIZE; y+=SQUARE_SIZE)
  262.             g.drawLine(START_X+(3*SQUARE_SIZE), y, START_X+(6*SQUARE_SIZE), y);
  263.         for (int y=START_Y+(3*SQUARE_SIZE); y<=START_Y+6*SQUARE_SIZE; y+=SQUARE_SIZE)
  264.             g.drawLine(START_X, y, START_X+(4*3*SQUARE_SIZE), y);
  265.  
  266.         // verticals
  267.         for (int x=START_X; x<=START_X+(4*3*SQUARE_SIZE); x+=SQUARE_SIZE)
  268.             g.drawLine(x, START_Y+(3*SQUARE_SIZE), x, START_Y+(6*SQUARE_SIZE));
  269.         for (int x=START_X+(3*SQUARE_SIZE); x<=START_X+(6*SQUARE_SIZE); x+=SQUARE_SIZE)
  270.             g.drawLine(x, START_Y, x, START_Y+(9*SQUARE_SIZE));
  271.     }
  272.  
  273.     public void drawThickBlackLines(Graphics g) {
  274.         // horizontals
  275.         int y=START_Y-1;        // top of face 0
  276.         int x=START_X-1;
  277.         g.drawLine(x+(3*SQUARE_SIZE), y, x+1+(6*SQUARE_SIZE), y);
  278.         y+=3*SQUARE_SIZE;   // top of faces 1-4
  279.         g.drawLine(x, y, x+1+(4*3*SQUARE_SIZE), y);
  280.         y+=3*SQUARE_SIZE;   // bottom of faces 1-4
  281.         g.drawLine(x, y, x+1+(4*3*SQUARE_SIZE), y);
  282.         y+=3*SQUARE_SIZE;   // bottom of face 5
  283.         g.drawLine(x+(3*SQUARE_SIZE), y, x+1+(6*SQUARE_SIZE), y);
  284.  
  285.         // verticals
  286.         y=START_Y-1;        // top of face 0
  287.         g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
  288.         x+=3*SQUARE_SIZE;   // left of faces 0, 2 & 5
  289.         g.drawLine(x, y, x, y+1+(9*SQUARE_SIZE));
  290.         x+=3*SQUARE_SIZE;   // left of face 3, right of 0, 2 & 5
  291.         g.drawLine(x, y, x, y+1+(9*SQUARE_SIZE));
  292.         x+=3*SQUARE_SIZE;   // right of face 3
  293.         g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
  294.         x+=3*SQUARE_SIZE;   // right of face 4
  295.         g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
  296.     }
  297.  
  298.     public boolean cubeIsSolved() {
  299.         // is cube solved?
  300.         for (int face=0; face<6; face++)
  301.             for (int row=0; row<3; row++)
  302.                 for (int col=0; col<3; col++)
  303.                     if (square[face][row][col]!=square[face][0][0])
  304.                         return false;
  305.         return true;
  306.     }
  307.  
  308.     public void update(Graphics g) {
  309.         paint(g);
  310.     }
  311.  
  312.     public void clearScreen(Graphics g) {
  313.         g.setColor(Color.WHITE);
  314.         g.fillRect(0, 0, 1024, 768);
  315.     }
  316.  
  317.     public void paint2Dimensional(Graphics g) {
  318.         // flat squares, all angles 90 degrees
  319.         clearScreen(g);
  320.         // upper face
  321.         for (int row=0; row<3; row++)
  322.             for (int col=0; col<3; col++) {
  323.                 setColour(g, square[0][row][col]);
  324.                 g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
  325.                  START_Y+row*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
  326.             }
  327.         // left face
  328.         for (int row=0; row<3; row++)
  329.             for (int col=0; col<3; col++) {
  330.                 setColour(g, square[1][row][col]);
  331.                 g.fillRect(START_X+col*SQUARE_SIZE,
  332.                  START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
  333.                  SQUARE_SIZE, SQUARE_SIZE);
  334.             }
  335.         // front face
  336.         for (int row=0; row<3; row++)
  337.             for (int col=0; col<3; col++) {
  338.                 setColour(g, square[2][row][col]);
  339.                 g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
  340.                  START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
  341.                  SQUARE_SIZE, SQUARE_SIZE);
  342.             }
  343.         // right face
  344.         for (int row=0; row<3; row++)
  345.             for (int col=0; col<3; col++) {
  346.                 setColour(g, square[3][row][col]);
  347.                 g.fillRect(START_X+(6*SQUARE_SIZE)+col*SQUARE_SIZE,
  348.                  START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
  349.                  SQUARE_SIZE, SQUARE_SIZE);
  350.             }
  351.         // back face
  352.         for (int row=0; row<3; row++)
  353.             for (int col=0; col<3; col++) {
  354.                 setColour(g, square[4][row][col]);
  355.                 g.fillRect(START_X+(9*SQUARE_SIZE)+col*SQUARE_SIZE,
  356.                  START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
  357.                  SQUARE_SIZE, SQUARE_SIZE);
  358.             }
  359.         // lower face
  360.         for (int row=0; row<3; row++)
  361.             for (int col=0; col<3; col++) {
  362.                 setColour(g, square[5][row][col]);
  363.                 g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
  364.                  START_Y+(6*SQUARE_SIZE)+row*SQUARE_SIZE,
  365.                  SQUARE_SIZE, SQUARE_SIZE);
  366.             }
  367.         g.setColor(Color.BLACK);
  368.         labelTheFaces(g);
  369.         drawBlackLines(g);
  370.         drawThickBlackLines(g);
  371.     }
  372.  
  373.     public void drawOneUpperDiamond(Graphics g, int x, int y) {
  374.         // individual upper face squares in 3-D
  375.         Trigonometry trig = new Trigonometry();
  376.         double angle=-30.0; // angle is in degrees, slopes upward left-right
  377.         double radAngle = trig.Degree2Radian(angle);    // radAngle is in radians
  378.         // P2R_X(int hypotenuse, double angle)  // angle is in radians
  379.         int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
  380.         int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is negative
  381.  
  382.         for (int i=1; i<30; i++) {
  383.             g.drawLine(x+i, y, x+xPlus, y+i+yPlus);
  384.             g.drawLine(x+xPlus, y+i+yPlus, x-i+2*xPlus, y);
  385.             g.drawLine(x-i+2*xPlus, y, x+xPlus, y-i-yPlus);
  386.             g.drawLine(x+xPlus, y-i-yPlus, x+i, y);
  387.         }
  388.         // draw black outline
  389.         g.setColor(Color.BLACK);
  390.         g.drawLine(x, y, x+xPlus, y+yPlus);
  391.         g.drawLine(x+xPlus, y+yPlus, x+2*xPlus, y);
  392.         g.drawLine(x+2*xPlus, y, x+xPlus, y-yPlus);
  393.         g.drawLine(x+xPlus, y-yPlus, x, y);
  394.     }
  395.  
  396.     public void drawOneLeftDiamond(Graphics g, int x, int y) {
  397.         // individual left face squares in 3-D
  398.         Trigonometry trig = new Trigonometry();
  399.         double angle=30.0;  // angle is in degrees, slopes downward left-right
  400.         double radAngle = trig.Degree2Radian(angle);    // radAngle is in radians
  401.         // P2R_X(int hypotenuse, double angle)  // angle is in radians
  402.         int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
  403.         int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is positive
  404.  
  405.         for (int i=1; i<=SQUARE_SIZE_3D; i++)
  406.             g.drawLine(x, y+i, x+xPlus-1, y+i+yPlus);
  407.  
  408.         // draw black outline
  409.         g.setColor(Color.BLACK);
  410.         g.drawLine(x, y, x+xPlus, y+yPlus);
  411.         g.drawLine(x+xPlus, y+yPlus, x+xPlus, y+yPlus+SQUARE_SIZE_3D);
  412.         g.drawLine(x, y+SQUARE_SIZE_3D, x, y);
  413.     }
  414.  
  415.     public void drawOneFrontDiamond(Graphics g, int x, int y) {
  416.         // individual front face squares in 3-D
  417.         Trigonometry trig = new Trigonometry();
  418.         double angle=-30.0; // angle is in degrees, slopes upward left-right
  419.         double radAngle = trig.Degree2Radian(angle);    // radAngle is in radians
  420.         // P2R_X(int hypotenuse, double angle)  // angle is in radians
  421.         int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
  422.         int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is negative
  423.  
  424.         for (int i=1; i<=SQUARE_SIZE_3D; i++) {
  425.             g.drawLine(x, y+i, x+xPlus-1, y+i+yPlus);
  426.         }
  427.         // draw black outline
  428.         g.setColor(Color.BLACK);
  429.         g.drawLine(x, y, x+xPlus, y+yPlus);
  430.         g.drawLine(x+xPlus, y+yPlus, x+xPlus, y+yPlus+SQUARE_SIZE_3D);
  431.         g.drawLine(x, y+SQUARE_SIZE_3D, x, y);
  432.     }
  433.  
  434.     public void drawUpperFace3D(Graphics g, int start_x, int start_y, int xPlus,
  435.      int yPlus) {
  436.         //
  437.         for (int row=0; row<3; row++)
  438.             for (int col=0; col<3; col++) {
  439.                 int x_inc=xPlus/3;
  440.                 int y_inc=yPlus/3;          // is negative
  441.                 setColour(g, square[0][row][col]);  // upper face
  442.                 int x=start_x+row*x_inc+col*x_inc;
  443.                 int y=start_y-row*y_inc+col*y_inc;
  444.                 drawOneUpperDiamond(g, x, y);
  445.             }
  446.     }
  447.  
  448.     public void drawLeftFace3D(Graphics g, int start_x, int start_y, int xPlus,
  449.      int yPlus) {
  450.         //
  451.         for (int row=0; row<3; row++)
  452.             for (int col=0; col<3; col++) {
  453.                 int x_inc=xPlus/3;
  454.                 int y_inc=-1*(yPlus/3);         // is positive
  455.                 setColour(g, square[1][row][col]);  // left face
  456.                 int x=start_x+col*x_inc;
  457.                 int y=start_y+row*SQUARE_SIZE_3D+col*y_inc;
  458.                 drawOneLeftDiamond(g, x, y);
  459.             }
  460.     }
  461.  
  462.     public void drawFrontFace3D(Graphics g, int start_x, int start_y, int xPlus,
  463.      int yPlus) {
  464.         //
  465.         for (int row=0; row<3; row++)
  466.             for (int col=0; col<3; col++) {
  467.                 int x_inc=xPlus/3;
  468.                 int y_inc=yPlus/3;          // is negative
  469.                 setColour(g, square[2][row][col]);  // front face
  470.                 int x=start_x+col*x_inc;
  471.                 int y=start_y+row*SQUARE_SIZE_3D+col*y_inc;
  472.                 drawOneFrontDiamond(g, x, y);
  473.             }
  474.     }
  475.  
  476.     public void labelTheFaces3D(Graphics g) {
  477.         g.drawString("upper", START_X+(3*SQUARE_SIZE), START_Y-70);
  478.         g.drawString("left", START_X-30, START_Y+(3*SQUARE_SIZE)+10);
  479.         g.drawString("front", START_X+(9*SQUARE_SIZE), START_Y+(3*SQUARE_SIZE)+10);
  480.     }
  481.  
  482.     public void drawBoldOutline3D(Graphics g, int x, int y, int xPlus, int yPlus) {
  483.         // draw upper face
  484.         g.drawLine(x, y, x+xPlus, y+yPlus);
  485.         g.drawLine(x+1, y+1, x+1+xPlus, y+1+yPlus);
  486.         g.drawLine(x+xPlus, y+yPlus, x+2*xPlus, y);
  487.         g.drawLine(x+1+xPlus, y+1+yPlus, x+1+2*xPlus, y+1);
  488.         g.drawLine(x+2*xPlus, y, x+xPlus, y-yPlus);
  489.         g.drawLine(x+1+2*xPlus, y+1, x+xPlus, y+1-yPlus);
  490.         g.drawLine(x+xPlus, y-yPlus, x, y);
  491.         g.drawLine(x+1+xPlus, y+1-yPlus, x+1, y+1);
  492.         // draw verticals
  493.         g.drawLine(x, y, x, y+3*SQUARE_SIZE_3D);
  494.         g.drawLine(x+1, y, x+1, y+3*SQUARE_SIZE_3D);
  495.         g.drawLine(x+2*xPlus, y, x+2*xPlus, y+3*SQUARE_SIZE_3D);
  496.         g.drawLine(x+1+2*xPlus, y, x+1+2*xPlus, y+3*SQUARE_SIZE_3D);
  497.         g.drawLine(x+xPlus, y-yPlus, x+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
  498.         g.drawLine(x+1+xPlus, y-yPlus, x+1+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
  499.         // draw 2 lower edges
  500.         g.drawLine(x, y+3*SQUARE_SIZE_3D, x+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
  501.         g.drawLine(x+1, y+1+3*SQUARE_SIZE_3D, x+1+xPlus,
  502.          y+1-yPlus+3*SQUARE_SIZE_3D);
  503.         g.drawLine(x+2*xPlus, y+3*SQUARE_SIZE_3D, x+xPlus,
  504.          y-yPlus+3*SQUARE_SIZE_3D);
  505.         g.drawLine(x+1+2*xPlus, y+1+3*SQUARE_SIZE_3D, x+1+xPlus,
  506.          y+1-yPlus+3*SQUARE_SIZE_3D);
  507.     }
  508.  
  509.     public void paint3Dimensional(Graphics g) {
  510.         // each cube section is diamond shaped, angles are 60 and 120 degrees
  511.         clearScreen(g);
  512.         Trigonometry trig = new Trigonometry();
  513.         int start_x_3D=START_X;
  514.         int start_y_3D=START_Y+50;
  515.         double angle=-30.0; // angle is in degrees, slopes upward left-right
  516.         double radAngle = trig.Degree2Radian(angle);    // radAngle is in radians
  517.         // P2R_X(int hypotenuse, double angle)  // angle is in radians
  518.         int xPlus=(int) (trig.P2R_X(3*SQUARE_SIZE_3D, radAngle));
  519.         int yPlus=(int) (trig.P2R_Y(3*SQUARE_SIZE_3D, radAngle)); // is negative
  520.  
  521.         drawUpperFace3D(g, start_x_3D, start_y_3D, xPlus, yPlus);
  522.         drawLeftFace3D(g, start_x_3D, start_y_3D, xPlus, yPlus); //
  523.         drawFrontFace3D(g, start_x_3D+xPlus, start_y_3D-yPlus, xPlus, yPlus);
  524.  
  525.         g.setColor(Color.BLACK);
  526.         labelTheFaces3D(g);
  527.         drawBoldOutline3D(g, start_x_3D, start_y_3D, xPlus, yPlus);
  528.     }
  529.  
  530.     public void paint(Graphics g) {
  531.         // display graphics
  532.         if (display=="2D")
  533.             paint2Dimensional(g);
  534.         else
  535.             paint3Dimensional(g);
  536.         if (jumbled) {
  537.             g.setColor(Color.WHITE);
  538.             g.fillRect(START_X+(8*SQUARE_SIZE), START_Y+(7*SQUARE_SIZE), 250,
  539.              150);
  540.             // show number of moves made
  541.             g.setColor(Color.BLACK);
  542.             g.drawString("Number of moves = "+moveCount,
  543.              START_X+(9*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE));
  544.             if (cubeIsSolved()) {
  545.                 AddLeadingZero a = new AddLeadingZero();
  546.                 GregorianCalendar start = new GregorianCalendar();
  547.                 g.setColor(Color.RED);
  548.                 g.fillRect(START_X+(8*SQUARE_SIZE), START_Y+
  549.                  (7*SQUARE_SIZE), 250, 250);
  550.                 g.setColor(Color.BLACK);
  551.                 g.drawString("Congratulations! Cube solved.", START_X+
  552.                  (9*SQUARE_SIZE), START_Y+(8*SQUARE_SIZE));
  553.                 // show number of moves made
  554.                 g.drawString("Number of moves = "+moveCount,
  555.                  START_X+(9*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE));
  556.  
  557.                 g.drawString("Started:  "+startHour+":"
  558.                  +a.addZeros(startMinute, 2)+":"+a.addZeros(
  559.                  startSecond, 2),
  560.                  START_X+(9*SQUARE_SIZE), START_Y+(10*SQUARE_SIZE));
  561.  
  562.                 GregorianCalendar now = new GregorianCalendar();
  563.                 g.drawString("Finished: "+now.get(Calendar.HOUR_OF_DAY)+":"
  564.                  +a.addZeros(now.get(Calendar.MINUTE), 2)+":"+a.addZeros(
  565.                  now.get(Calendar.SECOND), 2),
  566.                  START_X+(9*SQUARE_SIZE), START_Y+(11*SQUARE_SIZE));
  567.  
  568.                 GregorianCalendar started = new GregorianCalendar(
  569.                  startYear, startMonth, startDay, startHour, startMinute,
  570.                  startSecond);
  571.  
  572.                 int countSeconds=0;
  573.                 while(started.before(now)) {
  574.                     started.add(Calendar.SECOND, 1);
  575.                     countSeconds++;
  576.                 }
  577.                 countSeconds--;
  578.  
  579.                 int h=countSeconds/3600;
  580.                 countSeconds-=h*3600;
  581.                 int m=countSeconds/60;
  582.                 countSeconds-=m*60;
  583.                 int s=countSeconds;
  584.                 g.drawString("Time: "+h+" hour, "+m+" min & "+s+" sec",
  585.                  START_X+(9*SQUARE_SIZE), START_Y+(12*SQUARE_SIZE));
  586.             }
  587.         }
  588.     }
  589.  
  590.     public void turnFaceClockwise(int face) {
  591.         // universal method for turning any face clockwise through 90 degrees
  592.         int temp=square[face][0][0];
  593.         square[face][0][0]=square[face][2][0];
  594.         square[face][2][0]=square[face][2][2];
  595.         square[face][2][2]=square[face][0][2];
  596.         square[face][0][2]=temp;
  597.         temp=square[face][0][1];
  598.         // edge pieces
  599.         square[face][0][1]=square[face][1][0];
  600.         square[face][1][0]=square[face][2][1];
  601.         square[face][2][1]=square[face][1][2];
  602.         square[face][1][2]=temp;
  603.     }
  604.  
  605.     public void doLeft() {
  606.         // rotate the left face 90 degrees clockwise
  607.         turnFaceClockwise(1);
  608.  
  609.         // how does this affect the adjacent faces?
  610.         // copy upper
  611.         int temp0=square[0][0][0];
  612.         int temp1=square[0][1][0];
  613.         int temp2=square[0][2][0];
  614.         // change upper=back
  615.         square[0][0][0]=square[4][2][2];
  616.         square[0][1][0]=square[4][1][2];
  617.         square[0][2][0]=square[4][0][2];
  618.         // change back=lower
  619.         square[4][2][2]=square[5][0][0];
  620.         square[4][1][2]=square[5][1][0];
  621.         square[4][0][2]=square[5][2][0];
  622.         // change lower=front
  623.         square[5][0][0]=square[2][0][0];
  624.         square[5][1][0]=square[2][1][0];
  625.         square[5][2][0]=square[2][2][0];
  626.         // change front=upper
  627.         square[2][0][0]=temp0;
  628.         square[2][1][0]=temp1;
  629.         square[2][2][0]=temp2;
  630.     }
  631.  
  632.     public void doRight() {
  633.         // rotate the right face 90 degrees clockwise
  634.         turnFaceClockwise(3);
  635.  
  636.         // how does this affect the adjacent faces?
  637.         // copy upper
  638.         int temp0=square[0][0][2];
  639.         int temp1=square[0][1][2];
  640.         int temp2=square[0][2][2];
  641.         // change upper=front
  642.         square[0][0][2]=square[2][0][2];
  643.         square[0][1][2]=square[2][1][2];
  644.         square[0][2][2]=square[2][2][2];
  645.         // change front=lower
  646.         square[2][0][2]=square[5][0][2];
  647.         square[2][1][2]=square[5][1][2];
  648.         square[2][2][2]=square[5][2][2];
  649.         // change lower=back
  650.         square[5][0][2]=square[4][2][0];
  651.         square[5][1][2]=square[4][1][0];
  652.         square[5][2][2]=square[4][0][0];
  653.         // change back=upper
  654.         square[4][2][0]=temp0;
  655.         square[4][1][0]=temp1;
  656.         square[4][0][0]=temp2;
  657.     }
  658.  
  659.  
  660.     public void doFront() {
  661.         // rotate the front face 90 degrees clockwise
  662.         turnFaceClockwise(2);
  663.  
  664.         // how does this affect the adjacent faces?
  665.         // copy upper
  666.         int temp0=square[0][2][0];
  667.         int temp1=square[0][2][1];
  668.         int temp2=square[0][2][2];
  669.         // change upper=left
  670.         square[0][2][0]=square[1][2][2];
  671.         square[0][2][1]=square[1][1][2];
  672.         square[0][2][2]=square[1][0][2];
  673.         // change left=lower
  674.         square[1][2][2]=square[5][0][2];
  675.         square[1][1][2]=square[5][0][1];
  676.         square[1][0][2]=square[5][0][0];
  677.         // change lower=right
  678.         square[5][0][2]=square[3][0][0];
  679.         square[5][0][1]=square[3][1][0];
  680.         square[5][0][0]=square[3][2][0];
  681.         // change right=upper
  682.         square[3][0][0]=temp0;
  683.         square[3][1][0]=temp1;
  684.         square[3][2][0]=temp2;
  685.     }
  686.  
  687.     public void doUpper() {
  688.         // rotate the upper face 90 degrees clockwise
  689.         turnFaceClockwise(0);
  690.  
  691.         // how does this affect the adjacent faces?
  692.         // copy left
  693.         int temp0=square[1][0][0];
  694.         int temp1=square[1][0][1];
  695.         int temp2=square[1][0][2];
  696.         // change left=front
  697.         square[1][0][0]=square[2][0][0];
  698.         square[1][0][1]=square[2][0][1];
  699.         square[1][0][2]=square[2][0][2];
  700.         // change front=right
  701.         square[2][0][0]=square[3][0][0];
  702.         square[2][0][1]=square[3][0][1];
  703.         square[2][0][2]=square[3][0][2];
  704.         // change right=back
  705.         square[3][0][0]=square[4][0][0];
  706.         square[3][0][1]=square[4][0][1];
  707.         square[3][0][2]=square[4][0][2];
  708.         // change back=upper
  709.         square[4][0][0]=temp0;
  710.         square[4][0][1]=temp1;
  711.         square[4][0][2]=temp2;
  712.     }
  713.  
  714.     public void doLower() {
  715.         // rotate the lower face 90 degrees clockwise
  716.         turnFaceClockwise(5);
  717.  
  718.         // how does this affect the adjacent faces?
  719.         // copy left
  720.         int temp0=square[1][2][0];
  721.         int temp1=square[1][2][1];
  722.         int temp2=square[1][2][2];
  723.         // change left=back
  724.         square[1][2][0]=square[4][2][0];
  725.         square[1][2][1]=square[4][2][1];
  726.         square[1][2][2]=square[4][2][2];
  727.         // change back=right
  728.         square[4][2][0]=square[3][2][0];
  729.         square[4][2][1]=square[3][2][1];
  730.         square[4][2][2]=square[3][2][2];
  731.         // change right=front
  732.         square[3][2][0]=square[2][2][0];
  733.         square[3][2][1]=square[2][2][1];
  734.         square[3][2][2]=square[2][2][2];
  735.         // change back=upper
  736.         square[2][2][0]=temp0;
  737.         square[2][2][1]=temp1;
  738.         square[2][2][2]=temp2;
  739.     }
  740.  
  741.     public void doLeftMiddle() {
  742.         // middle column of left face goes up
  743.         int temp0=square[1][0][1];
  744.         int temp1=square[1][1][1];
  745.         int temp2=square[1][2][1];
  746.         //left mid column=lower mid row
  747.         square[1][0][1]=square[5][1][0];
  748.         square[1][1][1]=square[5][1][1];
  749.         square[1][2][1]=square[5][1][2];
  750.         // lower mid row=right mid col
  751.         square[5][1][0]=square[3][2][1];
  752.         square[5][1][1]=square[3][1][1];
  753.         square[5][1][2]=square[3][0][1];
  754.         // right mid col=upper mid row
  755.         square[3][2][1]=square[0][1][2];
  756.         square[3][1][1]=square[0][1][1];
  757.         square[3][0][1]=square[0][1][0];
  758.         // upper mid row=left mid col
  759.         square[0][1][2]=temp0;
  760.         square[0][1][1]=temp1;
  761.         square[0][1][0]=temp2;
  762.     }
  763.  
  764.     public void doFrontMiddle() {
  765.         // middle column of front face goes up
  766.         int temp0=square[2][0][1];
  767.         int temp1=square[2][1][1];
  768.         int temp2=square[2][2][1];
  769.         // front mid column=lower mid col
  770.         square[2][0][1]=square[5][0][1];
  771.         square[2][1][1]=square[5][1][1];
  772.         square[2][2][1]=square[5][2][1];
  773.         // lower mid col=back mid col
  774.         square[5][0][1]=square[4][2][1];
  775.         square[5][1][1]=square[4][1][1];
  776.         square[5][2][1]=square[4][0][1];
  777.         // back mid col=upper mid col
  778.         square[4][2][1]=square[0][0][1];
  779.         square[4][1][1]=square[0][1][1];
  780.         square[4][0][1]=square[0][2][1];
  781.         // upper mid col=front mid col
  782.         square[0][0][1]=temp0;
  783.         square[0][1][1]=temp1;
  784.         square[0][2][1]=temp2;
  785.     }
  786.  
  787.     public void doMiddle() {
  788.         // middle row of all lateral faces (Left/Front/Right/Back) goes clockwise
  789.         int temp0=square[1][1][0];
  790.         int temp1=square[1][1][1];
  791.         int temp2=square[1][1][2];
  792.         //left mid row=front mid row
  793.         square[1][1][0]=square[2][1][0];
  794.         square[1][1][1]=square[2][1][1];
  795.         square[1][1][2]=square[2][1][2];
  796.         // front mid row=right mid row
  797.         square[2][1][0]=square[3][1][0];
  798.         square[2][1][1]=square[3][1][1];
  799.         square[2][1][2]=square[3][1][2];
  800.         // right mid row=back mid row
  801.         square[3][1][0]=square[4][1][0];
  802.         square[3][1][1]=square[4][1][1];
  803.         square[3][1][2]=square[4][1][2];
  804.         // back mid row=left mid col
  805.         square[4][1][0]=temp0;
  806.         square[4][1][1]=temp1;
  807.         square[4][1][2]=temp2;
  808.     }
  809.  
  810.     public void rotateFront2Upper() {
  811.         // change orientation of whole cube so that front face is uppermost
  812.         int[][]temp=new int[3][3];
  813.         for (int row=0; row<3; row++)
  814.             for (int col=0; col<3; col++)
  815.                 temp[row][col]=square[0][row][col]; // copy upper face
  816.  
  817.         for (int row=0; row<3; row++)
  818.             for (int col=0; col<3; col++) {
  819.                 square[0][row][col]=square[2][row][col]; // front goes 2 top
  820.                 square[2][row][col]=square[5][row][col]; // lower 2 front
  821.                 square[5][row][col]=square[4][2-row][2-col]; // back 2 lower
  822.                 square[4][2-row][2-col]=temp[row][col];    // upper to back
  823.             }
  824.  
  825.         for (int i=0; i<3; i++)
  826.             turnFaceClockwise(1);   // left equal to 90 degrees anticlockwise
  827.         turnFaceClockwise(3);       // right face
  828.     }
  829.  
  830.     public void rotateLeft2Front() {
  831.         // change orientation of whole cube so that left face becomes front
  832.         int[][]temp=new int[3][3];
  833.         for (int row=0; row<3; row++)
  834.             for (int col=0; col<3; col++)
  835.                 temp[row][col]=square[2][row][col]; // copy front face
  836.  
  837.         for (int row=0; row<3; row++)
  838.             for (int col=0; col<3; col++) {
  839.                 square[2][row][col]=square[1][row][col]; //left goes 2 front
  840.                 square[1][row][col]=square[4][row][col]; //back goes 2 left
  841.                 square[4][row][col]=square[3][row][col]; //right 2 back
  842.                 square[3][row][col]=temp[row][col]; // front 2 right
  843.             }
  844.  
  845.         for (int i=0; i<3; i++)
  846.             turnFaceClockwise(0);   // upper equal to 90 degrees anticlockwise
  847.         turnFaceClockwise(5);       // lower face
  848.     }
  849.  
  850.     public void jumbleUpCube() {
  851.         // make several random moves to jumble up cube for you to solve
  852.         GregorianCalendar start = new GregorianCalendar();
  853.         startYear=start.get(Calendar.YEAR);
  854.         startMonth=start.get(Calendar.MONTH);
  855.         startDay=start.get(Calendar.DAY_OF_MONTH);
  856.         startHour=start.get(Calendar.HOUR_OF_DAY);
  857.         startMinute=start.get(Calendar.MINUTE);
  858.         startSecond=start.get(Calendar.SECOND);
  859.  
  860.         Random ran = new Random();
  861.  
  862.         for (int i=0; i<30; i++) {          // 30 random moves
  863.             int r = ran.nextInt(20) + 1;        // 1<=r<21
  864.             makeMove(r);
  865.         }
  866.         moveCount=0;
  867.         jumbled=true;       // so we can display solved message when solved
  868.         resetMI.setEnabled(false);  // once its jumbled, user can't reset
  869.     }
  870.  
  871.     public void makeMove(int n) {
  872.         // make one move according to a number (see method 'jumbleUpCube' above)
  873.         switch(n) {
  874.             case 1: doLeft();
  875.                 break;
  876.             case 2: for (int i=0; i<3; i++)
  877.                     doLeft();
  878.                 break;
  879.             case 3: doLeftMiddle();
  880.                 break;
  881.             case 4: for (int i=0; i<3; i++)
  882.                     doLeftMiddle();
  883.                 break;
  884.             case 5: doRight();
  885.                 break;
  886.             case 6: for (int i=0; i<3; i++)
  887.                     doRight();
  888.                 break;
  889.             case 7: doFront();
  890.                 break;
  891.             case 8: for (int i=0; i<3; i++)
  892.                 doFront();
  893.                 break;
  894.             case 9: doFrontMiddle();
  895.                 break;
  896.             case 10: for (int i=0; i<3; i++)
  897.                     doFrontMiddle();
  898.                 break;
  899.             case 11: doUpper();
  900.                 break;
  901.             case 12: for (int i=0; i<3; i++)
  902.                     doUpper();
  903.                 break;
  904.             case 13: doLower();
  905.                 break;
  906.             case 14: for (int i=0; i<3; i++)
  907.                         doLower();
  908.                 break;
  909.             case 15: doMiddle();
  910.                 break;
  911.             case 16: for (int i=0; i<3; i++)
  912.                     doMiddle();
  913.                 break;
  914.             case 17: rotateFront2Upper();
  915.                 break;
  916.             case 18: for (int i=0; i<3; i++)
  917.                     rotateFront2Upper();
  918.                 break;
  919.             case 19: rotateLeft2Front();
  920.                 break;
  921.             case 20: for (int i=0; i<3; i++)
  922.                     rotateLeft2Front();
  923.         }
  924.     }
  925.  
  926.     public void makeMove(char ch) {
  927.         // make a move according to current character of a String
  928.         if (ch=='L') {
  929.             doLeft();
  930.         } else if (ch=='l') {
  931.             for (int i=0; i<3; i++)
  932.                 doLeft();
  933.         } else if (ch=='X') {
  934.             doLeftMiddle();
  935.         } else if (ch=='x') {
  936.             for (int i=0; i<3; i++)
  937.                 doLeftMiddle();
  938.         } else if (ch=='R') {
  939.             doRight();
  940.         } else if (ch=='r') {
  941.             for (int i=0; i<3; i++)
  942.                 doRight();
  943.         } else if (ch=='F') {
  944.             doFront();
  945.         } else if (ch=='f') {
  946.             for (int i=0; i<3; i++)
  947.                 doFront();
  948.         } else if (ch=='Y') {
  949.             doFrontMiddle();
  950.         } else if (ch=='y') {
  951.             for (int i=0; i<3; i++)
  952.                 doFrontMiddle();
  953.         } else if (ch=='U') {
  954.             doUpper();
  955.         } else if (ch=='u') {
  956.             for (int i=0; i<3; i++)
  957.                 doUpper();
  958.         } else if (ch=='B') {
  959.             doLower();
  960.         } else if (ch=='b') {
  961.             for (int i=0; i<3; i++)
  962.                 doLower();
  963.         } else if (ch=='Z') {
  964.             doMiddle();
  965.         } else if (ch=='z') {
  966.             for (int i=0; i<3; i++)
  967.                 doMiddle();
  968.         } else if (ch=='G') {
  969.             rotateFront2Upper();
  970.         } else if (ch=='g') {
  971.             for (int i=0; i<3; i++)
  972.                 rotateFront2Upper();    // = upper face to front
  973.         } else if (ch=='H') {
  974.             rotateLeft2Front();
  975.         } else if (ch=='h') {
  976.             for (int i=0; i<3; i++)
  977.                 rotateLeft2Front(); // = front face to left
  978.         }
  979.     }
  980.  
  981.     public void enableOrDisableAllButtons(boolean b) {
  982.         // if b is true, enable buttons, otherwise disable them
  983.         btnLeft.setEnabled(b);
  984.         btnLeftMinus.setEnabled(b);
  985.         btnLeftMiddle.setEnabled(b);
  986.         btnLeftMiddleMinus.setEnabled(b);
  987.         btnFront.setEnabled(b);
  988.         btnFrontMinus.setEnabled(b);
  989.         btnFrontMiddle.setEnabled(b);
  990.         btnFrontMiddleMinus.setEnabled(b);
  991.         btnRight.setEnabled(b);
  992.         btnRightMinus.setEnabled(b);
  993.         btnUpper.setEnabled(b);
  994.         btnUpperMinus.setEnabled(b);
  995.         btnLower.setEnabled(b);
  996.         btnLowerMinus.setEnabled(b);
  997.         btnMiddle.setEnabled(b);
  998.         btnMiddleMinus.setEnabled(b);
  999.  
  1000.         btnRotateFront2Upper.setEnabled(b);
  1001.         btnRotateUpper2Front.setEnabled(b);
  1002.         btnRotateLeft2Front.setEnabled(b);
  1003.         btnRotateFront2Left.setEnabled(b);
  1004.         btnJumble.setEnabled(b);
  1005.         btnEnableFunctions.setEnabled(b);
  1006.  
  1007.         btnF1a.setEnabled(b);
  1008.         btnF1b.setEnabled(b);
  1009.         btnF2a.setEnabled(b);
  1010.         btnF2b.setEnabled(b);
  1011.         btnF3a.setEnabled(b);
  1012.         btnF3b.setEnabled(b);
  1013.     }
  1014.  
  1015.     public void enableFunctionButtons() {
  1016.         btnF1a.setEnabled(true);
  1017.         btnF1b.setEnabled(true);
  1018.         btnF2a.setEnabled(true);
  1019.         btnF2b.setEnabled(true);
  1020.         btnF3a.setEnabled(true);
  1021.         btnF3b.setEnabled(true);
  1022.     }
  1023.  
  1024.     public void doFormula(String strFormula, Button b) {
  1025.         // perform one move of formula
  1026.         if (!done) {
  1027.             moveNum_F=strFormula.length();
  1028.             F_index=0;
  1029.             done=true;
  1030.             enableOrDisableAllButtons(false);
  1031.             b.setEnabled(true);
  1032.         }
  1033.         if (F_index<moveNum_F) {
  1034.             makeMove(strFormula.charAt(F_index++));
  1035.             moveCount++;
  1036.         }
  1037.         if (F_index==moveNum_F) {
  1038.             done=false;
  1039.             enableOrDisableAllButtons(true);
  1040.             // don't click again!
  1041.             b.setEnabled(false);
  1042.         }
  1043.     }
  1044.  
  1045.     public void displayHelp() {
  1046.         JOptionPane.showMessageDialog(null,
  1047.          "To solve Rubiks Cube\n=================\n"
  1048.          +"First of all, with the cube in its START POSITION, (File/Reset)\n"
  1049.          +"PRACTISE moves using ALL the different buttons (except Jumble)\n"
  1050.          +"and see what each button does, including the Formula buttons.\n"
  1051.          +"You can click the same button more than once and see what happens.\n"
  1052.          +"Buttons turn a face a quarter-turn clockwise, except the ones\n"
  1053.          +"with \'-1\' which turn the face anti-clockwise.\n"
  1054.          +"Practise until you\'re familiar with what the buttons and formulae do.\n"
  1055.          +"Then, when you're ready, click \'Jumble up cube\' and solve as follows:\n\n"
  1056.          +"Step 0. Choose any colour face and complete it so that all it\'s edge and\n"
  1057.          +"corner pieces match the colours of the adjacent faces.\n\n"
  1058.          +"Step 1. Turn cube (using Front Down button) so that the completed\n"
  1059.          +"face is at the bottom, and you're now ready to use the Formula buttons\n"
  1060.          +"F1a and F1b to complete the MIDDLE LAYER.\n"
  1061.          +"F1a swaps the UPPER face\'s LEFT EDGE PIECE\n"
  1062.          +"with the FRONT face\'s RIGHT EDGE PIECE.\n"
  1063.          +"F1b swaps the UPPER face\'s RIGHT EDGE PIECE\n"
  1064.          +"with the FRONT face\'s LEFT EDGE PIECE.\n\n"
  1065.          +"Step 2. Use formula 2a to swap and get the upper edge pieces in their\n"
  1066.          +"right places, and formula 2b to get them all the right way round.\n"
  1067.          +"You may find you need to use each formula twice or more.\n"
  1068.          +"(If the Formula buttons aren't enabled, click the \'Enable Formulae\' "
  1069.          +"button.)\n\n"
  1070.          +"Step 3. Formula 3a is used on the upper face to swap its top left,\n"
  1071.          +"bottom left and top right corners in an anti-clockwise direction.\n"
  1072.          +"Using this formula twice will swap them in a clockwise direction.\n"
  1073.          +"Finally, formula 3b is used to \'twist\' two upper face corner pieces,\n"
  1074.          +"one clockwise, the other anti-clockwise.\n\n"
  1075.          +"Remember, PRACTISE moves & formulae on the cube in its START POSITION,\n"
  1076.          +"until you get the hang of what they do.\n"
  1077.          +"Good luck!");
  1078.     }
  1079.  
  1080.     public void actionPerformed(ActionEvent e) {
  1081.         if (e.getSource() == btnLeft) {         // "L"
  1082.             doLeft();
  1083.             moveCount++;
  1084.         } else if (e.getSource() == btnLeftMinus) {     // "l"
  1085.             for (int i=0; i<3; i++)
  1086.                 doLeft();
  1087.             moveCount++;
  1088.         } else if (e.getSource() == btnLeftMiddle) {    // "X"
  1089.             doLeftMiddle();
  1090.             moveCount++;
  1091.         } else if (e.getSource() == btnLeftMiddleMinus) { // "x"
  1092.             for (int i=0; i<3; i++)
  1093.                 doLeftMiddle();
  1094.             moveCount++;
  1095.         } else if (e.getSource() == btnRight) {     // "R"
  1096.             doRight();
  1097.             moveCount++;
  1098.         } else if (e.getSource() == btnRightMinus) {    // "r"
  1099.             for (int i=0; i<3; i++)
  1100.                 doRight();
  1101.             moveCount++;
  1102.         } else if (e.getSource() == btnFront) {     // "F"
  1103.             doFront();
  1104.             moveCount++;
  1105.         } else if (e.getSource() == btnFrontMinus) {    // "f"
  1106.             for (int i=0; i<3; i++)
  1107.                 doFront();
  1108.             moveCount++;
  1109.         } else if (e.getSource() == btnFrontMiddle) {   // "Y"
  1110.             doFrontMiddle();
  1111.             moveCount++;
  1112.         } else if (e.getSource() == btnFrontMiddleMinus) { // "y"
  1113.             for (int i=0; i<3; i++)
  1114.                 doFrontMiddle();
  1115.             moveCount++;
  1116.         } else if (e.getSource() == btnUpper) {     // "U"
  1117.             doUpper();
  1118.             moveCount++;
  1119.         } else if (e.getSource() == btnUpperMinus) {    // "u"
  1120.             for (int i=0; i<3; i++)
  1121.                 doUpper();
  1122.             moveCount++;
  1123.         } else if (e.getSource() == btnLower) {     // "B"  = base
  1124.             doLower();
  1125.             moveCount++;
  1126.         } else if (e.getSource() == btnLowerMinus) {    // "b"
  1127.             for (int i=0; i<3; i++)
  1128.                 doLower();
  1129.             moveCount++;
  1130.         } else if (e.getSource() == btnMiddle) {    // "Z"
  1131.             doMiddle();
  1132.             moveCount++;
  1133.         } else if (e.getSource() == btnMiddleMinus) {   // "z"
  1134.             for (int i=0; i<3; i++)
  1135.                 doMiddle();
  1136.             moveCount++;
  1137.         } else if (e.getSource() == btnRotateFront2Upper) { // "G";
  1138.             rotateFront2Upper();
  1139.         } else if (e.getSource() == btnRotateUpper2Front) { // "g";
  1140.             for (int i=0; i<3; i++)
  1141.                 rotateFront2Upper();    // = upper face to front
  1142.         } else if (e.getSource() == btnRotateLeft2Front) {  // "H";
  1143.             rotateLeft2Front();
  1144.         } else if (e.getSource() == btnRotateFront2Left) {  // "h";
  1145.             for (int i=0; i<3; i++)
  1146.                 rotateLeft2Front(); // = front face to left
  1147.         } else if (e.getSource() == btnJumble) {    // randomly mix up cube
  1148.             jumbleUpCube();
  1149.         } else if (e.getSource() == btnEnableFunctions) {
  1150.             enableFunctionButtons();
  1151.         } else if (e.getSource() == btnF1a) {   // makes 1 move at a time
  1152.             doFormula(SWAPTOPLEFTEDGEWITHFRONTRIGHTEDGE, btnF1a);
  1153.         } else if (e.getSource() == btnF1b) {   //
  1154.             doFormula(SWAPTOPRIGHTEDGEWITHFRONTLEFTEDGE, btnF1b);
  1155.         } else if (e.getSource() == btnF2a) {   //
  1156.             doFormula(SWAP2TOPEDGEPIECES, btnF2a);
  1157.         } else if (e.getSource() == btnF2b) {   //
  1158.             doFormula(ROTATETOPEDGEPIECE, btnF2b);
  1159.         } else if (e.getSource() == btnF3a) {   //
  1160.             doFormula(SWAP3CORNERSANTICLOCKWISE, btnF3a);
  1161.         } else if (e.getSource() == btnF3b) {   //
  1162.             doFormula(ROTATECORNERS1CLOCKWISE1ANTICLOCKWISE, btnF3b);
  1163.         } else if (e.getSource() == resetMI) {  // Menu Item reset
  1164.             reset();
  1165.         } else if (e.getSource() == TwoDMI) {   // Menu Item for 2-dimensional
  1166.             display="2D";
  1167.         } else if (e.getSource() == ThreeDMI) { // Menu Item for 3-dimensional
  1168.             display="3D";
  1169.         } else if (e.getSource() == helpMI) {   // Menu Item for displaying help
  1170.             displayHelp();
  1171.         } else if (e.getSource() == exitMI) {   // Menu Item for exit
  1172.             System.exit(0);
  1173.         }
  1174.         repaint();
  1175.     }
  1176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement