├── README.md └── RubixCube ├── Block.pde ├── Cube.pde ├── CubeAlgorithms.pde ├── FUCKYOU.pde ├── RubixCube.pde └── TurnO.pde /README.md: -------------------------------------------------------------------------------- 1 | # RubiksCubeAI -------------------------------------------------------------------------------- /RubixCube/Block.pde: -------------------------------------------------------------------------------- 1 | class Block { 2 | 3 | PVector pos; 4 | color[] colors = new color[6]; //left right up down back front 5 | boolean showBlack = false; 6 | int numberOfCols = 0; 7 | int id; 8 | Block(PVector pos) { 9 | this.pos = pos; 10 | id = (int)(pos.x*100*n*n + pos.y*10*n + pos.z*1) + floor(random(100000)); 11 | setColors(); 12 | } 13 | Block() { 14 | } 15 | 16 | Block clone() { 17 | 18 | Block clone = new Block(); 19 | clone.colors = colors.clone(); 20 | clone.pos = new PVector(pos.x, pos.y, pos.z); 21 | clone.numberOfCols = numberOfCols; 22 | clone.id = id; 23 | return clone; 24 | } 25 | void turn(int axisNo, boolean clockwise) { 26 | //assume always clockwise 27 | color[] newColors = colors.clone(); 28 | if (clockwise) { 29 | turn(axisNo, false); 30 | turn(axisNo, false); 31 | turn(axisNo, false); 32 | return; 33 | } 34 | switch(axisNo) { 35 | case 0://x axis 36 | //front becomes up 37 | //up becomes back 38 | //back becomes down 39 | //down becomes font 40 | 41 | newColors[2] = colors[5]; 42 | newColors[3] = colors[4]; 43 | newColors[4] = colors[2]; 44 | newColors[5] = colors[3]; 45 | break; 46 | case 1://yaxis 47 | newColors[0] = colors[4];//left = back 48 | newColors[1] = colors[5];//right = fron 49 | newColors[4] = colors[1];//back = right 50 | newColors[5] = colors[0];//front = left 51 | break; 52 | case 2://zaxis 53 | newColors[0] = colors[3]; 54 | newColors[1] = colors[2]; 55 | newColors[2] = colors[0]; 56 | newColors[3] = colors[1]; 57 | break; 58 | } 59 | colors = newColors.clone(); 60 | } 61 | void setColors() { 62 | //position 0 0 0 is the top left back which is the blue, white orange corner (respectively) 63 | for (int i = 0; i< colors.length; i++) { 64 | colors[i] = color(0); 65 | } 66 | if (pos.x==0) { 67 | colors[0] = color(255); 68 | numberOfCols++; 69 | } 70 | if (pos.x == numberOfSides-1) { 71 | colors[1] = color(255, 255, 0); 72 | numberOfCols++; 73 | } 74 | if (pos.y ==0) { 75 | colors[2] = color(0, 0, 255); 76 | numberOfCols++; 77 | } 78 | if (pos.y ==numberOfSides-1) { 79 | colors[3] = color(0, 255, 0); 80 | numberOfCols++; 81 | } 82 | if (pos.z ==0) { 83 | colors[4] = color(255, 140, 0);//orange 84 | numberOfCols++; 85 | } 86 | if (pos.z ==numberOfSides-1) { 87 | colors[5] = color(255, 0, 0); 88 | numberOfCols++; 89 | } 90 | } 91 | 92 | 93 | void show() { 94 | 95 | for (int i = 0; i< colors.length; i++) { 96 | drawFace(i, colors[i]); 97 | } 98 | } 99 | 100 | 101 | //left right up down back front 102 | void drawFace(int faceNo, color col) { 103 | 104 | //if (!showBlack && col == color(0)) { 105 | // return; 106 | //} 107 | if (col == color(0)) { 108 | return; 109 | } 110 | 111 | 112 | fill(col); 113 | stroke(0); 114 | float weightSize = max(1, blockWidth/20.0); 115 | strokeWeight(weightSize); 116 | //strokeWeight(2); 117 | //noStroke(); 118 | switch(faceNo) { 119 | case 0: 120 | //left 121 | beginShape(); 122 | addVertex(0, 0, 1); 123 | addVertex(0, 0, 0); 124 | addVertex(0, 1, 0); 125 | addVertex(0, 1, 1); 126 | endShape(CLOSE); 127 | break; 128 | case 1: 129 | //right 130 | beginShape(); 131 | addVertex(1, 0, 1); 132 | addVertex(1, 0, 0); 133 | addVertex(1, 1, 0); 134 | addVertex(1, 1, 1); 135 | endShape(CLOSE); 136 | break; 137 | case 2: 138 | //top 139 | beginShape(); 140 | addVertex(0, 0, 1); 141 | addVertex(0, 0, 0); 142 | addVertex(1, 0, 0); 143 | addVertex(1, 0, 1); 144 | endShape(CLOSE); 145 | break; 146 | case 3: 147 | //bottom 148 | beginShape(); 149 | addVertex(0, 1, 1); 150 | addVertex(0, 1, 0); 151 | addVertex(1, 1, 0); 152 | addVertex(1, 1, 1); 153 | endShape(CLOSE); 154 | break; 155 | case 4: 156 | //back 157 | beginShape(); 158 | addVertex(0, 0, 0); 159 | addVertex(1, 0, 0); 160 | addVertex(1, 1, 0); 161 | addVertex(0, 1, 0); 162 | endShape(CLOSE); 163 | break; 164 | case 5: 165 | //front 166 | beginShape(); 167 | addVertex(0, 0, 1); 168 | addVertex(1, 0, 1); 169 | addVertex(1, 1, 1); 170 | addVertex(0, 1, 1); 171 | endShape(CLOSE); 172 | break; 173 | } 174 | } 175 | 176 | 177 | //todo gonna need more info for larger problems 178 | boolean matchesColors(color[] cols) { 179 | if (numberOfCols != cols.length) { 180 | return false; 181 | } 182 | 183 | for (int i = 0; i< cols.length; i++) { 184 | boolean foundMatch = false; 185 | for (int j = 0; j < colors.length; j++) { 186 | if (colors[j] == cols[i]) { 187 | foundMatch = true; 188 | break; 189 | } 190 | } 191 | if (!foundMatch) { 192 | return false; 193 | } 194 | } 195 | 196 | 197 | return true; 198 | } 199 | 200 | boolean matchesColors(color col) { 201 | if (numberOfCols != 1) { 202 | return false; 203 | } 204 | for (int j = 0; j < colors.length; j++) { 205 | if (colors[j] == col) { 206 | return true; 207 | } 208 | } 209 | return false; 210 | } 211 | 212 | color[] getColors() { 213 | color[] cols = new color[numberOfCols]; 214 | int counter =0; 215 | for (int i = 0; i<6; i++) { 216 | if (colors[i]!= color(0)) { 217 | cols[counter] = colors[i]; 218 | counter++; 219 | } 220 | } 221 | return cols; 222 | } 223 | 224 | color getColorFromFace(char face) { 225 | String faces = "LRUDBF"; 226 | return colors[faces.indexOf(face)]; 227 | } 228 | 229 | 230 | char getFace(color col) { //left right up down back front 231 | for (int j = 0; j < colors.length; j++) { 232 | if (colors[j] == col) { 233 | String faces = "LRUDBF"; 234 | return faces.charAt(j); 235 | } 236 | } 237 | return ' '; 238 | } 239 | 240 | String getFaces() { 241 | String faces = ""; 242 | String faceOrder = "LRUDBF"; 243 | for (int j = 0; j < colors.length; j++) { 244 | if (colors[j] != color(0)) { 245 | faces += faceOrder.charAt(j); 246 | } 247 | } 248 | return faces; 249 | } 250 | 251 | 252 | void addVertex(int x, int y, int z) { 253 | vertex((x-0.5)*faceWidth, (y-0.5)*faceWidth, (z-0.5)*faceWidth); 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /RubixCube/Cube.pde: -------------------------------------------------------------------------------- 1 | class Cube { 2 | Block[][][] blocks; 3 | int rotationAxis = 0; 4 | int rotatingIndex = 0; 5 | float rotationAngle = 0; 6 | ArrayList rotatingBlocks = new ArrayList(); 7 | ArrayList showingBlack = new ArrayList(); 8 | int counter = 0; 9 | ArrayList> cycleLists = new ArrayList(); 10 | Block centerBlock = new Block(new PVector(0, 0, 0)); 11 | boolean turning = false; 12 | boolean turningClockwise = true; 13 | boolean turningWholeCube = false; 14 | boolean scrambling = true; 15 | float rotationSpeed = PI/20.0; 16 | 17 | CubeAlgorithms algos; 18 | Cube() { 19 | blocks = new Block[numberOfSides][numberOfSides][numberOfSides]; 20 | for (int i = 0; i< numberOfSides; i++) { 21 | for (int j = 0; j< numberOfSides; j++) { 22 | for (int k = 0; k< numberOfSides; k++) { 23 | blocks[i][j][k] = new Block(new PVector(i, j, k)); 24 | } 25 | } 26 | } 27 | algos = new CubeAlgorithms(this); 28 | } 29 | 30 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 31 | void show() { 32 | 33 | showBlacks(); 34 | int angleMultiplier = 1; 35 | if (turningClockwise) { 36 | angleMultiplier = -1; 37 | } 38 | //int otherCounter =0; 39 | //Block[][] face = getFace('D'); 40 | //for (int i = 0; i< numberOfSides; i++) { 41 | // for (int j = 0; j< numberOfSides; j++) { 42 | // pushMatrix(); 43 | // float x = face[i][j].pos.x; 44 | // float y = face[i][j].pos.y; 45 | // float z = face[i][j].pos.z; 46 | 47 | // float m =(numberOfSides-1)/2.0; 48 | // translate((x-m)*blockWidth, (y-m)*blockWidth, (z-m)*blockWidth); 49 | // face[i][j].show(); 50 | // popMatrix(); 51 | // otherCounter++; 52 | // if (otherCounter > counter) { 53 | // counter ++; 54 | // return; 55 | // } 56 | // } 57 | //} 58 | 59 | //counter =0; 60 | 61 | for (int i = 0; i< numberOfSides; i++) { 62 | for (int j = 0; j< numberOfSides; j++) { 63 | for (int k = 0; k< numberOfSides; k++) { 64 | pushMatrix(); 65 | if (turning && (turningWholeCube || rotatingBlocks.contains(blocks[i][j][k]) )) { 66 | switch(rotationAxis) { 67 | case 0: 68 | rotateX(angleMultiplier*rotationAngle); 69 | break; 70 | case 1: 71 | rotateY(angleMultiplier*rotationAngle); 72 | break; 73 | case 2: 74 | rotateZ(angleMultiplier*rotationAngle); 75 | break; 76 | } 77 | } 78 | float m =(numberOfSides-1)/2.0; 79 | translate((i-m)*blockWidth, (j-m)*blockWidth, (k-m)*blockWidth); 80 | blocks[i][j][k].show(); 81 | popMatrix(); 82 | } 83 | } 84 | } 85 | } 86 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 87 | void update() { 88 | if (turning) { 89 | if (rotationAngle < PI/2) { 90 | float scramblingMultiplier = 1; 91 | if (scrambling) { 92 | scramblingMultiplier = 5; 93 | } 94 | int turningEaseCoeff = 2; 95 | if (rotationAngle PI/2-PI/8) { 98 | rotationAngle += scramblingMultiplier*rotationSpeed/map(rotationAngle, PI/2-PI/8, PI/2, 1, turningEaseCoeff); 99 | } else { 100 | rotationAngle += scramblingMultiplier* rotationSpeed; 101 | } 102 | } 103 | if (rotationAngle >=PI/2) { 104 | rotationAngle = 0; 105 | turning= false; 106 | if (turningWholeCube) { 107 | finishTurningWholeCube(rotationAxis, turningClockwise); 108 | } else { 109 | finaliseTurn(rotatingIndex, rotationAxis, turningClockwise); 110 | } 111 | } 112 | } 113 | } 114 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 115 | 116 | void finaliseTurn(int index, int xOrYOrZ, boolean turnClockwise) { 117 | turning = false; 118 | 119 | ////to turn once clockwise take 2 from the back of the list and chuck em on the front 120 | 121 | for (int i = 0; i< rotatingBlocks.size(); i++) { 122 | rotatingBlocks.get(i).turn(xOrYOrZ, turnClockwise); 123 | } 124 | 125 | for (int j = 0; j < cycleLists.size(); j++) { 126 | ArrayList temp = cycleLists.get(j); 127 | for (int i = 0; i< numberOfSides-1-j*2; i++) { 128 | if (!turnClockwise) { 129 | //remove from end and add to start 130 | temp.add(0, temp.remove(temp.size()-1)); 131 | } else { 132 | //remove from front and add to the end 133 | temp.add(temp.remove(0)); 134 | } 135 | } 136 | returnListToCube(temp, index, xOrYOrZ, j); 137 | } 138 | } 139 | 140 | void finishTurningWholeCube(int axis, boolean clockwise) { 141 | turning = false; 142 | turningWholeCube = false; 143 | 144 | for (int i = 0; i< numberOfSides; i++) { 145 | for (int j = 0; j< numberOfSides; j++) { 146 | for (int k = 0; k< numberOfSides; k++) { 147 | blocks[i][j][k].turn(axis, clockwise); 148 | } 149 | } 150 | } 151 | 152 | for (int k = 0; k< numberOfSides; k++) { 153 | cycleLists = getAllBlocksToRotate(k, axis); 154 | for (int j = 0; j < cycleLists.size(); j++) { 155 | ArrayList temp = cycleLists.get(j); 156 | for (int i = 0; i< numberOfSides-1-j*2; i++) { 157 | if (!clockwise) { 158 | //remove from end and add to start 159 | temp.add(0, temp.remove(temp.size()-1)); 160 | } else { 161 | //remove from front and add to the end 162 | temp.add(temp.remove(0)); 163 | } 164 | } 165 | returnListToCube(temp, k, axis, j); 166 | } 167 | } 168 | } 169 | 170 | void turnWholeCube(int axis, boolean clockwise) { 171 | if (turning) { 172 | return; 173 | } 174 | turning = true; 175 | turningClockwise = clockwise; 176 | turningWholeCube = true; 177 | rotationAxis = axis; 178 | if (fixCubeRotation) { 179 | rotationAngle = 0; 180 | turning= false; 181 | finishTurningWholeCube(axis, clockwise); 182 | } 183 | } 184 | 185 | 186 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 187 | void turnCubeFromObj(TurnO t) { 188 | turnCube(t.index, t.axis, t.clockwise); 189 | } 190 | 191 | 192 | void turnCube(int index, int xOrYOrZ, boolean turnClockwise) { 193 | if (turning) {//finish the turn 194 | rotationAngle = 0; 195 | turning= false; 196 | finaliseTurn(rotatingIndex, rotationAxis, turningClockwise); 197 | } 198 | turning = true; 199 | this.turningClockwise = turnClockwise; 200 | cycleLists = getAllBlocksToRotate(index, xOrYOrZ); 201 | rotatingBlocks = new ArrayList(); 202 | for (int i = 0; i < cycleLists.size(); i++) { 203 | rotatingBlocks.addAll(cycleLists.get(i)); 204 | } 205 | rotationAxis = xOrYOrZ; 206 | rotatingIndex = index; 207 | } 208 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 209 | ArrayList> getAllBlocksToRotate(int index, int xOrYOrZ) { 210 | ArrayList> temp = new ArrayList(); 211 | if (index ==0 || index ==n-1) { 212 | for (int i = 0; i < floor((numberOfSides+1)/2); i++) { 213 | temp.add(getList(index, xOrYOrZ, i)); 214 | } 215 | } else { 216 | temp.add(getList(index, xOrYOrZ, 0)); 217 | } 218 | return temp; 219 | } 220 | 221 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 222 | //takes in an arraylist and adds it to the cube 223 | void returnListToCube(ArrayList list, int index, int xOrYOrZ, int listNumber) { 224 | int i = 0; 225 | int j = 0; 226 | int k = 0; 227 | int size = numberOfSides-2*listNumber; 228 | 229 | switch(xOrYOrZ) { 230 | case 0: 231 | //return all blocks with the x index of "index" 232 | i = index; 233 | 234 | //add all on top row 235 | k = 0; 236 | for (j = 0; j< size; j++) { 237 | blocks[i][j+listNumber][k+listNumber] = list.remove(0).clone(); 238 | } 239 | 240 | //add right row 241 | j=size-1; 242 | for (k = 1; k< size; k++) { 243 | blocks[i][j+listNumber][k+listNumber] = list.remove(0).clone(); 244 | } 245 | 246 | //add bottom 247 | k=size-1; 248 | for (j = size-2; j>=0; j--) { 249 | blocks[i][j+listNumber][k+listNumber] = list.remove(0).clone(); 250 | } 251 | 252 | //add left 253 | j=0; 254 | for (k = size-2; k>0; k--) { 255 | blocks[i][j+listNumber][k+listNumber] = list.remove(0).clone(); 256 | } 257 | break; 258 | case 1: 259 | //return all blocks with the y index of "index" 260 | j = index; 261 | 262 | //add all on top row 263 | i = 0; 264 | for (k = 0; k< size; k++) { 265 | blocks[i+listNumber][j][k+listNumber] = list.remove(0).clone(); 266 | } 267 | 268 | //add right row 269 | k=size -1; 270 | for (i = 1; i< size; i++) { 271 | blocks[i+listNumber][j][k+listNumber] = list.remove(0).clone(); 272 | } 273 | 274 | //add bottom 275 | i=size-1; 276 | for (k = size-2; k>=0; k--) { 277 | blocks[i+listNumber][j][k+listNumber] = list.remove(0).clone(); 278 | } 279 | 280 | //add left 281 | k=0; 282 | for (i = size-2; i>=1; i--) { 283 | blocks[i+listNumber][j][k+listNumber] = list.remove(0).clone(); 284 | } 285 | break; 286 | 287 | case 2: 288 | //return all blocks with the y index of "index" 289 | k = index; 290 | 291 | //add all on top row 292 | j = 0; 293 | for (i = 0; i< size; i++) { 294 | blocks[i+listNumber][j+listNumber][k] = list.remove(0).clone(); 295 | } 296 | 297 | //add right row 298 | i=size-1; 299 | for (j = 1; j< size; j++) { 300 | blocks[i+listNumber][j+listNumber][k] = list.remove(0).clone(); 301 | } 302 | 303 | //add bottom 304 | j=size-1; 305 | for (i = size-2; i>=0; i--) { 306 | blocks[i+listNumber][j+listNumber][k] = list.remove(0).clone(); 307 | } 308 | 309 | //add left 310 | i=0; 311 | for (j = size-2; j>=1; j--) { 312 | blocks[i+listNumber][j+listNumber][k] = list.remove(0).clone(); 313 | } 314 | break; 315 | } 316 | for ( i = 0; i< numberOfSides; i++) { 317 | for ( j = 0; j< numberOfSides; j++) { 318 | for ( k = 0; k< numberOfSides; k++) { 319 | blocks[i][j][k].pos = new PVector(i, j, k); 320 | } 321 | } 322 | } 323 | } 324 | //----------------------------------------------------------------------------------------------------------------------------------------------------------- 325 | //returns a list of all the blocks in that row/column thing 326 | //returns them in an order going clockwise around the center 327 | //todo only works for 3 length rubix cube 328 | ArrayList getList(int index, int xOrYOrZ, int listNumber) { 329 | ArrayList list = new ArrayList(); 330 | int i = 0; 331 | int j = 0; 332 | int k = 0; 333 | int size = numberOfSides-listNumber*2; 334 | 335 | switch(xOrYOrZ) { 336 | case 0: 337 | //return all blocks with the x index of "index" 338 | i = index; 339 | 340 | //add all on top row 341 | k = 0; 342 | for (j = 0; j< size; j++) { 343 | list.add(blocks[i][j+listNumber][k+listNumber]); 344 | } 345 | 346 | //add right row 347 | j=size-1; 348 | for (k = 1; k< size; k++) { 349 | list.add(blocks[i][j+listNumber][k+listNumber]); 350 | } 351 | 352 | //add bottom 353 | k=size-1; 354 | for (j = size-2; j>=0; j--) { 355 | list.add(blocks[i][j+listNumber][k+listNumber]); 356 | } 357 | 358 | //add left 359 | j=0; 360 | for (k = size-2; k>=1; k--) { 361 | list.add(blocks[i][j+listNumber][k+listNumber]); 362 | } 363 | break; 364 | case 1: 365 | //return all blocks with the y index of "index" 366 | j = index; 367 | 368 | //add all on top row 369 | i = 0; 370 | for (k = 0; k< size; k++) { 371 | list.add(blocks[i+listNumber][j][k+listNumber]); 372 | } 373 | 374 | //add right row 375 | k=size -1; 376 | for (i = 1; i< size; i++) { 377 | list.add(blocks[i+listNumber][j][k+listNumber]); 378 | } 379 | 380 | //add bottom 381 | i=size-1; 382 | for (k = size-2; k>=0; k--) { 383 | list.add(blocks[i+listNumber][j][k+listNumber]); 384 | } 385 | 386 | //add left 387 | k=0; 388 | for (i = size-2; i>=1; i--) { 389 | list.add(blocks[i+listNumber][j][k+listNumber]); 390 | } 391 | break; 392 | 393 | case 2: 394 | //return all blocks with the y index of "index" 395 | k = index; 396 | 397 | //add all on top row 398 | j = 0; 399 | for (i = 0; i< size; i++) { 400 | list.add(blocks[i+listNumber][j+listNumber][k]); 401 | } 402 | 403 | //add right row 404 | i=size -1; 405 | for (j = 1; j< size; j++) { 406 | list.add(blocks[i+listNumber][j+listNumber][k]); 407 | } 408 | 409 | //add bottom 410 | j=size-1; 411 | for (i = size-2; i>=0; i--) { 412 | list.add(blocks[i+listNumber][j+listNumber][k]); 413 | } 414 | 415 | //add left 416 | i=0; 417 | for (j = size-2; j>=1; j--) { 418 | list.add(blocks[i+listNumber][j+listNumber][k]); 419 | } 420 | break; 421 | } 422 | return list; 423 | } 424 | 425 | void showBlacks() { 426 | if (turning && !turningWholeCube) { 427 | pushMatrix(); 428 | translate((-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0); 429 | //now we are at 0,0,0 430 | fill(0); 431 | noStroke(); 432 | 433 | switch(rotationAxis) { 434 | case 0: 435 | break; 436 | 437 | case 1: //yaxis 438 | translate((numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0); 439 | rotateZ(PI/2); 440 | translate((-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0); 441 | break; 442 | case 2://zaxis 443 | translate((numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0); 444 | rotateY(-PI/2); 445 | translate((-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0); 446 | break; 447 | } 448 | 449 | 450 | if (rotatingIndex !=0) { 451 | beginShape(); 452 | vertex(blockWidth*rotatingIndex, 0, 0); 453 | vertex(blockWidth*rotatingIndex, numberOfSides*blockWidth, 0); 454 | vertex(blockWidth*rotatingIndex, numberOfSides*blockWidth, numberOfSides*blockWidth); 455 | vertex(blockWidth*rotatingIndex, 0, numberOfSides*blockWidth); 456 | endShape(CLOSE); 457 | } 458 | if (rotatingIndex !=numberOfSides-1) { 459 | beginShape(); 460 | vertex(blockWidth*(rotatingIndex+1), 0, 0); 461 | vertex(blockWidth*(rotatingIndex+1), numberOfSides*blockWidth, 0); 462 | vertex(blockWidth*(rotatingIndex+1), numberOfSides*blockWidth, numberOfSides*blockWidth); 463 | vertex(blockWidth*(rotatingIndex+1), 0, numberOfSides*blockWidth); 464 | endShape(CLOSE); 465 | } 466 | pushMatrix(); 467 | translate((numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0, (numberOfSides*blockWidth)/2.0); 468 | if (turningClockwise) { 469 | rotateX(-rotationAngle); 470 | } else { 471 | rotateX(rotationAngle); 472 | } 473 | translate((-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0, (-numberOfSides*blockWidth)/2.0); 474 | if (rotatingIndex !=0) { 475 | beginShape(); 476 | vertex(blockWidth*rotatingIndex, 0, 0); 477 | vertex(blockWidth*rotatingIndex, numberOfSides*blockWidth, 0); 478 | vertex(blockWidth*rotatingIndex, numberOfSides*blockWidth, numberOfSides*blockWidth); 479 | vertex(blockWidth*rotatingIndex, 0, numberOfSides*blockWidth); 480 | endShape(CLOSE); 481 | } 482 | if (rotatingIndex !=numberOfSides-1) { 483 | beginShape(); 484 | vertex(blockWidth*(rotatingIndex+1), 0, 0); 485 | vertex(blockWidth*(rotatingIndex+1), numberOfSides*blockWidth, 0); 486 | vertex(blockWidth*(rotatingIndex+1), numberOfSides*blockWidth, numberOfSides*blockWidth); 487 | vertex(blockWidth*(rotatingIndex+1), 0, numberOfSides*blockWidth); 488 | endShape(CLOSE); 489 | } 490 | 491 | popMatrix(); 492 | popMatrix(); 493 | } 494 | } 495 | 496 | 497 | //Block[][] getFace(char face) { 498 | // int minI =0; 499 | // int maxI = n-1; 500 | // int minJ = 0; 501 | // int maxJ = n-1; 502 | // int minK =0; 503 | // int maxK = n-1; 504 | // switch(face) { 505 | // case 'F': 506 | // minK = n-1; 507 | // break; 508 | // case 'B': 509 | // minI = n-1; 510 | // maxI = 0; 511 | // maxK = 0; 512 | // break; 513 | // case 'L': 514 | // maxI = 0; 515 | // break; 516 | // case 'R': 517 | // minI = n-1; 518 | // minK = n-1; 519 | // maxK = 0; 520 | // break; 521 | // case 'U': 522 | // maxJ = 0; 523 | // break; 524 | // case 'D': 525 | // minJ = n-1; 526 | // maxK = 0; 527 | // minK = n-1; 528 | // break; 529 | // } 530 | 531 | // Block[][] faceArr = new Block[n][n]; 532 | // int xCounter = 0; 533 | // int yCounter =0; 534 | // int negationI = 1; 535 | // if (maxI!=minI) { 536 | // negationI = (maxI-minI)/(abs(maxI-minI)); 537 | // } 538 | 539 | // for (int i = minI; i!=maxI+negationI; i+= negationI) { 540 | // int negationJ = 1; 541 | // if (maxJ!=minJ) { 542 | // negationJ = (maxJ-minJ)/(abs(maxJ-minJ)); 543 | // } 544 | 545 | // for (int j = minJ; j!=maxJ+negationJ; j+= negationJ) { 546 | // int negationK = 1; 547 | // if (maxK!=minK) { 548 | // negationK = (maxK-minK)/(abs(maxK-minK)); 549 | // } 550 | // for (int k = minK; k!=maxK+negationK; k+= negationK) { 551 | // faceArr[xCounter][yCounter] = blocks[i][j][k]; 552 | // xCounter++; 553 | // if (xCounter ==n) { 554 | // xCounter = 0; 555 | // yCounter++; 556 | // if (yCounter == n) { 557 | // return faceArr; 558 | // } 559 | // } 560 | // } 561 | // } 562 | // } 563 | // println("Fuck"); 564 | // return null; 565 | //} 566 | 567 | 568 | 569 | Block[][] getFace(char face) { 570 | 571 | Block[][] faceArr = new Block[n][n]; 572 | 573 | switch(face) { 574 | case 'F': 575 | for (int i = 0; i< n; i++) { 576 | for (int j = 0; j// //<>// //<>// //<>// //<>// //<>// //<>// //<>// //<>// //<>// //<>// 2 | Cube cube; 3 | int stageNo = 0; 4 | int largeCubeStageNo =0; 5 | boolean part1 = true; 6 | int completedCorners = 0; 7 | int completedEdges = 0; 8 | int turnsDone = 0; 9 | int rowStage =0; 10 | int rowUpTo = 0; 11 | 12 | int rowCounter =1; 13 | Block target; 14 | boolean newTarget = true; 15 | int targetId =0; 16 | boolean doneRedCenterRow = false; 17 | CubeAlgorithms(Cube cube) { 18 | this.cube = cube; 19 | if (numberOfSides ==3) { 20 | part1=false; 21 | largeCubeStageNo = 10; 22 | } 23 | } 24 | 25 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 26 | //called whenever the turn string is empty 27 | void continueSolve() { 28 | if (part1) { 29 | switch(largeCubeStageNo) { 30 | 31 | case -1: 32 | 33 | doEdges(); 34 | break; 35 | case 0: 36 | 37 | positionFace(green, 'D', 'X'); 38 | largeCubeStageNo ++; 39 | return; 40 | case 1: 41 | FirstCenter(); 42 | break; 43 | 44 | case 2: 45 | 46 | SecondCenter(); 47 | break; 48 | case 3: 49 | positionFace(red, 'L', 'Y'); 50 | largeCubeStageNo ++; 51 | break; 52 | case 4: 53 | 54 | ThirdCenter(); 55 | break; 56 | case 5: 57 | positionFace(yellow, 'L', 'Y'); 58 | largeCubeStageNo ++; 59 | break; 60 | case 6: 61 | FourthCenter(); 62 | break; 63 | 64 | case 7: 65 | positionFace(yellow, 'D', 'Z'); 66 | largeCubeStageNo ++; 67 | break; 68 | case 8: 69 | finalCenters(); 70 | break; 71 | case 9: 72 | doEdges(); 73 | break; 74 | default: 75 | //setup(); 76 | //pause = true; 77 | part1 = false; 78 | return; 79 | } 80 | } else { 81 | 82 | switch(stageNo) { 83 | 84 | case 0://cross 85 | greenCross(); 86 | break; 87 | case 1: 88 | positionBottomCorners(); 89 | break; 90 | case 2: 91 | finishBottom2Rows(); 92 | break; 93 | case 3: 94 | positionTopCross(); 95 | break; 96 | case 4: 97 | finishTopCross(); 98 | break; 99 | case 5: 100 | getCornersInCorrectPositions(); 101 | break; 102 | case 6: 103 | finalRotations(); 104 | break; 105 | case 7: 106 | int globalTimer = millis()-startTime; 107 | 108 | if (repeatSolves) { 109 | if (globalTimer <4109) { 110 | 111 | 112 | resetCube(); 113 | //pause = true; 114 | println("new cube", solveCounterThing, globalTimer); 115 | solveCounterThing++; 116 | } else { 117 | pause = true; 118 | println("Solved " + solveCounterThing + " rubik's cubes in " +(globalTimer/1000.0)+ " seconds"); 119 | println("averageTime = " + (float(globalTimer)/float(solveCounterThing))); 120 | } 121 | } else { 122 | pause = true; 123 | 124 | println("Solved in " +(globalTimer/1000.0)+ " seconds"); 125 | } 126 | return; 127 | } 128 | } 129 | } 130 | //edge stuff 131 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 132 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 133 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 134 | void doEdges() { 135 | color[][] colorOrder = {{red, blue}, {red, white}, {red, green}, {red, yellow}, {orange, blue}, {orange, white}, {orange, green}, {orange, yellow}, {white, green}, {yellow, green}, {blue, yellow}, {blue, white}}; 136 | for (int i = 0; i< colorOrder.length; i++) { 137 | if (!edgeFinished(colorOrder[i][0], colorOrder[i][1])) { 138 | solveEdge(colorOrder[i][0], colorOrder[i][1]); 139 | } 140 | if (moreTurns()) { 141 | return; 142 | } 143 | } 144 | 145 | 146 | 147 | //cube.rotationSpeed = PI/40.0; 148 | //setup(); 149 | //return; 150 | 151 | for (int i = 0; i< colorOrder.length; i++) { 152 | if (!edgeFinishedWithRotation(colorOrder[i][0], colorOrder[i][1])) { 153 | parityFixer(colorOrder[i][0], colorOrder[i][1]); 154 | return; 155 | } 156 | } 157 | 158 | 159 | 160 | largeCubeStageNo++; 161 | } 162 | 163 | void parityFixer(color c1, color c2) { 164 | Block middlePiece = getEdgePiece(c1, c2, middle); 165 | char f1 = middlePiece.getFace(c1); 166 | char f2 = middlePiece.getFace(c2); 167 | if (f1 != 'F') { 168 | String temp = getDirection(f1, 'F'); 169 | //println(f1, "F", temp); 170 | 171 | turns+=temp; 172 | //println("temp1 " + temp); 173 | if (moreTurns()) { 174 | //println("Turnes" + turns); 175 | return; 176 | } 177 | } 178 | if (f2!='U') { 179 | if (f2 == 'L') { 180 | turns+="Z'"; 181 | } 182 | if (f2 == 'D') { 183 | turns+="ZZ"; 184 | } 185 | if (f2 =='R') { 186 | 187 | turns+="Z"; 188 | } 189 | if (moreTurns()) { 190 | //println("Turnes" + turns); 191 | 192 | return; 193 | } 194 | } 195 | 196 | //so now its up and front 197 | Block[][] frontFace = cube.getFace('F'); 198 | ArrayList parityPositions = new ArrayList(); 199 | //get all the positions which are shit 200 | for (int i = 1; i< n-1; i++) { 201 | if (frontFace[i][0].getFace(c1) != f1) { 202 | parityPositions.add(i); 203 | } 204 | } 205 | 206 | //println("pairirir"); 207 | for (int i = 0; i parities, int axis, boolean clockwise, boolean left) { 240 | for (int i = 0; i< parities.size(); i++) { 241 | if (left && parities.get(i)middle) { 246 | //println("herherherherherherRIGHT"); 247 | 248 | turnOs.add(new TurnO(0, parities.get(i), !clockwise)); 249 | } 250 | } 251 | } 252 | 253 | void solveEdge(color c1, color c2) { 254 | color[] cols = {c1, c2}; 255 | Block edgeCenter = getEdgePiece(c1, c2, middle); 256 | 257 | if (!cube.blocks[n-1][middle][n-1].matchesColors(cols)) { 258 | //position front 259 | String edgeFaces = edgeCenter.getFaces(); 260 | turnOs.addAll(moveEdgeToFrontRight(edgeFaces.charAt(0), edgeFaces.charAt(1))); 261 | return; 262 | } 263 | 264 | //now center is in front right 265 | for (int i = 1; if2) { 335 | return c1; 336 | } else { 337 | return c2 ; 338 | } 339 | } else { 340 | if (f1 common = new ArrayList(); 453 | for (int i = 0; i< n; i++) { 454 | for (int j = 0; j< n; j++) { 455 | if (i==0 || i==n-1 || j==0 || j==n-1 ) { 456 | for (int k = 0; k common = new ArrayList(); 481 | for (int i = 0; i< n; i++) { 482 | for (int j = 0; j< n; j++) { 483 | if (i==0 || i==n-1 || j==0 || j==n-1 ) { 484 | for (int k = 0; k getEdgeFlippingTurns(char leftFace, char rightFace) { 517 | ArrayList t = new ArrayList(); 518 | //println(leftFace, rightFace); 519 | t.add(charToTurnO(rightFace, true)); 520 | t.add(charToTurnO(leftFace, false)); 521 | t.add(charToTurnO('U', true)); 522 | t.add(charToTurnO(rightFace, false)); 523 | t.add(charToTurnO(leftFace, true)); 524 | return t; 525 | } 526 | ArrayList getEdgeFlippingTurns() { 527 | ArrayList t = new ArrayList(); 528 | t.add(charToTurnO('R', true)); 529 | t.add(charToTurnO('F', false)); 530 | t.add(charToTurnO('U', true)); 531 | t.add(charToTurnO('R', false)); 532 | t.add(charToTurnO('F', true)); 533 | return t; 534 | } 535 | 536 | 537 | // STAGE 8L 538 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 539 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 540 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 541 | void finalCenters() { 542 | //cube.rotationSpeed = PI/20.0; 543 | 544 | for (int i = 1; i= n-1) { 637 | largeCubeStageNo++; 638 | } 639 | } 640 | 641 | void doYellowRow(int y) { 642 | switch(rowStage) { 643 | case 0: 644 | //println(0); 645 | turnOs.add(new TurnO(1, y, false)); //bring it out 646 | turnOs.add(charToTurnO('F', true)); 647 | rowStage++; 648 | return; 649 | 650 | case 1: 651 | //println(1); 652 | for (int i = middle-1; i> -middle; i--) { 653 | int xPos = n-1-y; 654 | if (!cube.blocks[xPos][middle-i][n-1].matchesColors(yellow)) { 655 | fillFaceGap('F', yellow, (xPos) - middle, i, 1, xPos, 4); 656 | } 657 | if (turnOs.size() >0 || turns.length()>0) { 658 | return; 659 | } 660 | } 661 | rowStage++; 662 | return; 663 | case 2: 664 | //println(2); 665 | turnOs.add(charToTurnO('F', false)); 666 | turnOs.add(new TurnO(1, y, true)); 667 | rowStage++; 668 | return; 669 | } 670 | } 671 | //this only works for y axis at the moment 672 | void fillFaceGap(char targetFace, color pieceColor, int xIndex, int yIndex, int axis, int rowNo, int faceNo) { 673 | 674 | String faces = "LRB"; 675 | if (faceNo ==3) { 676 | faces = "RB";//left is where we store shit 677 | } 678 | 679 | if (faceNo == 4) { 680 | faces = "R";//left is where we store shit 681 | } 682 | ArrayList adds = new ArrayList(); 683 | char faceChar = 'N'; 684 | boolean found = false; 685 | for (int i = 0; i< faces.length(); i++) { 686 | 687 | Block[][] face = cube.getFace(faces.charAt(i)); 688 | faceChar = faces.charAt(i); 689 | 690 | int xRel = xIndex; 691 | int yRel = yIndex; 692 | int xMatrix = middle+xRel; 693 | int yMatrix = middle-yRel; 694 | 695 | for (int j = 0; j< 4; j++) { 696 | if (face[xMatrix][yMatrix].matchesColors(pieceColor)) { 697 | for (int k = 0; k0) {//reverse the movements 721 | turnOs.add(adds.remove(adds.size()-1).getReverse()); 722 | } 723 | turnOs.add(charToTurnO('F', true));//get the thing back into its row 724 | } 725 | } 726 | 727 | if (faceNo ==4) { 728 | if (middle - yIndex == n-1-rowNo) { //need to turn other way 729 | turnOs.add(charToTurnO('F', true));//get the thing back into its row 730 | } else { 731 | turnOs.add(charToTurnO('F', false));//get the thing back into its row 732 | } 733 | while (adds.size() >0) {//reverse the movements 734 | turnOs.add(adds.remove(adds.size()-1).getReverse()); 735 | } 736 | if (middle - yIndex == n-1-rowNo) { //need to turn other way 737 | turnOs.add(charToTurnO('F', false));//get the thing back into its row 738 | } else { 739 | turnOs.add(charToTurnO('F', true));//get the thing back into its row 740 | } 741 | } 742 | 743 | 744 | 745 | 746 | return; 747 | } 748 | } 749 | 750 | 751 | 752 | //checked faces and none found 753 | //println("oi mate its fuckede"); 754 | //println(targetFace, pieceColor, xIndex, yIndex, axis, rowNo, faceNo); 755 | getToLRB(targetFace, pieceColor, xIndex, yIndex, axis, rowNo, faceNo); 756 | } 757 | 758 | 759 | //this only works for y axis at the moment 760 | void getToLRB(char targetFace, color pieceColor, int xIndex, int yIndex, int axis, int rowNo, int faceNo) { 761 | 762 | String faces = "DFU"; 763 | if (faceNo ==3) { 764 | faces = "FL"; 765 | } 766 | if (faceNo ==4) { 767 | faces = "FB"; 768 | } 769 | ArrayList adds = new ArrayList(); 770 | char faceChar = 'N'; 771 | int x = 0; 772 | int y =0; 773 | boolean found = false; 774 | for (int i = 0; i< faces.length(); i++) { 775 | Block[][] face = cube.getFace(faces.charAt(i)); 776 | faceChar = faces.charAt(i); 777 | 778 | int xRel = xIndex; 779 | int yRel = yIndex; 780 | int xMatrix = middle+xRel; 781 | int yMatrix = middle-yRel; 782 | 783 | for (int j = 0; j< 4; j++) { 784 | if (face[xMatrix][yMatrix].matchesColors(pieceColor)) { 785 | //println(faceChar, xMatrix, yMatrix); 786 | if (faceChar != 'L' || n-1-rowNo<= yMatrix) { 787 | if (faceChar == 'D') { 788 | if (!rowFinished('D', xMatrix, pieceColor)) { 789 | found = true; 790 | break; 791 | } else { 792 | int temp = xRel; 793 | xRel = yRel; 794 | yRel = -temp ; 795 | xMatrix = middle+xRel; 796 | yMatrix = middle-yRel; 797 | continue; 798 | } 799 | } 800 | if (faceChar != 'F' || xMatrix!=rowNo) { 801 | found = true; 802 | break; 803 | } 804 | } else { 805 | //println("here 782"); 806 | } 807 | } 808 | int temp = xRel; 809 | xRel = yRel; 810 | yRel = -temp ; 811 | xMatrix = middle+xRel; 812 | yMatrix = middle-yRel; 813 | } 814 | if (faceNo ==4) { 815 | if (found) { 816 | switch(faceChar) { 817 | case 'F': 818 | adds.add(charToTurnO('F', true)); 819 | int temp = xRel; 820 | xRel = yRel; 821 | yRel = -temp ; 822 | xMatrix = middle+xRel; 823 | yMatrix = middle-yRel; 824 | adds.add(new TurnO(1, yMatrix, false)); 825 | adds.add(charToTurnO('R', false)); 826 | if (yMatrix != middle) { 827 | adds.add(charToTurnO('R', false)); 828 | } 829 | adds.add(new TurnO(1, yMatrix, true)); 830 | adds.add(charToTurnO('F', false)); 831 | turnOs.addAll(adds); 832 | return; 833 | 834 | case 'B': 835 | adds.add(new TurnO(1, yMatrix, true)); 836 | adds.add(charToTurnO('R', false)); 837 | if (yMatrix != middle) { 838 | adds.add(charToTurnO('R', false)); 839 | } 840 | adds.add(new TurnO(1, yMatrix, false)); 841 | turnOs.addAll(adds); 842 | 843 | return; 844 | } 845 | } 846 | } 847 | 848 | if (faceNo ==3) { 849 | if (found) { 850 | switch(faceChar) { 851 | case 'F': 852 | adds.add(charToTurnO('F', true)); 853 | int temp = xRel; 854 | xRel = yRel; 855 | yRel = -temp ; 856 | xMatrix = middle+xRel; 857 | yMatrix = middle-yRel; 858 | adds.add(new TurnO(1, yMatrix, false)); 859 | adds.add(charToTurnO('R', false)); 860 | if (yMatrix != middle) { 861 | adds.add(charToTurnO('R', false)); 862 | } 863 | adds.add(new TurnO(1, yMatrix, true)); 864 | adds.add(charToTurnO('F', false)); 865 | turnOs.addAll(adds); 866 | return; 867 | case 'L': 868 | 869 | if (yRel == yIndex && xRel == xIndex) { 870 | //println("get it out", yRel, xRel); 871 | adds.add(new TurnO(1, yMatrix, false)); 872 | } else { 873 | adds.add(new TurnO(1, yMatrix, true)); 874 | adds.add(charToTurnO('B', false)); 875 | if (yMatrix!=middle) { 876 | adds.add(charToTurnO('B', false)); 877 | } 878 | adds.add(new TurnO(1, yMatrix, false)); 879 | } 880 | turnOs.addAll(adds); 881 | 882 | return; 883 | } 884 | } else { 885 | //println("not found and thats nor great"); 886 | } 887 | } else if (found) { 888 | switch(faceChar) { 889 | case 'F': 890 | adds.add(charToTurnO('F', true)); 891 | int temp = xRel; 892 | xRel = yRel; 893 | yRel = -temp ; 894 | xMatrix = middle+xRel; 895 | yMatrix = middle-yRel; 896 | adds.add(new TurnO(1, yMatrix, true)); 897 | adds.add(charToTurnO('F', false)); 898 | turnOs.addAll(adds); 899 | return; 900 | case 'U': 901 | if (faceNo ==2) { 902 | adds.add(charToTurnO('U', true)); 903 | temp = xRel; 904 | xRel = yRel; 905 | yRel = -temp ; 906 | xMatrix = middle+xRel; 907 | yMatrix = middle-yRel; 908 | } 909 | adds.add(new TurnO(2, yMatrix, true)); 910 | adds.add(charToTurnO('L', true)); 911 | adds.add(charToTurnO('L', true)); 912 | 913 | //adds.add(charToTurnO('L', true)); 914 | adds.add(new TurnO(2, yMatrix, false)); 915 | if (faceNo ==2) { 916 | adds.add(charToTurnO('U', false)); 917 | } 918 | turnOs.addAll(adds); 919 | return; 920 | 921 | case 'D': 922 | //println("<--------------------------------------------its down boi"); 923 | //cube.rotationSpeed = PI/50.0; 924 | adds.add(charToTurnO('D', true)); 925 | //adds.add(charToTurnO('L', true)); 926 | temp = xRel; 927 | xRel = yRel; 928 | yRel = -temp ; 929 | xMatrix = middle+xRel; 930 | yMatrix = middle-yRel; 931 | //adds.add(charToTurnO('L', true)); 932 | adds.add(new TurnO(2, n-1- yMatrix, false)); 933 | adds.add(charToTurnO('D', false)); 934 | turnOs.addAll(adds); 935 | return; 936 | } 937 | } 938 | } 939 | //println("FUCKUCKCUCKCUKCUCKCUC= n-1) { 964 | rowCounter =0; 965 | largeCubeStageNo++; 966 | } 967 | } 968 | 969 | void doRedRow(int y) { 970 | switch(rowStage) { 971 | case 0: 972 | //println(0); 973 | turnOs.add(new TurnO(1, y, false)); //bring it out 974 | turnOs.add(charToTurnO('F', true)); 975 | rowStage++; 976 | return; 977 | 978 | case 1: 979 | //println(1); 980 | for (int i = middle-1; i> -middle; i--) { 981 | int xPos = n-1-y; 982 | if (!cube.blocks[xPos][middle-i][n-1].matchesColors(red)) { 983 | fillFaceGap('F', red, (xPos) - middle, i, 1, xPos, 3); 984 | } 985 | if (turnOs.size() >0 || turns.length()>0) { 986 | return; 987 | } 988 | } 989 | rowStage++; 990 | return; 991 | case 2: 992 | //println(2); 993 | turnOs.add(charToTurnO('F', false)); 994 | turnOs.add(new TurnO(1, y, true)); 995 | rowStage++; 996 | return; 997 | } 998 | } 999 | 1000 | 1001 | 1002 | 1003 | // STAGE 2L 1004 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1005 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1006 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1007 | 1008 | void SecondCenter() { 1009 | //switch(rowUpTo) { 1010 | //case 0: 1011 | //if (!rowFinished('D', middle, green)) { 1012 | // doGreenRow(middle) ; 1013 | // if (turnOs.size()>0) { 1014 | // return; 1015 | // } 1016 | //} else { 1017 | //rowStage=0; 1018 | 1019 | 1020 | 1021 | if (!rowFinished('U', middle, blue)) { 1022 | 1023 | doMiddleBlueRow(); 1024 | return; 1025 | } 1026 | 1027 | //cube.rotationSpeed = PI/30.0; 1028 | 1029 | for (int i = 1; i< n-1; i++) { 1030 | if (i == middle) { 1031 | continue; 1032 | } 1033 | if (!rowFinished('U', i, blue)) { 1034 | doBlueRow(i); 1035 | return; 1036 | } else if (rowStage ==2) { 1037 | rowStage =0; 1038 | } 1039 | } 1040 | //} 1041 | 1042 | largeCubeStageNo++; 1043 | 1044 | //DOES MIDDLE ROWQ HEWAPS OF TIMES 1045 | 1046 | //rowUpTo ++; 1047 | //return; 1048 | //case 1: 1049 | 1050 | // doGreenRow(middle-1) ; 1051 | // if (turnOs.size()>0) { 1052 | // return; 1053 | // } 1054 | // //DOES MIDDLE ROWQ HEWAPS OF TIMES 1055 | // rowStage=0; 1056 | // rowUpTo ++; 1057 | // return; 1058 | } 1059 | //doGreenRow(middle-1) ; 1060 | 1061 | void doBlueRow(int x) { 1062 | switch(rowStage) { 1063 | 1064 | case 0: 1065 | //println("stage 0"); 1066 | for (int i = middle-1; i> -middle; i--) { 1067 | if (!cube.blocks[x][middle-i][n-1].matchesColors(blue)) { 1068 | fillFaceGap('F', blue, x-middle, i, 1, x, 2); 1069 | } 1070 | if (turnOs.size() >0 || turns.length()>0) { 1071 | return; 1072 | } 1073 | } 1074 | rowStage++; 1075 | return; 1076 | case 1: 1077 | //println("stage 1"); 1078 | boolean uppyUppy = false; 1079 | if (rowFinished('U', n-1-x, blue)) { 1080 | uppyUppy = true; 1081 | turnOs.add(charToTurnO('U', true)); 1082 | turnOs.add(charToTurnO('U', true)); 1083 | } 1084 | 1085 | turnOs.add(new TurnO(0, x, false)); 1086 | turnOs.add(charToTurnO('U', true)); 1087 | turnOs.add(charToTurnO('U', true)); 1088 | turnOs.add(new TurnO(0, x, true)); 1089 | 1090 | if (!uppyUppy) { 1091 | turnOs.add(charToTurnO('U', true)); 1092 | turnOs.add(charToTurnO('U', true)); 1093 | } 1094 | rowStage++; 1095 | return; 1096 | } 1097 | } 1098 | 1099 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1100 | // fillFaceGap('F', green, 0, 2, 1); 1101 | //} 1102 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1103 | // fillFaceGap('F', green, 0, 2, 1); 1104 | //} 1105 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1106 | // fillFaceGap('F', green, 0, 2, 1); 1107 | //} 1108 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1109 | // fillFaceGap('F', green, 0, 2, 1); 1110 | //} 1111 | //} 1112 | 1113 | void doMiddleBlueRow() { 1114 | for (int i = middle-1; i> -middle; i--) { 1115 | if (i == middle) { 1116 | continue; 1117 | } 1118 | if (!cube.blocks[middle][0][middle - i].matchesColors(blue)) { 1119 | 1120 | String faces = "LRBF"; 1121 | ArrayList adds = new ArrayList(); 1122 | char faceChar = 'N'; 1123 | boolean found = false; 1124 | for (int k = 0; k< faces.length(); k++) { 1125 | 1126 | Block[][] face = cube.getFace(faces.charAt(k)); 1127 | faceChar = faces.charAt(k); 1128 | 1129 | int xRel = 0; 1130 | int yRel = i; 1131 | int xMatrix = middle+xRel; 1132 | int yMatrix = middle-yRel; 1133 | 1134 | for (int j = 0; j< 4; j++) { 1135 | if (face[xMatrix][yMatrix].matchesColors(blue)) { 1136 | //println("found piece requires " + i + "face turns"); 1137 | ////println(f aceChar,); 1138 | for (int l = 0; l0) { 1197 | // return; 1198 | // } 1199 | //} else { 1200 | //rowStage=0; 1201 | 1202 | 1203 | if (!rowFinished('D', middle, green)) { 1204 | doGreenRow(middle); 1205 | return; 1206 | } else if (rowStage ==3) { 1207 | rowStage =0; 1208 | } 1209 | for (int i = 1; i< n-1; i++) { 1210 | if (i == middle) { 1211 | continue; 1212 | } 1213 | if (!rowFinished('D', i, green)) { 1214 | doGreenRow(i); 1215 | return; 1216 | } else if (rowStage ==3) { 1217 | rowStage =0; 1218 | } 1219 | } 1220 | //} 1221 | rowStage =0; 1222 | largeCubeStageNo++; 1223 | 1224 | //DOES MIDDLE ROWQ HEWAPS OF TIMES 1225 | 1226 | //rowUpTo ++; 1227 | //return; 1228 | //case 1: 1229 | 1230 | // doGreenRow(middle-1) ; 1231 | // if (turnOs.size()>0) { 1232 | // return; 1233 | // } 1234 | // //DOES MIDDLE ROWQ HEWAPS OF TIMES 1235 | // rowStage=0; 1236 | // rowUpTo ++; 1237 | // return; 1238 | } 1239 | //doGreenRow(middle-1) ; 1240 | 1241 | 1242 | 1243 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1244 | // fillFaceGap('F', green, 0, 2, 1); 1245 | //} 1246 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1247 | // fillFaceGap('F', green, 0, 2, 1); 1248 | //} 1249 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1250 | // fillFaceGap('F', green, 0, 2, 1); 1251 | //} 1252 | //if (!cube.blocks[middle][middle-2][n-1].matchesColors(green)) { 1253 | // fillFaceGap('F', green, 0, 2, 1); 1254 | //} 1255 | //} 1256 | 1257 | void doGreenRow(int x) { 1258 | switch(rowStage) { 1259 | case 0: 1260 | //println("stage 0"); 1261 | turnOs.add(new TurnO(0, x, false)); 1262 | rowStage++; 1263 | return; 1264 | case 1: 1265 | //println("stage 1"); 1266 | for (int i = middle-1; i> -middle; i--) { 1267 | if (!cube.blocks[x][middle-i][n-1].matchesColors(green)) { 1268 | fillFaceGap('F', green, x-middle, i, 1, x); 1269 | } 1270 | if (turnOs.size() >0 || turns.length()>0) { 1271 | return; 1272 | } 1273 | } 1274 | rowStage++; 1275 | return; 1276 | case 2: 1277 | //println("stage 2"); 1278 | turnOs.add(new TurnO(0, x, true)); 1279 | rowStage++; 1280 | return; 1281 | } 1282 | } 1283 | //this only works for y axis at the moment 1284 | void fillFaceGap(char targetFace, color pieceColor, int xIndex, int yIndex, int axis, int rowNo) { 1285 | 1286 | String faces = "LRB"; 1287 | ArrayList adds = new ArrayList(); 1288 | char faceChar = 'N'; 1289 | boolean found = false; 1290 | for (int i = 0; i< faces.length(); i++) { 1291 | 1292 | Block[][] face = cube.getFace(faces.charAt(i)); 1293 | faceChar = faces.charAt(i); 1294 | 1295 | int xRel = xIndex; 1296 | int yRel = yIndex; 1297 | int xMatrix = middle+xRel; 1298 | int yMatrix = middle-yRel; 1299 | 1300 | for (int j = 0; j< 4; j++) { 1301 | if (face[xMatrix][yMatrix].matchesColors(pieceColor)) { 1302 | //println("found piece requires " + i + "face turns"); 1303 | ////println(f aceChar,); 1304 | for (int k = 0; k adds = new ArrayList(); 1338 | char faceChar = 'N'; 1339 | int x = 0; 1340 | int y =0; 1341 | boolean found = false; 1342 | for (int i = 0; i< faces.length(); i++) { 1343 | 1344 | Block[][] face = cube.getFace(faces.charAt(i)); 1345 | faceChar = faces.charAt(i); 1346 | 1347 | 1348 | int xRel = xIndex; 1349 | int yRel = yIndex; 1350 | int xMatrix = middle+xRel; 1351 | int yMatrix = middle-yRel; 1352 | 1353 | for (int j = 0; j< 4; j++) { 1354 | if (face[xMatrix][yMatrix].matchesColors(pieceColor)) { 1355 | ////println(f aceChar,); 1356 | 1357 | if (faceChar == 'D') { 1358 | 1359 | if (!rowFinished('D', xMatrix, green) || xRel == xIndex ) { 1360 | //println("its NICEEEEEEEEE"); 1361 | 1362 | found = true; 1363 | break; 1364 | } else { 1365 | //println("its hererererereerer"); 1366 | int temp = xRel; 1367 | xRel = yRel; 1368 | yRel = -temp ; 1369 | xMatrix = middle+xRel; 1370 | yMatrix = middle-yRel; 1371 | continue; 1372 | } 1373 | } 1374 | if (faceChar != 'F' || xMatrix!=rowNo) { 1375 | found = true; 1376 | break; 1377 | } 1378 | } 1379 | int temp = xRel; 1380 | xRel = yRel; 1381 | yRel = -temp ; 1382 | xMatrix = middle+xRel; 1383 | yMatrix = middle-yRel; 1384 | } 1385 | 1386 | 1387 | if (found) { 1388 | switch(faceChar) { 1389 | case 'F': 1390 | adds.add(charToTurnO('F', true)); 1391 | int temp = xRel; 1392 | xRel = yRel; 1393 | yRel = -temp ; 1394 | xMatrix = middle+xRel; 1395 | yMatrix = middle-yRel; 1396 | adds.add(new TurnO(1, yMatrix, true)); 1397 | adds.add(charToTurnO('F', false)); 1398 | turnOs.addAll(adds); 1399 | return; 1400 | case 'U': 1401 | adds.add(new TurnO(2, yMatrix, true)); 1402 | adds.add(charToTurnO('L', true)); 1403 | //adds.add(charToTurnO('L', true)); 1404 | adds.add(new TurnO(2, yMatrix, false)); 1405 | turnOs.addAll(adds); 1406 | return; 1407 | 1408 | case 'D': 1409 | //println("its here boiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"); 1410 | //cube.rotationSpeed = PI/50.0; 1411 | adds.add(charToTurnO('D', true)); 1412 | //adds.add(charToTurnO('L', true)); 1413 | temp = xRel; 1414 | xRel = yRel; 1415 | yRel = -temp ; 1416 | xMatrix = middle+xRel; 1417 | yMatrix = middle-yRel; 1418 | //adds.add(charToTurnO('L', true)); 1419 | adds.add(new TurnO(2, n-1- yMatrix, false)); 1420 | adds.add(charToTurnO('D', false)); 1421 | turnOs.addAll(adds); 1422 | return; 1423 | } 1424 | } else { 1425 | //println("offfofofofofofofofofofofo"); 1426 | //pause = true; 1427 | } 1428 | } 1429 | 1430 | 1431 | 1432 | // if (face[middle-xIndex][middle-yIndex].matchesColors(pieceColor)) { 1433 | // x = xIndex; 1434 | // y = yIndex; 1435 | // if (faceChar != 'F' || x!=rowNo-middle) { 1436 | // break; 1437 | // } 1438 | // } 1439 | // if (face[middle-yIndex][middle+xIndex].matchesColors(pieceColor)) { 1440 | // x = yIndex; 1441 | // y = -xIndex; 1442 | // if (faceChar != 'F' || x!=rowNo-middle) { 1443 | // break; 1444 | // } 1445 | // } 1446 | // if (face[middle+xIndex][middle+yIndex].matchesColors(pieceColor)) { 1447 | // x = -xIndex; 1448 | // y = -yIndex; 1449 | // if (faceChar != 'F' || x!=rowNo-middle) { 1450 | // break; 1451 | // } 1452 | // } 1453 | // if (face[middle+yIndex][middle-xIndex].matchesColors(pieceColor)) { 1454 | // x = -yIndex; 1455 | // y = xIndex; 1456 | // if (faceChar != 'F' || x!=rowNo-middle) { 1457 | // break; 1458 | // } 1459 | // } 1460 | // } 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | //so now face is in the desired spot but its on a different face 1467 | //adds.addAll(getTurnObjects(faceChar, targetFace, middle-yIndex, axis)); 1468 | //turnOs.addAll(adds); 1469 | ////printTurnos(); 1470 | } 1471 | 1472 | 1473 | boolean rowFinished(char face, int index, color col ) { 1474 | Block[][] facePieces = cube.getFace(face); 1475 | 1476 | for (int i = 1; i< n-1; i++) { 1477 | if (!facePieces[index][i].matchesColors(col)) { 1478 | return false; 1479 | } 1480 | } 1481 | return true; 1482 | } 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | // STAGE 6 1489 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1490 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1491 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1492 | void finalRotations() { 1493 | if (!(getFaceColor('D') == blue)) { 1494 | positionFace(blue, 'D', 'X'); 1495 | return; 1496 | } 1497 | //now blue is down 1498 | if (correctRotation(cube.blocks[n-1][n-1][n-1])) { 1499 | if (turnsDone==4) { 1500 | ////println("FUCK you I did it"); 1501 | stageNo++; 1502 | return; 1503 | } else { 1504 | turns+="D"; 1505 | turnsDone++; 1506 | return; 1507 | } 1508 | } else { 1509 | turns += "RUR'U'RUR'U'"; 1510 | return; 1511 | } 1512 | } 1513 | 1514 | boolean correctRotation(Block piece) { 1515 | return(piece.colors[3] == blue); 1516 | } 1517 | 1518 | // STAGE 5 1519 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1520 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1521 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1522 | void getCornersInCorrectPositions() { 1523 | int correctCounter = 0; 1524 | Block correctPiece = cube.blocks[0][0][0]; 1525 | 1526 | Block testPiece = cube.blocks[0][0][0]; 1527 | ////println("enteringthe thing"); 1528 | 1529 | if (cornerInCorrectPosition('L', 'U', 'B', testPiece)) { 1530 | correctCounter ++; 1531 | } 1532 | testPiece = cube.blocks[n-1][0][0]; 1533 | if (cornerInCorrectPosition('R', 'U', 'B', testPiece)) { 1534 | correctCounter ++; 1535 | correctPiece = cube.blocks[n-1][0][0]; 1536 | } 1537 | 1538 | testPiece = cube.blocks[n-1][0][n-1]; 1539 | if (cornerInCorrectPosition('R', 'U', 'F', testPiece)) { 1540 | correctCounter ++; 1541 | correctPiece = cube.blocks[n-1][0][n-1]; 1542 | } 1543 | 1544 | testPiece = cube.blocks[0][0][n-1]; 1545 | if (cornerInCorrectPosition('L', 'U', 'F', testPiece)) { 1546 | correctCounter ++; 1547 | correctPiece = cube.blocks[0][0][n-1]; 1548 | } 1549 | 1550 | if (correctCounter ==4) { 1551 | ////println("allgbro"); 1552 | stageNo++; 1553 | return; 1554 | } 1555 | 1556 | if (correctCounter ==0) { 1557 | ////println("none of them are good mate"); 1558 | turns += "URU'L'UR'U'L"; 1559 | return; 1560 | } 1561 | 1562 | 1563 | //only one is correct 1564 | ////println("only one is tops aye"); 1565 | String temp =getDirectionsCorners(correctPiece.pos, new PVector(n-1, 0, n-1)); 1566 | ////println("temp:" + temp); 1567 | turns+=temp; 1568 | turns+="URU'L'UR'U'L"; 1569 | turns += reverseDirections(temp); 1570 | ////println("reverse Temp:" + reverseDirections(temp)); 1571 | } 1572 | 1573 | 1574 | boolean cornerInCorrectPosition(char face1, char face2, char face3, Block piece) { 1575 | 1576 | color c1 = getFaceColor(face1); 1577 | color c2 = getFaceColor(face2); 1578 | color c3 = getFaceColor(face3); 1579 | 1580 | 1581 | if (piece.getFace(c1) == ' ') { 1582 | return false; 1583 | } else { 1584 | 1585 | ////println((piece.getFace(c1))); 1586 | } 1587 | if (piece.getFace(c2) == ' ') { 1588 | return false; 1589 | } else { 1590 | 1591 | ////println((piece.getFace(c2))); 1592 | } 1593 | if (piece.getFace(c3) == ' ') { 1594 | return false; 1595 | } else { 1596 | 1597 | ////println((piece.getFace(c3))); 1598 | } 1599 | return true; 1600 | } 1601 | 1602 | // STAGE 4 1603 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1604 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1605 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1606 | 1607 | void finishTopCross() { 1608 | 1609 | if (!(getFaceColor('F') == red)) { 1610 | positionFace(red, 'F', 'Y'); 1611 | return; 1612 | } 1613 | 1614 | color[] order = {orange, yellow, red, white, orange, yellow, red, white, orange, yellow}; 1615 | 1616 | color[] currentOrder = { 1617 | cube.blocks[middle][0][0].colors[4], //add back color 1618 | cube.blocks[n-1][0][middle].colors[1], //right face 1619 | cube.blocks[middle][0][n-1].colors[5], //front face 1620 | cube.blocks[0][0][middle].colors[0], //left face 1621 | cube.blocks[middle][0][0].colors[4] //add back color again 1622 | 1623 | }; 1624 | 1625 | //also need to check if the order is already correct 1626 | for (int i = 0; i< order.length - 4; i++) { 1627 | boolean perfectMatch = true; 1628 | for (int j = 0; j<4; j++) { 1629 | if (order[i+j] != currentOrder[j]) { 1630 | perfectMatch = false; 1631 | } 1632 | } 1633 | if (perfectMatch) { 1634 | for (int k = 0; k < i%4; k++) { 1635 | turns+="U"; 1636 | } 1637 | stageNo++; 1638 | 1639 | return; 1640 | } 1641 | } 1642 | 1643 | for (int i = 0; i< order.length - 4; i++) { 1644 | boolean previousMatched = false; 1645 | for (int j = 0; j<5; j++) { 1646 | if (order[i+j] == currentOrder[j]) { 1647 | if (previousMatched) { 1648 | //foundPair 1649 | //for each i rotate U 1650 | for (int k = 0; k < i%4; k++) { 1651 | turns+="U"; 1652 | } 1653 | for (int k = 0; k< (i-1+j)%4; k++) { 1654 | turns+="Y'"; 1655 | } 1656 | 1657 | turns+= "RUR'URUUR'U"; 1658 | stageNo++; 1659 | return; 1660 | } else { 1661 | previousMatched = true; 1662 | } 1663 | } else { 1664 | previousMatched = false; 1665 | } 1666 | } 1667 | } 1668 | turns+= "RUR'URUUR'"; 1669 | return; 1670 | } 1671 | // STAGE 3 1672 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1673 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1674 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1675 | 1676 | void positionTopCross() { 1677 | int numberOfBlueEdgesOnTop = 0; 1678 | //back,front,left, right 1679 | boolean[] topBlueEdges={cube.blocks[middle][0][0].colors[2] == blue, cube.blocks[middle][0][n-1].colors[2] == blue, cube.blocks[0][0][middle].colors[2] == blue, cube.blocks[n-1][0][middle].colors[2] == blue}; 1680 | for (int i = 0; i< 4; i++) { 1681 | if (topBlueEdges[i]) { 1682 | numberOfBlueEdgesOnTop ++; 1683 | } 1684 | } 1685 | 1686 | //case 1 cross is already formed 1687 | if (numberOfBlueEdgesOnTop == 4) { 1688 | stageNo ++; 1689 | return; 1690 | } 1691 | 1692 | //case 2 line on top 1693 | 1694 | if (topBlueEdges[0] && topBlueEdges[1]) { 1695 | turns+= "UFRUR'U'F'"; 1696 | return; 1697 | } 1698 | 1699 | if (topBlueEdges[2] && topBlueEdges[3] ) { 1700 | turns+= "FRUR'U'F'"; 1701 | return; 1702 | } 1703 | 1704 | //case 3 just a dot on top 1705 | if (numberOfBlueEdgesOnTop ==0) { 1706 | //this should convert it to case 4 1707 | turns+= "FRUR'U'F'"; 1708 | return; 1709 | } 1710 | 1711 | //case 4 a little L 1712 | //first positionL to top left 1713 | if (!topBlueEdges[0] && topBlueEdges[2]) { 1714 | turns+="U"; 1715 | } else if (topBlueEdges[0] && !topBlueEdges[2]) { 1716 | turns+="U'"; 1717 | } else if (!topBlueEdges[0] && !topBlueEdges[2]) { 1718 | turns+="UU"; 1719 | } 1720 | turns += "FRUR'U'RUR'U'F'"; 1721 | } 1722 | 1723 | 1724 | 1725 | // STAGE 2 1726 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1727 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1728 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1729 | void finishBottom2Rows() { 1730 | color[][] colorOrder = {{red, yellow}, {yellow, orange}, {orange, white}, {white, red}}; 1731 | while (completedEdges<4) { 1732 | positionMiddleEdge(colorOrder[completedEdges][0], colorOrder[completedEdges][1]); 1733 | if (turns.length() > 0) { 1734 | return; 1735 | } 1736 | completedEdges++; 1737 | //////println("Next edge"); 1738 | } 1739 | stageNo++; 1740 | } 1741 | //--------------------------------------------------------------------------------------------------------------------------------------------------------- 1742 | void positionMiddleEdge(color c1, color c2) { 1743 | //c1 should be to the left of c2 when green is down 1744 | 1745 | 1746 | 1747 | color[] cols = {c1, c2}; 1748 | Block piece = findCenterEdge(cols); 1749 | if (piece.pos.y ==0) {//top layer 1750 | //////println("edge in top layer"); 1751 | color frontColor; 1752 | if (piece.colors[2] == c1) { 1753 | frontColor = c2; 1754 | } else { 1755 | frontColor = c1; 1756 | } 1757 | 1758 | if (getFaceColor('F') != frontColor) { 1759 | positionFace(frontColor, 'F', 'Y'); 1760 | //////println("turning to face"); 1761 | 1762 | return; 1763 | } 1764 | 1765 | //////println("facing correct direction"); 1766 | String temp = getDirectionsEdges(piece.pos, new PVector(middle, 0, n-1)); 1767 | if (!temp.equals("")) { 1768 | //////println("positioning edge:" + temp); 1769 | turns+=temp; 1770 | return; 1771 | } 1772 | //now the piece is in the top center 1773 | 1774 | //////println("piece in top center"); 1775 | if (frontColor == c1) {//need to put it in the right 1776 | turns += "URU'R'U'F'UF"; 1777 | } else { 1778 | turns += "U'L'ULUFU'F'"; 1779 | } 1780 | } else if (piece.pos.y ==middle) { 1781 | 1782 | //////println("edge in second layer"); 1783 | boolean inCorrectSpotAndRotation = true; 1784 | if (piece.colors[2] == c1) { 1785 | color frontColor = c2; 1786 | inCorrectSpotAndRotation = (pvectorsEqual(piece.pos, new PVector(0, middle, n-1)) && piece.colors[5] == getFaceColor('F')); 1787 | } else { 1788 | color frontColor = c1; 1789 | inCorrectSpotAndRotation = (pvectorsEqual(piece.pos, new PVector(n-1, middle, n-1)) && piece.colors[5] == getFaceColor('F')); 1790 | } 1791 | 1792 | 1793 | if (!inCorrectSpotAndRotation) { 1794 | //then its not in the right position 1795 | //take it out 1796 | //////println("edge in wrong spot direction"); 1797 | 1798 | turnCubeToFacePiece(piece, c1, 'Y') ; 1799 | if (turns.length() !=0) { 1800 | //////println("turning cube"); 1801 | return; 1802 | } 1803 | 1804 | //////println("get that shit out of here"); 1805 | 1806 | if (piece.pos.x == n-1) { 1807 | turns += "URU'R'U'F'UF"; 1808 | } else { 1809 | turns += "U'L'ULUFU'F'"; 1810 | } 1811 | } 1812 | } 1813 | } 1814 | 1815 | // STAGE 1 1816 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1817 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1818 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1819 | 1820 | void positionBottomCorners() { 1821 | color[][] colorOrder = {{red, yellow}, {yellow, orange}, {orange, white}, {white, red}}; 1822 | while (completedCorners<4) { 1823 | positionCornerAtBottom(colorOrder[completedCorners][0], colorOrder[completedCorners][1]); 1824 | if (turns.length() > 0) { 1825 | return; 1826 | } 1827 | completedCorners++; 1828 | } 1829 | stageNo++; 1830 | } 1831 | 1832 | 1833 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1834 | 1835 | 1836 | void positionCornerAtBottom(color c1, color c2) { 1837 | //c1 should be to the left of c2 when green is down 1838 | 1839 | 1840 | 1841 | color[] cols = {c1, c2, green}; 1842 | Block piece = findCornerPiece(cols); 1843 | if (!(getFaceColor('F') == c1)) { 1844 | positionFace(c1, 'F', 'Y'); 1845 | return; 1846 | } 1847 | 1848 | if (piece.pos.y ==0) {//top layer 1849 | String temp = getDirectionsCorners(piece.pos, new PVector(n-1, 0, n-1)); 1850 | if (!temp.equals("")) { 1851 | turns+=temp; 1852 | return; 1853 | } 1854 | //now the piece is in the top right 1855 | if (piece.colors[5] == green) { 1856 | turns+= "URU'R'"; 1857 | } else if (piece.colors[5] == c1) { 1858 | turns += "RUR'U'"; 1859 | } else if (piece.colors[5] == c2) { 1860 | turns += "RUUR'U'RUR'"; 1861 | } 1862 | //done 1863 | } else if (piece.pos.y == n-1) { 1864 | if (!pvectorsEqual(piece.pos, new PVector(n-1, n-1, n-1)) || piece.colors[3] != green) { 1865 | //then its not in the right position 1866 | //take it out 1867 | String temp = getDirectionsCorners(piece.pos, new PVector(n-1, n-1, n-1)); 1868 | turns+= temp; 1869 | ////////println("temp:" + temp); 1870 | turns+= "RUR'"; 1871 | turns += reverseDirections(temp); 1872 | } 1873 | } 1874 | } 1875 | 1876 | // STAGE 0 1877 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1878 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1879 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1880 | void greenCross() { 1881 | if (!(getFaceColor('D') == green)) { 1882 | ////////println("Shit man"); 1883 | positionFace(green, 'D', 'X'); 1884 | return; 1885 | } 1886 | 1887 | if (turns.length() != 0) { 1888 | return; 1889 | } 1890 | positionGreenCrossColor(red); 1891 | if (turns.length() != 0) { 1892 | return; 1893 | } 1894 | positionGreenCrossColor(orange); 1895 | if (turns.length() != 0) { 1896 | return; 1897 | } 1898 | positionGreenCrossColor(yellow); 1899 | if (turns.length() != 0) { 1900 | return; 1901 | } 1902 | positionGreenCrossColor(white); 1903 | if (turns.length() == 0) { 1904 | stageNo++; 1905 | } 1906 | } 1907 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1908 | 1909 | void positionGreenCrossColor(color col) { 1910 | color[] colors = {col, green}; 1911 | Block piece = findCenterEdge(colors); 1912 | if (piece.pos.y==n-1) { 1913 | if (piece.getFace(green) == 'D') { 1914 | if (getFaceColor(piece.getFace(col)) != col) {//if not inright place 1915 | char faceToTurn = piece.getFace(col); 1916 | turns += "" + faceToTurn+faceToTurn; 1917 | } 1918 | return;//ignore piece for now 1919 | } 1920 | //piece is on the bottom layer with green facing up 1921 | char pieceFace =piece.getFace(green); 1922 | String temp = getDirection(pieceFace, 'F'); 1923 | if (temp.length() ==2 && temp.charAt(0) == temp.charAt(1)) { 1924 | temp = "YY"; 1925 | } 1926 | turns+=temp; 1927 | //now the piece we want is at the bottom front edge 1928 | turns+= "FF";//chuck it at the top 1929 | return; 1930 | } 1931 | if (piece.pos.y==middle) {//if in the middle row 1932 | 1933 | turnCubeToFacePiece(piece, green, 'Y'); 1934 | if (turns.length() > 0) { 1935 | return; 1936 | } 1937 | 1938 | if (piece.pos.x ==0) { 1939 | turns+= "L'U'L"; 1940 | } else { 1941 | turns += "RUR'"; 1942 | } 1943 | } 1944 | if (piece.pos.y==0) {//if in the top row 1945 | ////////println("y=0"); 1946 | 1947 | if (getFaceColor('F') != col) { 1948 | positionFace(col, 'F', 'Y');//face the desired color to the front 1949 | return; 1950 | } 1951 | if (piece.getFace(green) == 'F') { 1952 | turns+="ULF'L'"; 1953 | } else if (piece.getFace(col) == 'F') { 1954 | turns+= "FF"; 1955 | } else { 1956 | char pieceFace =piece.getFace(col); 1957 | if (pieceFace =='U') { 1958 | pieceFace = piece.getFace(green); 1959 | } 1960 | 1961 | String temp = getTurns(pieceFace, 'F', 0); 1962 | temp = replaceDoubles(temp, 'U'); 1963 | ////////println(pieceFace, turns); 1964 | 1965 | turns +=temp; 1966 | } 1967 | } 1968 | } 1969 | 1970 | // HELPER FUNCTIONS 1971 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1972 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1973 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 1974 | 1975 | 1976 | color getFaceColor(char face) { 1977 | int middle = numberOfSides/2; 1978 | int last = numberOfSides-1; 1979 | switch( face) { 1980 | case 'D': 1981 | return(cube.blocks[middle][last][middle].colors[3]); 1982 | case 'U': 1983 | return(cube.blocks[middle][0][middle].colors[2]); 1984 | case 'L': 1985 | return(cube.blocks[0][middle][middle].colors[0]); 1986 | case 'R': 1987 | return(cube.blocks[last][middle][middle].colors[1]); 1988 | case 'F': 1989 | return(cube.blocks[middle][middle][last].colors[5]); 1990 | case 'B': 1991 | return(cube.blocks[middle][middle][0].colors[4]); 1992 | } 1993 | return color(0); 1994 | } 1995 | 1996 | 1997 | char getFaceGivenColor(color col) { 1998 | String faces = "UDLRFB"; 1999 | for (int i = 0; i< 6; i++) { 2000 | if (getFaceColor(faces.charAt(i)) == col) { 2001 | return faces.charAt(i); 2002 | } 2003 | } 2004 | return ' '; 2005 | } 2006 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | Block findCenterEdge(color[] pieceColors) { 2013 | for (int i = 0; i< edgeCenters.length; i++) { 2014 | PVector vec = edgeCenters[i]; 2015 | int x = (int)vec.x; 2016 | int y = (int)vec.y; 2017 | int z = (int)vec.z; 2018 | 2019 | if (cube.blocks[x][y][z].matchesColors(pieceColors)) { 2020 | return cube.blocks[x][y][z];//new PVector(i, j, k); 2021 | } 2022 | } 2023 | return null; 2024 | } 2025 | 2026 | Block findCornerPiece(color[] pieceColors) { 2027 | 2028 | for (int i = 0; i< numberOfSides; i+=n-1) { 2029 | for (int j = 0; j< numberOfSides; j+=n-1) { 2030 | for (int k = 0; k< numberOfSides; k+=n-1) { 2031 | if (cube.blocks[i][j][k].matchesColors(pieceColors)) { 2032 | return cube.blocks[i][j][k];//new PVector(i, j, k); 2033 | } 2034 | } 2035 | } 2036 | } 2037 | 2038 | return null; 2039 | } 2040 | 2041 | 2042 | 2043 | Block findPiece(color[] pieceColors) { 2044 | 2045 | for (int i = 0; i< numberOfSides; i++) { 2046 | for (int j = 0; j< numberOfSides; j++) { 2047 | for (int k = 0; k< numberOfSides; k++) { 2048 | if (cube.blocks[i][j][k].matchesColors(pieceColors)) { 2049 | return cube.blocks[i][j][k];//new PVector(i, j, k); 2050 | } 2051 | } 2052 | } 2053 | } 2054 | 2055 | return null; 2056 | } 2057 | 2058 | //ok so you only need to define a face piece by the position relative to the center in the 1st (top right) quadrant 2059 | // for example the very top right face piece on a 7x7 cube would be x =2 y = 2 2060 | Block findFacePiece(color pieceColor, int xIndex, int yIndex ) { 2061 | xIndex += middle; 2062 | yIndex += middle; 2063 | String faces = "LRUDFB"; 2064 | for (int i = 0; i< faces.length(); i++) { 2065 | 2066 | Block[][] face = cube.getFace(faces.charAt(i)); 2067 | 2068 | 2069 | if (face[xIndex][yIndex].matchesColors(pieceColor)) { 2070 | return face[xIndex][yIndex]; 2071 | } 2072 | if (face[yIndex][-xIndex].matchesColors(pieceColor)) { 2073 | return face[yIndex][-xIndex]; 2074 | } 2075 | if (face[-xIndex][-yIndex].matchesColors(pieceColor)) { 2076 | return face[-xIndex][-yIndex]; 2077 | } 2078 | if (face[-yIndex][xIndex].matchesColors(pieceColor)) { 2079 | return face[-yIndex][xIndex]; 2080 | } 2081 | } 2082 | 2083 | 2084 | return null; 2085 | } 2086 | 2087 | 2088 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2089 | 2090 | void scramble() { 2091 | stageNo = 0; 2092 | completedCorners = 0; 2093 | completedEdges = 0; 2094 | turnsDone = 0; 2095 | 2096 | 2097 | if (n>3) { 2098 | for (int i = 0; i< 15 * n; i++) { 2099 | turnOs.add(new TurnO()); 2100 | } 2101 | } else { 2102 | String options = "LRUDFBLRUDFBLRUDFBXYZ"; 2103 | for (int i = 0; i< 50; i++) { 2104 | turns += options.charAt(floor(random(options.length()))); 2105 | } 2106 | } 2107 | } 2108 | 2109 | //positions 2110 | 2111 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2112 | 2113 | void positionFace(color col, char face, char turnDirectionThatWontFuckShitUp) { 2114 | 2115 | String faces = "UDLRFB"; 2116 | char fromFace = 'F'; 2117 | for (int i = 0; i< faces.length(); i++) { 2118 | if (getFaceColor(faces.charAt(i)) == col) { 2119 | fromFace = faces.charAt(i); 2120 | break; 2121 | } 2122 | } 2123 | 2124 | String temp = getDirection(fromFace, face); 2125 | if (temp.length() ==2 && temp.charAt(0) == temp.charAt(1)) { 2126 | temp = "" + turnDirectionThatWontFuckShitUp + turnDirectionThatWontFuckShitUp; 2127 | } 2128 | 2129 | turns+=temp; 2130 | } 2131 | 2132 | 2133 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2134 | 2135 | 2136 | String replaceDoubles(String temp, char turnDirectionThatWontFuckShitUp) { 2137 | if (temp.length() ==2 && temp.charAt(0) == temp.charAt(1)) { 2138 | temp = "" + turnDirectionThatWontFuckShitUp + turnDirectionThatWontFuckShitUp; 2139 | } 2140 | return temp; 2141 | } 2142 | 2143 | 2144 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2145 | 2146 | void turnCubeToFacePiece(Block piece, color col, char turnDirectionThatWontFuckShitUp) { 2147 | char pieceFace =piece.getFace(col); 2148 | String temp = getDirection(pieceFace, 'F'); 2149 | if (temp.length() ==2 && temp.charAt(0) == temp.charAt(1)) { 2150 | temp = "" + turnDirectionThatWontFuckShitUp + turnDirectionThatWontFuckShitUp; 2151 | } 2152 | turns +=temp; 2153 | } 2154 | 2155 | //----------------------------------------------------------------------------------------------------------------------------------------------------------------- 2156 | 2157 | Block getCorner(char face1, char face2, char face3) { 2158 | color[] cols = {getFaceColor(face1), getFaceColor(face2), getFaceColor(face3)}; 2159 | return findCornerPiece(cols); 2160 | } 2161 | 2162 | 2163 | 2164 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 2165 | 2166 | 2167 | TurnO charToTurnO(char c, boolean clockwise) { 2168 | //println(c); 2169 | int axis =0; 2170 | int index=0; 2171 | switch(c) { 2172 | case 'D': 2173 | axis = 1; 2174 | index = n-1; 2175 | clockwise = !clockwise; 2176 | break; 2177 | case 'U': 2178 | axis = 1; 2179 | break; 2180 | case 'L': 2181 | break; 2182 | case 'R': 2183 | index = n-1; 2184 | clockwise = !clockwise; 2185 | break; 2186 | case 'F': 2187 | axis = 2; 2188 | index = n-1; 2189 | clockwise = !clockwise; 2190 | break; 2191 | case 'B': 2192 | axis = 2; 2193 | break; 2194 | } 2195 | 2196 | return new TurnO(axis, index, clockwise); 2197 | } 2198 | } 2199 | -------------------------------------------------------------------------------- /RubixCube/FUCKYOU.pde: -------------------------------------------------------------------------------- 1 | String XRotation = "FDBU"; 2 | String YRotation = "FLBR";//'F', 'R', 'B', 'R'}; 3 | String ZRotation = "LDRB";//{'L', 'D', 'R', 'B'}; 4 | 5 | ArrayList getTurnObjects(char fromFace, char toFace, int index, int idealAxis) { 6 | int fromIndex = XRotation.indexOf(fromFace); 7 | int toIndex = XRotation.indexOf(toFace); 8 | if (fromIndex != -1 && toIndex !=-1) { 9 | return foundRotationGimmeObj(fromIndex, toIndex, index, 0, idealAxis); 10 | } 11 | fromIndex = YRotation.indexOf(fromFace); 12 | toIndex = YRotation.indexOf(toFace); 13 | if (fromIndex != -1 && toIndex !=-1) { 14 | return foundRotationGimmeObj(fromIndex, toIndex, index, 1, idealAxis); 15 | } 16 | fromIndex = ZRotation.indexOf(fromFace); 17 | toIndex = ZRotation.indexOf(toFace); 18 | if (fromIndex != -1 && toIndex !=-1) { 19 | return foundRotationGimmeObj(fromIndex, toIndex, index, 2, idealAxis); 20 | } 21 | return null; 22 | } 23 | 24 | //move edge to front left if not alreay in the middle row 25 | ArrayList moveEdgeToFrontLeft(char face1, char face2) { 26 | ArrayList returnList = new ArrayList(); 27 | String middleRowFaces = "FRBL"; 28 | boolean face1Middle = middleRowFaces.indexOf(face1) != -1; 29 | boolean face2Middle = middleRowFaces.indexOf(face2) != -1; 30 | 31 | if (face1Middle && face2Middle) { 32 | return new ArrayList(); 33 | } 34 | char nonMidFace = face1; 35 | char midFace = face2; 36 | if (face1Middle) { 37 | nonMidFace = face2; 38 | midFace = face1; 39 | } 40 | int yIndex = 0; 41 | if (nonMidFace == 'D') { 42 | yIndex = n-1; 43 | } 44 | 45 | returnList.addAll(getTurnObjects(midFace, 'L', yIndex, 1)); 46 | 47 | 48 | if (nonMidFace == 'D') { 49 | returnList.add(new TurnO(0, 0, false)); 50 | } else { 51 | returnList.add(new TurnO(0, 0, true)); 52 | } 53 | return returnList; 54 | } 55 | 56 | 57 | 58 | //move edge to front right 59 | ArrayList moveEdgeToFrontRight(char face1, char face2) { 60 | 61 | ArrayList returnList = new ArrayList(); 62 | String middleRowFaces = "FRBL"; 63 | boolean face1Middle = middleRowFaces.indexOf(face1) != -1; 64 | boolean face2Middle = middleRowFaces.indexOf(face2) != -1; 65 | 66 | if (face1Middle && face2Middle) { 67 | String test = "FL"; 68 | if (test.indexOf(face1)!=-1 &&test.indexOf(face2)!=-1) { 69 | returnList.add(new TurnO(2, n-1, true)); 70 | returnList.add(new TurnO(2, n-1, true)); 71 | return returnList; 72 | } 73 | test = "BL"; 74 | if (test.indexOf(face1)!=-1 &&test.indexOf(face2)!=-1) { 75 | returnList.add(new TurnO(0, 0, true)); 76 | returnList.add(new TurnO(1, 0, false)); 77 | returnList.add(new TurnO(2, n-1, false)); 78 | return returnList; 79 | } 80 | 81 | test = "BR"; 82 | if (test.indexOf(face1)!=-1 &&test.indexOf(face2)!=-1) { 83 | returnList.add(new TurnO(0, n-1, true)); 84 | returnList.add(new TurnO(0, n-1, true)); 85 | 86 | return returnList; 87 | } 88 | return new ArrayList(); 89 | } 90 | 91 | 92 | char nonMidFace = face1; 93 | char midFace = face2; 94 | if (face1Middle) { 95 | nonMidFace = face2; 96 | midFace = face1; 97 | } 98 | int yIndex = 0; 99 | if (nonMidFace == 'D') { 100 | yIndex = n-1; 101 | } 102 | 103 | returnList.addAll(getTurnObjects(midFace, 'R', yIndex, 1)); 104 | 105 | 106 | if (nonMidFace == 'D') { 107 | returnList.add(new TurnO(0, n-1, false)); 108 | } else { 109 | returnList.add(new TurnO(0, n-1, true)); 110 | } 111 | return returnList; 112 | } 113 | 114 | 115 | String getTurns(char fromFace, char toFace, int index) { 116 | int fromIndex = XRotation.indexOf(fromFace); 117 | int toIndex = XRotation.indexOf(toFace); 118 | if (fromIndex != -1 && toIndex !=-1) { 119 | if (index ==0) { 120 | return foundRotation(fromIndex, toIndex, 'L'); 121 | } else { 122 | return foundRotation(fromIndex, toIndex, 'R'); 123 | } 124 | } 125 | fromIndex = YRotation.indexOf(fromFace); 126 | toIndex = YRotation.indexOf(toFace); 127 | if (fromIndex != -1 && toIndex !=-1) { 128 | if (index ==0) { 129 | return foundRotation(fromIndex, toIndex, 'U'); 130 | } else { 131 | return foundRotation(fromIndex, toIndex, 'D'); 132 | } 133 | } 134 | fromIndex = ZRotation.indexOf(fromFace); 135 | toIndex = ZRotation.indexOf(toFace); 136 | if (fromIndex != -1 && toIndex !=-1) { 137 | if (index ==0) { 138 | return foundRotation(fromIndex, toIndex, 'B'); 139 | } else { 140 | return foundRotation(fromIndex, toIndex, 'F'); 141 | } 142 | } 143 | return ""; 144 | } 145 | 146 | 147 | String getDirection(char fromFace, char toFace) { 148 | int fromIndex = XRotation.indexOf(fromFace); 149 | int toIndex = XRotation.indexOf(toFace); 150 | if (fromIndex != -1 && toIndex !=-1) { 151 | return foundRotation(fromIndex, toIndex, 'X'); 152 | } 153 | fromIndex = YRotation.indexOf(fromFace); 154 | toIndex = YRotation.indexOf(toFace); 155 | if (fromIndex != -1 && toIndex !=-1) { 156 | return foundRotation(fromIndex, toIndex, 'Y'); 157 | } 158 | fromIndex = ZRotation.indexOf(fromFace); 159 | toIndex = ZRotation.indexOf(toFace); 160 | if (fromIndex != -1 && toIndex !=-1) { 161 | return foundRotation(fromIndex, toIndex, 'Z'); 162 | } 163 | return ""; 164 | } 165 | 166 | 167 | 168 | ArrayList foundRotationGimmeObj(int fromIndex, int toIndex, int index, int axis, int idealAxis) { 169 | ArrayList turns = new ArrayList(); 170 | TurnO t = new TurnO(idealAxis, index, true); 171 | if (abs(fromIndex - toIndex) == 2) { 172 | turns.add(t); 173 | turns.add(t); 174 | return turns; 175 | } 176 | 177 | t.axis = axis; 178 | 179 | if (fromIndex<=toIndex) { 180 | for (int i = fromIndex; i< toIndex; i++) { 181 | turns.add(t); 182 | } 183 | } else { 184 | t.clockwise = false; 185 | for (int i = toIndex; i< fromIndex; i++) { 186 | turns.add(t); 187 | } 188 | } 189 | return turns; 190 | } 191 | 192 | String foundRotation(int fromIndex, int toIndex, char turnCharacter) { 193 | String returnString =""; 194 | if (abs(fromIndex - toIndex) ==2) { 195 | return "" + turnCharacter + turnCharacter; 196 | } 197 | if (fromIndex<=toIndex) { 198 | for (int i = fromIndex; i< toIndex; i++) { 199 | returnString += turnCharacter; 200 | } 201 | } else { 202 | for (int i = toIndex; i< fromIndex; i++) { 203 | returnString += turnCharacter + "\'"; 204 | } 205 | } 206 | return returnString; 207 | } 208 | 209 | 210 | 211 | 212 | PVector[] cornerRotationU = {new PVector(0, 0, 0), new PVector(n-1, 0, 0), new PVector(n-1, 0, n-1), new PVector(0, 0, n-1)}; 213 | PVector[] cornerRotationD = {new PVector(0, n-1, 0), new PVector(0, n-1, n-1), new PVector(n-1, n-1, n-1), new PVector(n-1, n-1, 0)}; 214 | 215 | 216 | String getDirectionsCorners(PVector from, PVector to) { 217 | 218 | int fromIndex = getIndex(cornerRotationU, from); 219 | int toIndex = getIndex(cornerRotationU, to); 220 | if (fromIndex != -1 && toIndex !=-1) { 221 | return foundRotation(fromIndex, toIndex, 'U'); 222 | } 223 | 224 | fromIndex = getIndex(cornerRotationD, from); 225 | toIndex = getIndex(cornerRotationD, to); 226 | if (fromIndex != -1 && toIndex !=-1) { 227 | return foundRotation(fromIndex, toIndex, 'D'); 228 | } 229 | 230 | return ""; 231 | //will add others if needed 232 | } 233 | 234 | 235 | int getIndex(PVector[] arr, PVector c) { 236 | for (int i = 0; i< arr.length; i++) { 237 | if (pvectorsEqual(arr[i], c)) { 238 | return i; 239 | } 240 | } 241 | return -1; 242 | } 243 | boolean pvectorsEqual(PVector p1, PVector p2) { 244 | return(p1.x ==p2.x && p1.y == p2.y && p1.z == p2.z); 245 | } 246 | //converts into reverse e.g. RULR' becomes RL'U'R' 247 | String reverseDirections(String original) { 248 | String reverse = ""; 249 | for (int i = 0; i< original.length(); i++) { 250 | if (i+1< original.length() && original.charAt(i+1) == '\'') { 251 | reverse = original.charAt(i) + reverse; 252 | i+=1; 253 | } else { 254 | reverse = original.charAt(i) + "'" + reverse; 255 | } 256 | } 257 | 258 | return reverse; 259 | } 260 | 261 | 262 | 263 | 264 | PVector[] edgeRotationU = {new PVector(middle, 0, 0), new PVector(n-1, 0, middle), new PVector(middle, 0, n-1), new PVector(0, 0, middle)}; 265 | PVector[] edgeRotationD = {new PVector(middle, n-1, 0), new PVector(0, n-1, middle), new PVector(middle, n-1, n-1), new PVector(n-1, n-1, middle)}; 266 | 267 | 268 | String getDirectionsEdges(PVector from, PVector to) { 269 | 270 | int fromIndex = getIndex(edgeRotationU, from); 271 | int toIndex = getIndex(edgeRotationU, to); 272 | if (fromIndex != -1 && toIndex !=-1) { 273 | return foundRotation(fromIndex, toIndex, 'U'); 274 | } 275 | 276 | fromIndex = getIndex(edgeRotationD, from); 277 | toIndex = getIndex(cornerRotationD, to); 278 | if (fromIndex != -1 && toIndex !=-1) { 279 | return foundRotation(fromIndex, toIndex, 'D'); 280 | } 281 | 282 | return ""; 283 | //will add others if needed 284 | } 285 | -------------------------------------------------------------------------------- /RubixCube/RubixCube.pde: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------------------------- 2 | //Hey bro, here are some values you can change so go nuts... 3 | //actually probably dont 4 | //dont go too big (trust me) 5 | //dont do even sized cubes (it wont work) 6 | //Have fun 7 | 8 | int numberOfSides = 25;//<<< change this to change the size of the cube 9 | float cubeSpeed = PI/20.0; //<<< this is the speed that the cube rotates 10 | 11 | /* 12 | some controls 13 | L lock/unlock cube (allows you to turn the cube with the mouse) 14 | SPACE pause/play (the program will automatically pause after the scramble, you will need to play the thing when you wanna start the scramble and when you wanna start the solve. 15 | */ 16 | 17 | //---------------------------------------------------------------------------------------------- 18 | 19 | int blockWidth = 400/numberOfSides; //you can change this value to increase the size of the cube in the window 20 | //also if you've got a 4k monitor then check out line 97 21 | 22 | 23 | //Global colors 24 | 25 | color green = color(0, 255, 0); 26 | color blue = color(0, 0, 255); 27 | color red = color(255, 0, 0); 28 | color white = color(255); 29 | color yellow = color(255, 255, 0); 30 | color orange = color(255, 140, 0); 31 | 32 | 33 | 34 | int n = numberOfSides;//better variable name 35 | int middle = n/2; 36 | int faceWidth = blockWidth; 37 | int blacksShown = 0; 38 | int speedUpCounter = 1; 39 | boolean pause = true; 40 | int rotateYCounter = 0; 41 | int rotateXCounter = 0; 42 | Cube cube; 43 | int stageTestCounter =100; 44 | int scrambleCounter = 100; 45 | String turns = ""; 46 | ArrayList turnOs = new ArrayList(); 47 | 48 | int moveCount = 0; 49 | int solveCounter =0; 50 | 51 | boolean fixCubeRotation = false; 52 | float XRotationCompensation = 0; 53 | float YRotationCompensation = 0; 54 | float ZRotationCompensation = 0; 55 | 56 | ArrayList rotations = new ArrayList(); 57 | int[] turnCounter = new int[7]; 58 | 59 | float spinCounter =0; 60 | 61 | boolean lockRotation = true; 62 | float xRotationKey = 0; 63 | float yRotationKey = 0; 64 | float xRotationKeyTarget = 0; 65 | float yRotationKeyTarget= 0; 66 | //float zRotationKey = 0; 67 | float rotationSpeed =100.0; 68 | 69 | boolean justScrambled = true; 70 | int pauseCounter = 0; 71 | 72 | boolean showingOffFace = true; 73 | float xTargetRotation = PI; 74 | float yTargetRotation = PI; 75 | 76 | int previousStageNo = 0; 77 | int previousLargeCubeStageNo = 0; 78 | 79 | boolean actualPause = false; 80 | PVector lockedMousePos = new PVector(); 81 | PVector[] edgeCenters= {new PVector(middle, 0, 0), new PVector(n-1, 0, middle), new PVector(middle, 0, n-1), 82 | new PVector(0, 0, middle), new PVector(middle, n-1, 0), new PVector(0, n-1, middle), new PVector(middle, n-1, n-1), new PVector(n-1, n-1, middle), 83 | new PVector(0, middle, 0), new PVector(n-1, middle, 0), new PVector(0, middle, n-1), new PVector(n-1, middle, n-1)}; 84 | 85 | boolean firstPause = true; 86 | 87 | 88 | boolean enableMouseX = true; 89 | boolean enableMouseY = true; 90 | boolean enableSpin = false; 91 | boolean autoShow = false; 92 | boolean repeatSolves = false; 93 | int solveCounterThing =0; 94 | int startTime =0; 95 | void setup() { 96 | size(1000, 1000, P3D); 97 | //size(2000, 2000, P3D); //if you've got a 4K monitor then you can uncomment this out to have a bigger window, also make sure to comment out the line before 98 | 99 | //turns+= "FFULL"; 100 | cube = new Cube(); 101 | for (int i= 0; i < 7; i++) { 102 | turnCounter[i] = 0; 103 | } 104 | cube.algos.scramble(); 105 | //turns+= "XYZXYZXYZXYZXYZXYZXYZXYZYXYZXYZXYZXYZYXYZXYXZ"; 106 | frameRate(60); 107 | } 108 | 109 | void resetCube() { 110 | cube = new Cube(); 111 | cube.algos.scramble(); 112 | } 113 | 114 | void draw() { 115 | if (!actualPause) { 116 | 117 | if (autoShow) { 118 | if (!pause && !cube.scrambling && cubeSpeed < PI) { 119 | if (cubeSpeed > PI/3) { 120 | cubeSpeed =PI; 121 | speedUpCounter =1; 122 | } else { 123 | cubeSpeed+=0.005; 124 | } 125 | } 126 | } 127 | println(cubeSpeed, PI); 128 | //cubeSpeed = PI; 129 | cube.rotationSpeed = cubeSpeed; 130 | //if (showingOffFace) { 131 | // //pause = true; 132 | // float wholeCubeRotationSpeed = 2; 133 | // yRotationKey += yTargetRotation-yRotationKey/ abs(yRotationKey-yTargetRotation)*wholeCubeRotationSpeed; 134 | // xRotationKey += xTargetRotation-xRotationKey/ abs(xRotationKey-xTargetRotation)*wholeCubeRotationSpeed; 135 | //} 136 | 137 | 138 | //println(frameRate); 139 | pushMatrix(); 140 | 141 | translate(width/2, height/2, 0); 142 | rotateX(-PI/6); 143 | if (autoShow) { 144 | if (!lockRotation && pause && spinCounter/rotationSpeed>2*PI) { 145 | //println(spinCounter); 146 | pause = false; 147 | lockRotation=true; 148 | spinCounter = 0; 149 | 150 | switch(cube.algos.largeCubeStageNo) { 151 | case 1: 152 | xRotationKeyTarget -=PI/2.0; 153 | break; 154 | case 2: 155 | xRotationKeyTarget +=PI/2.0; 156 | break; 157 | case 9: 158 | yRotationKeyTarget +=PI/2.0; 159 | break; 160 | case 10: 161 | yRotationKeyTarget -=PI/2.0; 162 | break; 163 | } 164 | if (cube.algos.stageNo ==7) { 165 | actualPause = true; 166 | } 167 | } 168 | } 169 | 170 | if (abs(yRotationKey - yRotationKeyTarget)>0.15) { 171 | if (yRotationKey < yRotationKeyTarget) { 172 | yRotationKey+=0.1; 173 | } else { 174 | yRotationKey-=0.1; 175 | } 176 | } else { 177 | 178 | yRotationKey = yRotationKeyTarget; 179 | } 180 | if (abs(xRotationKey - xRotationKeyTarget) >0.15) { 181 | if (xRotationKey < xRotationKeyTarget) { 182 | xRotationKey+=0.1; 183 | } else { 184 | xRotationKey-=0.1; 185 | } 186 | } else { 187 | 188 | xRotationKey = xRotationKeyTarget; 189 | } 190 | if (lockRotation) { 191 | rotateY(PI/5- yRotationKey); 192 | rotateX(-xRotationKey); 193 | } else { 194 | //println(lockedMousePos, mouseX, mouseY); 195 | 196 | if (enableMouseY) { 197 | rotateX(-xRotationKey +((lockedMousePos.y -mouseY))/rotationSpeed); 198 | } else { 199 | rotateX(-xRotationKey); 200 | } 201 | 202 | if (enableMouseX) { 203 | rotateY(PI/5- yRotationKey-((lockedMousePos.x -mouseX) + spinCounter)/rotationSpeed); 204 | } else { 205 | //rotateY(PI/5- yRotationKey); 206 | 207 | rotateY(PI/5- yRotationKey-(spinCounter)/rotationSpeed); 208 | } 209 | 210 | if (enableSpin) { 211 | spinCounter+=1.0; 212 | } 213 | } 214 | 215 | 216 | for (int i = 0; i< rotations.size(); i++) { 217 | int rotationDirection = 1; 218 | 219 | if (rotations.get(i).length() ==2) { 220 | rotationDirection = -1; 221 | } 222 | 223 | switch(rotations.get(i).charAt(0)) { 224 | case 'X': 225 | rotateX(rotationDirection * PI/2); 226 | break; 227 | case 'Y': 228 | rotateY(rotationDirection * PI/2); 229 | break; 230 | case 'Z': 231 | rotateZ(rotationDirection * PI/2); 232 | break; 233 | } 234 | } 235 | //rotateX(XRotationCompensation) ; 236 | //rotateY(YRotationCompensation); 237 | 238 | //rotateZ(ZRotationCompensation); 239 | //if (cube.algos.stageNo ==7) { 240 | // cube.rotationSpeed = PI/50.0; 241 | //} 242 | 243 | // if (cube.algos.stageNo ==5) { 244 | // cube.rotationSpeed = PI/1.0; 245 | 246 | // //pause = true; 247 | // } 248 | //} 249 | if (pause) { 250 | //print("paused"); 251 | } 252 | if (!autoShow || cube.algos.largeCubeStageNo > 5) { 253 | background(255); 254 | cube.show(); 255 | //saveFrame(n+"x" + n+"_rubiksCube_part2/"+ n+"x" + n+"_rubiksCube#########.jpg"); 256 | } else { 257 | if (frameCount%10==0) { 258 | background(255); 259 | cube.show(); 260 | } 261 | } 262 | int upTo =30; 263 | if (n<30) { 264 | upTo =1; 265 | } 266 | if (!autoShow && cube.scrambling && justScrambled) { 267 | //if first run through show the scramble slowly 268 | upTo = 1; 269 | } 270 | if (autoShow && speedUpCounter 9) { 275 | upTo =1; 276 | cubeSpeed = PI/10.0; 277 | } 278 | if (autoShow && cubeSpeed 6 )) { 289 | 290 | if (previousLargeCubeStageNo!= 3 && previousLargeCubeStageNo!= 5 && previousLargeCubeStageNo!= 7) { 291 | spinCounter =0; 292 | pause = true; 293 | lockRotation = false; 294 | cubeSpeed = PI/60.0; 295 | } 296 | previousStageNo = cube.algos.stageNo; 297 | previousLargeCubeStageNo = cube.algos.largeCubeStageNo; 298 | } 299 | } 300 | } 301 | 302 | 303 | 304 | if (!cube.scrambling && justScrambled) { 305 | 306 | //cubeSpeed= PI; 307 | pause = true; 308 | if (autoShow) { 309 | upTo=1; 310 | cubeSpeed = PI/60.0; 311 | } 312 | //if( 313 | justScrambled = false; 314 | } 315 | 316 | 317 | if (!pause &&!cube.turning) { 318 | if (!cube.scrambling) { 319 | //turnCounter[cube.algos.stageNo]+=1; 320 | } 321 | if (turns.length() >0 ) { 322 | doTurn(); 323 | } else if (turnOs.size() >0) { 324 | doTurnFromObj(); 325 | } 326 | } 327 | } 328 | 329 | 330 | //if (cube.algos.stageNo ==7) { 331 | 332 | // if (scrambleCounter <0) { 333 | // int sum = 0; 334 | // solveCounter +=1; 335 | // for (int i = 0; i< 7; i++) { 336 | // println("stage " + i + ": " + (turnCounter[i]/solveCounter) + " turns"); 337 | // sum += turnCounter[i]; 338 | // //turnCounter[i] =0; 339 | // } 340 | // println("Total : " + (sum/solveCounter)); 341 | // println("____________________________________________________"); 342 | // scrambleCounter = 1; 343 | // cube.algos.scramble(); 344 | // cube.scrambling = true; 345 | // } else { 346 | // scrambleCounter--; 347 | // } 348 | //} 349 | 350 | 351 | 352 | popMatrix(); 353 | } 354 | } 355 | 356 | 357 | void keyPressed() { 358 | 359 | switch(key) { 360 | case 'p': 361 | actualPause =!actualPause; 362 | break; 363 | case 'l': 364 | lockRotation = !lockRotation; 365 | lockedMousePos = new PVector(mouseX, mouseY); 366 | spinCounter =0; 367 | break; 368 | case ' ': 369 | pause=!pause; 370 | if (!pause && !justScrambled) { 371 | startTime = millis(); 372 | } 373 | break; 374 | case 'm': 375 | enableMouseX = !enableMouseX; 376 | enableMouseY = !enableMouseY; 377 | break; 378 | case 's': 379 | enableSpin = !enableSpin; 380 | break; 381 | } 382 | float spinVal = PI/2; 383 | switch(keyCode) { 384 | case RIGHT: 385 | yRotationKey +=spinVal; 386 | break; 387 | case LEFT: 388 | yRotationKey -=spinVal; 389 | break; 390 | case UP: 391 | xRotationKey +=spinVal; 392 | break; 393 | case DOWN: 394 | xRotationKey -=spinVal; 395 | break; 396 | } 397 | } 398 | 399 | void doTurn() { 400 | //input is a string e.g. RUL'DD 401 | // void turnCube(int index, int xOrYOrZ, boolean turnClockwise) { 402 | char turn = turns.charAt(0); 403 | turns = turns.substring(1, turns.length()); 404 | 405 | boolean clockwise = true; 406 | 407 | 408 | 409 | 410 | if (turns.length() > 0 && turns.charAt(0) == '\'') { 411 | clockwise = false; 412 | turns = turns.substring(1, turns.length()); 413 | //println("Turning cube " + turn +"'"); 414 | if (turns.length()>=4) { 415 | if (turns.substring(0, 4).equals( "" + turn + "'" + turn + "'")) { 416 | //println("replaced: " + turn + "'" + turns.substring(0, 4) + " with " +turn); 417 | 418 | clockwise = true; 419 | turns = turns.substring(4, turns.length()); 420 | } 421 | } 422 | } else { 423 | //println("Turning cube " + turn); 424 | if (turns.length()>=2) { 425 | if (turns.charAt(0)== turn && turns.charAt(1) == turn) { 426 | //println("replaced: " + turn+ turns.substring(0, 2) + " with " +turn + "'"); 427 | clockwise = false; 428 | turns = turns.substring(2, turns.length()); 429 | } 430 | } 431 | } 432 | 433 | 434 | 435 | if (turn == 'R' || turn =='D' || turn == 'F') { 436 | clockwise = !clockwise; 437 | } 438 | 439 | 440 | if (fixCubeRotation) { 441 | compensateForTurn(turn, clockwise); 442 | } 443 | 444 | 445 | switch(turn) { 446 | case 'R': 447 | cube.turnCube(numberOfSides-1, 0, clockwise); 448 | break; 449 | case 'L': 450 | cube.turnCube(0, 0, clockwise ); 451 | break; 452 | case 'U': 453 | cube.turnCube(0, 1, clockwise); 454 | break; 455 | case 'D': 456 | cube.turnCube(numberOfSides-1, 1, clockwise); 457 | break; 458 | case 'F': 459 | cube.turnCube(numberOfSides-1, 2, clockwise); 460 | break; 461 | case 'B': 462 | cube.turnCube(0, 2, clockwise); 463 | break; 464 | case 'X': 465 | cube.turnWholeCube(0, clockwise); 466 | 467 | break; 468 | case 'Y': 469 | cube.turnWholeCube(1, clockwise); 470 | break; 471 | case 'Z': 472 | cube.turnWholeCube(2, clockwise); 473 | break; 474 | } 475 | } 476 | 477 | void doTurnFromObj() { 478 | //println("turnos"); 479 | //input is a string e.g. RUL'DD 480 | // void turnCube(int index, int xOrYOrZ, boolean turnClockwise) { 481 | TurnO turn = turnOs.remove(0); 482 | 483 | if (turnOs.size() >= 2) { 484 | if (turn.matches(turnOs.get(0)) && turn.matches(turnOs.get(1))) { 485 | turnOs.remove(0); 486 | turnOs.remove(0); 487 | turn.clockwise = !turn.clockwise; 488 | } 489 | } 490 | cube.turnCubeFromObj(turn); 491 | } 492 | 493 | void compensateForTurn(char direction, boolean clockwise) { 494 | if (clockwise) { 495 | rotations.add(""+direction); 496 | } else { 497 | rotations.add(""+direction +"'"); 498 | } 499 | switch(direction) { 500 | case 'X': 501 | if (clockwise) { 502 | XRotationCompensation += PI/2; 503 | } else { 504 | XRotationCompensation -= PI/2; 505 | } 506 | break; 507 | case 'Y': 508 | if (clockwise) { 509 | YRotationCompensation += PI/2; 510 | } else { 511 | YRotationCompensation -= PI/2; 512 | } 513 | break; 514 | 515 | case 'Z': 516 | if (clockwise) { 517 | ZRotationCompensation += PI/2; 518 | } else { 519 | ZRotationCompensation -= PI/2; 520 | } 521 | break;// float YRotationCompensation = 0; 522 | // float ZRotationCompensation = 0; 523 | } 524 | } 525 | 526 | String mappings = "LRUDBF"; 527 | 528 | 529 | void simulateRotation(int axis, boolean clockwise) { 530 | if (!clockwise) { 531 | simulateRotation(axis, true); 532 | simulateRotation(axis, true); 533 | simulateRotation(axis, true); 534 | } 535 | //LRUDBF 536 | switch(axis) { 537 | case 0: 538 | for (int i = 0; i< mappings.length(); i++) { 539 | int index = XRotation.indexOf(mappings.charAt(i)); 540 | if (index != -1) { 541 | mappings = mappings.substring(0, i) + XRotation.charAt((index +1)%4) + mappings.substring(i+1, mappings.length()); 542 | } 543 | } 544 | break; 545 | case 1: 546 | for (int i = 0; i< mappings.length(); i++) { 547 | int index = YRotation.indexOf(mappings.charAt(i)); 548 | if (index != -1) { 549 | mappings = mappings.substring(0, i) + YRotation.charAt((index +1)%4) + mappings.substring(i+1, mappings.length()); 550 | } 551 | } 552 | break; 553 | case 2: 554 | for (int i = 0; i< mappings.length(); i++) { 555 | int index = ZRotation.indexOf(mappings.charAt(i)); 556 | if (index != -1) { 557 | mappings = mappings.substring(0, i) + ZRotation.charAt((index +1)%4) + mappings.substring(i+1, mappings.length()); 558 | } 559 | } 560 | break; 561 | } 562 | } 563 | 564 | 565 | void printTurnos() { 566 | println("turnos mamte"); 567 | for (int i = 0; i< turnOs.size(); i++) { 568 | turnOs.get(i).printTurn(); 569 | } 570 | } 571 | 572 | boolean moreTurns() { 573 | return turnOs.size() != 0 || turns.length() !=0; 574 | } 575 | -------------------------------------------------------------------------------- /RubixCube/TurnO.pde: -------------------------------------------------------------------------------- 1 | class TurnO { 2 | int axis = 0; 3 | int index = 0; 4 | boolean clockwise = true; 5 | 6 | TurnO(int a, int i, boolean c) { 7 | axis =a; 8 | index = i; 9 | clockwise = c; 10 | } 11 | TurnO() { 12 | axis =floor(random(3)); 13 | index = floor(random(n)); 14 | if (random(1) <0.5) { 15 | clockwise =false; 16 | } 17 | } 18 | 19 | boolean matches(TurnO t) { 20 | return t.axis ==axis && t.index == index && clockwise == t.clockwise; 21 | } 22 | 23 | 24 | void printTurn(){ 25 | println("axis: " + axis +", index " + index + ", isclockwise " +clockwise); 26 | 27 | } 28 | 29 | TurnO getReverse(){ 30 | TurnO reverse = new TurnO(axis,index,!clockwise); 31 | return reverse; 32 | } 33 | } 34 | --------------------------------------------------------------------------------