diff options
Diffstat (limited to 'src/steps.c')
| -rw-r--r-- | src/steps.c | 1514 |
1 files changed, 127 insertions, 1387 deletions
diff --git a/src/steps.c b/src/steps.c index 3189811..81af269 100644 --- a/src/steps.c +++ b/src/steps.c | |||
| @@ -1,1372 +1,112 @@ | |||
| 1 | #include "steps.h" | 1 | #define STEPS_C |
| 2 | |||
| 3 | #define UPDATECHECKSTOP(a, b, c) if ((a=(MAX((a),(b))))>(c)) return (a); | ||
| 4 | |||
| 5 | /* Checkers, estimators and validators ***************************************/ | ||
| 6 | |||
| 7 | static bool check_centers(Cube cube); | ||
| 8 | static bool check_coud_HTM(Cube cube); | ||
| 9 | static bool check_coud_URF(Cube cube); | ||
| 10 | static bool check_corners_HTM(Cube cube); | ||
| 11 | static bool check_corners_URF(Cube cube); | ||
| 12 | static bool check_cornershtr(Cube cube); | ||
| 13 | static bool check_eofb(Cube cube); | ||
| 14 | static bool check_drud(Cube cube); | ||
| 15 | static bool check_htr(Cube cube); | ||
| 16 | |||
| 17 | static int estimate_eofb_HTM(DfsArg *arg); | ||
| 18 | static int estimate_coud_HTM(DfsArg *arg); | ||
| 19 | static int estimate_coud_URF(DfsArg *arg); | ||
| 20 | static int estimate_corners_HTM(DfsArg *arg); | ||
| 21 | static int estimate_cornershtr_HTM(DfsArg *arg); | ||
| 22 | static int estimate_corners_URF(DfsArg *arg); | ||
| 23 | static int estimate_cornershtr_URF(DfsArg *arg); | ||
| 24 | static int estimate_drud_HTM(DfsArg *arg); | ||
| 25 | static int estimate_drud_eofb(DfsArg *arg); | ||
| 26 | static int estimate_dr_eofb(DfsArg *arg); | ||
| 27 | static int estimate_drudfin_drud(DfsArg *arg); | ||
| 28 | static int estimate_htr_drud(DfsArg *arg); | ||
| 29 | static int estimate_htrfin_htr(DfsArg *arg); | ||
| 30 | static int estimate_nxopt31_HTM(DfsArg *arg); | ||
| 31 | static int estimate_light_HTM(DfsArg *arg); | ||
| 32 | |||
| 33 | static int estimate_nxoptlike(DfsArg *arg, PruneData *pd); | ||
| 34 | |||
| 35 | static bool always_valid(Alg *alg); | ||
| 36 | static bool validate_singlecw_ending(Alg *alg); | ||
| 37 | |||
| 38 | /* Pre-transformation detectors **********************************************/ | ||
| 39 | |||
| 40 | static int detect_pretrans_eofb(Cube cube, Trans *ret); | ||
| 41 | static int detect_pretrans_drud(Cube cube, Trans *ret); | ||
| 42 | static int detect_pretrans_void_3axis(Cube cube, Trans *ret); | ||
| 43 | |||
| 44 | /* Messages for when cube is not ready ***************************************/ | ||
| 45 | |||
| 46 | static char check_centers_msg[100] = "cube must be oriented (centers solved)"; | ||
| 47 | static char check_eo_msg[100] = "EO must be solved on given axis"; | ||
| 48 | static char check_dr_msg[100] = "DR must be solved on given axis"; | ||
| 49 | static char check_htr_msg[100] = "HTR must be solved"; | ||
| 50 | static char check_drany_msg[100] = "DR must be solved on at least one axis"; | ||
| 51 | |||
| 52 | /* Steps *********************************************************************/ | ||
| 53 | |||
| 54 | /* Optimal solvers *******************/ | ||
| 55 | |||
| 56 | Step | ||
| 57 | optimal_HTM = { | ||
| 58 | .shortname = "optimal", | ||
| 59 | .name = "Optimal solve (in HTM)", | ||
| 60 | |||
| 61 | .final = true, | ||
| 62 | .is_done = is_solved, | ||
| 63 | .estimate = estimate_nxopt31_HTM, | ||
| 64 | .ready = check_centers, | ||
| 65 | .ready_msg = check_centers_msg, | ||
| 66 | .is_valid = always_valid, | ||
| 67 | .moveset = &moveset_HTM, | ||
| 68 | |||
| 69 | .pre_trans = uf, | ||
| 70 | |||
| 71 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 72 | .ntables = 2, | ||
| 73 | }; | ||
| 74 | |||
| 75 | Step | ||
| 76 | optimal_light_HTM = { | ||
| 77 | .shortname = "light", | ||
| 78 | .name = "Optimal solve (in HTM), small table (500Mb RAM total)", | ||
| 79 | |||
| 80 | .final = true, | ||
| 81 | .is_done = is_solved, | ||
| 82 | .estimate = estimate_light_HTM, | ||
| 83 | .ready = check_centers, | ||
| 84 | .ready_msg = check_centers_msg, | ||
| 85 | .is_valid = always_valid, | ||
| 86 | .moveset = &moveset_HTM, | ||
| 87 | |||
| 88 | .pre_trans = uf, | ||
| 89 | |||
| 90 | .tables = {&pd_drud_sym16_HTM, &pd_corners_HTM}, | ||
| 91 | .ntables = 2, | ||
| 92 | }; | ||
| 93 | |||
| 94 | /* Optimal after EO ******************/ | ||
| 95 | |||
| 96 | Step | ||
| 97 | eofin_eo = { | ||
| 98 | .shortname = "eofin", | ||
| 99 | .name = "Optimal solve after EO without breaking EO (detected)", | ||
| 100 | |||
| 101 | .final = true, | ||
| 102 | .is_done = is_solved, | ||
| 103 | .estimate = estimate_nxopt31_HTM, | ||
| 104 | .ready = check_eofb, | ||
| 105 | .ready_msg = check_eo_msg, | ||
| 106 | .is_valid = always_valid, | ||
| 107 | .moveset = &moveset_eofb, | ||
| 108 | |||
| 109 | .detect = detect_pretrans_eofb, | ||
| 110 | |||
| 111 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 112 | .ntables = 2, | ||
| 113 | }; | ||
| 114 | |||
| 115 | Step | ||
| 116 | eofbfin_eofb = { | ||
| 117 | .shortname = "eofbfin", | ||
| 118 | .name = "Optimal after EO on F/B without breaking EO", | ||
| 119 | |||
| 120 | .final = true, | ||
| 121 | .is_done = is_solved, | ||
| 122 | .estimate = estimate_nxopt31_HTM, | ||
| 123 | .ready = check_eofb, | ||
| 124 | .ready_msg = check_eo_msg, | ||
| 125 | .is_valid = always_valid, | ||
| 126 | .moveset = &moveset_eofb, | ||
| 127 | |||
| 128 | .pre_trans = uf, | ||
| 129 | |||
| 130 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 131 | .ntables = 2, | ||
| 132 | }; | ||
| 133 | |||
| 134 | Step | ||
| 135 | eorlfin_eorl = { | ||
| 136 | .shortname = "eorlfin", | ||
| 137 | .name = "Optimal after EO on R/L without breaking EO", | ||
| 138 | |||
| 139 | .final = true, | ||
| 140 | .is_done = is_solved, | ||
| 141 | .estimate = estimate_nxopt31_HTM, | ||
| 142 | .ready = check_eofb, | ||
| 143 | .ready_msg = check_eo_msg, | ||
| 144 | .is_valid = always_valid, | ||
| 145 | .moveset = &moveset_eofb, | ||
| 146 | |||
| 147 | .pre_trans = ur, | ||
| 148 | |||
| 149 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 150 | .ntables = 2, | ||
| 151 | }; | ||
| 152 | |||
| 153 | Step | ||
| 154 | eoudfin_eoud = { | ||
| 155 | .shortname = "eoudfin", | ||
| 156 | .name = "Optimal after EO on U/D without breaking EO", | ||
| 157 | |||
| 158 | .final = true, | ||
| 159 | .is_done = is_solved, | ||
| 160 | .estimate = estimate_nxopt31_HTM, | ||
| 161 | .ready = check_eofb, | ||
| 162 | .ready_msg = check_eo_msg, | ||
| 163 | .is_valid = always_valid, | ||
| 164 | .moveset = &moveset_eofb, | ||
| 165 | |||
| 166 | .pre_trans = fd, | ||
| 167 | |||
| 168 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 169 | .ntables = 2, | ||
| 170 | }; | ||
| 171 | |||
| 172 | /* EO steps **************************/ | ||
| 173 | Step | ||
| 174 | eoany_HTM = { | ||
| 175 | .shortname = "eo", | ||
| 176 | .name = "EO on any axis", | ||
| 177 | |||
| 178 | .final = false, | ||
| 179 | .is_done = check_eofb, | ||
| 180 | .estimate = estimate_eofb_HTM, | ||
| 181 | .ready = check_centers, | ||
| 182 | .ready_msg = check_centers_msg, | ||
| 183 | .is_valid = validate_singlecw_ending, | ||
| 184 | .moveset = &moveset_HTM, | ||
| 185 | |||
| 186 | .detect = detect_pretrans_void_3axis, | ||
| 187 | |||
| 188 | .tables = {&pd_eofb_HTM}, | ||
| 189 | .ntables = 1, | ||
| 190 | }; | ||
| 191 | |||
| 192 | Step | ||
| 193 | eofb_HTM = { | ||
| 194 | .shortname = "eofb", | ||
| 195 | .name = "EO on F/B", | ||
| 196 | |||
| 197 | .final = false, | ||
| 198 | .is_done = check_eofb, | ||
| 199 | .estimate = estimate_eofb_HTM, | ||
| 200 | .ready = check_centers, | ||
| 201 | .ready_msg = check_centers_msg, | ||
| 202 | .is_valid = validate_singlecw_ending, | ||
| 203 | .moveset = &moveset_HTM, | ||
| 204 | |||
| 205 | .pre_trans = uf, | ||
| 206 | |||
| 207 | .tables = {&pd_eofb_HTM}, | ||
| 208 | .ntables = 1, | ||
| 209 | }; | ||
| 210 | |||
| 211 | Step | ||
| 212 | eorl_HTM = { | ||
| 213 | .shortname = "eorl", | ||
| 214 | .name = "EO on R/L", | ||
| 215 | |||
| 216 | .final = false, | ||
| 217 | .is_done = check_eofb, | ||
| 218 | .estimate = estimate_eofb_HTM, | ||
| 219 | .ready = check_centers, | ||
| 220 | .ready_msg = check_centers_msg, | ||
| 221 | .is_valid = validate_singlecw_ending, | ||
| 222 | .moveset = &moveset_HTM, | ||
| 223 | |||
| 224 | .pre_trans = ur, | ||
| 225 | |||
| 226 | .tables = {&pd_eofb_HTM}, | ||
| 227 | .ntables = 1, | ||
| 228 | }; | ||
| 229 | |||
| 230 | Step | ||
| 231 | eoud_HTM = { | ||
| 232 | .shortname = "eoud", | ||
| 233 | .name = "EO on U/D", | ||
| 234 | |||
| 235 | .final = false, | ||
| 236 | .is_done = check_eofb, | ||
| 237 | .estimate = estimate_eofb_HTM, | ||
| 238 | .ready = check_centers, | ||
| 239 | .ready_msg = check_centers_msg, | ||
| 240 | .is_valid = validate_singlecw_ending, | ||
| 241 | .moveset = &moveset_HTM, | ||
| 242 | |||
| 243 | .pre_trans = fd, | ||
| 244 | |||
| 245 | .tables = {&pd_eofb_HTM}, | ||
| 246 | .ntables = 1, | ||
| 247 | }; | ||
| 248 | |||
| 249 | /* CO steps **************************/ | ||
| 250 | Step | ||
| 251 | coany_HTM = { | ||
| 252 | .shortname = "co", | ||
| 253 | .name = "CO on any axis", | ||
| 254 | |||
| 255 | .final = false, | ||
| 256 | .is_done = check_coud_HTM, | ||
| 257 | .estimate = estimate_coud_HTM, | ||
| 258 | .ready = NULL, | ||
| 259 | .is_valid = validate_singlecw_ending, | ||
| 260 | .moveset = &moveset_HTM, | ||
| 261 | |||
| 262 | .detect = detect_pretrans_void_3axis, | ||
| 263 | |||
| 264 | .tables = {&pd_coud_HTM}, | ||
| 265 | .ntables = 1, | ||
| 266 | }; | ||
| 267 | |||
| 268 | Step | ||
| 269 | coud_HTM = { | ||
| 270 | .shortname = "coud", | ||
| 271 | .name = "CO on U/D", | ||
| 272 | |||
| 273 | .final = false, | ||
| 274 | .is_done = check_coud_HTM, | ||
| 275 | .estimate = estimate_coud_HTM, | ||
| 276 | .ready = NULL, | ||
| 277 | .is_valid = validate_singlecw_ending, | ||
| 278 | .moveset = &moveset_HTM, | ||
| 279 | |||
| 280 | .pre_trans = uf, | ||
| 281 | |||
| 282 | .tables = {&pd_coud_HTM}, | ||
| 283 | .ntables = 1, | ||
| 284 | }; | ||
| 285 | |||
| 286 | Step | ||
| 287 | corl_HTM = { | ||
| 288 | .shortname = "corl", | ||
| 289 | .name = "CO on R/L", | ||
| 290 | |||
| 291 | .final = false, | ||
| 292 | .is_done = check_coud_HTM, | ||
| 293 | .estimate = estimate_coud_HTM, | ||
| 294 | .ready = NULL, | ||
| 295 | .is_valid = validate_singlecw_ending, | ||
| 296 | .moveset = &moveset_HTM, | ||
| 297 | |||
| 298 | .pre_trans = rf, | ||
| 299 | |||
| 300 | .tables = {&pd_coud_HTM}, | ||
| 301 | .ntables = 1, | ||
| 302 | }; | ||
| 303 | |||
| 304 | Step | ||
| 305 | cofb_HTM = { | ||
| 306 | .shortname = "cofb", | ||
| 307 | .name = "CO on F/B", | ||
| 308 | |||
| 309 | .final = false, | ||
| 310 | .is_done = check_coud_HTM, | ||
| 311 | .estimate = estimate_coud_HTM, | ||
| 312 | .ready = NULL, | ||
| 313 | .is_valid = validate_singlecw_ending, | ||
| 314 | .moveset = &moveset_HTM, | ||
| 315 | |||
| 316 | .pre_trans = fd, | ||
| 317 | |||
| 318 | .tables = {&pd_coud_HTM}, | ||
| 319 | .ntables = 1, | ||
| 320 | }; | ||
| 321 | |||
| 322 | Step | ||
| 323 | coany_URF = { | ||
| 324 | .shortname = "co-URF", | ||
| 325 | .name = "CO any axis (URF moveset)", | ||
| 326 | |||
| 327 | .final = false, | ||
| 328 | .is_done = check_coud_URF, | ||
| 329 | .estimate = estimate_coud_URF, | ||
| 330 | .ready = NULL, | ||
| 331 | .is_valid = validate_singlecw_ending, | ||
| 332 | .moveset = &moveset_URF, | ||
| 333 | |||
| 334 | .detect = detect_pretrans_void_3axis, | ||
| 335 | |||
| 336 | .tables = {&pd_coud_HTM}, | ||
| 337 | .ntables = 1, | ||
| 338 | }; | ||
| 339 | |||
| 340 | Step | ||
| 341 | coud_URF = { | ||
| 342 | .shortname = "coud-URF", | ||
| 343 | .name = "CO on U/D (URF moveset)", | ||
| 344 | |||
| 345 | .final = false, | ||
| 346 | .is_done = check_coud_URF, | ||
| 347 | .estimate = estimate_coud_URF, | ||
| 348 | .ready = NULL, | ||
| 349 | .is_valid = validate_singlecw_ending, | ||
| 350 | .moveset = &moveset_URF, | ||
| 351 | |||
| 352 | .pre_trans = uf, | ||
| 353 | |||
| 354 | .tables = {&pd_coud_HTM}, | ||
| 355 | .ntables = 1, | ||
| 356 | }; | ||
| 357 | |||
| 358 | Step | ||
| 359 | corl_URF = { | ||
| 360 | .shortname = "corl-URF", | ||
| 361 | .name = "CO on R/L (URF moveset)", | ||
| 362 | |||
| 363 | .final = false, | ||
| 364 | .is_done = check_coud_URF, | ||
| 365 | .estimate = estimate_coud_URF, | ||
| 366 | .ready = NULL, | ||
| 367 | .is_valid = validate_singlecw_ending, | ||
| 368 | .moveset = &moveset_URF, | ||
| 369 | |||
| 370 | .pre_trans = rf, | ||
| 371 | |||
| 372 | .tables = {&pd_coud_HTM}, | ||
| 373 | .ntables = 1, | ||
| 374 | }; | ||
| 375 | |||
| 376 | Step | ||
| 377 | cofb_URF = { | ||
| 378 | .shortname = "cofb-URF", | ||
| 379 | .name = "CO on F/B (URF moveset)", | ||
| 380 | |||
| 381 | .final = false, | ||
| 382 | .is_done = check_coud_URF, | ||
| 383 | .estimate = estimate_coud_URF, | ||
| 384 | .ready = NULL, | ||
| 385 | .is_valid = validate_singlecw_ending, | ||
| 386 | .moveset = &moveset_URF, | ||
| 387 | |||
| 388 | .pre_trans = fd, | ||
| 389 | |||
| 390 | .tables = {&pd_coud_HTM}, | ||
| 391 | .ntables = 1, | ||
| 392 | }; | ||
| 393 | |||
| 394 | /* Misc corner steps *****************/ | ||
| 395 | Step | ||
| 396 | cornershtr_HTM = { | ||
| 397 | .shortname = "chtr", | ||
| 398 | .name = "Solve corners to HTR state", | ||
| 399 | |||
| 400 | .final = false, | ||
| 401 | .is_done = check_cornershtr, | ||
| 402 | .estimate = estimate_cornershtr_HTM, | ||
| 403 | .ready = NULL, | ||
| 404 | .is_valid = validate_singlecw_ending, | ||
| 405 | .moveset = &moveset_HTM, | ||
| 406 | |||
| 407 | .pre_trans = uf, | ||
| 408 | |||
| 409 | .tables = {&pd_cornershtr_HTM}, | ||
| 410 | .ntables = 1, | ||
| 411 | }; | ||
| 412 | |||
| 413 | Step | ||
| 414 | cornershtr_URF = { | ||
| 415 | .shortname = "chtr-URF", | ||
| 416 | .name = "Solve corners to HTR state (URF moveset)", | ||
| 417 | |||
| 418 | .final = false, | ||
| 419 | .is_done = check_cornershtr, | ||
| 420 | .estimate = estimate_cornershtr_URF, | ||
| 421 | .ready = NULL, | ||
| 422 | .is_valid = validate_singlecw_ending, | ||
| 423 | .moveset = &moveset_URF, | ||
| 424 | |||
| 425 | .pre_trans = uf, | ||
| 426 | |||
| 427 | .tables = {&pd_cornershtr_HTM}, | ||
| 428 | .ntables = 1, | ||
| 429 | }; | ||
| 430 | |||
| 431 | Step | ||
| 432 | corners_HTM = { | ||
| 433 | .shortname = "corners", | ||
| 434 | .name = "Solve corners", | ||
| 435 | |||
| 436 | .final = true, | ||
| 437 | .is_done = check_corners_HTM, | ||
| 438 | .estimate = estimate_corners_HTM, | ||
| 439 | .ready = NULL, | ||
| 440 | .is_valid = always_valid, | ||
| 441 | .moveset = &moveset_HTM, | ||
| 442 | |||
| 443 | .pre_trans = uf, | ||
| 444 | |||
| 445 | .tables = {&pd_corners_HTM}, | ||
| 446 | .ntables = 1, | ||
| 447 | }; | ||
| 448 | |||
| 449 | Step | ||
| 450 | corners_URF = { | ||
| 451 | .shortname = "corners-URF", | ||
| 452 | .name = "Solve corners (URF moveset)", | ||
| 453 | |||
| 454 | .final = true, /* TODO: check if this works with reorient */ | ||
| 455 | .is_done = check_corners_URF, | ||
| 456 | .estimate = estimate_corners_URF, | ||
| 457 | .ready = NULL, | ||
| 458 | .is_valid = always_valid, | ||
| 459 | .moveset = &moveset_URF, | ||
| 460 | |||
| 461 | .pre_trans = uf, | ||
| 462 | |||
| 463 | .tables = {&pd_corners_HTM}, | ||
| 464 | .ntables = 1, | ||
| 465 | }; | ||
| 466 | |||
| 467 | /* DR steps **************************/ | ||
| 468 | Step | ||
| 469 | drany_HTM = { | ||
| 470 | .shortname = "dr", | ||
| 471 | .name = "DR on any axis", | ||
| 472 | |||
| 473 | .final = false, | ||
| 474 | .is_done = check_drud, | ||
| 475 | .estimate = estimate_drud_HTM, | ||
| 476 | .ready = check_centers, | ||
| 477 | .ready_msg = check_centers_msg, | ||
| 478 | .is_valid = validate_singlecw_ending, | ||
| 479 | .moveset = &moveset_HTM, | ||
| 480 | |||
| 481 | .detect = detect_pretrans_void_3axis, | ||
| 482 | |||
| 483 | .tables = {&pd_drud_sym16_HTM}, | ||
| 484 | .ntables = 1, | ||
| 485 | }; | ||
| 486 | |||
| 487 | Step | ||
| 488 | drud_HTM = { | ||
| 489 | .shortname = "drud", | ||
| 490 | .name = "DR on U/D", | ||
| 491 | |||
| 492 | .final = false, | ||
| 493 | .is_done = check_drud, | ||
| 494 | .estimate = estimate_drud_HTM, | ||
| 495 | .ready = check_centers, | ||
| 496 | .ready_msg = check_centers_msg, | ||
| 497 | .is_valid = validate_singlecw_ending, | ||
| 498 | .moveset = &moveset_HTM, | ||
| 499 | |||
| 500 | .pre_trans = uf, | ||
| 501 | |||
| 502 | .tables = {&pd_drud_sym16_HTM}, | ||
| 503 | .ntables = 1, | ||
| 504 | }; | ||
| 505 | |||
| 506 | Step | ||
| 507 | drrl_HTM = { | ||
| 508 | .shortname = "drrl", | ||
| 509 | .name = "DR on R/L", | ||
| 510 | |||
| 511 | .final = false, | ||
| 512 | .is_done = check_drud, | ||
| 513 | .estimate = estimate_drud_HTM, | ||
| 514 | .ready = check_centers, | ||
| 515 | .ready_msg = check_centers_msg, | ||
| 516 | .is_valid = validate_singlecw_ending, | ||
| 517 | .moveset = &moveset_HTM, | ||
| 518 | |||
| 519 | .pre_trans = rf, | ||
| 520 | |||
| 521 | .tables = {&pd_drud_sym16_HTM}, | ||
| 522 | .ntables = 1, | ||
| 523 | }; | ||
| 524 | |||
| 525 | Step | ||
| 526 | drfb_HTM = { | ||
| 527 | .shortname = "drfb", | ||
| 528 | .name = "DR on F/B", | ||
| 529 | |||
| 530 | .final = false, | ||
| 531 | .is_done = check_drud, | ||
| 532 | .estimate = estimate_drud_HTM, | ||
| 533 | .ready = check_centers, | ||
| 534 | .ready_msg = check_centers_msg, | ||
| 535 | .is_valid = validate_singlecw_ending, | ||
| 536 | .moveset = &moveset_HTM, | ||
| 537 | |||
| 538 | .pre_trans = fd, | ||
| 539 | |||
| 540 | .tables = {&pd_drud_sym16_HTM}, | ||
| 541 | .ntables = 1, | ||
| 542 | }; | ||
| 543 | |||
| 544 | /* DR from EO */ | ||
| 545 | Step | ||
| 546 | dr_eo = { | ||
| 547 | .shortname = "dr-eo", | ||
| 548 | .name = "DR without breaking EO (automatically detected)", | ||
| 549 | |||
| 550 | .final = false, | ||
| 551 | .is_done = check_drud, | ||
| 552 | .estimate = estimate_dr_eofb, | ||
| 553 | .ready = check_eofb, | ||
| 554 | .ready_msg = check_eo_msg, | ||
| 555 | .is_valid = validate_singlecw_ending, | ||
| 556 | .moveset = &moveset_eofb, | ||
| 557 | |||
| 558 | .detect = detect_pretrans_eofb, | ||
| 559 | |||
| 560 | .tables = {&pd_drud_eofb}, | ||
| 561 | .ntables = 1, | ||
| 562 | }; | ||
| 563 | |||
| 564 | Step | ||
| 565 | dr_eofb = { | ||
| 566 | .shortname = "dr-eofb", | ||
| 567 | .name = "DR on U/D or R/L without breaking EO on F/B", | ||
| 568 | |||
| 569 | .final = false, | ||
| 570 | .is_done = check_drud, | ||
| 571 | .estimate = estimate_dr_eofb, | ||
| 572 | .ready = check_eofb, | ||
| 573 | .ready_msg = check_eo_msg, | ||
| 574 | .is_valid = validate_singlecw_ending, | ||
| 575 | .moveset = &moveset_eofb, | ||
| 576 | |||
| 577 | .pre_trans = uf, | ||
| 578 | |||
| 579 | .tables = {&pd_drud_eofb}, | ||
| 580 | .ntables = 1, | ||
| 581 | }; | ||
| 582 | |||
| 583 | Step | ||
| 584 | dr_eorl = { | ||
| 585 | .shortname = "dr-eorl", | ||
| 586 | .name = "DR on U/D or F/B without breaking EO on R/L", | ||
| 587 | |||
| 588 | .final = false, | ||
| 589 | .is_done = check_drud, | ||
| 590 | .estimate = estimate_dr_eofb, | ||
| 591 | .ready = check_eofb, | ||
| 592 | .ready_msg = check_eo_msg, | ||
| 593 | .is_valid = validate_singlecw_ending, | ||
| 594 | .moveset = &moveset_eofb, | ||
| 595 | |||
| 596 | .pre_trans = ur, | ||
| 597 | |||
| 598 | .tables = {&pd_drud_eofb}, | ||
| 599 | .ntables = 1, | ||
| 600 | }; | ||
| 601 | |||
| 602 | Step | ||
| 603 | dr_eoud = { | ||
| 604 | .shortname = "dr-eoud", | ||
| 605 | .name = "DR on R/L or F/B without breaking EO on U/D", | ||
| 606 | |||
| 607 | .final = false, | ||
| 608 | .is_done = check_drud, | ||
| 609 | .estimate = estimate_dr_eofb, | ||
| 610 | .ready = check_eofb, | ||
| 611 | .ready_msg = check_eo_msg, | ||
| 612 | .is_valid = validate_singlecw_ending, | ||
| 613 | .moveset = &moveset_eofb, | ||
| 614 | |||
| 615 | .pre_trans = fd, | ||
| 616 | |||
| 617 | .tables = {&pd_drud_eofb}, | ||
| 618 | .ntables = 1, | ||
| 619 | }; | ||
| 620 | |||
| 621 | Step | ||
| 622 | drud_eofb = { | ||
| 623 | .shortname = "drud-eofb", | ||
| 624 | .name = "DR on U/D without breaking EO on F/B", | ||
| 625 | |||
| 626 | .final = false, | ||
| 627 | .is_done = check_drud, | ||
| 628 | .estimate = estimate_drud_eofb, | ||
| 629 | .ready = check_eofb, | ||
| 630 | .ready_msg = check_eo_msg, | ||
| 631 | .is_valid = validate_singlecw_ending, | ||
| 632 | .moveset = &moveset_eofb, | ||
| 633 | |||
| 634 | .pre_trans = uf, | ||
| 635 | |||
| 636 | .tables = {&pd_drud_eofb}, | ||
| 637 | .ntables = 1, | ||
| 638 | }; | ||
| 639 | |||
| 640 | Step | ||
| 641 | drrl_eofb = { | ||
| 642 | .shortname = "drrl-eofb", | ||
| 643 | .name = "DR on R/L without breaking EO on F/B", | ||
| 644 | |||
| 645 | .final = false, | ||
| 646 | .is_done = check_drud, | ||
| 647 | .estimate = estimate_drud_eofb, | ||
| 648 | .ready = check_eofb, | ||
| 649 | .ready_msg = check_eo_msg, | ||
| 650 | .is_valid = validate_singlecw_ending, | ||
| 651 | .moveset = &moveset_eofb, | ||
| 652 | |||
| 653 | .pre_trans = rf, | ||
| 654 | |||
| 655 | .tables = {&pd_drud_eofb}, | ||
| 656 | .ntables = 1, | ||
| 657 | }; | ||
| 658 | |||
| 659 | Step | ||
| 660 | drud_eorl = { | ||
| 661 | .shortname = "drud-eorl", | ||
| 662 | .name = "DR on U/D without breaking EO on R/L", | ||
| 663 | |||
| 664 | .final = false, | ||
| 665 | .is_done = check_drud, | ||
| 666 | .estimate = estimate_drud_eofb, | ||
| 667 | .ready = check_eofb, | ||
| 668 | .ready_msg = check_eo_msg, | ||
| 669 | .is_valid = validate_singlecw_ending, | ||
| 670 | .moveset = &moveset_eofb, | ||
| 671 | |||
| 672 | .pre_trans = ur, | ||
| 673 | |||
| 674 | .tables = {&pd_drud_eofb}, | ||
| 675 | .ntables = 1, | ||
| 676 | }; | ||
| 677 | |||
| 678 | Step | ||
| 679 | drfb_eorl = { | ||
| 680 | .shortname = "drfb-eorl", | ||
| 681 | .name = "DR on F/B without breaking EO on R/L", | ||
| 682 | |||
| 683 | .final = false, | ||
| 684 | .is_done = check_drud, | ||
| 685 | .estimate = estimate_drud_eofb, | ||
| 686 | .ready = check_eofb, | ||
| 687 | .ready_msg = check_eo_msg, | ||
| 688 | .is_valid = validate_singlecw_ending, | ||
| 689 | .moveset = &moveset_eofb, | ||
| 690 | |||
| 691 | .pre_trans = fr, | ||
| 692 | |||
| 693 | .tables = {&pd_drud_eofb}, | ||
| 694 | .ntables = 1, | ||
| 695 | }; | ||
| 696 | |||
| 697 | Step | ||
| 698 | drfb_eoud = { | ||
| 699 | .shortname = "drfb-eoud", | ||
| 700 | .name = "DR on F/B without breaking EO on U/D", | ||
| 701 | |||
| 702 | .final = false, | ||
| 703 | .is_done = check_drud, | ||
| 704 | .estimate = estimate_drud_eofb, | ||
| 705 | .ready = check_eofb, | ||
| 706 | .ready_msg = check_eo_msg, | ||
| 707 | .is_valid = validate_singlecw_ending, | ||
| 708 | .moveset = &moveset_eofb, | ||
| 709 | |||
| 710 | .pre_trans = fd, | ||
| 711 | |||
| 712 | .tables = {&pd_drud_eofb}, | ||
| 713 | .ntables = 1, | ||
| 714 | }; | ||
| 715 | |||
| 716 | Step | ||
| 717 | drrl_eoud = { | ||
| 718 | .shortname = "drrl-eoud", | ||
| 719 | .name = "DR on R/L without breaking EO on U/D", | ||
| 720 | |||
| 721 | .final = false, | ||
| 722 | .is_done = check_drud, | ||
| 723 | .estimate = estimate_drud_eofb, | ||
| 724 | .ready = check_eofb, | ||
| 725 | .ready_msg = check_eo_msg, | ||
| 726 | .is_valid = validate_singlecw_ending, | ||
| 727 | .moveset = &moveset_eofb, | ||
| 728 | |||
| 729 | .pre_trans = rd, | ||
| 730 | |||
| 731 | .tables = {&pd_drud_eofb}, | ||
| 732 | .ntables = 1, | ||
| 733 | }; | ||
| 734 | |||
| 735 | /* DR finish steps */ | ||
| 736 | Step | ||
| 737 | dranyfin_DR = { | ||
| 738 | .shortname = "drfin", | ||
| 739 | .name = "DR finish on any axis without breaking DR", | ||
| 740 | |||
| 741 | .final = true, | ||
| 742 | .is_done = is_solved, | ||
| 743 | .estimate = estimate_drudfin_drud, | ||
| 744 | .ready = check_drud, | ||
| 745 | .ready_msg = check_drany_msg, | ||
| 746 | .is_valid = always_valid, | ||
| 747 | .moveset = &moveset_drud, | ||
| 748 | |||
| 749 | .detect = detect_pretrans_drud, | ||
| 750 | |||
| 751 | .tables = {&pd_drudfin_noE_sym16_drud}, | ||
| 752 | .ntables = 1, | ||
| 753 | }; | ||
| 754 | |||
| 755 | Step | ||
| 756 | drudfin_drud = { | ||
| 757 | .shortname = "drudfin", | ||
| 758 | .name = "DR finish on U/D without breaking DR", | ||
| 759 | |||
| 760 | .final = true, | ||
| 761 | .is_done = is_solved, | ||
| 762 | .estimate = estimate_drudfin_drud, | ||
| 763 | .ready = check_drud, | ||
| 764 | .ready_msg = check_dr_msg, | ||
| 765 | .is_valid = always_valid, | ||
| 766 | .moveset = &moveset_drud, | ||
| 767 | |||
| 768 | .pre_trans = uf, | ||
| 769 | |||
| 770 | .tables = {&pd_drudfin_noE_sym16_drud}, | ||
| 771 | .ntables = 1, | ||
| 772 | }; | ||
| 773 | |||
| 774 | Step | ||
| 775 | drrlfin_drrl = { | ||
| 776 | .shortname = "drrlfin", | ||
| 777 | .name = "DR finish on R/L without breaking DR", | ||
| 778 | |||
| 779 | .final = true, | ||
| 780 | .is_done = is_solved, | ||
| 781 | .estimate = estimate_drudfin_drud, | ||
| 782 | .ready = check_drud, | ||
| 783 | .ready_msg = check_dr_msg, | ||
| 784 | .is_valid = always_valid, | ||
| 785 | .moveset = &moveset_drud, | ||
| 786 | |||
| 787 | .pre_trans = rf, | ||
| 788 | |||
| 789 | .tables = {&pd_drudfin_noE_sym16_drud}, | ||
| 790 | .ntables = 1, | ||
| 791 | }; | ||
| 792 | |||
| 793 | Step | ||
| 794 | drfbfin_drfb = { | ||
| 795 | .shortname = "drfbfin", | ||
| 796 | .name = "DR finish on F/B without breaking DR", | ||
| 797 | |||
| 798 | .final = true, | ||
| 799 | .is_done = is_solved, | ||
| 800 | .estimate = estimate_drudfin_drud, | ||
| 801 | .ready = check_drud, | ||
| 802 | .ready_msg = check_dr_msg, | ||
| 803 | .is_valid = always_valid, | ||
| 804 | .moveset = &moveset_drud, | ||
| 805 | |||
| 806 | .pre_trans = fd, | ||
| 807 | |||
| 808 | .tables = {&pd_drudfin_noE_sym16_drud}, | ||
| 809 | .ntables = 1, | ||
| 810 | }; | ||
| 811 | |||
| 812 | /* HTR from DR */ | ||
| 813 | Step | ||
| 814 | htr_any = { | ||
| 815 | .shortname = "htr", | ||
| 816 | .name = "HTR from DR", | ||
| 817 | |||
| 818 | .final = false, | ||
| 819 | .is_done = check_htr, | ||
| 820 | .estimate = estimate_htr_drud, | ||
| 821 | .ready = check_drud, | ||
| 822 | .ready_msg = check_drany_msg, | ||
| 823 | .is_valid = validate_singlecw_ending, | ||
| 824 | .moveset = &moveset_drud, | ||
| 825 | 2 | ||
| 826 | .detect = detect_pretrans_drud, | 3 | #include "steps.h" |
| 827 | |||
| 828 | .tables = {&pd_htr_drud}, | ||
| 829 | .ntables = 1, | ||
| 830 | }; | ||
| 831 | |||
| 832 | Step | ||
| 833 | htr_drud = { | ||
| 834 | .shortname = "htr-drud", | ||
| 835 | .name = "HTR from DR on U/D", | ||
| 836 | |||
| 837 | .final = false, | ||
| 838 | .is_done = check_htr, | ||
| 839 | .estimate = estimate_htr_drud, | ||
| 840 | .ready = check_drud, | ||
| 841 | .ready_msg = check_dr_msg, | ||
| 842 | .is_valid = validate_singlecw_ending, | ||
| 843 | .moveset = &moveset_drud, | ||
| 844 | |||
| 845 | .pre_trans = uf, | ||
| 846 | |||
| 847 | .tables = {&pd_htr_drud}, | ||
| 848 | .ntables = 1, | ||
| 849 | }; | ||
| 850 | |||
| 851 | Step | ||
| 852 | htr_drrl = { | ||
| 853 | .shortname = "htr-drrl", | ||
| 854 | .name = "HTR from DR on R/L", | ||
| 855 | |||
| 856 | .final = false, | ||
| 857 | .is_done = check_htr, | ||
| 858 | .estimate = estimate_htr_drud, | ||
| 859 | .ready = check_drud, | ||
| 860 | .ready_msg = check_dr_msg, | ||
| 861 | .is_valid = validate_singlecw_ending, | ||
| 862 | .moveset = &moveset_drud, | ||
| 863 | |||
| 864 | .pre_trans = rf, | ||
| 865 | |||
| 866 | .tables = {&pd_htr_drud}, | ||
| 867 | .ntables = 1, | ||
| 868 | }; | ||
| 869 | |||
| 870 | Step | ||
| 871 | htr_drfb = { | ||
| 872 | .shortname = "htr-drfb", | ||
| 873 | .name = "HTR from DR on F/B", | ||
| 874 | |||
| 875 | .final = false, | ||
| 876 | .is_done = check_htr, | ||
| 877 | .estimate = estimate_htr_drud, | ||
| 878 | .ready = check_drud, | ||
| 879 | .ready_msg = check_dr_msg, | ||
| 880 | .is_valid = validate_singlecw_ending, | ||
| 881 | .moveset = &moveset_drud, | ||
| 882 | |||
| 883 | .pre_trans = fd, | ||
| 884 | |||
| 885 | .tables = {&pd_htr_drud}, | ||
| 886 | .ntables = 1, | ||
| 887 | }; | ||
| 888 | |||
| 889 | /* HTR finish */ | ||
| 890 | Step | ||
| 891 | htrfin_htr = { | ||
| 892 | .shortname = "htrfin", | ||
| 893 | .name = "HTR finish without breaking HTR", | ||
| 894 | |||
| 895 | .final = true, | ||
| 896 | .is_done = is_solved, | ||
| 897 | .estimate = estimate_htrfin_htr, | ||
| 898 | .ready = check_htr, | ||
| 899 | .ready_msg = check_htr_msg, | ||
| 900 | .is_valid = always_valid, | ||
| 901 | .moveset = &moveset_htr, | ||
| 902 | |||
| 903 | .pre_trans = uf, | ||
| 904 | |||
| 905 | .tables = {&pd_htrfin_htr}, | ||
| 906 | .ntables = 1, | ||
| 907 | }; | ||
| 908 | |||
| 909 | Step *steps[] = { | ||
| 910 | &optimal_HTM, /* first is default */ | ||
| 911 | &optimal_light_HTM, | ||
| 912 | |||
| 913 | &eofin_eo, | ||
| 914 | &eofbfin_eofb, | ||
| 915 | &eorlfin_eorl, | ||
| 916 | &eoudfin_eoud, | ||
| 917 | |||
| 918 | &eoany_HTM, | ||
| 919 | &eofb_HTM, | ||
| 920 | &eorl_HTM, | ||
| 921 | &eoud_HTM, | ||
| 922 | |||
| 923 | &coany_HTM, | ||
| 924 | &coud_HTM, | ||
| 925 | &corl_HTM, | ||
| 926 | &cofb_HTM, | ||
| 927 | |||
| 928 | &coany_URF, | ||
| 929 | &coud_URF, | ||
| 930 | &corl_URF, | ||
| 931 | &cofb_URF, | ||
| 932 | |||
| 933 | &drany_HTM, | ||
| 934 | &drud_HTM, | ||
| 935 | &drrl_HTM, | ||
| 936 | &drfb_HTM, | ||
| 937 | |||
| 938 | &dr_eo, | ||
| 939 | &dr_eofb, | ||
| 940 | &dr_eorl, | ||
| 941 | &dr_eoud, | ||
| 942 | &drud_eofb, | ||
| 943 | &drrl_eofb, | ||
| 944 | &drud_eorl, | ||
| 945 | &drfb_eorl, | ||
| 946 | &drfb_eoud, | ||
| 947 | &drrl_eoud, | ||
| 948 | |||
| 949 | &dranyfin_DR, | ||
| 950 | &drudfin_drud, | ||
| 951 | &drrlfin_drrl, | ||
| 952 | &drfbfin_drfb, | ||
| 953 | |||
| 954 | &htr_any, | ||
| 955 | &htr_drud, | ||
| 956 | &htr_drrl, | ||
| 957 | &htr_drfb, | ||
| 958 | |||
| 959 | &htrfin_htr, | ||
| 960 | |||
| 961 | &cornershtr_HTM, | ||
| 962 | &cornershtr_URF, | ||
| 963 | &corners_HTM, | ||
| 964 | &corners_URF, | ||
| 965 | |||
| 966 | NULL | ||
| 967 | }; | ||
| 968 | |||
| 969 | /* Checkers, estimators and validators ***************************************/ | ||
| 970 | |||
| 971 | static bool | ||
| 972 | check_centers(Cube cube) | ||
| 973 | { | ||
| 974 | return cube.cpos == 0; | ||
| 975 | } | ||
| 976 | |||
| 977 | static bool | ||
| 978 | check_coud_HTM(Cube cube) | ||
| 979 | { | ||
| 980 | return cube.coud == 0; | ||
| 981 | } | ||
| 982 | |||
| 983 | static bool | ||
| 984 | check_coud_URF(Cube cube) | ||
| 985 | { | ||
| 986 | Cube c2, c3; | ||
| 987 | |||
| 988 | c2 = apply_move(z, cube); | ||
| 989 | c3 = apply_move(x, cube); | ||
| 990 | 4 | ||
| 991 | return cube.coud == 0 || c2.coud == 0 || c3.coud == 0; | 5 | /* TODO: change all checkers to use coordinates! */ |
| 992 | } | ||
| 993 | 6 | ||
| 994 | static bool | 7 | bool |
| 995 | check_corners_URF(Cube cube) | 8 | check_centers(Cube *cube) |
| 996 | { | 9 | { |
| 997 | Cube c; | 10 | int i; |
| 998 | Trans i; | ||
| 999 | 11 | ||
| 1000 | for (i = 0; i < NROTATIONS; i++) { | 12 | for (i = 0; i < 6; i++) |
| 1001 | c = apply_alg(rotation_alg(i), cube); | 13 | if (cube->xp[i] != i) |
| 1002 | if (c.cp && c.coud) | 14 | return false; |
| 1003 | return true; | ||
| 1004 | } | ||
| 1005 | 15 | ||
| 1006 | return false; | 16 | return true; |
| 1007 | } | 17 | } |
| 1008 | 18 | ||
| 1009 | static bool | 19 | bool |
| 1010 | check_corners_HTM(Cube cube) | 20 | check_coud_HTM(Cube *cube) |
| 1011 | { | 21 | { |
| 1012 | return cube.cp == 0 && cube.coud == 0; | 22 | int i; |
| 1013 | } | ||
| 1014 | 23 | ||
| 1015 | static bool | 24 | for (i = 0; i < 8; i++) |
| 1016 | check_cornershtr(Cube cube) | 25 | if (cube->co[i] != 0) |
| 1017 | { | 26 | return false; |
| 1018 | return coord_cornershtr.index(cube) == 0; | ||
| 1019 | } | ||
| 1020 | 27 | ||
| 1021 | static bool | 28 | return true; |
| 1022 | check_eofb(Cube cube) | ||
| 1023 | { | ||
| 1024 | return cube.eofb == 0; | ||
| 1025 | } | 29 | } |
| 1026 | 30 | ||
| 1027 | static bool | 31 | bool |
| 1028 | check_drud(Cube cube) | 32 | check_coud_URF(Cube *cube) |
| 1029 | { | 33 | { |
| 1030 | return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0; | 34 | Cube c2, c3; |
| 1031 | } | ||
| 1032 | 35 | ||
| 1033 | static bool | 36 | copy_cube(cube, &c2); |
| 1034 | check_htr(Cube cube) | 37 | copy_cube(cube, &c3); |
| 1035 | { | ||
| 1036 | return check_drud(cube) && coord_htr_drud.index(cube) == 0; | ||
| 1037 | } | ||
| 1038 | 38 | ||
| 1039 | static int | 39 | apply_move(z, &c2); |
| 1040 | estimate_eofb_HTM(DfsArg *arg) | 40 | apply_move(x, &c3); |
| 1041 | { | ||
| 1042 | return ptableval(&pd_eofb_HTM, arg->cube); | ||
| 1043 | } | ||
| 1044 | 41 | ||
| 1045 | static int | 42 | return check_coud_HTM(cube) || |
| 1046 | estimate_coud_HTM(DfsArg *arg) | 43 | check_coud_HTM(&c2) || |
| 1047 | { | 44 | check_coud_HTM(&c3); |
| 1048 | return ptableval(&pd_coud_HTM, arg->cube); | ||
| 1049 | } | 45 | } |
| 1050 | 46 | ||
| 1051 | static int | 47 | bool |
| 1052 | estimate_coud_URF(DfsArg *arg) | 48 | check_cp_HTM(Cube *cube) |
| 1053 | { | 49 | { |
| 1054 | /* TODO: I can improve this by checking first the orientation of | 50 | int i; |
| 1055 | * the corner in DBL and use that as a reference */ | ||
| 1056 | |||
| 1057 | Cube c; | ||
| 1058 | |||
| 1059 | c = arg->cube; | ||
| 1060 | |||
| 1061 | int ud = estimate_coud_HTM(arg); | ||
| 1062 | arg->cube = apply_move(z, c); | ||
| 1063 | int rl = estimate_coud_HTM(arg); | ||
| 1064 | arg->cube = apply_move(x, c); | ||
| 1065 | int fb = estimate_coud_HTM(arg); | ||
| 1066 | |||
| 1067 | arg->cube = c; | ||
| 1068 | 51 | ||
| 1069 | return MIN(ud, MIN(rl, fb)); | 52 | for (i = 0; i < 8; i++) |
| 1070 | } | 53 | if (cube->cp[i] != i) |
| 54 | return false; | ||
| 1071 | 55 | ||
| 1072 | static int | 56 | return true; |
| 1073 | estimate_corners_HTM(DfsArg *arg) | ||
| 1074 | { | ||
| 1075 | return ptableval(&pd_corners_HTM, arg->cube); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int | ||
| 1079 | estimate_cornershtr_HTM(DfsArg *arg) | ||
| 1080 | { | ||
| 1081 | return ptableval(&pd_cornershtr_HTM, arg->cube); | ||
| 1082 | } | 57 | } |
| 1083 | 58 | ||
| 1084 | static int | 59 | bool |
| 1085 | estimate_cornershtr_URF(DfsArg *arg) | 60 | check_corners_HTM(Cube *cube) |
| 1086 | { | 61 | { |
| 1087 | /* TODO: I can improve this by checking first the corner in DBL | 62 | return check_coud_HTM(cube) && check_cp_HTM(cube); |
| 1088 | * and use that as a reference */ | ||
| 1089 | |||
| 1090 | int ret; | ||
| 1091 | Cube c; | ||
| 1092 | Trans i; | ||
| 1093 | |||
| 1094 | c = arg->cube; | ||
| 1095 | ret = 15; | ||
| 1096 | |||
| 1097 | for (i = 0; i < NROTATIONS; i++) { | ||
| 1098 | arg->cube = apply_alg(rotation_alg(i), c); | ||
| 1099 | ret = MIN(ret, estimate_cornershtr_HTM(arg)); | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | arg->cube = c; | ||
| 1103 | |||
| 1104 | return ret; | ||
| 1105 | } | 63 | } |
| 1106 | 64 | ||
| 1107 | static int | 65 | bool |
| 1108 | estimate_corners_URF(DfsArg *arg) | 66 | check_corners_URF(Cube *cube) |
| 1109 | { | 67 | { |
| 1110 | /* TODO: I can improve this by checking first the corner in DBL | ||
| 1111 | * and use that as a reference */ | ||
| 1112 | |||
| 1113 | int ret; | ||
| 1114 | Cube c; | 68 | Cube c; |
| 1115 | Trans i; | 69 | Trans i; |
| 1116 | 70 | ||
| 1117 | c = arg->cube; | ||
| 1118 | ret = 15; | ||
| 1119 | |||
| 1120 | for (i = 0; i < NROTATIONS; i++) { | 71 | for (i = 0; i < NROTATIONS; i++) { |
| 1121 | arg->cube = apply_alg(rotation_alg(i), c); | 72 | copy_cube(cube, &c); |
| 1122 | ret = MIN(ret, estimate_corners_HTM(arg)); | 73 | apply_alg(rotation_alg(i), &c); |
| 74 | if (check_corners_HTM(&c)) | ||
| 75 | return true; | ||
| 1123 | } | 76 | } |
| 1124 | 77 | ||
| 1125 | arg->cube = c; | 78 | return false; |
| 1126 | |||
| 1127 | return ret; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | static int | ||
| 1131 | estimate_drud_HTM(DfsArg *arg) | ||
| 1132 | { | ||
| 1133 | return ptableval(&pd_drud_sym16_HTM, arg->cube); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static int | ||
| 1137 | estimate_drud_eofb(DfsArg *arg) | ||
| 1138 | { | ||
| 1139 | return ptableval(&pd_drud_eofb, arg->cube); | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | static int | ||
| 1143 | estimate_dr_eofb(DfsArg *arg) | ||
| 1144 | { | ||
| 1145 | int r1, r2; | ||
| 1146 | |||
| 1147 | r1 = ptableval(&pd_drud_eofb, arg->cube); | ||
| 1148 | r2 = ptableval(&pd_drud_eofb, apply_trans(rf, arg->cube)); | ||
| 1149 | |||
| 1150 | return MIN(r1, r2); | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | static int | ||
| 1154 | estimate_drudfin_drud(DfsArg *arg) | ||
| 1155 | { | ||
| 1156 | int val = ptableval(&pd_drudfin_noE_sym16_drud, arg->cube); | ||
| 1157 | |||
| 1158 | if (val != 0) | ||
| 1159 | return val; | ||
| 1160 | |||
| 1161 | return arg->cube.epose % 24 == 0 ? 0 : 1; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | static int | ||
| 1165 | estimate_htr_drud(DfsArg *arg) | ||
| 1166 | { | ||
| 1167 | return ptableval(&pd_htr_drud, arg->cube); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | static int | ||
| 1171 | estimate_htrfin_htr(DfsArg *arg) | ||
| 1172 | { | ||
| 1173 | return ptableval(&pd_htrfin_htr, arg->cube); | ||
| 1174 | } | 79 | } |
| 1175 | 80 | ||
| 1176 | static int | 81 | bool |
| 1177 | estimate_nxopt31_HTM(DfsArg *arg) | 82 | check_cornershtr(Cube *cube) |
| 1178 | { | 83 | { |
| 1179 | return estimate_nxoptlike(arg, &pd_nxopt31_HTM); | 84 | /* TODO (use coord) */ |
| 85 | return true; | ||
| 1180 | } | 86 | } |
| 1181 | 87 | ||
| 1182 | /* TODO: also use generic procedure for this */ | 88 | bool |
| 1183 | static int | 89 | check_eofb(Cube *cube) |
| 1184 | estimate_light_HTM(DfsArg *arg) | ||
| 1185 | { | 90 | { |
| 1186 | int target, ret; | 91 | /* TODO (use coord) */ |
| 1187 | Cube aux; | 92 | return true; |
| 1188 | |||
| 1189 | static const uint64_t udmask = (1<<U) | (1<<U2) | (1<<U3) | | ||
| 1190 | (1<<D) | (1<<D2) | (1<<D3); | ||
| 1191 | static const uint64_t rlmask = (1<<R) | (1<<R2) | (1<<R3) | | ||
| 1192 | (1<<L) | (1<<L2) | (1<<L3); | ||
| 1193 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | | ||
| 1194 | (1<<B) | (1<<B2) | (1<<B3); | ||
| 1195 | static const uint64_t htmask = (1<<U2) | (1<<D2) | | ||
| 1196 | (1<<R2) | (1<<L2) | | ||
| 1197 | (1<<F2) | (1<<B2); | ||
| 1198 | |||
| 1199 | ret = -1; | ||
| 1200 | target = arg->d - arg->current_alg->len; | ||
| 1201 | arg->inverse = (Cube){0}; | ||
| 1202 | arg->badmovesinv = 0; | ||
| 1203 | arg->badmoves = 0; | ||
| 1204 | |||
| 1205 | /* Corners */ | ||
| 1206 | arg->ed->corners = ptableval(&pd_corners_HTM, arg->cube); | ||
| 1207 | UPDATECHECKSTOP(ret, arg->ed->corners, target); | ||
| 1208 | |||
| 1209 | /* Normal probing */ | ||
| 1210 | arg->ed->normal_ud = ptableval(&pd_drud_sym16_HTM, arg->cube); | ||
| 1211 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); | ||
| 1212 | aux = apply_trans(fd, arg->cube); | ||
| 1213 | arg->ed->normal_fb = ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1214 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); | ||
| 1215 | aux = apply_trans(rf, arg->cube); | ||
| 1216 | arg->ed->normal_rl = ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1217 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); | ||
| 1218 | |||
| 1219 | /* If ret == 0, it's solved (corners + triple slice solved) */ | ||
| 1220 | if (ret == 0) | ||
| 1221 | return is_solved(arg->cube) ? 0 : 1; | ||
| 1222 | |||
| 1223 | /* Michel de Bondt's trick*/ | ||
| 1224 | if (arg->ed->normal_ud == arg->ed->normal_fb && | ||
| 1225 | arg->ed->normal_fb == arg->ed->normal_rl) { | ||
| 1226 | UPDATECHECKSTOP(ret, arg->ed->normal_ud + 1, target); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /* Inverse probing */ | ||
| 1230 | if (!((1<<arg->last1) & htmask)) { | ||
| 1231 | aux = arg->inverse = inverse_cube(arg->cube); | ||
| 1232 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud==-1)) { | ||
| 1233 | arg->ed->inverse_ud = | ||
| 1234 | ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1235 | } | ||
| 1236 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | ||
| 1237 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb==-1)) { | ||
| 1238 | aux = apply_trans(fd, arg->inverse); | ||
| 1239 | arg->ed->inverse_fb = | ||
| 1240 | ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1241 | } | ||
| 1242 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | ||
| 1243 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl==-1)) { | ||
| 1244 | aux = apply_trans(rf, arg->inverse); | ||
| 1245 | arg->ed->inverse_rl = | ||
| 1246 | ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1247 | } | ||
| 1248 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1249 | } else { | ||
| 1250 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | ||
| 1251 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | ||
| 1252 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | /* Michel de Bondt's trick*/ | ||
| 1256 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && | ||
| 1257 | arg->ed->inverse_fb == arg->ed->inverse_rl) { | ||
| 1258 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | /* nxopt trick + half turn trick */ | ||
| 1262 | if (arg->ed->normal_ud == target) | ||
| 1263 | arg->badmovesinv |= udmask | htmask; | ||
| 1264 | if (arg->ed->normal_fb == target) | ||
| 1265 | arg->badmovesinv |= fbmask | htmask; | ||
| 1266 | if (arg->ed->normal_rl == target) | ||
| 1267 | arg->badmovesinv |= rlmask | htmask; | ||
| 1268 | |||
| 1269 | if (arg->ed->inverse_ud == target) | ||
| 1270 | arg->badmoves |= udmask | htmask; | ||
| 1271 | if (arg->ed->inverse_fb == target) | ||
| 1272 | arg->badmoves |= fbmask | htmask; | ||
| 1273 | if (arg->ed->inverse_rl == target) | ||
| 1274 | arg->badmoves |= rlmask | htmask; | ||
| 1275 | |||
| 1276 | return arg->ed->oldret = ret; | ||
| 1277 | } | 93 | } |
| 1278 | 94 | ||
| 1279 | static int | 95 | bool |
| 1280 | estimate_nxoptlike(DfsArg *arg, PruneData *pd) | 96 | check_drud(Cube *cube) |
| 1281 | { | 97 | { |
| 1282 | int target, ret; | 98 | /* TODO (use coord) */ |
| 1283 | Cube aux; | 99 | return true; |
| 1284 | |||
| 1285 | static const uint64_t udmask = (1<<U) | (1<<U2) | (1<<U3) | | ||
| 1286 | (1<<D) | (1<<D2) | (1<<D3); | ||
| 1287 | static const uint64_t rlmask = (1<<R) | (1<<R2) | (1<<R3) | | ||
| 1288 | (1<<L) | (1<<L2) | (1<<L3); | ||
| 1289 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | | ||
| 1290 | (1<<B) | (1<<B2) | (1<<B3); | ||
| 1291 | |||
| 1292 | ret = -1; | ||
| 1293 | target = arg->d - arg->current_alg->len; | ||
| 1294 | arg->inverse = (Cube){0}; | ||
| 1295 | arg->badmovesinv = 0; | ||
| 1296 | arg->badmoves = 0; | ||
| 1297 | |||
| 1298 | /* Corners */ | ||
| 1299 | arg->ed->corners = ptableval(&pd_corners_HTM, arg->cube); | ||
| 1300 | UPDATECHECKSTOP(ret, arg->ed->corners, target); | ||
| 1301 | |||
| 1302 | /* Normal probing */ | ||
| 1303 | arg->ed->normal_ud = ptableval(pd, arg->cube); | ||
| 1304 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); | ||
| 1305 | aux = apply_trans(fd, arg->cube); | ||
| 1306 | arg->ed->normal_fb = ptableval(pd, aux); | ||
| 1307 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); | ||
| 1308 | aux = apply_trans(rf, arg->cube); | ||
| 1309 | arg->ed->normal_rl = ptableval(pd, aux); | ||
| 1310 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); | ||
| 1311 | |||
| 1312 | if (ret == 0) | ||
| 1313 | return arg->step->is_done(arg->cube) ? 0 : 1; | ||
| 1314 | |||
| 1315 | /* Michel de Bondt's trick*/ | ||
| 1316 | if (arg->ed->normal_ud == arg->ed->normal_fb && | ||
| 1317 | arg->ed->normal_fb == arg->ed->normal_rl) { | ||
| 1318 | UPDATECHECKSTOP(ret, arg->ed->normal_ud + 1, target); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | /* Inverse probing */ | ||
| 1322 | aux = arg->inverse = inverse_cube(arg->cube); | ||
| 1323 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud == -1)) { | ||
| 1324 | arg->ed->inverse_ud = ptableval(pd, aux); | ||
| 1325 | } | ||
| 1326 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | ||
| 1327 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb == -1)) { | ||
| 1328 | aux = apply_trans(fd, arg->inverse); | ||
| 1329 | arg->ed->inverse_fb = ptableval(pd, aux); | ||
| 1330 | } | ||
| 1331 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | ||
| 1332 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl == -1)) { | ||
| 1333 | aux = apply_trans(rf, arg->inverse); | ||
| 1334 | arg->ed->inverse_rl = ptableval(pd, aux); | ||
| 1335 | } | ||
| 1336 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1337 | |||
| 1338 | /* Michel de Bondt's trick*/ | ||
| 1339 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && | ||
| 1340 | arg->ed->inverse_fb == arg->ed->inverse_rl) { | ||
| 1341 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /* nxopt trick */ | ||
| 1345 | if (arg->ed->normal_ud == target) | ||
| 1346 | arg->badmovesinv |= udmask; | ||
| 1347 | if (arg->ed->normal_fb == target) | ||
| 1348 | arg->badmovesinv |= fbmask; | ||
| 1349 | if (arg->ed->normal_rl == target) | ||
| 1350 | arg->badmovesinv |= rlmask; | ||
| 1351 | |||
| 1352 | if (arg->ed->inverse_ud == target) | ||
| 1353 | arg->badmoves |= udmask; | ||
| 1354 | if (arg->ed->inverse_fb == target) | ||
| 1355 | arg->badmoves |= fbmask; | ||
| 1356 | if (arg->ed->inverse_rl == target) | ||
| 1357 | arg->badmoves |= rlmask; | ||
| 1358 | |||
| 1359 | return arg->ed->oldret = ret; | ||
| 1360 | } | 100 | } |
| 1361 | 101 | ||
| 1362 | 102 | bool | |
| 1363 | static bool | 103 | check_htr(Cube *cube) |
| 1364 | always_valid(Alg *alg) | ||
| 1365 | { | 104 | { |
| 105 | /* TODO (check_drud(cube) and coord_htr_drud == 0) */ | ||
| 1366 | return true; | 106 | return true; |
| 1367 | } | 107 | } |
| 1368 | 108 | ||
| 1369 | static bool | 109 | bool |
| 1370 | validate_singlecw_ending(Alg *alg) | 110 | validate_singlecw_ending(Alg *alg) |
| 1371 | { | 111 | { |
| 1372 | int i; | 112 | int i; |
| @@ -1389,93 +129,93 @@ validate_singlecw_ending(Alg *alg) | |||
| 1389 | return nor && inv; | 129 | return nor && inv; |
| 1390 | } | 130 | } |
| 1391 | 131 | ||
| 1392 | /* Pre-transformation detectors **********************************************/ | 132 | /* Public functions **********************************************************/ |
| 1393 | 133 | ||
| 1394 | static int | 134 | void |
| 1395 | detect_pretrans_eofb(Cube cube, Trans *ret) | 135 | compute_ind(StepAlt *a, Cube *cube, Movable *ind) |
| 1396 | { | 136 | { |
| 1397 | int i, n; | 137 | int i; |
| 1398 | static Trans tt[3] = {uf, ur, fd}; | 138 | Cube mvd; |
| 139 | Trans t, tt; | ||
| 1399 | 140 | ||
| 1400 | for (i = 0, n = 0; i < 3; i++) | 141 | for (i = 0; i < a->n_coord; i++) { |
| 1401 | if (check_eofb(apply_trans(tt[i], cube))) | 142 | t = a->coord_trans[i]; |
| 1402 | ret[n++] = tt[i]; | 143 | copy_cube(cube, &mvd); |
| 144 | apply_trans(t, &mvd); | ||
| 1403 | 145 | ||
| 1404 | return n; | 146 | ind[i].val = index_coord(a->coord[i], &mvd, &tt); |
| 147 | ind[i].t = transform_trans(tt, t); | ||
| 148 | } | ||
| 1405 | } | 149 | } |
| 1406 | 150 | ||
| 1407 | static int | 151 | int |
| 1408 | detect_pretrans_drud(Cube cube, Trans *ret) | 152 | estimate_stepalt(StepAlt *a, Movable *ind, int goal) |
| 1409 | { | 153 | { |
| 1410 | int i, n; | 154 | int i, ret, est[a->n_coord]; |
| 1411 | static Trans tt[3] = {uf, fr, rd}; | ||
| 1412 | 155 | ||
| 1413 | for (i = 0, n = 0; i < 3; i++) | 156 | for (i = 0; i < a->n_coord; i++) { |
| 1414 | if (check_drud(apply_trans(tt[i], cube))) | 157 | est[i] = ptableval(a->pd[i], ind[i].val); |
| 1415 | ret[n++] = tt[i]; | 158 | if (est[i] == a->pd[i]->base && a->compact_pd[i]) |
| 159 | est[i] = ptableval(a->fallback_pd[i], | ||
| 160 | ind[i].val/a->fbmod[i]); | ||
| 161 | if (ind[i].val != 0 && est[i] == 0) /* est == 0 iff solved */ | ||
| 162 | est[i] = 1; | ||
| 163 | /* | ||
| 164 | TODO: remove this debug code | ||
| 165 | printf("%d: est=%d | ", i, est[i]); | ||
| 166 | */ | ||
| 1416 | 167 | ||
| 1417 | return n; | 168 | if (est[i] > goal) |
| 1418 | } | 169 | return est[i]; |
| 170 | } | ||
| 1419 | 171 | ||
| 1420 | static int | 172 | for (i = 0; i < a->n_dbtrick; i++) |
| 1421 | detect_pretrans_void_3axis(Cube cube, Trans *ret) | 173 | if (est[a->dbtrick[i][0]] > 0 && |
| 1422 | { | 174 | est[a->dbtrick[i][0]] == est[a->dbtrick[i][1]] && |
| 1423 | ret[0] = uf; | 175 | est[a->dbtrick[i][0]] == est[a->dbtrick[i][2]]) |
| 1424 | ret[1] = fr; | 176 | est[a->dbtrick[i][0]] += 1; |
| 1425 | ret[2] = rd; | ||
| 1426 | 177 | ||
| 1427 | return 3; | 178 | for (i = 0, ret = -1; i < a->n_coord; i++) |
| 1428 | } | 179 | ret = MAX(ret, est[i]); |
| 1429 | 180 | ||
| 1430 | /* Public functions **********************************************************/ | 181 | /* |
| 182 | TODO: remove this debug code | ||
| 183 | printf("Final estimate: %d\n", ret); | ||
| 184 | */ | ||
| 1431 | 185 | ||
| 1432 | void | 186 | return ret; |
| 1433 | copy_estimatedata(EstimateData *src, EstimateData *dst) | ||
| 1434 | { | ||
| 1435 | dst->corners = src->corners; | ||
| 1436 | dst->normal_ud = src->normal_ud; | ||
| 1437 | dst->normal_fb = src->normal_fb; | ||
| 1438 | dst->normal_rl = src->normal_rl; | ||
| 1439 | dst->inverse_ud = src->inverse_ud; | ||
| 1440 | dst->inverse_fb = src->inverse_fb; | ||
| 1441 | dst->inverse_rl = src->inverse_rl; | ||
| 1442 | dst->oldret = src->oldret; | ||
| 1443 | } | 187 | } |
| 1444 | 188 | ||
| 1445 | void | 189 | void |
| 1446 | invert_estimatedata(EstimateData *ed) | 190 | prepare_step(Step *step, SolveOptions *opts) |
| 1447 | { | 191 | { |
| 1448 | swap(&(ed->normal_ud), &(ed->inverse_ud)); | 192 | int i, j; |
| 1449 | swap(&(ed->normal_fb), &(ed->inverse_fb)); | 193 | PDGenData pdg; |
| 1450 | swap(&(ed->normal_rl), &(ed->inverse_rl)); | 194 | StepAlt *a; |
| 1451 | } | ||
| 1452 | 195 | ||
| 1453 | void | 196 | for (i = 0; step->alt[i] != NULL; i++) { |
| 1454 | reset_estimatedata(EstimateData *ed) | 197 | a = step->alt[i]; |
| 1455 | { | 198 | init_moveset(a->moveset); |
| 1456 | ed->corners = -1; | 199 | pdg.moveset = a->moveset; |
| 1457 | ed->normal_ud = -1; | 200 | for (j = 0; j < a->n_coord; j++) { |
| 1458 | ed->normal_fb = -1; | 201 | gen_coord(a->coord[j]); |
| 1459 | ed->normal_rl = -1; | ||
| 1460 | ed->inverse_ud = -1; | ||
| 1461 | ed->inverse_fb = -1; | ||
| 1462 | ed->inverse_rl = -1; | ||
| 1463 | ed->oldret = -1; | ||
| 1464 | } | ||
| 1465 | 202 | ||
| 1466 | void | 203 | pdg.coord = a->coord[j]; |
| 1467 | prepare_step(Step *step, SolveOptions *opts) | 204 | pdg.compact = a->compact_pd[j]; |
| 1468 | { | 205 | pdg.pd = NULL; |
| 1469 | int i; | ||
| 1470 | 206 | ||
| 1471 | if (step->final && opts->can_niss) { | 207 | a->pd[j] = genptable(&pdg, opts->nthreads); |
| 1472 | opts->can_niss = false; | 208 | |
| 1473 | fprintf(stderr, "Step is final, NISS not used (-n ignored)\n"); | 209 | if (a->compact_pd[j]) { |
| 1474 | } | 210 | gen_coord(a->fallback_coord[j]); |
| 1475 | 211 | ||
| 1476 | for (i = 0; i < step->ntables; i++) { | 212 | pdg.coord = a->fallback_coord[j]; |
| 1477 | genptable(step->tables[i], opts->nthreads); | 213 | pdg.compact = false; |
| 1478 | if (step->tables[i]->compact) | 214 | pdg.pd = NULL; |
| 1479 | genptable(step->tables[i]->fallback, opts->nthreads); | 215 | |
| 216 | a->fallback_pd[j] = | ||
| 217 | genptable(&pdg, opts->nthreads); | ||
| 218 | } | ||
| 219 | } | ||
| 1480 | } | 220 | } |
| 1481 | } | 221 | } |
