aboutsummaryrefslogtreecommitdiff
path: root/src/steps.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-12-07 12:20:51 +0100
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-12-07 12:20:51 +0100
commitb6fd508253bce9225dd24b6538adb5093892c4f8 (patch)
tree75f58f26fca63f0bbda0a351a2cb8f514194a35b /src/steps.c
parente528411b1a1be45e1bef0f525fd0f411c9689b11 (diff)
downloadnissy-b6fd508253bce9225dd24b6538adb5093892c4f8.tar.gz
nissy-b6fd508253bce9225dd24b6538adb5093892c4f8.zip
Little performance improvement in optimal solver - more to come!
Diffstat (limited to '')
-rw-r--r--src/steps.c277
1 files changed, 172 insertions, 105 deletions
diff --git a/src/steps.c b/src/steps.c
index 6478bc2..4646abd 100644
--- a/src/steps.c
+++ b/src/steps.c
@@ -1,5 +1,7 @@
1#include "steps.h" 1#include "steps.h"
2 2
3#define UPDATECHECKSTOP(a, b, c) if ((a=(MAX((a),(b))))>(c)) return (a);
4
3/* Checkers, estimators and validators ***************************************/ 5/* Checkers, estimators and validators ***************************************/
4 6
5static bool check_centers(Cube cube); 7static bool check_centers(Cube cube);
@@ -7,24 +9,24 @@ static bool check_eofb(Cube cube);
7static bool check_drud(Cube cube); 9static bool check_drud(Cube cube);
8static bool check_htr(Cube cube); 10static bool check_htr(Cube cube);
9 11
10static int estimate_eoany_HTM(CubeTarget ct); 12static int estimate_eoany_HTM(EstimateData *ed);
11static int estimate_eofb_HTM(CubeTarget ct); 13static int estimate_eofb_HTM(EstimateData *ed);
12static int estimate_coany_HTM(CubeTarget ct); 14static int estimate_coany_HTM(EstimateData *ed);
13static int estimate_coud_HTM(CubeTarget ct); 15static int estimate_coud_HTM(EstimateData *ed);
14static int estimate_coany_URF(CubeTarget ct); 16static int estimate_coany_URF(EstimateData *ed);
15static int estimate_coud_URF(CubeTarget ct); 17static int estimate_coud_URF(EstimateData *ed);
16static int estimate_corners_HTM(CubeTarget ct); 18static int estimate_corners_HTM(EstimateData *ed);
17static int estimate_cornershtr_HTM(CubeTarget ct); 19static int estimate_cornershtr_HTM(EstimateData *ed);
18static int estimate_corners_URF(CubeTarget ct); 20static int estimate_corners_URF(EstimateData *ed);
19static int estimate_cornershtr_URF(CubeTarget ct); 21static int estimate_cornershtr_URF(EstimateData *ed);
20static int estimate_drany_HTM(CubeTarget ct); 22static int estimate_drany_HTM(EstimateData *ed);
21static int estimate_drud_HTM(CubeTarget ct); 23static int estimate_drud_HTM(EstimateData *ed);
22static int estimate_drud_eofb(CubeTarget ct); 24static int estimate_drud_eofb(EstimateData *ed);
23static int estimate_dr_eofb(CubeTarget ct); 25static int estimate_dr_eofb(EstimateData *ed);
24static int estimate_drudfin_drud(CubeTarget ct); 26static int estimate_drudfin_drud(EstimateData *ed);
25static int estimate_htr_drud(CubeTarget ct); 27static int estimate_htr_drud(EstimateData *ed);
26static int estimate_htrfin_htr(CubeTarget ct); 28static int estimate_htrfin_htr(EstimateData *ed);
27static int estimate_optimal_HTM(CubeTarget ct); 29static int estimate_optimal_HTM(EstimateData *ed);
28 30
29static bool always_valid(Alg *alg); 31static bool always_valid(Alg *alg);
30static bool validate_singlecw_ending(Alg *alg); 32static bool validate_singlecw_ending(Alg *alg);
@@ -799,90 +801,106 @@ check_htr(Cube cube)
799} 801}
800 802
801static int 803static int
802estimate_eoany_HTM(CubeTarget ct) 804estimate_eoany_HTM(EstimateData *ed)
803{ 805{
804 int r1, r2, r3; 806 int r1, r2, r3;
805 807
806 r1 = ptableval(&pd_eofb_HTM, ct.cube); 808 r1 = ptableval(&pd_eofb_HTM, ed->cube);
807 r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ct.cube)); 809 r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ed->cube));
808 r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ct.cube)); 810 r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ed->cube));
809 811
810 return MIN(r1, MIN(r2, r3)); 812 return MIN(r1, MIN(r2, r3));
811} 813}
812 814
813static int 815static int
814estimate_eofb_HTM(CubeTarget ct) 816estimate_eofb_HTM(EstimateData *ed)
815{ 817{
816 return ptableval(&pd_eofb_HTM, ct.cube); 818 return ptableval(&pd_eofb_HTM, ed->cube);
817} 819}
818 820
819static int 821static int
820estimate_coany_HTM(CubeTarget ct) 822estimate_coany_HTM(EstimateData *ed)
821{ 823{
822 int r1, r2, r3; 824 int r1, r2, r3;
823 825
824 r1 = ptableval(&pd_coud_HTM, ct.cube); 826 r1 = ptableval(&pd_coud_HTM, ed->cube);
825 r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ct.cube)); 827 r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ed->cube));
826 r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ct.cube)); 828 r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ed->cube));
827 829
828 return MIN(r1, MIN(r2, r3)); 830 return MIN(r1, MIN(r2, r3));
829} 831}
830 832
831static int 833static int
832estimate_coud_HTM(CubeTarget ct) 834estimate_coud_HTM(EstimateData *ed)
833{ 835{
834 return ptableval(&pd_coud_HTM, ct.cube); 836 return ptableval(&pd_coud_HTM, ed->cube);
835} 837}
836 838
837static int 839static int
838estimate_coany_URF(CubeTarget ct) 840estimate_coany_URF(EstimateData *ed)
839{ 841{
840 int r1, r2, r3; 842 int r1, r2, r3;
841 CubeTarget ct2, ct3; 843 EstimateData *ed2, *ed3;
844
845 ed2 = malloc(sizeof(EstimateData));
846 ed3 = malloc(sizeof(EstimateData));
842 847
843 ct2.cube = apply_trans(rf, ct.cube); 848 ed2->cube = apply_trans(rf, ed->cube);
844 ct2.target = ct.target; 849 ed2->target = ed->target;
845 850
846 ct3.cube = apply_trans(fd, ct.cube); 851 ed3->cube = apply_trans(fd, ed->cube);
847 ct3.target = ct.target; 852 ed3->target = ed->target;
848 853
849 r1 = estimate_coud_URF(ct); 854 r1 = estimate_coud_URF(ed);
850 r2 = estimate_coud_URF(ct2); 855 r2 = estimate_coud_URF(ed2);
851 r3 = estimate_coud_URF(ct3); 856 r3 = estimate_coud_URF(ed3);
857
858 free(ed2);
859 free(ed3);
852 860
853 return MIN(r1, MIN(r2, r3)); 861 return MIN(r1, MIN(r2, r3));
854} 862}
855 863
856static int 864static int
857estimate_coud_URF(CubeTarget ct) 865estimate_coud_URF(EstimateData *ed)
858{ 866{
859 /* TODO: I can improve this by checking first the orientation of 867 /* TODO: I can improve this by checking first the orientation of
860 * the corner in DBL and use that as a reference */ 868 * the corner in DBL and use that as a reference */
861 869
862 CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target}; 870 EstimateData *ed2, *ed3;
863 CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target}; 871
872 ed2 = malloc(sizeof(EstimateData));
873 ed2->cube = apply_move(z, ed->cube);
874 ed2->target = ed->target;
864 875
865 int ud = estimate_coud_HTM(ct); 876 ed3 = malloc(sizeof(EstimateData));
866 int rl = estimate_coud_HTM(ct2); 877 ed3->cube = apply_move(x, ed->cube);
867 int fb = estimate_coud_HTM(ct3); 878 ed3->target = ed->target;
879
880 int ud = estimate_coud_HTM(ed);
881 int rl = estimate_coud_HTM(ed2);
882 int fb = estimate_coud_HTM(ed3);
883
884 free(ed2);
885 free(ed3);
868 886
869 return MIN(ud, MIN(rl, fb)); 887 return MIN(ud, MIN(rl, fb));
870} 888}
871 889
872static int 890static int
873estimate_corners_HTM(CubeTarget ct) 891estimate_corners_HTM(EstimateData *ed)
874{ 892{
875 return ptableval(&pd_corners_HTM, ct.cube); 893 return ptableval(&pd_corners_HTM, ed->cube);
876} 894}
877 895
878static int 896static int
879estimate_cornershtr_HTM(CubeTarget ct) 897estimate_cornershtr_HTM(EstimateData *ed)
880{ 898{
881 return ptableval(&pd_cornershtr_HTM, ct.cube); 899 return ptableval(&pd_cornershtr_HTM, ed->cube);
882} 900}
883 901
884static int 902static int
885estimate_cornershtr_URF(CubeTarget ct) 903estimate_cornershtr_URF(EstimateData *ed)
886{ 904{
887 /* TODO: I can improve this by checking first the corner in DBL 905 /* TODO: I can improve this by checking first the corner in DBL
888 * and use that as a reference */ 906 * and use that as a reference */
@@ -891,8 +909,8 @@ estimate_cornershtr_URF(CubeTarget ct)
891 Trans i; 909 Trans i;
892 910
893 for (i = 0; i < NROTATIONS; i++) { 911 for (i = 0; i < NROTATIONS; i++) {
894 ct.cube = apply_alg(rotation_alg(i), ct.cube); 912 ed->cube = apply_alg(rotation_alg(i), ed->cube);
895 c = estimate_cornershtr_HTM(ct); 913 c = estimate_cornershtr_HTM(ed);
896 ret = MIN(ret, c); 914 ret = MIN(ret, c);
897 } 915 }
898 916
@@ -900,7 +918,7 @@ estimate_cornershtr_URF(CubeTarget ct)
900} 918}
901 919
902static int 920static int
903estimate_corners_URF(CubeTarget ct) 921estimate_corners_URF(EstimateData *ed)
904{ 922{
905 /* TODO: I can improve this by checking first the corner in DBL 923 /* TODO: I can improve this by checking first the corner in DBL
906 * and use that as a reference */ 924 * and use that as a reference */
@@ -909,8 +927,8 @@ estimate_corners_URF(CubeTarget ct)
909 Trans i; 927 Trans i;
910 928
911 for (i = 0; i < NROTATIONS; i++) { 929 for (i = 0; i < NROTATIONS; i++) {
912 ct.cube = apply_alg(rotation_alg(i), ct.cube); 930 ed->cube = apply_alg(rotation_alg(i), ed->cube);
913 c = estimate_corners_HTM(ct); 931 c = estimate_corners_HTM(ed);
914 ret = MIN(ret, c); 932 ret = MIN(ret, c);
915 } 933 }
916 934
@@ -918,104 +936,130 @@ estimate_corners_URF(CubeTarget ct)
918} 936}
919 937
920static int 938static int
921estimate_drany_HTM(CubeTarget ct) 939estimate_drany_HTM(EstimateData *ed)
922{ 940{
923 int r1, r2, r3; 941 int r1, r2, r3;
924 942
925 r1 = ptableval(&pd_drud_sym16_HTM, ct.cube); 943 r1 = ptableval(&pd_drud_sym16_HTM, ed->cube);
926 r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ct.cube)); 944 r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ed->cube));
927 r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ct.cube)); 945 r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ed->cube));
928 946
929 return MIN(r1, MIN(r2, r3)); 947 return MIN(r1, MIN(r2, r3));
930} 948}
931 949
932static int 950static int
933estimate_drud_HTM(CubeTarget ct) 951estimate_drud_HTM(EstimateData *ed)
934{ 952{
935 return ptableval(&pd_drud_sym16_HTM, ct.cube); 953 return ptableval(&pd_drud_sym16_HTM, ed->cube);
936} 954}
937 955
938static int 956static int
939estimate_drud_eofb(CubeTarget ct) 957estimate_drud_eofb(EstimateData *ed)
940{ 958{
941 return ptableval(&pd_drud_eofb, ct.cube); 959 return ptableval(&pd_drud_eofb, ed->cube);
942} 960}
943 961
944static int 962static int
945estimate_dr_eofb(CubeTarget ct) 963estimate_dr_eofb(EstimateData *ed)
946{ 964{
947 int r1, r2; 965 int r1, r2;
948 966
949 r1 = ptableval(&pd_drud_eofb, ct.cube); 967 r1 = ptableval(&pd_drud_eofb, ed->cube);
950 r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ct.cube)); 968 r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ed->cube));
951 969
952 return MIN(r1, r2); 970 return MIN(r1, r2);
953} 971}
954 972
955static int 973static int
956estimate_drudfin_drud(CubeTarget ct) 974estimate_drudfin_drud(EstimateData *ed)
957{ 975{
958 int val = ptableval(&pd_drudfin_noE_sym16_drud, ct.cube); 976 int val = ptableval(&pd_drudfin_noE_sym16_drud, ed->cube);
959 977
960 if (val != 0) 978 if (val != 0)
961 return val; 979 return val;
962 980
963 return ct.cube.epose % 24 == 0 ? 0 : 1; 981 return ed->cube.epose % 24 == 0 ? 0 : 1;
964} 982}
965 983
966static int 984static int
967estimate_htr_drud(CubeTarget ct) 985estimate_htr_drud(EstimateData *ed)
968{ 986{
969 return ptableval(&pd_htr_drud, ct.cube); 987 return ptableval(&pd_htr_drud, ed->cube);
970} 988}
971 989
972static int 990static int
973estimate_htrfin_htr(CubeTarget ct) 991estimate_htrfin_htr(EstimateData *ed)
974{ 992{
975 return ptableval(&pd_htrfin_htr, ct.cube); 993 return ptableval(&pd_htrfin_htr, ed->cube);
976} 994}
977 995
978static int 996static int
979estimate_optimal_HTM(CubeTarget ct) 997estimate_optimal_HTM(EstimateData *ed)
980{ 998{
981 int dr1, dr2, dr3, cor, ret; 999 int ret = -1;
982 Cube inv; 1000 Move lbase;
1001 Cube cubeaux, inv;
983 1002
984 dr1 = ptableval(&pd_khuge_HTM, ct.cube); 1003 ed->li->corners = ptableval(&pd_corners_HTM, ed->cube);
985 cor = estimate_corners_HTM(ct); 1004 UPDATECHECKSTOP(ret, ed->li->corners, ed->target);
986 ret = MAX(dr1, cor);
987 if (ret > ct.target)
988 return ret;
989 1005
990 dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, ct.cube)); 1006 ed->li->normal_ud = ptableval(&pd_khuge_HTM, ed->cube);
991 ret = MAX(ret, dr2); 1007 UPDATECHECKSTOP(ret, ed->li->normal_ud, ed->target);
992 if (ret > ct.target)
993 return ret;
994 1008
995 dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, ct.cube)); 1009 cubeaux = apply_trans(fd, ed->cube);
996 if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) 1010 ed->li->normal_fb = ptableval(&pd_khuge_HTM, cubeaux);
997 dr3++; 1011 UPDATECHECKSTOP(ret, ed->li->normal_fb, ed->target);
998 ret = MAX(ret, dr3);
999 if (ret > ct.target || ret == 0)
1000 return ret;
1001 1012
1002 /* Inverse cube probing */ 1013 cubeaux = apply_trans(rf, ed->cube);
1014 ed->li->normal_rl = ptableval(&pd_khuge_HTM, cubeaux);
1015 UPDATECHECKSTOP(ret, ed->li->normal_rl, ed->target);
1003 1016
1004 inv = inverse_cube(ct.cube); 1017 if (ret == 0)
1005 dr1 = ptableval(&pd_khuge_HTM, inv);
1006 ret = MAX(ret, dr1);
1007 if (ret > ct.target)
1008 return ret; 1018 return ret;
1009 1019
1010 dr2 = ptableval(&pd_khuge_HTM, apply_trans(rf, inv)); 1020 if (ed->li->normal_ud == ed->li->normal_fb &&
1011 ret = MAX(ret, dr2); 1021 ed->li->normal_fb == ed->li->normal_rl)
1012 if (ret > ct.target) 1022 UPDATECHECKSTOP(ret, ed->li->normal_ud + 1, ed->target);
1013 return ret; 1023
1014 1024 /* TODO: avoid computation of inverse if unnecessary */
1015 dr3 = ptableval(&pd_khuge_HTM, apply_trans(fd, inv)); 1025 lbase = base_move(ed->lastmove);
1016 if (dr1 == dr2 && dr2 == dr3 && dr1 != 0) 1026 inv = inverse_cube(ed->cube);
1017 dr3++; 1027
1018 return MAX(ret, dr3); 1028 if ((lbase != U && lbase != D) ||
1029 (ed->li->inverse_ud == -1)) {
1030 ed->li->inverse_ud = ptableval(&pd_khuge_HTM, inv);
1031 }
1032 UPDATECHECKSTOP(ret, ed->li->inverse_ud, ed->target);
1033
1034 if ((lbase != F && lbase != B) ||
1035 (ed->li->inverse_fb == -1)) {
1036 cubeaux = apply_trans(fd, inv);
1037 ed->li->inverse_fb = ptableval(&pd_khuge_HTM, cubeaux);
1038 }
1039 UPDATECHECKSTOP(ret, ed->li->inverse_fb, ed->target);
1040
1041 if ((lbase != R && lbase != L) ||
1042 (ed->li->inverse_rl == -1)) {
1043 cubeaux = apply_trans(rf, inv);
1044 ed->li->inverse_rl = ptableval(&pd_khuge_HTM, cubeaux);
1045 }
1046 UPDATECHECKSTOP(ret, ed->li->inverse_rl, ed->target);
1047
1048 if (ed->li->inverse_ud == ed->li->inverse_fb &&
1049 ed->li->inverse_fb == ed->li->inverse_rl)
1050 UPDATECHECKSTOP(ret, ed->li->inverse_ud + 1, ed->target);
1051
1052 if (ed->li->inverse_ud == ed->target)
1053 ed->movebitmask |= (1<<U) | (1<<U2) | (1<<U3) |
1054 (1<<D) | (1<<D2) | (1<<D3);
1055 if (ed->li->inverse_fb == ed->target)
1056 ed->movebitmask |= (1<<F) | (1<<F2) | (1<<F3) |
1057 (1<<B) | (1<<B2) | (1<<B3);
1058 if (ed->li->inverse_rl == ed->target)
1059 ed->movebitmask |= (1<<R) | (1<<R2) | (1<<R3) |
1060 (1<<L) | (1<<L2) | (1<<L3);
1061
1062 return ret;
1019} 1063}
1020 1064
1021static bool 1065static bool
@@ -1076,6 +1120,29 @@ detect_pretrans_drud(Cube cube)
1076/* Public functions **********************************************************/ 1120/* Public functions **********************************************************/
1077 1121
1078void 1122void
1123free_localinfo(LocalInfo *li)
1124{
1125 free(li);
1126}
1127
1128LocalInfo *
1129new_localinfo()
1130{
1131 LocalInfo *ret = malloc(sizeof(LocalInfo));
1132
1133 ret->corners = -1;
1134 ret->normal_ud = -1;
1135 ret->normal_fb = -1;
1136 ret->normal_rl = -1;
1137 ret->inverse_ud = -1;
1138 ret->inverse_fb = -1;
1139 ret->inverse_rl = -1;
1140 ret->prev_ret = -1;
1141
1142 return ret;
1143}
1144
1145void
1079prepare_step(Step *step) 1146prepare_step(Step *step)
1080{ 1147{
1081 int i; 1148 int i;

Generated with cgit - Back to sebastiano.tronto.net