diff options
Diffstat (limited to 'src/cube.c')
| -rw-r--r-- | src/cube.c | 220 |
1 files changed, 219 insertions, 1 deletions
| @@ -1,6 +1,21 @@ | |||
| 1 | #include "cube.h" | 1 | #include "cube.h" |
| 2 | 2 | ||
| 3 | /* Public functions implementation *******************************************/ | 3 | /* Local functions ***********************************************************/ |
| 4 | |||
| 5 | static void init_inverse(); | ||
| 6 | static bool read_invtables_file(); | ||
| 7 | static bool write_invtables_file(); | ||
| 8 | |||
| 9 | /* Tables ********************************************************************/ | ||
| 10 | |||
| 11 | static uint16_t eo_invtable_e[POW2TO11][BINOM12ON4*FACTORIAL4]; | ||
| 12 | static uint16_t eo_invtable_s[POW2TO11][BINOM12ON4*FACTORIAL4]; | ||
| 13 | static uint16_t eo_invtable_m[POW2TO11][BINOM12ON4*FACTORIAL4]; | ||
| 14 | static uint16_t co_invtable[POW3TO7][FACTORIAL8]; | ||
| 15 | static uint16_t cp_invtable[FACTORIAL8]; | ||
| 16 | static uint16_t cpos_invtable[FACTORIAL6]; | ||
| 17 | |||
| 18 | /* Functions implementation **************************************************/ | ||
| 4 | 19 | ||
| 5 | int | 20 | int |
| 6 | array_ep_to_epos(int *ep, int *ss) | 21 | array_ep_to_epos(int *ep, int *ss) |
| @@ -284,6 +299,7 @@ equal(Cube c1, Cube c2) | |||
| 284 | c1.cpos == c2.cpos; | 299 | c1.cpos == c2.cpos; |
| 285 | } | 300 | } |
| 286 | 301 | ||
| 302 | /* | ||
| 287 | Cube | 303 | Cube |
| 288 | inverse_cube(Cube cube) | 304 | inverse_cube(Cube cube) |
| 289 | { | 305 | { |
| @@ -319,6 +335,37 @@ inverse_cube(Cube cube) | |||
| 319 | 335 | ||
| 320 | return ret; | 336 | return ret; |
| 321 | } | 337 | } |
| 338 | */ | ||
| 339 | |||
| 340 | Cube | ||
| 341 | inverse_cube(Cube cube) | ||
| 342 | { | ||
| 343 | CubeArray inv; | ||
| 344 | Cube ret; | ||
| 345 | int i, ep[12]; | ||
| 346 | |||
| 347 | for (i = 0; i < 12; i++) | ||
| 348 | ep[i] = where_is_edge(cube, i); | ||
| 349 | inv = (CubeArray){.ep = ep}; | ||
| 350 | ret = arrays_to_cube(&inv, pf_ep); | ||
| 351 | |||
| 352 | ret.eofb = ((int)eo_invtable_e[cube.eofb][cube.epose]) | | ||
| 353 | ((int)eo_invtable_m[cube.eofb][cube.eposm]) | | ||
| 354 | ((int)eo_invtable_s[cube.eofb][cube.eposs]); | ||
| 355 | ret.eorl = ((int)eo_invtable_e[cube.eorl][cube.epose]) | | ||
| 356 | ((int)eo_invtable_m[cube.eorl][cube.eposm]) | | ||
| 357 | ((int)eo_invtable_s[cube.eorl][cube.eposs]); | ||
| 358 | ret.eoud = ((int)eo_invtable_e[cube.eoud][cube.epose]) | | ||
| 359 | ((int)eo_invtable_m[cube.eoud][cube.eposm]) | | ||
| 360 | ((int)eo_invtable_s[cube.eoud][cube.eposs]); | ||
| 361 | ret.cp = cp_invtable[cube.cp]; | ||
| 362 | ret.cpos = cpos_invtable[cube.cpos]; | ||
| 363 | ret.coud = co_invtable[cube.coud][cube.cp]; | ||
| 364 | ret.corl = co_invtable[cube.corl][cube.cp]; | ||
| 365 | ret.cofb = co_invtable[cube.cofb][cube.cp]; | ||
| 366 | |||
| 367 | return ret; | ||
| 368 | } | ||
| 322 | 369 | ||
| 323 | bool | 370 | bool |
| 324 | is_admissible(Cube cube) { | 371 | is_admissible(Cube cube) { |
| @@ -684,3 +731,174 @@ where_is_edge(Cube c, Edge e) | |||
| 684 | r2 = aux[2][c.eposm][e]; | 731 | r2 = aux[2][c.eposm][e]; |
| 685 | return MAX(r0, MAX(r1, r2)); | 732 | return MAX(r0, MAX(r1, r2)); |
| 686 | } | 733 | } |
| 734 | |||
| 735 | static bool | ||
| 736 | read_invtables_file() | ||
| 737 | { | ||
| 738 | init_env(); | ||
| 739 | |||
| 740 | FILE *f; | ||
| 741 | char fname[strlen(tabledir)+20]; | ||
| 742 | int b; | ||
| 743 | unsigned int ui, meeo, meco, mecp, mecpos; | ||
| 744 | bool r; | ||
| 745 | |||
| 746 | strcpy(fname, tabledir); | ||
| 747 | strcat(fname, "/invtables"); | ||
| 748 | |||
| 749 | if ((f = fopen(fname, "rb")) == NULL) | ||
| 750 | return false; | ||
| 751 | |||
| 752 | b = sizeof(uint16_t); | ||
| 753 | r = true; | ||
| 754 | meeo = BINOM12ON4*FACTORIAL4; | ||
| 755 | meco = FACTORIAL8; | ||
| 756 | mecp = FACTORIAL8; | ||
| 757 | mecpos = FACTORIAL6; | ||
| 758 | |||
| 759 | for (ui = 0; ui < POW2TO11; ui++) { | ||
| 760 | r = r && fread(eo_invtable_e[ui], b, meeo, f) == meeo; | ||
| 761 | r = r && fread(eo_invtable_m[ui], b, meeo, f) == meeo; | ||
| 762 | r = r && fread(eo_invtable_s[ui], b, meeo, f) == meeo; | ||
| 763 | } | ||
| 764 | |||
| 765 | for (ui = 0; ui < POW3TO7; ui++) { | ||
| 766 | r = r && fread(co_invtable[ui], b, meco, f) == meco; | ||
| 767 | } | ||
| 768 | |||
| 769 | r = r && fread(cp_invtable, b, mecp, f) == mecp; | ||
| 770 | r = r && fread(cpos_invtable, b, mecpos, f) == mecpos; | ||
| 771 | |||
| 772 | fclose(f); | ||
| 773 | return r; | ||
| 774 | } | ||
| 775 | |||
| 776 | static bool | ||
| 777 | write_invtables_file() | ||
| 778 | { | ||
| 779 | init_env(); | ||
| 780 | |||
| 781 | FILE *f; | ||
| 782 | char fname[strlen(tabledir)+20]; | ||
| 783 | unsigned int ui, meeo, meco, mecp, mecpos; | ||
| 784 | int b; | ||
| 785 | bool r; | ||
| 786 | |||
| 787 | strcpy(fname, tabledir); | ||
| 788 | strcat(fname, "/invtables"); | ||
| 789 | |||
| 790 | if ((f = fopen(fname, "wb")) == NULL) | ||
| 791 | return false; | ||
| 792 | |||
| 793 | b = sizeof(uint16_t); | ||
| 794 | r = true; | ||
| 795 | meeo = BINOM12ON4*FACTORIAL4; | ||
| 796 | meco = FACTORIAL8; | ||
| 797 | mecp = FACTORIAL8; | ||
| 798 | mecpos = FACTORIAL6; | ||
| 799 | |||
| 800 | for (ui = 0; ui < POW2TO11; ui++) { | ||
| 801 | r = r && fwrite(eo_invtable_e[ui], b, meeo, f) == meeo; | ||
| 802 | r = r && fwrite(eo_invtable_m[ui], b, meeo, f) == meeo; | ||
| 803 | r = r && fwrite(eo_invtable_s[ui], b, meeo, f) == meeo; | ||
| 804 | } | ||
| 805 | |||
| 806 | for (ui = 0; ui < POW3TO7; ui++) { | ||
| 807 | r = r && fwrite(co_invtable[ui], b, meco, f) == meco; | ||
| 808 | } | ||
| 809 | |||
| 810 | r = r && fwrite(cp_invtable, b, mecp, f) == mecp; | ||
| 811 | r = r && fwrite(cpos_invtable, b, mecpos, f) == mecpos; | ||
| 812 | |||
| 813 | fclose(f); | ||
| 814 | return r; | ||
| 815 | } | ||
| 816 | |||
| 817 | void | ||
| 818 | init_inverse() | ||
| 819 | { | ||
| 820 | static bool initialized = false; | ||
| 821 | if (initialized) | ||
| 822 | return; | ||
| 823 | initialized = true; | ||
| 824 | |||
| 825 | if (read_invtables_file()) | ||
| 826 | return; | ||
| 827 | |||
| 828 | fprintf(stderr, "Cannot load invtables, generating it\n"); | ||
| 829 | |||
| 830 | CubeArray *aux, *inv; | ||
| 831 | Cube c; | ||
| 832 | int i, j, eoaux[12], eoinv[12]; | ||
| 833 | unsigned int ui, uj; | ||
| 834 | |||
| 835 | aux = new_cubearray((Cube){0}, pf_all); | ||
| 836 | inv = new_cubearray((Cube){0}, pf_all); | ||
| 837 | |||
| 838 | for (ui = 0; ui < POW2TO11; ui++) { | ||
| 839 | int_to_sum_zero_array(ui, 2, 12, eoaux); | ||
| 840 | for (uj = 0; uj < BINOM12ON4*FACTORIAL4; uj++) { | ||
| 841 | for (j = 0; j < 12; j++) | ||
| 842 | eoinv[j] = 0; | ||
| 843 | c = (Cube){.epose = uj, .eposm = 0, .eposs = 0}; | ||
| 844 | eoinv[FR] = eoaux[where_is_edge(c, FR)]; | ||
| 845 | eoinv[FL] = eoaux[where_is_edge(c, FL)]; | ||
| 846 | eoinv[BL] = eoaux[where_is_edge(c, BL)]; | ||
| 847 | eoinv[BR] = eoaux[where_is_edge(c, BR)]; | ||
| 848 | eo_invtable_e[ui][uj] = digit_array_to_int(eoinv,11,2); | ||
| 849 | |||
| 850 | for (j = 0; j < 12; j++) | ||
| 851 | eoinv[j] = 0; | ||
| 852 | c = (Cube){.epose = 0, .eposm = uj, .eposs = 0}; | ||
| 853 | eoinv[UF] = eoaux[where_is_edge(c, UF)]; | ||
| 854 | eoinv[UB] = eoaux[where_is_edge(c, UB)]; | ||
| 855 | eoinv[DF] = eoaux[where_is_edge(c, DF)]; | ||
| 856 | eoinv[DB] = eoaux[where_is_edge(c, DB)]; | ||
| 857 | eo_invtable_m[ui][uj] = digit_array_to_int(eoinv,11,2); | ||
| 858 | |||
| 859 | for (j = 0; j < 12; j++) | ||
| 860 | eoinv[j] = 0; | ||
| 861 | c = (Cube){.epose = 0, .eposm = 0, .eposs = uj}; | ||
| 862 | eoinv[UL] = eoaux[where_is_edge(c, UL)]; | ||
| 863 | eoinv[UR] = eoaux[where_is_edge(c, UR)]; | ||
| 864 | eoinv[DL] = eoaux[where_is_edge(c, DL)]; | ||
| 865 | eoinv[DR] = eoaux[where_is_edge(c, DR)]; | ||
| 866 | eo_invtable_s[ui][uj] = digit_array_to_int(eoinv,11,2); | ||
| 867 | } | ||
| 868 | } | ||
| 869 | |||
| 870 | for (ui = 0; ui < FACTORIAL8; ui++) { | ||
| 871 | cube_to_arrays((Cube){.cp = ui}, aux, pf_cp); | ||
| 872 | for (i = 0; i < 8; i++) | ||
| 873 | inv->cp[aux->cp[i]] = i; | ||
| 874 | cp_invtable[ui] = (uint16_t)arrays_to_cube(inv, pf_cp).cp; | ||
| 875 | |||
| 876 | for (uj = 0; uj < POW3TO7; uj++) { | ||
| 877 | cube_to_arrays((Cube){.coud = uj}, aux, pf_coud); | ||
| 878 | for (i = 0; i < 8; i++) | ||
| 879 | inv->coud[aux->cp[i]] = (3-aux->coud[i])%3; | ||
| 880 | co_invtable[uj][ui] = | ||
| 881 | (uint16_t)arrays_to_cube(inv, pf_coud).coud; | ||
| 882 | } | ||
| 883 | } | ||
| 884 | |||
| 885 | for (ui = 0; ui < FACTORIAL6; ui++) { | ||
| 886 | cube_to_arrays((Cube){.cpos = ui}, aux, pf_cpos); | ||
| 887 | for (i = 0; i < 6; i++) | ||
| 888 | inv->cpos[aux->cpos[i]] = i; | ||
| 889 | cpos_invtable[ui] = | ||
| 890 | (uint16_t)arrays_to_cube(inv, pf_cpos).cpos; | ||
| 891 | } | ||
| 892 | |||
| 893 | free_cubearray(aux, pf_all); | ||
| 894 | free_cubearray(inv, pf_all); | ||
| 895 | |||
| 896 | if (!write_invtables_file()) | ||
| 897 | fprintf(stderr, "Error writing invtables\n"); | ||
| 898 | } | ||
| 899 | |||
| 900 | void | ||
| 901 | init_cube() | ||
| 902 | { | ||
| 903 | init_inverse(); | ||
| 904 | } | ||
