Created
August 13, 2018 00:48
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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