Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.*; // for Frame
- import java.awt.event.*; // for Buttons and Menu Items
- import java.util.*; // for date/time and Random functions
- import javax.swing.*; // for pop-up help message, JFrame
- public class RubiksCube {
- public static void main(String[] args) {
- RubiksCubeJFrame frame = new RubiksCubeJFrame();
- frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
- frame.setVisible(true);
- }
- }
- class RubiksCubeJFrame extends JFrame implements ActionListener {
- /**
- * Program: RubiksCube.java
- * Purpose: Solve Rubik's Cube in 2-D or glorious 3-D. Very addictive!
- * Creator: Chris Clarke
- * Created: 31.01.2010 to 08.02.2010
- * Modified: 09.04.2010 Timer added
- * Modified: 13.11.2012 (converted Frame to JFrame)
- */
- // make clockwise moves ("Minus" implies anti-clockwise)
- private Button btnLeft, btnLeftMinus, btnRight, btnRightMinus;
- private Button btnFront, btnFrontMinus, btnUpper, btnUpperMinus;
- private Button btnLower, btnLowerMinus;
- private Button btnLeftMiddle, btnLeftMiddleMinus;
- private Button btnFrontMiddle, btnFrontMiddleMinus;
- private Button btnMiddle, btnMiddleMinus;
- // turn whole cube's orientation
- private Button btnRotateFront2Upper, btnRotateUpper2Front;
- private Button btnRotateLeft2Front, btnRotateFront2Left;
- private Button btnJumble; // to jumble cube up
- // Function/Formula buttons
- private Button btnEnableFunctions;
- private Button btnF1a, btnF1b, btnF2a, btnF2b, btnF3a, btnF3b;
- MenuItem resetMI, exitMI, TwoDMI, ThreeDMI, helpMI;
- public int[][][] square=new int[6][3][3];
- public static final int START_X=200;
- public static final int START_Y=200;
- public static final int SQUARE_SIZE=40;
- public static final int SQUARE_SIZE_3D=(int) (SQUARE_SIZE*1.5);
- public int moveCount=0; // counts no. of moves to solve cube
- public int moveNum_F; // Function/Formula number of moves
- public int F_index; // " " move index
- public boolean done=false; // true when in middle of a function
- public static boolean jumble; // to jumble upon startup or not?
- public boolean jumbled=false; // false until user jumbles it up
- public String display="3D"; // 2-Dimensional or 3-Dimensional
- // record time when cube jumbled up
- public int startYear=0, startMonth=0, startDay=0;
- public int startHour=0, startMinute=0, startSecond=0;
- // Function F1a
- // left/upper/front2/upper2/front2/upper2/front2/upper/leftMinus
- public static final String SWAPTOPLEFTEDGEWITHFRONTRIGHTEDGE = "LUFFUUFFUUFFUl";
- // Function F1b
- // rightMinus/upper/front2/upper2/front2/upper2/front2/upper/right
- public static final String SWAPTOPRIGHTEDGEWITHFRONTLEFTEDGE = "rUFFUUFFUUFFUR";
- // Function F2a
- // leftMiddleMinus/frontMiddleMinus/base/frontMiddle/base/base/
- // leftMiddle/base
- public static final String SWAP2TOPEDGEPIECES = "xyBYBBXB";
- // Function F2b
- // right/middleMinus/right/middleMinus/right/middleMinus/right/middleMinus
- public static final String ROTATETOPEDGEPIECE = "RzRzRzRz";
- // Function F3a
- // left/front/rightMinus/frontMinus/leftMinus/front/right/frontMinus
- public static final String SWAP3CORNERSANTICLOCKWISE = "LFrflFRf";
- /* Function F3b
- left/front/rightMinus/frontMinus/leftMinus/front/right/frontMinus
- rotateLeft2Front
- front/right/frontMinus/left/front/rightMinus/frontMinus/leftMinus
- rotateFront2Left
- */
- public static final String ROTATECORNERS1CLOCKWISE1ANTICLOCKWISE="LFrflFRf" +"HFRfLFrflh";
- RubiksCubeJFrame() {
- setTitle("Rubik\'s Cube by Chris Clarke");
- MenuBar mbar = new MenuBar();
- Menu fileMenu = new Menu("File");
- resetMI = new MenuItem("Reset");
- resetMI.addActionListener(this);
- fileMenu.add(resetMI);
- exitMI = new MenuItem("Exit");
- exitMI.addActionListener(this);
- fileMenu.add(exitMI);
- mbar.add(fileMenu);
- Menu viewMenu = new Menu("View");
- TwoDMI = new MenuItem("2-D");
- TwoDMI.addActionListener(this);
- viewMenu.add(TwoDMI);
- ThreeDMI = new MenuItem("3-D");
- ThreeDMI.addActionListener(this);
- viewMenu.add(ThreeDMI);
- mbar.add(viewMenu);
- Menu helpMenu = new Menu("Help");
- helpMI = new MenuItem("Help");
- helpMI.addActionListener(this);
- helpMenu.add(helpMI);
- mbar.add(helpMenu);
- setMenuBar(mbar);
- // Build control panel.
- Panel panel = new Panel();
- btnLeft = new Button("Left");
- btnLeft.addActionListener(this);
- panel.add(btnLeft);
- btnLeftMinus = new Button("Left-1");
- btnLeftMinus.addActionListener(this);
- panel.add(btnLeftMinus);
- btnLeftMiddle = new Button("Left Mid Col");
- btnLeftMiddle.addActionListener(this);
- panel.add(btnLeftMiddle);
- btnLeftMiddleMinus = new Button("Left Mid-1");
- btnLeftMiddleMinus.addActionListener(this);
- panel.add(btnLeftMiddleMinus);
- btnFront = new Button("Front");
- btnFront.addActionListener(this);
- panel.add(btnFront);
- btnFrontMinus = new Button("Front-1");
- btnFrontMinus.addActionListener(this);
- panel.add(btnFrontMinus);
- btnFrontMiddle = new Button("Front Mid Col");
- btnFrontMiddle.addActionListener(this);
- panel.add(btnFrontMiddle);
- btnFrontMiddleMinus = new Button("Front Mid-1");
- btnFrontMiddleMinus.addActionListener(this);
- panel.add(btnFrontMiddleMinus);
- btnRight = new Button("Right");
- btnRight.addActionListener(this);
- panel.add(btnRight);
- btnRightMinus = new Button("Right-1");
- btnRightMinus.addActionListener(this);
- panel.add(btnRightMinus);
- btnUpper = new Button("Upper");
- btnUpper.addActionListener(this);
- panel.add(btnUpper);
- btnUpperMinus = new Button("Upper-1");
- btnUpperMinus.addActionListener(this);
- panel.add(btnUpperMinus);
- btnLower = new Button("Lower");
- btnLower.addActionListener(this);
- panel.add(btnLower);
- btnLowerMinus = new Button("Lower-1");
- btnLowerMinus.addActionListener(this);
- panel.add(btnLowerMinus);
- btnMiddle = new Button("Middle");
- btnMiddle.addActionListener(this);
- panel.add(btnMiddle);
- btnMiddleMinus = new Button("Middle-1");
- btnMiddleMinus.addActionListener(this);
- panel.add(btnMiddleMinus);
- add(panel, BorderLayout.NORTH);
- // Build control panel2.
- Panel panel2 = new Panel();
- Label lblTurnCube=new Label("Turn cube");
- panel2.add(lblTurnCube);
- btnRotateFront2Upper = new Button("Front Up");
- btnRotateFront2Upper.addActionListener(this);
- panel2.add(btnRotateFront2Upper);
- btnRotateUpper2Front = new Button("Front Down");
- btnRotateUpper2Front.addActionListener(this);
- panel2.add(btnRotateUpper2Front);
- btnRotateLeft2Front = new Button("Front to Right");
- btnRotateLeft2Front.addActionListener(this);
- panel2.add(btnRotateLeft2Front);
- btnRotateFront2Left = new Button("Front to Left");
- btnRotateFront2Left.addActionListener(this);
- panel2.add(btnRotateFront2Left);
- Label lblSpc1=new Label(" "); // spacer
- panel2.add(lblSpc1);
- btnJumble=new Button("Jumble up cube!");
- btnJumble.addActionListener(this);
- panel2.add(btnJumble);
- Label lblSpc2=new Label(" "); // spacer
- panel2.add(lblSpc2);
- btnEnableFunctions = new Button("Enable Formulae");
- btnEnableFunctions.addActionListener(this);
- panel2.add(btnEnableFunctions);
- // Function/Formula buttons
- btnF1a=new Button("F1a");
- btnF1a.addActionListener(this);
- panel2.add(btnF1a);
- btnF1b=new Button("F1b");
- btnF1b.addActionListener(this);
- panel2.add(btnF1b);
- btnF2a=new Button("F2a");
- btnF2a.addActionListener(this);
- panel2.add(btnF2a);
- btnF2b=new Button("F2b");
- btnF2b.addActionListener(this);
- panel2.add(btnF2b);
- btnF3a=new Button("F3a");
- btnF3a.addActionListener(this);
- panel2.add(btnF3a);
- btnF3b=new Button("F3b");
- btnF3b.addActionListener(this);
- panel2.add(btnF3b);
- add(panel2, BorderLayout.SOUTH);
- reset();
- // Set to a reasonable size.
- setSize(1024, 768);
- }
- public void reset() {
- // set cube to start position
- for (int face=0; face<6; face++)
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++)
- square[face][row][col]=face;
- moveCount=0;
- jumbled=false;
- enableFunctionButtons();
- }
- public void setColour(Graphics g, int c) {
- switch(c) {
- case 0: g.setColor(Color.RED); break;
- case 1: g.setColor(Color.YELLOW); break;
- case 2: g.setColor(Color.BLUE); break;
- case 3: g.setColor(Color.GREEN); break;
- case 4: g.setColor(Color.WHITE); break;
- case 5: g.setColor(new Color(230, 120, 0)); // orange
- }
- }
- public void labelTheFaces(Graphics g) {
- g.drawString("upper", START_X+(3*SQUARE_SIZE), START_Y-10);
- g.drawString("left", START_X-30, START_Y+(3*SQUARE_SIZE)+10);
- g.drawString("front", START_X+(3*SQUARE_SIZE)+2, START_Y+(3*SQUARE_SIZE)+10);
- g.drawString("right", START_X+(6*SQUARE_SIZE)+2, START_Y+(3*SQUARE_SIZE)+10);
- g.drawString("back", START_X+(12*SQUARE_SIZE)+10, START_Y+(3*SQUARE_SIZE)+10);
- g.drawString("lower", START_X+(3*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE)+20);
- }
- public void drawBlackLines(Graphics g) {
- // horizontals
- for (int y=START_Y; y<=START_Y+9*SQUARE_SIZE; y+=SQUARE_SIZE)
- g.drawLine(START_X+(3*SQUARE_SIZE), y, START_X+(6*SQUARE_SIZE), y);
- for (int y=START_Y+(3*SQUARE_SIZE); y<=START_Y+6*SQUARE_SIZE; y+=SQUARE_SIZE)
- g.drawLine(START_X, y, START_X+(4*3*SQUARE_SIZE), y);
- // verticals
- for (int x=START_X; x<=START_X+(4*3*SQUARE_SIZE); x+=SQUARE_SIZE)
- g.drawLine(x, START_Y+(3*SQUARE_SIZE), x, START_Y+(6*SQUARE_SIZE));
- for (int x=START_X+(3*SQUARE_SIZE); x<=START_X+(6*SQUARE_SIZE); x+=SQUARE_SIZE)
- g.drawLine(x, START_Y, x, START_Y+(9*SQUARE_SIZE));
- }
- public void drawThickBlackLines(Graphics g) {
- // horizontals
- int y=START_Y-1; // top of face 0
- int x=START_X-1;
- g.drawLine(x+(3*SQUARE_SIZE), y, x+1+(6*SQUARE_SIZE), y);
- y+=3*SQUARE_SIZE; // top of faces 1-4
- g.drawLine(x, y, x+1+(4*3*SQUARE_SIZE), y);
- y+=3*SQUARE_SIZE; // bottom of faces 1-4
- g.drawLine(x, y, x+1+(4*3*SQUARE_SIZE), y);
- y+=3*SQUARE_SIZE; // bottom of face 5
- g.drawLine(x+(3*SQUARE_SIZE), y, x+1+(6*SQUARE_SIZE), y);
- // verticals
- y=START_Y-1; // top of face 0
- g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
- x+=3*SQUARE_SIZE; // left of faces 0, 2 & 5
- g.drawLine(x, y, x, y+1+(9*SQUARE_SIZE));
- x+=3*SQUARE_SIZE; // left of face 3, right of 0, 2 & 5
- g.drawLine(x, y, x, y+1+(9*SQUARE_SIZE));
- x+=3*SQUARE_SIZE; // right of face 3
- g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
- x+=3*SQUARE_SIZE; // right of face 4
- g.drawLine(x, y+(3*SQUARE_SIZE), x, y+1+(6*SQUARE_SIZE));
- }
- public boolean cubeIsSolved() {
- // is cube solved?
- for (int face=0; face<6; face++)
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++)
- if (square[face][row][col]!=square[face][0][0])
- return false;
- return true;
- }
- public void update(Graphics g) {
- paint(g);
- }
- public void clearScreen(Graphics g) {
- g.setColor(Color.WHITE);
- g.fillRect(0, 0, 1024, 768);
- }
- public void paint2Dimensional(Graphics g) {
- // flat squares, all angles 90 degrees
- clearScreen(g);
- // upper face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[0][row][col]);
- g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
- START_Y+row*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
- }
- // left face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[1][row][col]);
- g.fillRect(START_X+col*SQUARE_SIZE,
- START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
- SQUARE_SIZE, SQUARE_SIZE);
- }
- // front face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[2][row][col]);
- g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
- START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
- SQUARE_SIZE, SQUARE_SIZE);
- }
- // right face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[3][row][col]);
- g.fillRect(START_X+(6*SQUARE_SIZE)+col*SQUARE_SIZE,
- START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
- SQUARE_SIZE, SQUARE_SIZE);
- }
- // back face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[4][row][col]);
- g.fillRect(START_X+(9*SQUARE_SIZE)+col*SQUARE_SIZE,
- START_Y+(3*SQUARE_SIZE)+row*SQUARE_SIZE,
- SQUARE_SIZE, SQUARE_SIZE);
- }
- // lower face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- setColour(g, square[5][row][col]);
- g.fillRect(START_X+(3*SQUARE_SIZE)+col*SQUARE_SIZE,
- START_Y+(6*SQUARE_SIZE)+row*SQUARE_SIZE,
- SQUARE_SIZE, SQUARE_SIZE);
- }
- g.setColor(Color.BLACK);
- labelTheFaces(g);
- drawBlackLines(g);
- drawThickBlackLines(g);
- }
- public void drawOneUpperDiamond(Graphics g, int x, int y) {
- // individual upper face squares in 3-D
- Trigonometry trig = new Trigonometry();
- double angle=-30.0; // angle is in degrees, slopes upward left-right
- double radAngle = trig.Degree2Radian(angle); // radAngle is in radians
- // P2R_X(int hypotenuse, double angle) // angle is in radians
- int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
- int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is negative
- for (int i=1; i<30; i++) {
- g.drawLine(x+i, y, x+xPlus, y+i+yPlus);
- g.drawLine(x+xPlus, y+i+yPlus, x-i+2*xPlus, y);
- g.drawLine(x-i+2*xPlus, y, x+xPlus, y-i-yPlus);
- g.drawLine(x+xPlus, y-i-yPlus, x+i, y);
- }
- // draw black outline
- g.setColor(Color.BLACK);
- g.drawLine(x, y, x+xPlus, y+yPlus);
- g.drawLine(x+xPlus, y+yPlus, x+2*xPlus, y);
- g.drawLine(x+2*xPlus, y, x+xPlus, y-yPlus);
- g.drawLine(x+xPlus, y-yPlus, x, y);
- }
- public void drawOneLeftDiamond(Graphics g, int x, int y) {
- // individual left face squares in 3-D
- Trigonometry trig = new Trigonometry();
- double angle=30.0; // angle is in degrees, slopes downward left-right
- double radAngle = trig.Degree2Radian(angle); // radAngle is in radians
- // P2R_X(int hypotenuse, double angle) // angle is in radians
- int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
- int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is positive
- for (int i=1; i<=SQUARE_SIZE_3D; i++)
- g.drawLine(x, y+i, x+xPlus-1, y+i+yPlus);
- // draw black outline
- g.setColor(Color.BLACK);
- g.drawLine(x, y, x+xPlus, y+yPlus);
- g.drawLine(x+xPlus, y+yPlus, x+xPlus, y+yPlus+SQUARE_SIZE_3D);
- g.drawLine(x, y+SQUARE_SIZE_3D, x, y);
- }
- public void drawOneFrontDiamond(Graphics g, int x, int y) {
- // individual front face squares in 3-D
- Trigonometry trig = new Trigonometry();
- double angle=-30.0; // angle is in degrees, slopes upward left-right
- double radAngle = trig.Degree2Radian(angle); // radAngle is in radians
- // P2R_X(int hypotenuse, double angle) // angle is in radians
- int xPlus=(int) (trig.P2R_X(SQUARE_SIZE_3D, radAngle));
- int yPlus=(int) (trig.P2R_Y(SQUARE_SIZE_3D, radAngle)); // is negative
- for (int i=1; i<=SQUARE_SIZE_3D; i++) {
- g.drawLine(x, y+i, x+xPlus-1, y+i+yPlus);
- }
- // draw black outline
- g.setColor(Color.BLACK);
- g.drawLine(x, y, x+xPlus, y+yPlus);
- g.drawLine(x+xPlus, y+yPlus, x+xPlus, y+yPlus+SQUARE_SIZE_3D);
- g.drawLine(x, y+SQUARE_SIZE_3D, x, y);
- }
- public void drawUpperFace3D(Graphics g, int start_x, int start_y, int xPlus,
- int yPlus) {
- //
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- int x_inc=xPlus/3;
- int y_inc=yPlus/3; // is negative
- setColour(g, square[0][row][col]); // upper face
- int x=start_x+row*x_inc+col*x_inc;
- int y=start_y-row*y_inc+col*y_inc;
- drawOneUpperDiamond(g, x, y);
- }
- }
- public void drawLeftFace3D(Graphics g, int start_x, int start_y, int xPlus,
- int yPlus) {
- //
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- int x_inc=xPlus/3;
- int y_inc=-1*(yPlus/3); // is positive
- setColour(g, square[1][row][col]); // left face
- int x=start_x+col*x_inc;
- int y=start_y+row*SQUARE_SIZE_3D+col*y_inc;
- drawOneLeftDiamond(g, x, y);
- }
- }
- public void drawFrontFace3D(Graphics g, int start_x, int start_y, int xPlus,
- int yPlus) {
- //
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- int x_inc=xPlus/3;
- int y_inc=yPlus/3; // is negative
- setColour(g, square[2][row][col]); // front face
- int x=start_x+col*x_inc;
- int y=start_y+row*SQUARE_SIZE_3D+col*y_inc;
- drawOneFrontDiamond(g, x, y);
- }
- }
- public void labelTheFaces3D(Graphics g) {
- g.drawString("upper", START_X+(3*SQUARE_SIZE), START_Y-70);
- g.drawString("left", START_X-30, START_Y+(3*SQUARE_SIZE)+10);
- g.drawString("front", START_X+(9*SQUARE_SIZE), START_Y+(3*SQUARE_SIZE)+10);
- }
- public void drawBoldOutline3D(Graphics g, int x, int y, int xPlus, int yPlus) {
- // draw upper face
- g.drawLine(x, y, x+xPlus, y+yPlus);
- g.drawLine(x+1, y+1, x+1+xPlus, y+1+yPlus);
- g.drawLine(x+xPlus, y+yPlus, x+2*xPlus, y);
- g.drawLine(x+1+xPlus, y+1+yPlus, x+1+2*xPlus, y+1);
- g.drawLine(x+2*xPlus, y, x+xPlus, y-yPlus);
- g.drawLine(x+1+2*xPlus, y+1, x+xPlus, y+1-yPlus);
- g.drawLine(x+xPlus, y-yPlus, x, y);
- g.drawLine(x+1+xPlus, y+1-yPlus, x+1, y+1);
- // draw verticals
- g.drawLine(x, y, x, y+3*SQUARE_SIZE_3D);
- g.drawLine(x+1, y, x+1, y+3*SQUARE_SIZE_3D);
- g.drawLine(x+2*xPlus, y, x+2*xPlus, y+3*SQUARE_SIZE_3D);
- g.drawLine(x+1+2*xPlus, y, x+1+2*xPlus, y+3*SQUARE_SIZE_3D);
- g.drawLine(x+xPlus, y-yPlus, x+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
- g.drawLine(x+1+xPlus, y-yPlus, x+1+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
- // draw 2 lower edges
- g.drawLine(x, y+3*SQUARE_SIZE_3D, x+xPlus, y-yPlus+3*SQUARE_SIZE_3D);
- g.drawLine(x+1, y+1+3*SQUARE_SIZE_3D, x+1+xPlus,
- y+1-yPlus+3*SQUARE_SIZE_3D);
- g.drawLine(x+2*xPlus, y+3*SQUARE_SIZE_3D, x+xPlus,
- y-yPlus+3*SQUARE_SIZE_3D);
- g.drawLine(x+1+2*xPlus, y+1+3*SQUARE_SIZE_3D, x+1+xPlus,
- y+1-yPlus+3*SQUARE_SIZE_3D);
- }
- public void paint3Dimensional(Graphics g) {
- // each cube section is diamond shaped, angles are 60 and 120 degrees
- clearScreen(g);
- Trigonometry trig = new Trigonometry();
- int start_x_3D=START_X;
- int start_y_3D=START_Y+50;
- double angle=-30.0; // angle is in degrees, slopes upward left-right
- double radAngle = trig.Degree2Radian(angle); // radAngle is in radians
- // P2R_X(int hypotenuse, double angle) // angle is in radians
- int xPlus=(int) (trig.P2R_X(3*SQUARE_SIZE_3D, radAngle));
- int yPlus=(int) (trig.P2R_Y(3*SQUARE_SIZE_3D, radAngle)); // is negative
- drawUpperFace3D(g, start_x_3D, start_y_3D, xPlus, yPlus);
- drawLeftFace3D(g, start_x_3D, start_y_3D, xPlus, yPlus); //
- drawFrontFace3D(g, start_x_3D+xPlus, start_y_3D-yPlus, xPlus, yPlus);
- g.setColor(Color.BLACK);
- labelTheFaces3D(g);
- drawBoldOutline3D(g, start_x_3D, start_y_3D, xPlus, yPlus);
- }
- public void paint(Graphics g) {
- // display graphics
- if (display=="2D")
- paint2Dimensional(g);
- else
- paint3Dimensional(g);
- if (jumbled) {
- g.setColor(Color.WHITE);
- g.fillRect(START_X+(8*SQUARE_SIZE), START_Y+(7*SQUARE_SIZE), 250,
- 150);
- // show number of moves made
- g.setColor(Color.BLACK);
- g.drawString("Number of moves = "+moveCount,
- START_X+(9*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE));
- if (cubeIsSolved()) {
- AddLeadingZero a = new AddLeadingZero();
- GregorianCalendar start = new GregorianCalendar();
- g.setColor(Color.RED);
- g.fillRect(START_X+(8*SQUARE_SIZE), START_Y+
- (7*SQUARE_SIZE), 250, 250);
- g.setColor(Color.BLACK);
- g.drawString("Congratulations! Cube solved.", START_X+
- (9*SQUARE_SIZE), START_Y+(8*SQUARE_SIZE));
- // show number of moves made
- g.drawString("Number of moves = "+moveCount,
- START_X+(9*SQUARE_SIZE), START_Y+(9*SQUARE_SIZE));
- g.drawString("Started: "+startHour+":"
- +a.addZeros(startMinute, 2)+":"+a.addZeros(
- startSecond, 2),
- START_X+(9*SQUARE_SIZE), START_Y+(10*SQUARE_SIZE));
- GregorianCalendar now = new GregorianCalendar();
- g.drawString("Finished: "+now.get(Calendar.HOUR_OF_DAY)+":"
- +a.addZeros(now.get(Calendar.MINUTE), 2)+":"+a.addZeros(
- now.get(Calendar.SECOND), 2),
- START_X+(9*SQUARE_SIZE), START_Y+(11*SQUARE_SIZE));
- GregorianCalendar started = new GregorianCalendar(
- startYear, startMonth, startDay, startHour, startMinute,
- startSecond);
- int countSeconds=0;
- while(started.before(now)) {
- started.add(Calendar.SECOND, 1);
- countSeconds++;
- }
- countSeconds--;
- int h=countSeconds/3600;
- countSeconds-=h*3600;
- int m=countSeconds/60;
- countSeconds-=m*60;
- int s=countSeconds;
- g.drawString("Time: "+h+" hour, "+m+" min & "+s+" sec",
- START_X+(9*SQUARE_SIZE), START_Y+(12*SQUARE_SIZE));
- }
- }
- }
- public void turnFaceClockwise(int face) {
- // universal method for turning any face clockwise through 90 degrees
- int temp=square[face][0][0];
- square[face][0][0]=square[face][2][0];
- square[face][2][0]=square[face][2][2];
- square[face][2][2]=square[face][0][2];
- square[face][0][2]=temp;
- temp=square[face][0][1];
- // edge pieces
- square[face][0][1]=square[face][1][0];
- square[face][1][0]=square[face][2][1];
- square[face][2][1]=square[face][1][2];
- square[face][1][2]=temp;
- }
- public void doLeft() {
- // rotate the left face 90 degrees clockwise
- turnFaceClockwise(1);
- // how does this affect the adjacent faces?
- // copy upper
- int temp0=square[0][0][0];
- int temp1=square[0][1][0];
- int temp2=square[0][2][0];
- // change upper=back
- square[0][0][0]=square[4][2][2];
- square[0][1][0]=square[4][1][2];
- square[0][2][0]=square[4][0][2];
- // change back=lower
- square[4][2][2]=square[5][0][0];
- square[4][1][2]=square[5][1][0];
- square[4][0][2]=square[5][2][0];
- // change lower=front
- square[5][0][0]=square[2][0][0];
- square[5][1][0]=square[2][1][0];
- square[5][2][0]=square[2][2][0];
- // change front=upper
- square[2][0][0]=temp0;
- square[2][1][0]=temp1;
- square[2][2][0]=temp2;
- }
- public void doRight() {
- // rotate the right face 90 degrees clockwise
- turnFaceClockwise(3);
- // how does this affect the adjacent faces?
- // copy upper
- int temp0=square[0][0][2];
- int temp1=square[0][1][2];
- int temp2=square[0][2][2];
- // change upper=front
- square[0][0][2]=square[2][0][2];
- square[0][1][2]=square[2][1][2];
- square[0][2][2]=square[2][2][2];
- // change front=lower
- square[2][0][2]=square[5][0][2];
- square[2][1][2]=square[5][1][2];
- square[2][2][2]=square[5][2][2];
- // change lower=back
- square[5][0][2]=square[4][2][0];
- square[5][1][2]=square[4][1][0];
- square[5][2][2]=square[4][0][0];
- // change back=upper
- square[4][2][0]=temp0;
- square[4][1][0]=temp1;
- square[4][0][0]=temp2;
- }
- public void doFront() {
- // rotate the front face 90 degrees clockwise
- turnFaceClockwise(2);
- // how does this affect the adjacent faces?
- // copy upper
- int temp0=square[0][2][0];
- int temp1=square[0][2][1];
- int temp2=square[0][2][2];
- // change upper=left
- square[0][2][0]=square[1][2][2];
- square[0][2][1]=square[1][1][2];
- square[0][2][2]=square[1][0][2];
- // change left=lower
- square[1][2][2]=square[5][0][2];
- square[1][1][2]=square[5][0][1];
- square[1][0][2]=square[5][0][0];
- // change lower=right
- square[5][0][2]=square[3][0][0];
- square[5][0][1]=square[3][1][0];
- square[5][0][0]=square[3][2][0];
- // change right=upper
- square[3][0][0]=temp0;
- square[3][1][0]=temp1;
- square[3][2][0]=temp2;
- }
- public void doUpper() {
- // rotate the upper face 90 degrees clockwise
- turnFaceClockwise(0);
- // how does this affect the adjacent faces?
- // copy left
- int temp0=square[1][0][0];
- int temp1=square[1][0][1];
- int temp2=square[1][0][2];
- // change left=front
- square[1][0][0]=square[2][0][0];
- square[1][0][1]=square[2][0][1];
- square[1][0][2]=square[2][0][2];
- // change front=right
- square[2][0][0]=square[3][0][0];
- square[2][0][1]=square[3][0][1];
- square[2][0][2]=square[3][0][2];
- // change right=back
- square[3][0][0]=square[4][0][0];
- square[3][0][1]=square[4][0][1];
- square[3][0][2]=square[4][0][2];
- // change back=upper
- square[4][0][0]=temp0;
- square[4][0][1]=temp1;
- square[4][0][2]=temp2;
- }
- public void doLower() {
- // rotate the lower face 90 degrees clockwise
- turnFaceClockwise(5);
- // how does this affect the adjacent faces?
- // copy left
- int temp0=square[1][2][0];
- int temp1=square[1][2][1];
- int temp2=square[1][2][2];
- // change left=back
- square[1][2][0]=square[4][2][0];
- square[1][2][1]=square[4][2][1];
- square[1][2][2]=square[4][2][2];
- // change back=right
- square[4][2][0]=square[3][2][0];
- square[4][2][1]=square[3][2][1];
- square[4][2][2]=square[3][2][2];
- // change right=front
- square[3][2][0]=square[2][2][0];
- square[3][2][1]=square[2][2][1];
- square[3][2][2]=square[2][2][2];
- // change back=upper
- square[2][2][0]=temp0;
- square[2][2][1]=temp1;
- square[2][2][2]=temp2;
- }
- public void doLeftMiddle() {
- // middle column of left face goes up
- int temp0=square[1][0][1];
- int temp1=square[1][1][1];
- int temp2=square[1][2][1];
- //left mid column=lower mid row
- square[1][0][1]=square[5][1][0];
- square[1][1][1]=square[5][1][1];
- square[1][2][1]=square[5][1][2];
- // lower mid row=right mid col
- square[5][1][0]=square[3][2][1];
- square[5][1][1]=square[3][1][1];
- square[5][1][2]=square[3][0][1];
- // right mid col=upper mid row
- square[3][2][1]=square[0][1][2];
- square[3][1][1]=square[0][1][1];
- square[3][0][1]=square[0][1][0];
- // upper mid row=left mid col
- square[0][1][2]=temp0;
- square[0][1][1]=temp1;
- square[0][1][0]=temp2;
- }
- public void doFrontMiddle() {
- // middle column of front face goes up
- int temp0=square[2][0][1];
- int temp1=square[2][1][1];
- int temp2=square[2][2][1];
- // front mid column=lower mid col
- square[2][0][1]=square[5][0][1];
- square[2][1][1]=square[5][1][1];
- square[2][2][1]=square[5][2][1];
- // lower mid col=back mid col
- square[5][0][1]=square[4][2][1];
- square[5][1][1]=square[4][1][1];
- square[5][2][1]=square[4][0][1];
- // back mid col=upper mid col
- square[4][2][1]=square[0][0][1];
- square[4][1][1]=square[0][1][1];
- square[4][0][1]=square[0][2][1];
- // upper mid col=front mid col
- square[0][0][1]=temp0;
- square[0][1][1]=temp1;
- square[0][2][1]=temp2;
- }
- public void doMiddle() {
- // middle row of all lateral faces (Left/Front/Right/Back) goes clockwise
- int temp0=square[1][1][0];
- int temp1=square[1][1][1];
- int temp2=square[1][1][2];
- //left mid row=front mid row
- square[1][1][0]=square[2][1][0];
- square[1][1][1]=square[2][1][1];
- square[1][1][2]=square[2][1][2];
- // front mid row=right mid row
- square[2][1][0]=square[3][1][0];
- square[2][1][1]=square[3][1][1];
- square[2][1][2]=square[3][1][2];
- // right mid row=back mid row
- square[3][1][0]=square[4][1][0];
- square[3][1][1]=square[4][1][1];
- square[3][1][2]=square[4][1][2];
- // back mid row=left mid col
- square[4][1][0]=temp0;
- square[4][1][1]=temp1;
- square[4][1][2]=temp2;
- }
- public void rotateFront2Upper() {
- // change orientation of whole cube so that front face is uppermost
- int[][]temp=new int[3][3];
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++)
- temp[row][col]=square[0][row][col]; // copy upper face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- square[0][row][col]=square[2][row][col]; // front goes 2 top
- square[2][row][col]=square[5][row][col]; // lower 2 front
- square[5][row][col]=square[4][2-row][2-col]; // back 2 lower
- square[4][2-row][2-col]=temp[row][col]; // upper to back
- }
- for (int i=0; i<3; i++)
- turnFaceClockwise(1); // left equal to 90 degrees anticlockwise
- turnFaceClockwise(3); // right face
- }
- public void rotateLeft2Front() {
- // change orientation of whole cube so that left face becomes front
- int[][]temp=new int[3][3];
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++)
- temp[row][col]=square[2][row][col]; // copy front face
- for (int row=0; row<3; row++)
- for (int col=0; col<3; col++) {
- square[2][row][col]=square[1][row][col]; //left goes 2 front
- square[1][row][col]=square[4][row][col]; //back goes 2 left
- square[4][row][col]=square[3][row][col]; //right 2 back
- square[3][row][col]=temp[row][col]; // front 2 right
- }
- for (int i=0; i<3; i++)
- turnFaceClockwise(0); // upper equal to 90 degrees anticlockwise
- turnFaceClockwise(5); // lower face
- }
- public void jumbleUpCube() {
- // make several random moves to jumble up cube for you to solve
- GregorianCalendar start = new GregorianCalendar();
- startYear=start.get(Calendar.YEAR);
- startMonth=start.get(Calendar.MONTH);
- startDay=start.get(Calendar.DAY_OF_MONTH);
- startHour=start.get(Calendar.HOUR_OF_DAY);
- startMinute=start.get(Calendar.MINUTE);
- startSecond=start.get(Calendar.SECOND);
- Random ran = new Random();
- for (int i=0; i<30; i++) { // 30 random moves
- int r = ran.nextInt(20) + 1; // 1<=r<21
- makeMove(r);
- }
- moveCount=0;
- jumbled=true; // so we can display solved message when solved
- resetMI.setEnabled(false); // once its jumbled, user can't reset
- }
- public void makeMove(int n) {
- // make one move according to a number (see method 'jumbleUpCube' above)
- switch(n) {
- case 1: doLeft();
- break;
- case 2: for (int i=0; i<3; i++)
- doLeft();
- break;
- case 3: doLeftMiddle();
- break;
- case 4: for (int i=0; i<3; i++)
- doLeftMiddle();
- break;
- case 5: doRight();
- break;
- case 6: for (int i=0; i<3; i++)
- doRight();
- break;
- case 7: doFront();
- break;
- case 8: for (int i=0; i<3; i++)
- doFront();
- break;
- case 9: doFrontMiddle();
- break;
- case 10: for (int i=0; i<3; i++)
- doFrontMiddle();
- break;
- case 11: doUpper();
- break;
- case 12: for (int i=0; i<3; i++)
- doUpper();
- break;
- case 13: doLower();
- break;
- case 14: for (int i=0; i<3; i++)
- doLower();
- break;
- case 15: doMiddle();
- break;
- case 16: for (int i=0; i<3; i++)
- doMiddle();
- break;
- case 17: rotateFront2Upper();
- break;
- case 18: for (int i=0; i<3; i++)
- rotateFront2Upper();
- break;
- case 19: rotateLeft2Front();
- break;
- case 20: for (int i=0; i<3; i++)
- rotateLeft2Front();
- }
- }
- public void makeMove(char ch) {
- // make a move according to current character of a String
- if (ch=='L') {
- doLeft();
- } else if (ch=='l') {
- for (int i=0; i<3; i++)
- doLeft();
- } else if (ch=='X') {
- doLeftMiddle();
- } else if (ch=='x') {
- for (int i=0; i<3; i++)
- doLeftMiddle();
- } else if (ch=='R') {
- doRight();
- } else if (ch=='r') {
- for (int i=0; i<3; i++)
- doRight();
- } else if (ch=='F') {
- doFront();
- } else if (ch=='f') {
- for (int i=0; i<3; i++)
- doFront();
- } else if (ch=='Y') {
- doFrontMiddle();
- } else if (ch=='y') {
- for (int i=0; i<3; i++)
- doFrontMiddle();
- } else if (ch=='U') {
- doUpper();
- } else if (ch=='u') {
- for (int i=0; i<3; i++)
- doUpper();
- } else if (ch=='B') {
- doLower();
- } else if (ch=='b') {
- for (int i=0; i<3; i++)
- doLower();
- } else if (ch=='Z') {
- doMiddle();
- } else if (ch=='z') {
- for (int i=0; i<3; i++)
- doMiddle();
- } else if (ch=='G') {
- rotateFront2Upper();
- } else if (ch=='g') {
- for (int i=0; i<3; i++)
- rotateFront2Upper(); // = upper face to front
- } else if (ch=='H') {
- rotateLeft2Front();
- } else if (ch=='h') {
- for (int i=0; i<3; i++)
- rotateLeft2Front(); // = front face to left
- }
- }
- public void enableOrDisableAllButtons(boolean b) {
- // if b is true, enable buttons, otherwise disable them
- btnLeft.setEnabled(b);
- btnLeftMinus.setEnabled(b);
- btnLeftMiddle.setEnabled(b);
- btnLeftMiddleMinus.setEnabled(b);
- btnFront.setEnabled(b);
- btnFrontMinus.setEnabled(b);
- btnFrontMiddle.setEnabled(b);
- btnFrontMiddleMinus.setEnabled(b);
- btnRight.setEnabled(b);
- btnRightMinus.setEnabled(b);
- btnUpper.setEnabled(b);
- btnUpperMinus.setEnabled(b);
- btnLower.setEnabled(b);
- btnLowerMinus.setEnabled(b);
- btnMiddle.setEnabled(b);
- btnMiddleMinus.setEnabled(b);
- btnRotateFront2Upper.setEnabled(b);
- btnRotateUpper2Front.setEnabled(b);
- btnRotateLeft2Front.setEnabled(b);
- btnRotateFront2Left.setEnabled(b);
- btnJumble.setEnabled(b);
- btnEnableFunctions.setEnabled(b);
- btnF1a.setEnabled(b);
- btnF1b.setEnabled(b);
- btnF2a.setEnabled(b);
- btnF2b.setEnabled(b);
- btnF3a.setEnabled(b);
- btnF3b.setEnabled(b);
- }
- public void enableFunctionButtons() {
- btnF1a.setEnabled(true);
- btnF1b.setEnabled(true);
- btnF2a.setEnabled(true);
- btnF2b.setEnabled(true);
- btnF3a.setEnabled(true);
- btnF3b.setEnabled(true);
- }
- public void doFormula(String strFormula, Button b) {
- // perform one move of formula
- if (!done) {
- moveNum_F=strFormula.length();
- F_index=0;
- done=true;
- enableOrDisableAllButtons(false);
- b.setEnabled(true);
- }
- if (F_index<moveNum_F) {
- makeMove(strFormula.charAt(F_index++));
- moveCount++;
- }
- if (F_index==moveNum_F) {
- done=false;
- enableOrDisableAllButtons(true);
- // don't click again!
- b.setEnabled(false);
- }
- }
- public void displayHelp() {
- JOptionPane.showMessageDialog(null,
- "To solve Rubiks Cube\n=================\n"
- +"First of all, with the cube in its START POSITION, (File/Reset)\n"
- +"PRACTISE moves using ALL the different buttons (except Jumble)\n"
- +"and see what each button does, including the Formula buttons.\n"
- +"You can click the same button more than once and see what happens.\n"
- +"Buttons turn a face a quarter-turn clockwise, except the ones\n"
- +"with \'-1\' which turn the face anti-clockwise.\n"
- +"Practise until you\'re familiar with what the buttons and formulae do.\n"
- +"Then, when you're ready, click \'Jumble up cube\' and solve as follows:\n\n"
- +"Step 0. Choose any colour face and complete it so that all it\'s edge and\n"
- +"corner pieces match the colours of the adjacent faces.\n\n"
- +"Step 1. Turn cube (using Front Down button) so that the completed\n"
- +"face is at the bottom, and you're now ready to use the Formula buttons\n"
- +"F1a and F1b to complete the MIDDLE LAYER.\n"
- +"F1a swaps the UPPER face\'s LEFT EDGE PIECE\n"
- +"with the FRONT face\'s RIGHT EDGE PIECE.\n"
- +"F1b swaps the UPPER face\'s RIGHT EDGE PIECE\n"
- +"with the FRONT face\'s LEFT EDGE PIECE.\n\n"
- +"Step 2. Use formula 2a to swap and get the upper edge pieces in their\n"
- +"right places, and formula 2b to get them all the right way round.\n"
- +"You may find you need to use each formula twice or more.\n"
- +"(If the Formula buttons aren't enabled, click the \'Enable Formulae\' "
- +"button.)\n\n"
- +"Step 3. Formula 3a is used on the upper face to swap its top left,\n"
- +"bottom left and top right corners in an anti-clockwise direction.\n"
- +"Using this formula twice will swap them in a clockwise direction.\n"
- +"Finally, formula 3b is used to \'twist\' two upper face corner pieces,\n"
- +"one clockwise, the other anti-clockwise.\n\n"
- +"Remember, PRACTISE moves & formulae on the cube in its START POSITION,\n"
- +"until you get the hang of what they do.\n"
- +"Good luck!");
- }
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == btnLeft) { // "L"
- doLeft();
- moveCount++;
- } else if (e.getSource() == btnLeftMinus) { // "l"
- for (int i=0; i<3; i++)
- doLeft();
- moveCount++;
- } else if (e.getSource() == btnLeftMiddle) { // "X"
- doLeftMiddle();
- moveCount++;
- } else if (e.getSource() == btnLeftMiddleMinus) { // "x"
- for (int i=0; i<3; i++)
- doLeftMiddle();
- moveCount++;
- } else if (e.getSource() == btnRight) { // "R"
- doRight();
- moveCount++;
- } else if (e.getSource() == btnRightMinus) { // "r"
- for (int i=0; i<3; i++)
- doRight();
- moveCount++;
- } else if (e.getSource() == btnFront) { // "F"
- doFront();
- moveCount++;
- } else if (e.getSource() == btnFrontMinus) { // "f"
- for (int i=0; i<3; i++)
- doFront();
- moveCount++;
- } else if (e.getSource() == btnFrontMiddle) { // "Y"
- doFrontMiddle();
- moveCount++;
- } else if (e.getSource() == btnFrontMiddleMinus) { // "y"
- for (int i=0; i<3; i++)
- doFrontMiddle();
- moveCount++;
- } else if (e.getSource() == btnUpper) { // "U"
- doUpper();
- moveCount++;
- } else if (e.getSource() == btnUpperMinus) { // "u"
- for (int i=0; i<3; i++)
- doUpper();
- moveCount++;
- } else if (e.getSource() == btnLower) { // "B" = base
- doLower();
- moveCount++;
- } else if (e.getSource() == btnLowerMinus) { // "b"
- for (int i=0; i<3; i++)
- doLower();
- moveCount++;
- } else if (e.getSource() == btnMiddle) { // "Z"
- doMiddle();
- moveCount++;
- } else if (e.getSource() == btnMiddleMinus) { // "z"
- for (int i=0; i<3; i++)
- doMiddle();
- moveCount++;
- } else if (e.getSource() == btnRotateFront2Upper) { // "G";
- rotateFront2Upper();
- } else if (e.getSource() == btnRotateUpper2Front) { // "g";
- for (int i=0; i<3; i++)
- rotateFront2Upper(); // = upper face to front
- } else if (e.getSource() == btnRotateLeft2Front) { // "H";
- rotateLeft2Front();
- } else if (e.getSource() == btnRotateFront2Left) { // "h";
- for (int i=0; i<3; i++)
- rotateLeft2Front(); // = front face to left
- } else if (e.getSource() == btnJumble) { // randomly mix up cube
- jumbleUpCube();
- } else if (e.getSource() == btnEnableFunctions) {
- enableFunctionButtons();
- } else if (e.getSource() == btnF1a) { // makes 1 move at a time
- doFormula(SWAPTOPLEFTEDGEWITHFRONTRIGHTEDGE, btnF1a);
- } else if (e.getSource() == btnF1b) { //
- doFormula(SWAPTOPRIGHTEDGEWITHFRONTLEFTEDGE, btnF1b);
- } else if (e.getSource() == btnF2a) { //
- doFormula(SWAP2TOPEDGEPIECES, btnF2a);
- } else if (e.getSource() == btnF2b) { //
- doFormula(ROTATETOPEDGEPIECE, btnF2b);
- } else if (e.getSource() == btnF3a) { //
- doFormula(SWAP3CORNERSANTICLOCKWISE, btnF3a);
- } else if (e.getSource() == btnF3b) { //
- doFormula(ROTATECORNERS1CLOCKWISE1ANTICLOCKWISE, btnF3b);
- } else if (e.getSource() == resetMI) { // Menu Item reset
- reset();
- } else if (e.getSource() == TwoDMI) { // Menu Item for 2-dimensional
- display="2D";
- } else if (e.getSource() == ThreeDMI) { // Menu Item for 3-dimensional
- display="3D";
- } else if (e.getSource() == helpMI) { // Menu Item for displaying help
- displayHelp();
- } else if (e.getSource() == exitMI) { // Menu Item for exit
- System.exit(0);
- }
- repaint();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement