0

I'm trying to create a Rubiks cube using 6, 2D arrays for each face of the cube. I'm able to spin the entire cube using this code but for some reason when I try and "turn" one vertical strip of the cube it does not work properly. Here is what I have so far

import java.util.*;
public class RubiksCube {
    public static void main(String[] args) {
        String Empty[][] = {{"0","0","0"},{"0","0","0"},{"0","0","0"}};
        String Front[][] = {{"F1","F1","F1"},{"F2","F2","F2"},{"F3","F3","F3"}};
        String Back [][] = {{"B1","B1","B1"},{"B2","B2","B2"},{"B3","B3","B3"}};
        String Top  [][] = {{"T1","T1","T1"},{"T2","T2","T2"},{"T3","T3","T3"}};
        String Under[][] = {{"U1","U1","U1"},{"U2","U2","U2"},{"U3","U3","U3"}};
        String Left [][] = {{"L1","L1","L1"},{"L2","L2","L2"},{"L3","L3","L3"}};
        String Right[][] = {{"R1","R1","R1"},{"R2","R2","R2"},{"R3","R3","R3"}};

        Scanner Scan = new Scanner(System.in);
        boolean repeat = true;

        while (repeat) {
            for (int x = 0; x < Front.length; x++) {
                for (int y = 0; y < Front[0].length; y++) {
                    System.out.print(Under[x][y]);
                }
                System.out.println();
             }

            String command = Scan.nextLine();
            Empty = Back;

            if (command.equalsIgnoreCase("Up")) {
                Back  = Top;
                Top   = Front;
                Front = Under;
                Under = Empty;
            }

            if (command.equalsIgnoreCase("up1")) {
                for (int x = 0; x < 3; x++) {
                    Back [x][0] = Top  [x][0];
                    Top  [x][0] = Front[x][0];
                    Front[x][0] = Under[x][0];  
                    Under[x][0] = Empty[x][0];
               }
            }
        }
    }
}

So if this cube is being flipped up then the bottom of the cube become the front, the back becomes the bottom, etc. When I do this using the "Up1" command however the bottom of the cube seems to disappear from my arrays and the top gets doubled into two of the arrays. What am I doing wrong? I'm very new to using multidimensional arrays so am I making some silly mistake?

Edit: So to simplify things for some reason this works

if (command.equalsIgnoreCase("up1")) {
     String[] tmp = { Back[0][0], Back[1][0], Back[2][0] };
        for (int x=0;x<3;x++) {
          Back[x][0] = Top[x][0];
          Top[x][0] = Front[x][0];
          Front[x][0] = Under[x][0];    
          Under[x][0] = tmp[x];
        }
    }

But this does not

 if (command.equalsIgnoreCase("up1")) {
     String tmp [][] = Back;
        for (int x=0;x<3;x++) {
          Back[x][0] = Top[x][0];
          Top[x][0] = Front[x][0];
          Front[x][0] = Under[x][0];    
          Under[x][0] = tmp[x][0];
        }
    }

Why does the second version not work correctly?

Edit2:

Example with code that works correctly. It cycles through the under, bottom, top, front, and then under again

U1 U1 U1    
U2 U2 U2    
U3 U3 U3

Input: up1

B1 U1 U1    
B2 U2 U2    
B3 U3 U3    

Input: up1

T1 U1 U1    
T2 U2 U2    
T3 U3 U3    

Input: up1

F1 U1 U1    
F2 U2 U2    
F3 U3 U3

Input: up1

U1 U1 U1    
U2 U2 U2    
U3 U3 U3    

Example with the code that uses a 2D temporary array that does not work properly. It skips the bottom of the cube for some reason

U1 U1 U1    
U2 U2 U2    
U3 U3 U3   

Input: up1

T1 U1 U1    
T2 U2 U2    
T3 U3 U3    

Input: up1

F1 U1 U1    
F2 U2 U2    
F3 U3 U3 

Input up1

U1 U1 U1    
U2 U2 U2    
U3 U3 U3

Input: up1

T1 U1 U1    
T2 U2 U2    
T3 U3 U3
Dici
  • 25,226
  • 7
  • 41
  • 82
Samantha Clark
  • 201
  • 2
  • 9
  • What is `Empty` supposed to represent ? If you notice, even your sentence in english doesn't match your code: `bottom of the cube become the front, the back becomes the bottom`. In your code, the bottom becomes empty (`Under[x][0] = Empty[x][0]`) and the back becomes the top (`Back[x][0] = Top[x][0]`) – Dici Dec 22 '17 at 22:40
  • Empty is used to store one array outside of the normal faces because the arrays are overwriting each other. Without it, the "Up" code would not work because the Back array is already overwritten so the Under array could not copy it. Instead the Back array is copied to the Empty array for storage until it's needed – Samantha Clark Dec 22 '17 at 22:43
  • Well it doesn't make much sense does it ? At the end of the rotation the you must have rotated the last block as well, here you're just assigning it a dummy value. What you should do instead is copying the first block in a temporary array before starting the overwrites. – Dici Dec 22 '17 at 22:44
  • The Empty array is the temporary array. Before any of the swapping happens the Back array is stored to the Empty array – Samantha Clark Dec 22 '17 at 22:46
  • It's not really temporary, you're never assigning the right values to it. I'll show you what I mean – Dici Dec 22 '17 at 22:47

1 Answers1

0

I believe a more correct (but still incomplete) logic would rather be:

 String[] tmp = { Back[0][0], Back[1][0], Back[2][0] };

 // this logic only takes into account the changes that occur             
 for (int i = 0; i < 3; i++) {
     Back [i][0] = Under[i][0];
     Under[i][0] = Front[i][0];
     Front[i][0] = Top  [i][0];
     Top  [i][0] = tmp  [i];
 }

You need to use a temporary array that stores the values of the first block that you are about to move to record its value before you start overwriting it and re-use it at the end of the rotation to update the last block with the previous values of the first block.

Also, the order of the blocks to move in your english sentence did not match with your code, so I corrected this as well. Finally, I don't think only moving the first value of each block will be enough. I can't really propose a complete solution because I don't know in which order you decided to index the arrays. For example, is Back[0][0] at the top-left or at the top-right ? I could see arguments for both decisions.

Tip: to optimize a little bit and avoid re-allocating a temporary array every time you can allocate a single array of three elements at the start and then always re-use the same during swapping.

Edit:

Your second version doesn't work because you're not copying the array, you're just obtaining a reference to the array, which means that if the array is modified your tmp variable is also affected since tmp and Back are two pointers to exactly the same array.

Dici
  • 25,226
  • 7
  • 41
  • 82
  • Thank you, that works. Why does it not work if tmp is 2D array? I tried using that code but with the 2D array Empty from my original code and I ended up having the same problem – Samantha Clark Dec 22 '17 at 23:01
  • I have several things to tell you: firstly, I don't think my solution works, it's missing various element swaps and it may not correspond to the order of indexing you decided to use for non-front blocks. Secondly, you don't need a temporary 2D array because you're never swapping 3x3 blocks at a time. Lastly, I'm not sure what you tried exactly so I can't tell you why it doesn't work. – Dici Dec 22 '17 at 23:06
  • If (command == "Up") the whole cube is rotated so in that case I used a 2D temporary array. When I try using that same temporary "Empty" Array for "Up1" the code doesn't work properly. If I switch to a 1 dimensional array however (like the one in the code you posted) it works properly. – Samantha Clark Dec 22 '17 at 23:14
  • Can you please do the following: give an example of inputs and the outputs you're expecting vs what you're actually getting, and join your code to this example – Dici Dec 22 '17 at 23:23
  • I attached the code that works and the code that does not work, along with examples of the inputs and outputs for the two in the original post – Samantha Clark Dec 22 '17 at 23:32
  • I edited my answer to explain you why this does not work with your code – Dici Dec 22 '17 at 23:43
  • Thank you very much. It is now working the way I wanted it to. I appreciate all your help – Samantha Clark Dec 23 '17 at 00:18
  • No worries :) Bye – Dici Dec 23 '17 at 14:16