Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save LucasAlfare/0a3089b60c908ac6147336445641f247 to your computer and use it in GitHub Desktop.
Save LucasAlfare/0a3089b60c908ac6147336445641f247 to your computer and use it in GitHub Desktop.
Using this to generate custom cubeshape random state scrambles using sq2phase, written by Chen Shuang.
package main.sq12phase;
import java.util.Random;
/**
* @author Lucas Sousa
*
* THIS CLASS IS A SUGGESTION!
*
* I've been using this to training CSP (cube shape parity) in main.sq12phase.Square-1.
*
* The advantage is that we can practice isolated cube shapes several times
* instead of randomly waiting for the case we need to practice to appear
* in the timer.
*
* The logic is just build a random cube using a specific shape index, once
* the code uses this to build the random states.
*
* Then, after some convertions, I created a enumaration to hold all these
* cube shapes indexes, wich is written as a internal enum bellow. Might
* have some another pretty ways to do this, anyway this works to the main
* proporse.
*
* In the method getRandomCube() we can tell to Java get only one value from
* the ShapeIdx array, instead of getting a random value (from it) in its full
* length (3678 values).
*
* This is a good idea to used in main csTimer. To this, can be thought a
* comboBox to select the cube shape case, or implement images and so on.
*
* TODO: to speed up the code, instead building the source shape array fully,
* build only the specified cube shape indexes.
*
*/
@SuppressWarnings("JavadocReference")
public class CustomCubeShapeScrambler {
/**
* This enumeration holds all cube shapes with their respective
* indexes.
*
* The nomenclature used to the cases was the same used by Laars
* Vandenbergh in his site: {@link http://www.cubezone.be/square1step1.html}.
*
* Also notice that, e.g., {@code KITE_SCALLOP} case holds all indexes to
* your same inverted, in this case {@code SCALLOP_KITE}.
*/
public enum CubeShapeIndex {
x44_STAR(18, 142, 266, 801, 1747, 3647, 3653, 3659, 3666, 3674),
x53_STAR(19, 141, 143, 265, 279, 788, 826, 1722, 3648, 3652, 3654, 3658, 3660, 3665, 3667, 3673),
x62_STAR(3, 20, 156, 264, 304, 787, 1709, 1830, 3644, 3649, 3655, 3657, 3661, 3664, 3672, 3675),
x71_STAR(1, 4, 33, 181, 786, 909, 1708, 2229, 3642, 3645, 3650, 3656, 3663, 3668, 3671, 3676),
x8_STAR(0, 2, 5, 58, 387, 1308, 1707, 2628, 3641, 3643, 3646, 3651, 3662, 3669, 3670, 3677),
x222_PAIRED(305, 308, 310, 311, 314, 316, 1855, 1858, 1860, 1861, 1864, 1866, 740, 772, 2183, 2215, 2981, 3013, 3193, 3225, 3471, 3503, 3595, 3627),
x222_PERPENDICULAR(306, 309, 312, 315, 1856, 1859, 1862, 1865, 1262, 1294, 2582, 2614, 3301, 3333, 3533, 3565),
x222_PARALLEL(307, 313, 1857, 1863, 1661, 1693, 3363, 3395),
x33_PAIRED(144, 147, 149, 150, 153, 155, 292, 295, 297, 298, 301, 303, 400, 403, 405, 406, 409, 411, 851, 854, 856, 857, 860, 862, 1333, 1336, 1338, 1339, 1342, 1344, 2711, 2714, 2716, 2717, 2720, 2722, 731, 739, 744, 753, 761, 783, 2174, 2182, 2187, 2196, 2204, 2226, 2972, 2980, 2985, 2994, 3002, 3024, 3184, 3192, 3197, 3206, 3214, 3236, 3462, 3470, 3475, 3484, 3492, 3514, 3586, 3594, 3599, 3608, 3616, 3638),
x33_PERPENDICULAR(145, 148, 151, 154, 293, 296, 299, 302, 401, 404, 407, 410, 852, 855, 858, 861, 1334, 1337, 1340, 1343, 2712, 2715, 2718, 2721, 1253, 1261, 1266, 1275, 1283, 1305, 2573, 2581, 2586, 2595, 2603, 2625, 3292, 3300, 3305, 3314, 3322, 3344, 3524, 3532, 3537, 3546, 3554, 3576),
x33_PARALLEL(146, 152, 294, 300, 402, 408, 853, 859, 1335, 1341, 2713, 2719, 1652, 1660, 1665, 1674, 1682, 1704, 3354, 3362, 3367, 3376, 3384, 3406),
x321_PAIRED(182, 185, 187, 188, 191, 193, 280, 283, 285, 286, 289, 291, 839, 842, 844, 845, 848, 850, 934, 937, 939, 940, 943, 945, 1843, 1846, 1848, 1849, 1852, 1854, 2312, 2315, 2317, 2318, 2321, 2323, 734, 738, 752, 756, 771, 778, 2177, 2181, 2195, 2199, 2214, 2221, 2975, 2979, 2993, 2997, 3012, 3019, 3187, 3191, 3205, 3209, 3224, 3231, 3465, 3469, 3483, 3487, 3502, 3509, 3589, 3593, 3607, 3611, 3626, 3633),
x321_PERPENDICULAR(183, 186, 189, 192, 281, 284, 287, 290, 840, 843, 846, 849, 935, 938, 941, 944, 1844, 1847, 1850, 1853, 2313, 2316, 2319, 2322, 1256, 1260, 1274, 1278, 1293, 1300, 2576, 2580, 2594, 2598, 2613, 2620, 3295, 3299, 3313, 3317, 3332, 3339, 3527, 3531, 3545, 3549, 3564, 3571),
x321_PARALLEL(184, 190, 282, 288, 841, 847, 936, 942, 1845, 1851, 2314, 2320, 1655, 1659, 1673, 1677, 1692, 1699, 3357, 3361, 3375, 3379, 3394, 3401),
x312_PAIRED(157, 160, 162, 163, 166, 168, 317, 320, 322, 323, 326, 328, 827, 830, 832, 833, 836, 838, 922, 925, 927, 928, 931, 933, 1913, 1916, 1918, 1919, 1922, 1924, 2254, 2257, 2259, 2260, 2263, 2265, 732, 741, 751, 755, 773, 777, 2175, 2184, 2194, 2198, 2216, 2220, 2973, 2982, 2992, 2996, 3014, 3018, 3185, 3194, 3204, 3208, 3226, 3230, 3463, 3472, 3482, 3486, 3504, 3508, 3587, 3596, 3606, 3610, 3628, 3632),
x312_PERPENDICULAR(158, 161, 164, 167, 318, 321, 324, 327, 828, 831, 834, 837, 923, 926, 929, 932, 1914, 1917, 1920, 1923, 2255, 2258, 2261, 2264, 1254, 1263, 1273, 1277, 1295, 1299, 2574, 2583, 2593, 2597, 2615, 2619, 3293, 3302, 3312, 3316, 3334, 3338, 3525, 3534, 3544, 3548, 3566, 3570),
x312_PARALLEL(159, 165, 319, 325, 829, 835, 924, 930, 1915, 1921, 2256, 2262, 1653, 1662, 1672, 1676, 1694, 1698, 3355, 3364, 3374, 3378, 3396, 3400),
L42_PAIRED(59, 62, 64, 65, 68, 70, 267, 270, 272, 273, 276, 278, 412, 415, 417, 418, 421, 423, 814, 817, 819, 820, 823, 825, 1391, 1394, 1396, 1397, 1400, 1402, 1772, 1775, 1777, 1778, 1781, 1783, 1831, 1834, 1836, 1837, 1840, 1842, 2815, 2818, 2820, 2821, 2824, 2826, 728, 737, 745, 750, 762, 769, 770, 784, 2171, 2180, 2188, 2193, 2205, 2212, 2213, 2227, 2969, 2978, 2986, 2991, 3003, 3010, 3011, 3025, 3181, 3190, 3198, 3203, 3215, 3222, 3223, 3237, 3459, 3468, 3476, 3481, 3493, 3500, 3501, 3515, 3583, 3592, 3600, 3605, 3617, 3624, 3625, 3639),
L42_PERPENDICULAR(60, 63, 66, 69, 268, 271, 274, 277, 413, 416, 419, 422, 815, 818, 821, 824, 1392, 1395, 1398, 1401, 1773, 1776, 1779, 1782, 1832, 1835, 1838, 1841, 2816, 2819, 2822, 2825, 1250, 1259, 1267, 1272, 1284, 1291, 1292, 1306, 2570, 2579, 2587, 2592, 2604, 2611, 2612, 2626, 3289, 3298, 3306, 3311, 3323, 3330, 3331, 3345, 3521, 3530, 3538, 3543, 3555, 3562, 3563, 3577),
L42_PARALLEL(61, 67, 269, 275, 414, 420, 816, 822, 1393, 1399, 1774, 1780, 1833, 1839, 2817, 2823, 1649, 1658, 1666, 1671, 1683, 1690, 1691, 1705, 3351, 3360, 3368, 3373, 3385, 3392, 3393, 3407),
R42_PAIRED(21, 24, 26, 27, 30, 32, 169, 172, 174, 175, 178, 180, 329, 332, 334, 335, 338, 340, 388, 391, 393, 394, 397, 399, 1321, 1324, 1326, 1327, 1330, 1332, 1748, 1751, 1753, 1754, 1757, 1759, 2017, 2020, 2022, 2023, 2026, 2028, 2653, 2656, 2658, 2659, 2662, 2664, 725, 733, 742, 743, 760, 767, 774, 782, 2168, 2176, 2185, 2186, 2203, 2210, 2217, 2225, 2966, 2974, 2983, 2984, 3001, 3008, 3015, 3023, 3178, 3186, 3195, 3196, 3213, 3220, 3227, 3235, 3456, 3464, 3473, 3474, 3491, 3498, 3505, 3513, 3580, 3588, 3597, 3598, 3615, 3622, 3629, 3637),
R42_PERPENDICULAR(22, 25, 28, 31, 170, 173, 176, 179, 330, 333, 336, 339, 389, 392, 395, 398, 1322, 1325, 1328, 1331, 1749, 1752, 1755, 1758, 2018, 2021, 2024, 2027, 2654, 2657, 2660, 2663, 1247, 1255, 1264, 1265, 1282, 1289, 1296, 1304, 2567, 2575, 2584, 2585, 2602, 2609, 2616, 2624, 3286, 3294, 3303, 3304, 3321, 3328, 3335, 3343, 3518, 3526, 3535, 3536, 3553, 3560, 3567, 3575),
R42_PARALLEL(23, 29, 171, 177, 331, 337, 390, 396, 1323, 1329, 1750, 1756, 2019, 2025, 2655, 2661, 1646, 1654, 1663, 1664, 1681, 1688, 1695, 1703, 3348, 3356, 3365, 3366, 3383, 3390, 3397, 3405),
x411_PAIRED(34, 37, 39, 40, 43, 45, 194, 197, 199, 200, 203, 205, 802, 805, 807, 808, 811, 813, 910, 913, 915, 916, 919, 921, 992, 995, 997, 998, 1001, 1003, 1760, 1763, 1765, 1766, 1769, 1771, 2242, 2245, 2247, 2248, 2251, 2253, 2416, 2419, 2421, 2422, 2425, 2427, 726, 735, 749, 754, 757, 768, 776, 779, 2169, 2178, 2192, 2197, 2200, 2211, 2219, 2222, 2967, 2976, 2990, 2995, 2998, 3009, 3017, 3020, 3179, 3188, 3202, 3207, 3210, 3221, 3229, 3232, 3457, 3466, 3480, 3485, 3488, 3499, 3507, 3510, 3581, 3590, 3604, 3609, 3612, 3623, 3631, 3634),
x411_PERPENDICULAR(35, 38, 41, 44, 195, 198, 201, 204, 803, 806, 809, 812, 911, 914, 917, 920, 993, 996, 999, 1002, 1761, 1764, 1767, 1770, 2243, 2246, 2249, 2252, 2417, 2420, 2423, 2426, 1248, 1257, 1271, 1276, 1279, 1290, 1298, 1301, 2568, 2577, 2591, 2596, 2599, 2610, 2618, 2621, 3287, 3296, 3310, 3315, 3318, 3329, 3337, 3340, 3519, 3528, 3542, 3547, 3550, 3561, 3569, 3572),
x411_PARALLEL(36, 42, 196, 202, 804, 810, 912, 918, 994, 1000, 1762, 1768, 2244, 2250, 2418, 2424, 1647, 1656, 1670, 1675, 1678, 1689, 1697, 1700, 3349, 3358, 3372, 3377, 3380, 3391, 3399, 3402),
L51_PAIRED(71, 74, 76, 77, 80, 82, 470, 473, 475, 476, 479, 481, 789, 792, 794, 795, 798, 800, 1495, 1498, 1500, 1501, 1504, 1506, 1735, 1738, 1740, 1741, 1744, 1746, 2230, 2233, 2235, 2236, 2239, 2241, 729, 746, 748, 763, 766, 775, 2172, 2189, 2191, 2206, 2209, 2218, 2970, 2987, 2989, 3004, 3007, 3016, 3182, 3199, 3201, 3216, 3219, 3228, 3460, 3477, 3479, 3494, 3497, 3506, 3584, 3601, 3603, 3618, 3621, 3630),
L51_PERPENDICULAR(72, 75, 78, 81, 471, 474, 477, 480, 790, 793, 796, 799, 1496, 1499, 1502, 1505, 1736, 1739, 1742, 1745, 2231, 2234, 2237, 2240, 1251, 1268, 1270, 1285, 1288, 1297, 2571, 2588, 2590, 2605, 2608, 2617, 3290, 3307, 3309, 3324, 3327, 3336, 3522, 3539, 3541, 3556, 3559, 3568),
L51_PARALLEL(73, 79, 472, 478, 791, 797, 1497, 1503, 1737, 1743, 2232, 2238, 1650, 1667, 1669, 1684, 1687, 1696, 3352, 3369, 3371, 3386, 3389, 3398),
R51_PAIRED(46, 49, 51, 52, 55, 57, 206, 209, 211, 212, 215, 217, 1096, 1099, 1101, 1102, 1105, 1107, 1309, 1312, 1314, 1315, 1318, 1320, 1723, 1726, 1728, 1729, 1732, 1734, 2641, 2644, 2646, 2647, 2650, 2652, 727, 736, 758, 759, 765, 781, 2170, 2179, 2201, 2202, 2208, 2224, 2968, 2977, 2999, 3000, 3006, 3022, 3180, 3189, 3211, 3212, 3218, 3234, 3458, 3467, 3489, 3490, 3496, 3512, 3582, 3591, 3613, 3614, 3620, 3636),
R51_PERPENDICULAR(47, 50, 53, 56, 207, 210, 213, 216, 1097, 1100, 1103, 1106, 1310, 1313, 1316, 1319, 1724, 1727, 1730, 1733, 2642, 2645, 2648, 2651, 1249, 1258, 1280, 1281, 1287, 1303, 2569, 2578, 2600, 2601, 2607, 2623, 3288, 3297, 3319, 3320, 3326, 3342, 3520, 3529, 3551, 3552, 3558, 3574),
R51_PARALLEL(48, 54, 208, 214, 1098, 1104, 1311, 1317, 1725, 1731, 2643, 2649, 1648, 1657, 1679, 1680, 1686, 1702, 3350, 3359, 3381, 3382, 3388, 3404),
x6_PAIRED(6, 9, 11, 12, 15, 17, 83, 86, 88, 89, 92, 94, 574, 577, 579, 580, 583, 585, 1710, 1713, 1715, 1716, 1719, 1721, 2629, 2632, 2634, 2635, 2638, 2640, 3027, 3030, 3032, 3033, 3036, 3038, 724, 730, 747, 764, 780, 785, 2167, 2173, 2190, 2207, 2223, 2228, 2965, 2971, 2988, 3005, 3021, 3026, 3177, 3183, 3200, 3217, 3233, 3238, 3455, 3461, 3478, 3495, 3511, 3516, 3579, 3585, 3602, 3619, 3635, 3640),
x6_PERPENDICULAR(7, 10, 13, 16, 84, 87, 90, 93, 575, 578, 581, 584, 1711, 1714, 1717, 1720, 2630, 2633, 2636, 2639, 3028, 3031, 3034, 3037, 1246, 1252, 1269, 1286, 1302, 1307, 2566, 2572, 2589, 2606, 2622, 2627, 3285, 3291, 3308, 3325, 3341, 3346, 3517, 3523, 3540, 3557, 3573, 3578),
x6_PARALLEL(8, 14, 85, 91, 576, 582, 1712, 1718, 2631, 2637, 3029, 3035, 1645, 1651, 1668, 1685, 1701, 1706, 3347, 3353, 3370, 3387, 3403, 3408),
SQUARE_SQUARE(1015, 1037, 2485, 2507),
SQUARE_KITE(1018, 1023, 1029, 1034, 2488, 2493, 2499, 2504, 1165, 1187, 1518, 1540, 1982, 2004, 2335, 2357),
SQUARE_BARREL(1007, 1022, 1030, 1044, 2477, 2492, 2500, 2514, 435, 457, 1460, 1482, 2040, 2062, 2930, 2952),
SQUARE_SHIELD(1006, 1010, 1027, 1032, 1042, 1047, 2476, 2480, 2497, 2502, 2512, 2517, 352, 374, 597, 619, 1878, 1900, 2132, 2154, 2838, 2860, 3142, 3164),
SQUARE_lFIST(1016, 1017, 1021, 1028, 1038, 1043, 2486, 2487, 2491, 2498, 2508, 2513, 1061, 1083, 1119, 1141, 1414, 1436, 1936, 1958, 2531, 2553, 2884, 2906),
SQUARE_rFIST(1008, 1014, 1024, 1031, 1035, 1036, 2478, 2484, 2494, 2501, 2505, 2506, 493, 515, 957, 979, 1564, 1586, 2086, 2108, 2381, 2403, 2439, 2461),
SQUARE_lPAW(1011, 1013, 1033, 1048, 2481, 2483, 2503, 2518, 643, 665, 874, 896, 2277, 2299, 3250, 3272),
SQUARE_rPAW(1005, 1019, 1040, 1046, 2475, 2489, 2510, 2516, 229, 251, 1211, 1233, 2734, 2756, 3096, 3118),
SQUARE_MUSHROOM(1009, 1020, 1025, 1041, 2479, 2490, 2495, 2511, 539, 561, 1356, 1378, 1610, 1632, 2780, 2802),
SQUARE_SCALLOP(1004, 1012, 1026, 1039, 1045, 1049, 2474, 2482, 2496, 2509, 2515, 2519, 106, 128, 689, 711, 1795, 1817, 2676, 2698, 3050, 3072, 3420, 3442),
KITE_KITE(1168, 1173, 1179, 1184, 1521, 1526, 1532, 1537, 1985, 1990, 1996, 2001, 2338, 2343, 2349, 2354),
KITE_BARREL(1157, 1172, 1180, 1194, 1510, 1525, 1533, 1547, 1974, 1989, 1997, 2011, 2327, 2342, 2350, 2364, 438, 443, 449, 454, 1463, 1468, 1474, 1479, 2043, 2048, 2054, 2059, 2933, 2938, 2944, 2949),
KITE_SHIELD(1156, 1160, 1177, 1182, 1192, 1197, 1509, 1513, 1530, 1535, 1545, 1550, 1973, 1977, 1994, 1999, 2009, 2014, 2326, 2330, 2347, 2352, 2362, 2367, 355, 360, 366, 371, 600, 605, 611, 616, 1881, 1886, 1892, 1897, 2135, 2140, 2146, 2151, 2841, 2846, 2852, 2857, 3145, 3150, 3156, 3161),
KITE_lFIST(1166, 1167, 1171, 1178, 1188, 1193, 1519, 1520, 1524, 1531, 1541, 1546, 1983, 1984, 1988, 1995, 2005, 2010, 2336, 2337, 2341, 2348, 2358, 2363, 1064, 1069, 1075, 1080, 1122, 1127, 1133, 1138, 1417, 1422, 1428, 1433, 1939, 1944, 1950, 1955, 2534, 2539, 2545, 2550, 2887, 2892, 2898, 2903),
KITE_rFIST(1158, 1164, 1174, 1181, 1185, 1186, 1511, 1517, 1527, 1534, 1538, 1539, 1975, 1981, 1991, 1998, 2002, 2003, 2328, 2334, 2344, 2351, 2355, 2356, 496, 501, 507, 512, 960, 965, 971, 976, 1567, 1572, 1578, 1583, 2089, 2094, 2100, 2105, 2384, 2389, 2395, 2400, 2442, 2447, 2453, 2458),
KITE_lPAW(1161, 1163, 1183, 1198, 1514, 1516, 1536, 1551, 1978, 1980, 2000, 2015, 2331, 2333, 2353, 2368, 646, 651, 657, 662, 877, 882, 888, 893, 2280, 2285, 2291, 2296, 3253, 3258, 3264, 3269),
KITE_rPAW(1155, 1169, 1190, 1196, 1508, 1522, 1543, 1549, 1972, 1986, 2007, 2013, 2325, 2339, 2360, 2366, 232, 237, 243, 248, 1214, 1219, 1225, 1230, 2737, 2742, 2748, 2753, 3099, 3104, 3110, 3115),
KITE_MUSHROOM(1159, 1170, 1175, 1191, 1512, 1523, 1528, 1544, 1976, 1987, 1992, 2008, 2329, 2340, 2345, 2361, 542, 547, 553, 558, 1359, 1364, 1370, 1375, 1613, 1618, 1624, 1629, 2783, 2788, 2794, 2799),
KITE_SCALLOP(1154, 1162, 1176, 1189, 1195, 1199, 1507, 1515, 1529, 1542, 1548, 1552, 1971, 1979, 1993, 2006, 2012, 2016, 2324, 2332, 2346, 2359, 2365, 2369, 109, 114, 120, 125, 692, 697, 703, 708, 1798, 1803, 1809, 1814, 2679, 2684, 2690, 2695, 3053, 3058, 3064, 3069, 3423, 3428, 3434, 3439),
BARREL_BARREL(427, 442, 450, 464, 1452, 1467, 1475, 1489, 2032, 2047, 2055, 2069, 2922, 2937, 2945, 2959),
BARREL_SHIELD(426, 430, 447, 452, 462, 467, 1451, 1455, 1472, 1477, 1487, 1492, 2031, 2035, 2052, 2057, 2067, 2072, 2921, 2925, 2942, 2947, 2957, 2962, 344, 359, 367, 381, 589, 604, 612, 626, 1870, 1885, 1893, 1907, 2124, 2139, 2147, 2161, 2830, 2845, 2853, 2867, 3134, 3149, 3157, 3171),
BARREL_lFIST(436, 437, 441, 448, 458, 463, 1461, 1462, 1466, 1473, 1483, 1488, 2041, 2042, 2046, 2053, 2063, 2068, 2931, 2932, 2936, 2943, 2953, 2958, 1053, 1068, 1076, 1090, 1111, 1126, 1134, 1148, 1406, 1421, 1429, 1443, 1928, 1943, 1951, 1965, 2523, 2538, 2546, 2560, 2876, 2891, 2899, 2913),
BARREL_rFIST(428, 434, 444, 451, 455, 456, 1453, 1459, 1469, 1476, 1480, 1481, 2033, 2039, 2049, 2056, 2060, 2061, 2923, 2929, 2939, 2946, 2950, 2951, 485, 500, 508, 522, 949, 964, 972, 986, 1556, 1571, 1579, 1593, 2078, 2093, 2101, 2115, 2373, 2388, 2396, 2410, 2431, 2446, 2454, 2468),
BARREL_lPAW(431, 433, 453, 468, 1456, 1458, 1478, 1493, 2036, 2038, 2058, 2073, 2926, 2928, 2948, 2963, 635, 650, 658, 672, 866, 881, 889, 903, 2269, 2284, 2292, 2306, 3242, 3257, 3265, 3279),
BARREL_rPAW(425, 439, 460, 466, 1450, 1464, 1485, 1491, 2030, 2044, 2065, 2071, 2920, 2934, 2955, 2961, 221, 236, 244, 258, 1203, 1218, 1226, 1240, 2726, 2741, 2749, 2763, 3088, 3103, 3111, 3125),
BARREL_MUSHROOM(429, 440, 445, 461, 1454, 1465, 1470, 1486, 2034, 2045, 2050, 2066, 2924, 2935, 2940, 2956, 531, 546, 554, 568, 1348, 1363, 1371, 1385, 1602, 1617, 1625, 1639, 2772, 2787, 2795, 2809),
BARREL_SCALLOP(424, 432, 446, 459, 465, 469, 1449, 1457, 1471, 1484, 1490, 1494, 2029, 2037, 2051, 2064, 2070, 2074, 2919, 2927, 2941, 2954, 2960, 2964, 98, 113, 121, 135, 681, 696, 704, 718, 1787, 1802, 1810, 1824, 2668, 2683, 2691, 2705, 3042, 3057, 3065, 3079, 3412, 3427, 3435, 3449),
SHIELD_SHIELD(343, 347, 364, 369, 379, 384, 588, 592, 609, 614, 624, 629, 1869, 1873, 1890, 1895, 1905, 1910, 2123, 2127, 2144, 2149, 2159, 2164, 2829, 2833, 2850, 2855, 2865, 2870, 3133, 3137, 3154, 3159, 3169, 3174),
SHIELD_lFIST(353, 354, 358, 365, 375, 380, 598, 599, 603, 610, 620, 625, 1879, 1880, 1884, 1891, 1901, 1906, 2133, 2134, 2138, 2145, 2155, 2160, 2839, 2840, 2844, 2851, 2861, 2866, 3143, 3144, 3148, 3155, 3165, 3170, 1052, 1056, 1073, 1078, 1088, 1093, 1110, 1114, 1131, 1136, 1146, 1151, 1405, 1409, 1426, 1431, 1441, 1446, 1927, 1931, 1948, 1953, 1963, 1968, 2522, 2526, 2543, 2548, 2558, 2563, 2875, 2879, 2896, 2901, 2911, 2916),
SHIELD_rFIST(345, 351, 361, 368, 372, 373, 590, 596, 606, 613, 617, 618, 1871, 1877, 1887, 1894, 1898, 1899, 2125, 2131, 2141, 2148, 2152, 2153, 2831, 2837, 2847, 2854, 2858, 2859, 3135, 3141, 3151, 3158, 3162, 3163, 484, 488, 505, 510, 520, 525, 948, 952, 969, 974, 984, 989, 1555, 1559, 1576, 1581, 1591, 1596, 2077, 2081, 2098, 2103, 2113, 2118, 2372, 2376, 2393, 2398, 2408, 2413, 2430, 2434, 2451, 2456, 2466, 2471),
SHIELD_lPAW(348, 350, 370, 385, 593, 595, 615, 630, 1874, 1876, 1896, 1911, 2128, 2130, 2150, 2165, 2834, 2836, 2856, 2871, 3138, 3140, 3160, 3175, 634, 638, 655, 660, 670, 675, 865, 869, 886, 891, 901, 906, 2268, 2272, 2289, 2294, 2304, 2309, 3241, 3245, 3262, 3267, 3277, 3282),
SHIELD_rPAW(342, 356, 377, 383, 587, 601, 622, 628, 1868, 1882, 1903, 1909, 2122, 2136, 2157, 2163, 2828, 2842, 2863, 2869, 3132, 3146, 3167, 3173, 220, 224, 241, 246, 256, 261, 1202, 1206, 1223, 1228, 1238, 1243, 2725, 2729, 2746, 2751, 2761, 2766, 3087, 3091, 3108, 3113, 3123, 3128),
SHIELD_MUSHROOM(346, 357, 362, 378, 591, 602, 607, 623, 1872, 1883, 1888, 1904, 2126, 2137, 2142, 2158, 2832, 2843, 2848, 2864, 3136, 3147, 3152, 3168, 530, 534, 551, 556, 566, 571, 1347, 1351, 1368, 1373, 1383, 1388, 1601, 1605, 1622, 1627, 1637, 1642, 2771, 2775, 2792, 2797, 2807, 2812),
SHIELD_SCALLOP(341, 349, 363, 376, 382, 386, 586, 594, 608, 621, 627, 631, 1867, 1875, 1889, 1902, 1908, 1912, 2121, 2129, 2143, 2156, 2162, 2166, 2827, 2835, 2849, 2862, 2868, 2872, 3131, 3139, 3153, 3166, 3172, 3176, 97, 101, 118, 123, 133, 138, 680, 684, 701, 706, 716, 721, 1786, 1790, 1807, 1812, 1822, 1827, 2667, 2671, 2688, 2693, 2703, 2708, 3041, 3045, 3062, 3067, 3077, 3082, 3411, 3415, 3432, 3437, 3447, 3452),
llFIST_lFIST(1062, 1063, 1067, 1074, 1084, 1089, 1120, 1121, 1125, 1132, 1142, 1147, 1415, 1416, 1420, 1427, 1437, 1442, 1937, 1938, 1942, 1949, 1959, 1964, 2532, 2533, 2537, 2544, 2554, 2559, 2885, 2886, 2890, 2897, 2907, 2912),
lFIST_rFIST(1054, 1060, 1070, 1077, 1081, 1082, 1112, 1118, 1128, 1135, 1139, 1140, 1407, 1413, 1423, 1430, 1434, 1435, 1929, 1935, 1945, 1952, 1956, 1957, 2524, 2530, 2540, 2547, 2551, 2552, 2877, 2883, 2893, 2900, 2904, 2905, 494, 495, 499, 506, 516, 521, 958, 959, 963, 970, 980, 985, 1565, 1566, 1570, 1577, 1587, 1592, 2087, 2088, 2092, 2099, 2109, 2114, 2382, 2383, 2387, 2394, 2404, 2409, 2440, 2441, 2445, 2452, 2462, 2467),
lFIST_lPAW(1057, 1059, 1079, 1094, 1115, 1117, 1137, 1152, 1410, 1412, 1432, 1447, 1932, 1934, 1954, 1969, 2527, 2529, 2549, 2564, 2880, 2882, 2902, 2917, 644, 645, 649, 656, 666, 671, 875, 876, 880, 887, 897, 902, 2278, 2279, 2283, 2290, 2300, 2305, 3251, 3252, 3256, 3263, 3273, 3278),
lFIST_rPAW(1051, 1065, 1086, 1092, 1109, 1123, 1144, 1150, 1404, 1418, 1439, 1445, 1926, 1940, 1961, 1967, 2521, 2535, 2556, 2562, 2874, 2888, 2909, 2915, 230, 231, 235, 242, 252, 257, 1212, 1213, 1217, 1224, 1234, 1239, 2735, 2736, 2740, 2747, 2757, 2762, 3097, 3098, 3102, 3109, 3119, 3124),
lFIST_MUSHROOM(1055, 1066, 1071, 1087, 1113, 1124, 1129, 1145, 1408, 1419, 1424, 1440, 1930, 1941, 1946, 1962, 2525, 2536, 2541, 2557, 2878, 2889, 2894, 2910, 540, 541, 545, 552, 562, 567, 1357, 1358, 1362, 1369, 1379, 1384, 1611, 1612, 1616, 1623, 1633, 1638, 2781, 2782, 2786, 2793, 2803, 2808),
lFIST_SCALLOP(1050, 1058, 1072, 1085, 1091, 1095, 1108, 1116, 1130, 1143, 1149, 1153, 1403, 1411, 1425, 1438, 1444, 1448, 1925, 1933, 1947, 1960, 1966, 1970, 2520, 2528, 2542, 2555, 2561, 2565, 2873, 2881, 2895, 2908, 2914, 2918, 107, 108, 112, 119, 129, 134, 690, 691, 695, 702, 712, 717, 1796, 1797, 1801, 1808, 1818, 1823, 2677, 2678, 2682, 2689, 2699, 2704, 3051, 3052, 3056, 3063, 3073, 3078, 3421, 3422, 3426, 3433, 3443, 3448),
rFIST_rFIST(486, 492, 502, 509, 513, 514, 950, 956, 966, 973, 977, 978, 1557, 1563, 1573, 1580, 1584, 1585, 2079, 2085, 2095, 2102, 2106, 2107, 2374, 2380, 2390, 2397, 2401, 2402, 2432, 2438, 2448, 2455, 2459, 2460),
rFIST_lPAW(489, 491, 511, 526, 953, 955, 975, 990, 1560, 1562, 1582, 1597, 2082, 2084, 2104, 2119, 2377, 2379, 2399, 2414, 2435, 2437, 2457, 2472, 636, 642, 652, 659, 663, 664, 867, 873, 883, 890, 894, 895, 2270, 2276, 2286, 2293, 2297, 2298, 3243, 3249, 3259, 3266, 3270, 3271),
rFIST_rPAW(483, 497, 518, 524, 947, 961, 982, 988, 1554, 1568, 1589, 1595, 2076, 2090, 2111, 2117, 2371, 2385, 2406, 2412, 2429, 2443, 2464, 2470, 222, 228, 238, 245, 249, 250, 1204, 1210, 1220, 1227, 1231, 1232, 2727, 2733, 2743, 2750, 2754, 2755, 3089, 3095, 3105, 3112, 3116, 3117),
rFIST_MUSHROOM(487, 498, 503, 519, 951, 962, 967, 983, 1558, 1569, 1574, 1590, 2080, 2091, 2096, 2112, 2375, 2386, 2391, 2407, 2433, 2444, 2449, 2465, 532, 538, 548, 555, 559, 560, 1349, 1355, 1365, 1372, 1376, 1377, 1603, 1609, 1619, 1626, 1630, 1631, 2773, 2779, 2789, 2796, 2800, 2801),
rFIST_SCALLOP(482, 490, 504, 517, 523, 527, 946, 954, 968, 981, 987, 991, 1553, 1561, 1575, 1588, 1594, 1598, 2075, 2083, 2097, 2110, 2116, 2120, 2370, 2378, 2392, 2405, 2411, 2415, 2428, 2436, 2450, 2463, 2469, 2473, 99, 105, 115, 122, 126, 127, 682, 688, 698, 705, 709, 710, 1788, 1794, 1804, 1811, 1815, 1816, 2669, 2675, 2685, 2692, 2696, 2697, 3043, 3049, 3059, 3066, 3070, 3071, 3413, 3419, 3429, 3436, 3440, 3441),
lPAW_lPAW(639, 641, 661, 676, 870, 872, 892, 907, 2273, 2275, 2295, 2310, 3246, 3248, 3268, 3283),
lPAW_rPAW(633, 647, 668, 674, 864, 878, 899, 905, 2267, 2281, 2302, 2308, 3240, 3254, 3275, 3281, 633, 647, 668, 674, 864, 878, 899, 905, 2267, 2281, 2302, 2308, 3240, 3254, 3275, 3281),
lPAW_MUSHROOM(637, 648, 653, 669, 868, 879, 884, 900, 2271, 2282, 2287, 2303, 3244, 3255, 3260, 3276, 540, 541, 545, 552, 562, 567, 1357, 1358, 1362, 1369, 1379, 1384, 1611, 1612, 1616, 1623, 1633, 1638, 2781, 2782, 2786, 2793, 2803, 2808),
lPAW_SCALLOP(632, 640, 654, 667, 673, 677, 863, 871, 885, 898, 904, 908, 2266, 2274, 2288, 2301, 2307, 2311, 3239, 3247, 3261, 3274, 3280, 3284, 102, 104, 124, 139, 685, 687, 707, 722, 1791, 1793, 1813, 1828, 2672, 2674, 2694, 2709, 3046, 3048, 3068, 3083, 3416, 3418, 3438, 3453),
rPAW_rPAW(219, 233, 254, 260, 1201, 1215, 1236, 1242, 2724, 2738, 2759, 2765, 3086, 3100, 3121, 3127),
rPAW_MUSHROOM(223, 234, 239, 255, 1205, 1216, 1221, 1237, 2728, 2739, 2744, 2760, 3090, 3101, 3106, 3122, 529, 543, 564, 570, 1346, 1360, 1381, 1387, 1600, 1614, 1635, 1641, 2770, 2784, 2805, 2811),
rPAW_SCALLOP(218, 226, 240, 253, 259, 263, 1200, 1208, 1222, 1235, 1241, 1245, 2723, 2731, 2745, 2758, 2764, 2768, 3085, 3093, 3107, 3120, 3126, 3130, 96, 110, 131, 137, 679, 693, 714, 720, 1785, 1799, 1820, 1826, 2666, 2680, 2701, 2707, 3040, 3054, 3075, 3081, 3410, 3424, 3445, 3451),
MUSHROOM_MUSHROOM(533, 544, 549, 565, 1350, 1361, 1366, 1382, 1604, 1615, 1620, 1636, 2774, 2785, 2790, 2806),
MUSHROOM_SCALLOP(528, 536, 550, 563, 569, 573, 1345, 1353, 1367, 1380, 1386, 1390, 1599, 1607, 1621, 1634, 1640, 1644, 2769, 2777, 2791, 2804, 2810, 2814, 100, 111, 116, 132, 683, 694, 699, 715, 1789, 1800, 1805, 1821, 2670, 2681, 2686, 2702, 3044, 3055, 3060, 3076, 3414, 3425, 3430, 3446),
SCALLOP_SCALLOP(95, 103, 117, 130, 136, 140, 678, 686, 700, 713, 719, 723, 1784, 1792, 1806, 1819, 1825, 1829, 2665, 2673, 2687, 2700, 2706, 2710, 3039, 3047, 3061, 3074, 3080, 3084, 3409, 3417, 3431, 3444, 3450, 3454);
/**
* represents all possible values of alignments to a same cube shape.
*/
public int[] indexes;
CubeShapeIndex(int... indexes) {
this.indexes = indexes;
}
/**
* This is used to get a random index -- a random alignment -- of
* the cube shape.
*
* @return a integer value wich represents the cube shape.
*/
public int randomIndex(){
Random r = new Random(System.nanoTime());
return indexes[r.nextInt(indexes.length)];
}
}
private CubeShapeIndex customCubeShapeCase;
private Random random;
public CustomCubeShapeScrambler() {
/*pass*/
}
/**
* Creates a new object using a specific value from CubeShapeIndex
* enumeration.
*
* @param customCubeShapeCase the custom cube shape result you aim for.
*/
public CustomCubeShapeScrambler(CubeShapeIndex customCubeShapeCase) {
this.customCubeShapeCase = customCubeShapeCase;
}
/**
* Use this to get a full scramble sequence generated to current
* {@code customCubeShapeCase} passed.
*
* @return a finished random state scramble to specified cube shape.
*/
public String randomStateScramble() {
return randomStateScramble(random);
}
public String randomStateScramble(Random r){
return new Search().solution(getRandomCube(r));
}
/**
* This wil return a main.sq12phase.FullCube built in the passed shape index.
*
* @return a full cube built in the specified cube shape value.
*/
public FullCube getRandomCube() {
return getRandomCube(random);
}
public FullCube getRandomCube(Random r){
/*
just takes a specific index of the array, instead a random in
it full length (3678).
*/
int shape = Shape.ShapeIdx[customCubeShapeCase.randomIndex()];
FullCube f = new FullCube();
int corner = 0x01234567 << 1 | 0x11111111;
int edge = 0x01234567 << 1;
int n_corner = 8, n_edge = 8;
int rnd;
int m;
for (int i = 0; i < 24; i++) {
if (((shape >> i) & 1) == 0) {//edge
rnd = r.nextInt(n_edge) << 2;
f.setPiece(23 - i, (edge >> rnd) & 0xf);
m = (1 << rnd) - 1;
edge = (edge & m) + ((edge >> 4) & ~m);
--n_edge;
} else {//corner
rnd = r.nextInt(n_corner) << 2;
f.setPiece(23 - i, (corner >> rnd) & 0xf);
f.setPiece(22 - i, (corner >> rnd) & 0xf);
m = (1 << rnd) - 1;
corner = (corner & m) + ((corner >> 4) & ~m);
--n_corner;
++i;
}
}
f.ml = r.nextInt(2);
return f;
}
public CubeShapeIndex getCustomCubeShapeCase() {
return customCubeShapeCase;
}
public void setCustomCubeShapeCase(CubeShapeIndex customCubeShapeCase) {
this.customCubeShapeCase = customCubeShapeCase;
}
public Random getRandom() {
return random;
}
public void setRandom(Random random) {
this.random = random;
}
/**
* Example of use.
*
* @param args ?
*/
public static void main(String[] args) {
CustomCubeShapeScrambler generator = new CustomCubeShapeScrambler();
//GENERATING SCRAMBLES TO A SINGLE CASE
generator.setCustomCubeShapeCase(CubeShapeIndex.x8_STAR);
for (int i = 0; i < 50; i++) {
System.out.println(generator.randomStateScramble());
}
System.out.println();
System.out.println();
//GENERATING SCRAMBLES BASED IN A LIST OF CASES
CustomCubeShapeScrambler.CubeShapeIndex[] userCases = {
CubeShapeIndex.x8_STAR,
CubeShapeIndex.KITE_SCALLOP,
CubeShapeIndex.SQUARE_SHIELD
};
for (int i = 0; i < 50; i++) {
//set to a random userCase (CubeShapeIndex)
generator.setCustomCubeShapeCase(userCases[generator.random.nextInt(userCases.length)]);
System.out.println(generator.randomStateScramble());
}
}
}
package main.sq12phase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class FullCube implements Comparable<FullCube> {
int ul = 0x011233;
int ur = 0x455677;
int dl = 0x998bba;
int dr = 0xddcffe;
int ml = 0;
FullCube(String s) { //whats param s? scramble?
//TODO
}
public FullCube() {
}
/**
* Applies a move to a cube face (true for top and false to bottom).
* The {@code move} param is taked as we have in standard scrambles.
*
* Example:
* (6, -5) -> move(true, 6); move(false, -5);
*
* @param face The face you want to move.
* @param move the value of the move you want to do.
*/
public void move(boolean face, int move){
this.doMove(face ? (move > 0 ? move : 12 - (move * -1)) : (move > 0 ? move : 12 - (move * -1)) * -1);
}
/**
* Applies a twist (slash "/") to current cube.
*/
public void twist(){
if (this.isTwistable()){
this.doMove(0);
}
}
static Random r = new Random();
public static FullCube randomCube() {
return randomCube(r);
}
public static FullCube randomCube(Random r) {
int shape = Shape.ShapeIdx[r.nextInt(3678)];
FullCube f = new FullCube();
int corner = 0x01234567 << 1 | 0x11111111;
int edge = 0x01234567 << 1;
int n_corner = 8, n_edge = 8;
buildRandomCube(r, shape, f, corner, edge, n_corner, n_edge);
f.ml = r.nextInt(2);
return f;
}
public static FullCube randomCube(Random r, int indiceDoShape) {
int shape = Shape.ShapeIdx[indiceDoShape];
FullCube f = new FullCube();
int corner = 0x01234567 << 1 | 0x11111111;
int edge = 0x01234567 << 1;
int n_corner = 8, n_edge = 8;
buildRandomCube(r, shape, f, corner, edge, n_corner, n_edge);
f.ml = r.nextInt(2);
return f;
}
private static void buildRandomCube(Random r, int shape, FullCube f, int corner, int edge, int n_corner, int n_edge) {
int rnd;
int m;
for (int i = 0; i < 24; i++) {
if (((shape >> i) & 1) == 0) {//edge
rnd = r.nextInt(n_edge) << 2;
f.setPiece(23 - i, (edge >> rnd) & 0xf);
m = (1 << rnd) - 1;
edge = (edge & m) + ((edge >> 4) & ~m);
--n_edge;
} else {//corner
rnd = r.nextInt(n_corner) << 2;
f.setPiece(23 - i, (corner >> rnd) & 0xf);
f.setPiece(22 - i, (corner >> rnd) & 0xf);
m = (1 << rnd) - 1;
corner = (corner & m) + ((corner >> 4) & ~m);
--n_corner;
++i;
}
}
}
/**
* @param move
* 0 = twist
* [1, 11] = top move
* [-1, -11] = bottom move
* for example, 6 == (6, 0), 9 == (-3, 0), -4 == (0, 4)
*/
public void doMove(int move) {
move <<= 2;
if (move > 24) {
move = 48 - move;
int temp = ul;
ul = (ul >> move | ur << (24 - move)) & 0xffffff;
ur = (ur >> move | temp << (24 - move)) & 0xffffff;
} else if (move > 0) {
int temp = ul;
ul = (ul << move | ur >> (24 - move)) & 0xffffff;
ur = (ur << move | temp >> (24 - move)) & 0xffffff;
} else if (move == 0) {
int temp = ur;
ur = dl;
dl = temp;
ml = 1 - ml;
} else if (move >= -24) {
move = -move;
int temp = dl;
dl = (dl << move | dr >> (24 - move)) & 0xffffff;
dr = (dr << move | temp >> (24 - move)) & 0xffffff;
} else if (move < -24) {
move = 48 + move;
int temp = dl;
dl = (dl >> move | dr << (24 - move)) & 0xffffff;
dr = (dr >> move | temp << (24 - move)) & 0xffffff;
}
}
public byte pieceAt(int idx) {
int ret;
if (idx < 6) {
ret = ul >> ((5 - idx) << 2);
} else if (idx < 12) {
ret = ur >> ((11 - idx) << 2);
} else if (idx < 18) {
ret = dl >> ((17 - idx) << 2);
} else {
ret = dr >> ((23 - idx) << 2);
}
return (byte) (ret & 0x0f);
}
public void setPiece(int idx, int value) {
if (idx < 6) {
ul &= ~(0xf << ((5 - idx) << 2));
ul |= value << ((5 - idx) << 2);
} else if (idx < 12) {
ur &= ~(0xf << ((11 - idx) << 2));
ur |= value << ((11 - idx) << 2);
} else if (idx < 18) {
dl &= ~(0xf << ((17 - idx) << 2));
dl |= value << ((17 - idx) << 2);
} else if (idx < 24) {
dr &= ~(0xf << ((23 - idx) << 2));
dr |= value << ((23 - idx) << 2);
} else {
ml = value;
}
}
int[] arr = new int[16];
int getParity() {
int cnt = 0;
arr[0] = pieceAt(0);
for (int i = 1; i < 24; i++) {
if (pieceAt(i) != arr[cnt]) {
arr[++cnt] = pieceAt(i);
}
}
int p = 0;
for (int a = 0; a < 16; a++) {
for (int b = a + 1 ; b < 16 ; b++) {
if (arr[a] > arr[b]) {
p ^= 1;
}
}
}
return p;
}
boolean isTwistable() {
return pieceAt(0) != pieceAt(11)
&& pieceAt(5) != pieceAt(6)
&& pieceAt(12) != pieceAt(23)
&& pieceAt(17) != pieceAt(18);
}
int getShapeIdx() {
int urx = ur & 0x111111;
urx |= urx >> 3;
urx |= urx >> 6;
urx = (urx & 0xf) | ((urx >> 12) & 0x30);
int ulx = ul & 0x111111;
ulx |= ulx >> 3;
ulx |= ulx >> 6;
ulx = (ulx & 0xf) | ((ulx >> 12) & 0x30);
int drx = dr & 0x111111;
drx |= drx >> 3;
drx |= drx >> 6;
drx = (drx & 0xf) | ((drx >> 12) & 0x30);
int dlx = dl & 0x111111;
dlx |= dlx >> 3;
dlx |= dlx >> 6;
dlx = (dlx & 0xf) | ((dlx >> 12) & 0x30);
return Shape.getShape2Idx(getParity() << 24 | ulx << 18 | urx << 12 | dlx << 6 | drx);
}
void print() {
System.out.println(Integer.toHexString(ul));
System.out.println(Integer.toHexString(ur));
System.out.println(Integer.toHexString(dl));
System.out.println(Integer.toHexString(dr));
}
byte[] prm = new byte[8];
void getSquare(Square sq) {
for (int a = 0; a < 8; a++) {
prm[a] = (byte) (pieceAt(a * 3 + 1) >> 1);
}
//convert to number
sq.cornperm = Square.get8Perm(prm);
int a, b;
//Strip top layer edges
sq.topEdgeFirst = pieceAt(0) == pieceAt(1);
a = sq.topEdgeFirst ? 2 : 0;
for (b = 0; b < 4; a += 3, b++) {
prm[b] = (byte)(pieceAt(a) >> 1);
}
sq.botEdgeFirst = pieceAt(12) == pieceAt(13);
a = sq.botEdgeFirst ? 14 : 12;
for ( ; b < 8; a += 3, b++) {
prm[b] = (byte)(pieceAt(a) >> 1);
}
sq.edgeperm = Square.get8Perm(prm);
sq.ml = ml;
}
/**
* Returns a "binary" representation to this cube.
* Each edge is a 0 and each corner is a 1.
* This is usefull to shape analysis.
*
* The pieces from top are represented from UB edge to UBL corner (clock-wise).
* The pieces from bottom are represented from DF edge to DFL corner (clock-wise).
*
* @param face the face you want to see binary representation.
* @return a binary representation of a square-1 face.
*/
public String binString(boolean face){
String r = "";
r += pieceAt(face ? 0 : 17) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 11 : 16) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 10 : 15) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 9 : 14) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 8 : 13) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 7 : 12) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 6 : 23) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 5 : 22) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 4 : 21) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 3 : 20) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 2 : 19) % 2 == 0 ? 0 : 1;
r += pieceAt(face ? 1 : 18) % 2 == 0 ? 0 : 1;
return r;
}
public void copy(FullCube c) {
this.ul = c.ul;
this.ur = c.ur;
this.dl = c.dl;
this.dr = c.dr;
this.ml = c.ml;
}
@Override
public int compareTo(FullCube f) {
if (ul != f.ul) {
return ul - f.ul;
}
if (ur != f.ur) {
return ur - f.ur;
}
if (dl != f.dl) {
return dl - f.dl;
}
if (dr != f.dr) {
return dr - f.dr;
}
return ml - f.ml;
}
@Override
public String toString() {
/*
* COMEÇA A CONTAR NA PEÇA WO E VAI INDO ANTIHORÁRIO
*
* 0 = WO
* 1 = WOG
* 2 = WG
* 3 = WGR
* 4 = WR
* 5 = WRB
* 6 = WB
* 7 = WBO
*
* 8 = YB
* 9 = YBO
* 10 = YR
* 11 = YRB
* 12 = YG
* 13 = YRG
* 14 = YO
* 15 = YGO
*/
ArrayList<Byte> aux = new ArrayList<>();
for (int i = 0; i < 24; i++) {
aux.add(pieceAt(i));
}
return aux.toString();
//return fullBin();
}
}
package main.sq12phase;
public class Search {
int[] move = new int[100];
FullCube c = null;
FullCube d = new FullCube("");
int length1;
int maxlen2;
String sol_string;
static int getNParity(int idx, int n) {
int p = 0;
for (int i = n - 2; i >= 0; i--) {
p ^= idx % (n - i);
idx /= (n - i);
}
return p & 1;
}
static {
Shape.init();
Square.init();
}
public String solution(FullCube c) {
this.c = c;
sol_string = null;
int shape = c.getShapeIdx();
for (length1 = Shape.ShapePrun[shape]; length1 < 100; length1++) {
maxlen2 = Math.min(31 - length1, 17);
if (phase1(shape, Shape.ShapePrun[shape], length1, 0, -1)) {
break;
}
}
return sol_string;
}
public String solutionOpt(FullCube c, int maxl) {
this.c = c;
sol_string = null;
int shape = c.getShapeIdx();
for (length1 = Shape.ShapePrunOpt[shape]; length1 <= maxl; length1++) {
if (phase1Opt(shape, Shape.ShapePrunOpt[shape], length1, 0, -1)) {
break;
}
}
return sol_string;
}
boolean phase1Opt(int shape, int prunvalue, int maxl, int depth, int lm) {
if (maxl == 0) {
return isSolvedInPhase1();
}
//try each possible move. First twist;
if (lm != 0) {
int shapex = Shape.TwistMove[shape];
int prunx = Shape.ShapePrunOpt[shapex];
if (prunx < maxl) {
move[depth] = 0;
if (phase1Opt(shapex, prunx, maxl - 1, depth + 1, 0)) {
return true;
}
}
}
//Try top layer
int shapex = shape;
if (lm <= 0) {
int m = 0;
while (true) {
m += Shape.TopMove[shapex];
shapex = m >> 4;
m &= 0xf;
if (m >= 12) {
break;
}
int prunx = Shape.ShapePrunOpt[shapex];
if (prunx > maxl) {
break;
} else if (prunx == maxl) {
continue;
}
move[depth] = m;
if (phase1Opt(shapex, prunx, maxl - 1, depth + 1, 1)) {
return true;
}
}
}
shapex = shape;
//Try bottom layer
if (lm <= 1) {
int m = 0;
while (true) {
m += Shape.BottomMove[shapex];
shapex = m >> 4;
m &= 0xf;
if (m >= 12) {
break;
}
int prunx = Shape.ShapePrunOpt[shapex];
if (prunx > maxl) {
break;
} else if (prunx < maxl) {
move[depth] = -m;
if (phase1Opt(shapex, prunx, maxl - 1, depth + 1, 2)) {
return true;
}
}
}
}
return false;
}
boolean phase1(int shape, int prunvalue, int maxl, int depth, int lm) {
if (prunvalue == 0 && maxl < 4) {
return maxl == 0 && init2();
}
//try each possible move. First twist;
if (lm != 0) {
int shapex = Shape.TwistMove[shape];
int prunx = Shape.ShapePrun[shapex];
if (prunx < maxl) {
move[depth] = 0;
if (phase1(shapex, prunx, maxl - 1, depth + 1, 0)) {
return true;
}
}
}
//Try top layer
int shapex = shape;
if (lm <= 0) {
int m = 0;
while (true) {
m += Shape.TopMove[shapex];
shapex = m >> 4;
m &= 0xf;
if (m >= 12) {
break;
}
int prunx = Shape.ShapePrun[shapex];
if (prunx > maxl) {
break;
} else if (prunx < maxl) {
move[depth] = m;
if (phase1(shapex, prunx, maxl - 1, depth + 1, 1)) {
return true;
}
}
}
}
shapex = shape;
//Try bottom layer
if (lm <= 1) {
int m = 0;
while (true) {
m += Shape.BottomMove[shapex];
shapex = m >> 4;
m &= 0xf;
if (m >= 6) {
break;
}
int prunx = Shape.ShapePrun[shapex];
if (prunx > maxl) {
break;
} else if (prunx < maxl) {
move[depth] = -m;
if (phase1(shapex, prunx, maxl - 1, depth + 1, 2)) {
return true;
}
}
}
}
return false;
}
int count = 0;
Square sq = new Square();
boolean isSolvedInPhase1() {
d.copy(c);
for (int i = 0; i < length1; i++) {
d.doMove(move[i]);
}
boolean isSolved = d.ul == 0x011233 && d.ur == 0x455677 && d.dl == 0x998bba && d.dr == 0xddcffe && d.ml == 0;
if (isSolved) {
sol_string = move2string(length1);
}
return isSolved;
}
boolean init2() {
d.copy(c);
for (int i = 0; i < length1; i++) {
d.doMove(move[i]);
}
assert Shape.ShapePrun[d.getShapeIdx()] == 0;
d.getSquare(sq);
int edge = sq.edgeperm;
int corner = sq.cornperm;
int ml = sq.ml;
int prun = Math.max(Square.SquarePrun[sq.edgeperm << 1 | ml], Square.SquarePrun[sq.cornperm << 1 | ml]);
for (int i = prun; i < maxlen2; i++) {
if (phase2(edge, corner, sq.topEdgeFirst, sq.botEdgeFirst, ml, i, length1, 0)) {
sol_string = move2string(i + length1);
return true;
}
}
return false;
}
int[] pruncomb = new int[100];
String move2string(int len) {
//TODO whether to invert the solution or not should be set by params.
StringBuffer s = new StringBuffer();
int top = 0, bottom = 0;
for (int i = len - 1; i >= 0; i--) {
int val = move[i];
if (val > 0) {
val = 12 - val;
top = (val > 6) ? (val - 12) : val;
} else if (val < 0) {
val = 12 + val;
bottom = (val > 6) ? (val - 12) : val;
} else {
if (top == 0 && bottom == 0) {
s.append(" / ");
} else {
s.append('(').append(top).append(",").append(bottom).append(") / ");
}
top = 0;
bottom = 0;
}
}
if (top == 0 && bottom == 0) {
} else {
s.append('(').append(top).append(",").append(bottom).append(")");
}
return s.toString();
}
boolean phase2(int edge, int corner, boolean topEdgeFirst, boolean botEdgeFirst, int ml, int maxl, int depth, int lm) {
if (maxl == 0 && !topEdgeFirst && botEdgeFirst) {
assert edge == 0 && corner == 0 && ml == 0;
return true;
}
//try each possible move. First twist;
if (lm != 0 && topEdgeFirst == botEdgeFirst) {
int edgex = Square.TwistMove[edge];
int cornerx = Square.TwistMove[corner];
if (Square.SquarePrun[edgex << 1 | (1 - ml)] < maxl && Square.SquarePrun[cornerx << 1 | (1 - ml)] < maxl) {
move[depth] = 0;
if (phase2(edgex, cornerx, topEdgeFirst, botEdgeFirst, 1 - ml, maxl - 1, depth + 1, 0)) {
return true;
}
}
}
//Try top layer
if (lm <= 0) {
boolean topEdgeFirstx = !topEdgeFirst;
int edgex = topEdgeFirstx ? Square.TopMove[edge] : edge;
int cornerx = topEdgeFirstx ? corner : Square.TopMove[corner];
int m = topEdgeFirstx ? 1 : 2;
int prun1 = Square.SquarePrun[edgex << 1 | ml];
int prun2 = Square.SquarePrun[cornerx << 1 | ml];
while (m < 12 && prun1 <= maxl && prun1 <= maxl) {
if (prun1 < maxl && prun2 < maxl) {
move[depth] = m;
if (phase2(edgex, cornerx, topEdgeFirstx, botEdgeFirst, ml, maxl - 1, depth + 1, 1)) {
return true;
}
}
topEdgeFirstx = !topEdgeFirstx;
if (topEdgeFirstx) {
edgex = Square.TopMove[edgex];
prun1 = Square.SquarePrun[edgex << 1 | ml];
m += 1;
} else {
cornerx = Square.TopMove[cornerx];
prun2 = Square.SquarePrun[cornerx << 1 | ml];
m += 2;
}
}
}
if (lm <= 1) {
boolean botEdgeFirstx = !botEdgeFirst;
int edgex = botEdgeFirstx ? Square.BottomMove[edge] : edge;
int cornerx = botEdgeFirstx ? corner : Square.BottomMove[corner];
int m = botEdgeFirstx ? 1 : 2;
int prun1 = Square.SquarePrun[edgex << 1 | ml];
int prun2 = Square.SquarePrun[cornerx << 1 | ml];
while (m < (maxl > 6 ? 6 : 12) && prun1 <= maxl && prun1 <= maxl) {
if (prun1 < maxl && prun2 < maxl) {
move[depth] = -m;
if (phase2(edgex, cornerx, topEdgeFirst, botEdgeFirstx, ml, maxl - 1, depth + 1, 2)) {
return true;
}
}
botEdgeFirstx = !botEdgeFirstx;
if (botEdgeFirstx) {
edgex = Square.BottomMove[edgex];
prun1 = Square.SquarePrun[edgex << 1 | ml];
m += 1;
} else {
cornerx = Square.BottomMove[cornerx];
prun2 = Square.SquarePrun[cornerx << 1 | ml];
m += 2;
}
}
}
return false;
}
}
package main.sq12phase;
import java.util.Arrays;
class Shape {
//1 = corner, 0 = edge.
static int[] halflayer = {0x00, 0x03, 0x06, 0x0c, 0x0f, 0x18, 0x1b, 0x1e,
0x30, 0x33, 0x36, 0x3c, 0x3f
};
static int[] ShapeIdx = new int[3678];
static int[] ShapePrun = new int[3768 * 2];
static int[] ShapePrunOpt = new int[3768 * 2];
static int[] TopMove = new int[3678 * 2];
static int[] BottomMove = new int[3678 * 2];
static int[] TwistMove = new int[3678 * 2];
private Shape() {}
int top;
int bottom;
int parity;
static int getShape2Idx(int shp) {
int ret = Arrays.binarySearch(ShapeIdx, shp & 0xffffff) << 1 | shp >> 24;
return ret;
}
int getIdx() {
int ret = Arrays.binarySearch(ShapeIdx, top << 12 | bottom) << 1 | parity;
return ret;
}
void setIdx(int idx) {
parity = idx & 1;
top = ShapeIdx[idx >> 1];
bottom = top & 0xfff;
top >>= 12;
}
int topMove() {
int move = 0;
int moveParity = 0;
do {
if ((top & 0x800) == 0) {
move += 1;
top = top << 1;
} else {
move += 2;
top = (top << 2) ^ 0x3003;
}
moveParity = 1 - moveParity;
} while ((Integer.bitCount(top & 0x3f) & 1) != 0);
if ((Integer.bitCount(top) & 2) == 0) {
parity ^= moveParity;
}
return move;
}
int bottomMove() {
int move = 0;
int moveParity = 0;
do {
if ((bottom & 0x800) == 0) {
move += 1;
bottom = bottom << 1;
} else {
move += 2;
bottom = (bottom << 2) ^ 0x3003;
}
moveParity = 1 - moveParity;
} while ((Integer.bitCount(bottom & 0x3f) & 1) != 0);
if ((Integer.bitCount(bottom) & 2) == 0) {
parity ^= moveParity;
}
return move;
}
void twistMove() {
int temp = top & 0x3f;
int p1 = Integer.bitCount(temp);
int p3 = Integer.bitCount(bottom & 0xfc0);
parity ^= 1 & ((p1 & p3) >> 1);
top = (top & 0xfc0) | ((bottom >> 6) & 0x3f);
bottom = (bottom & 0x3f) | temp << 6;
}
static boolean inited = false;
static void init() {
if (inited) {
return;
}
int count = 0;
for (int i = 0; i < 13 * 13 * 13 * 13; i++) {
int dr = halflayer[i % 13];
int dl = halflayer[i / 13 % 13];
int ur = halflayer[i / 13 / 13 % 13];
int ul = halflayer[i / 13 / 13 / 13];
int value = ul << 18 | ur << 12 | dl << 6 | dr;
if (Integer.bitCount(value) == 16) {
ShapeIdx[count++] = value;
}
}
// System.out.println(count);
Shape s = new Shape();
for (int i = 0; i < 3678 * 2; i++) {
s.setIdx(i);
TopMove[i] = s.topMove();
TopMove[i] |= s.getIdx() << 4;
s.setIdx(i);
BottomMove[i] = s.bottomMove();
BottomMove[i] |= s.getIdx() << 4;
s.setIdx(i);
s.twistMove();
TwistMove[i] = s.getIdx();
}
for (int i = 0; i < 3768 * 2; i++) {
ShapePrun[i] = -1;
ShapePrunOpt[i] = -1;
}
//0 110110110110 011011011011
//1 110110110110 110110110110
//1 011011011011 011011011011
//0 011011011011 110110110110
ShapePrun[getShape2Idx(0x0db66db)] = 0;
ShapePrun[getShape2Idx(0x1db6db6)] = 0;
ShapePrun[getShape2Idx(0x16db6db)] = 0;
ShapePrun[getShape2Idx(0x06dbdb6)] = 0;
ShapePrunOpt[new FullCube().getShapeIdx()] = 0;
int done = 4;
int done0 = 0;
int depth = -1;
while (done != done0) {
done0 = done;
++depth;
// System.out.println(done);
for (int i = 0; i < 3768 * 2; i++) {
if (ShapePrun[i] == depth) {
// try top
int m = 0;
int idx = i;
do {
idx = TopMove[idx];
m += idx & 0xf;
idx >>= 4;
if (ShapePrun[idx] == -1) {
++done;
ShapePrun[idx] = depth + 1;
}
} while (m != 12);
// try bottom
m = 0;
idx = i;
do {
idx = BottomMove[idx];
m += idx & 0xf;
idx >>= 4;
if (ShapePrun[idx] == -1) {
++done;
ShapePrun[idx] = depth + 1;
}
} while (m != 12);
// try twist
idx = TwistMove[i];
if (ShapePrun[idx] == -1) {
++done;
ShapePrun[idx] = depth + 1;
}
}
}
}
done = 1;
done0 = 0;
depth = -1;
while (done != done0) {
done0 = done;
++depth;
// System.out.println(done);
for (int i = 0; i < 3768 * 2; i++) {
if (ShapePrunOpt[i] == depth) {
// try top
int m = 0;
int idx = i;
do {
idx = TopMove[idx];
m += idx & 0xf;
idx >>= 4;
if (ShapePrunOpt[idx] == -1) {
++done;
ShapePrunOpt[idx] = depth + 1;
}
} while (m != 12);
// try bottom
m = 0;
idx = i;
do {
idx = BottomMove[idx];
m += idx & 0xf;
idx >>= 4;
if (ShapePrunOpt[idx] == -1) {
++done;
ShapePrunOpt[idx] = depth + 1;
}
} while (m != 12);
// try twist
idx = TwistMove[i];
if (ShapePrunOpt[idx] == -1) {
++done;
ShapePrunOpt[idx] = depth + 1;
}
}
}
}
inited = true;
}
}
package main.sq12phase;
class Square {
int edgeperm; //number encoding the edge permutation 0-40319
int cornperm; //number encoding the corner permutation 0-40319
boolean topEdgeFirst; //true if top layer starts with edge left of seam
boolean botEdgeFirst; //true if bottom layer starts with edge right of seam
int ml; //shape of middle layer (+/-1, or 0 if ignored)
static byte[] SquarePrun = new byte[40320 * 2]; //pruning table; #twists to solve corner|edge permutation
static char[] TwistMove = new char[40320]; //transition table for twists
static char[] TopMove = new char[40320]; //transition table for top layer turns
static char[] BottomMove = new char[40320]; //transition table for bottom layer turns
private static int[] fact = {1, 1, 2, 6, 24, 120, 720, 5040};
static void set8Perm(byte[] arr, int idx) {
int val = 0x76543210;
for (int i = 0; i < 7; i++) {
int p = fact[7 - i];
int v = idx / p;
idx -= v * p;
v <<= 2;
arr[i] = (byte) ((val >> v) & 07);
int m = (1 << v) - 1;
val = (val & m) + ((val >> 4) & ~m);
}
arr[7] = (byte)val;
}
static char get8Perm(byte[] arr) {
int idx = 0;
int val = 0x76543210;
for (int i = 0; i < 7; i++) {
int v = arr[i] << 2;
idx = (8 - i) * idx + ((val >> v) & 07);
val -= 0x11111110 << v;
}
return (char)idx;
}
static int[][] Cnk = new int[12][12];
static int get8Comb(byte[] arr) {
int idx = 0, r = 4;
for (int i = 0; i < 8; i++) {
if (arr[i] >= 4) {
idx += Cnk[7 - i][r--];
}
}
return idx;
}
static boolean inited = false;
static void init() {
if (inited) {
return;
}
for (int i = 0; i < 12; i++) {
Cnk[i][0] = 1;
Cnk[i][i] = 1;
for (int j = 1; j < i; j++) {
Cnk[i][j] = Cnk[i - 1][j - 1] + Cnk[i - 1][j];
}
}
byte[] pos = new byte[8];
byte temp;
for (int i = 0; i < 40320; i++) {
//twist
set8Perm(pos, i);
temp = pos[2]; pos[2] = pos[4]; pos[4] = temp;
temp = pos[3]; pos[3] = pos[5]; pos[5] = temp;
TwistMove[i] = get8Perm(pos);
//top layer turn
set8Perm(pos, i);
temp = pos[0]; pos[0] = pos[1]; pos[1] = pos[2]; pos[2] = pos[3]; pos[3] = temp;
TopMove[i] = get8Perm(pos);
//bottom layer turn
set8Perm(pos, i);
temp = pos[4]; pos[4] = pos[5]; pos[5] = pos[6]; pos[6] = pos[7]; pos[7] = temp;
BottomMove[i] = get8Perm(pos);
}
for (int i = 0; i < 40320 * 2; i++) {
SquarePrun[i] = -1;
}
SquarePrun[0] = 0;
int depth = 0;
int done = 1;
while (done < 40320 * 2) {
boolean inv = depth >= 11;
int find = inv ? -1 : depth;
int check = inv ? depth : -1;
++depth;
OUT:
for (int i = 0; i < 40320 * 2; i++) {
if (SquarePrun[i] == find) {
int idx = i >> 1;
int ml = i & 1;
//try twist
int idxx = TwistMove[idx] << 1 | (1 - ml);
if (SquarePrun[idxx] == check) {
++done;
SquarePrun[inv ? i : idxx] = (byte) (depth);
if (inv) {
continue OUT;
}
}
//try turning top layer
idxx = idx;
for (int m = 0; m < 4; m++) {
idxx = TopMove[idxx];
if (SquarePrun[idxx << 1 | ml] == check) {
++done;
SquarePrun[inv ? i : (idxx << 1 | ml)] = (byte) (depth);
if (inv) {
continue OUT;
}
}
}
assert idxx == idx;
//try turning bottom layer
for (int m = 0; m < 4; m++) {
idxx = BottomMove[idxx];
if (SquarePrun[idxx << 1 | ml] == check) {
++done;
SquarePrun[inv ? i : (idxx << 1 | ml)] = (byte) (depth);
if (inv) {
continue OUT;
}
}
}
}
}
// System.out.print(depth);
// System.out.print('\t');
// System.out.println(done);
}
inited = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment