00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "g-map-generic.hh"
00026 #include <cstring>
00027 using namespace GMap3d;
00028
00029 CDart * CGMapGeneric::go(TMovement ADirection, CDart * ALastDart, TOrbit AOrbit,
00030 int AMarkNumber, bool ASelect)
00031 {
00032 assert(ALastDart!=NULL);
00033 assert(AOrbit==ORBIT_03 || AOrbit==ORBIT_02 || AOrbit==ORBIT_023 ||
00034 AOrbit==ORBIT_01 || AOrbit==ORBIT_013 || AOrbit==ORBIT_012);
00035
00036 static const char * forward[16] =
00037 {
00038 "",
00039 "",
00040 "",
00041 "2101",
00042 "",
00043 "1[21]0",
00044 "",
00045 "321012",
00046 "",
00047 "10",
00048 "",
00049 "2[32]101",
00050 "",
00051 "1[2[32]1]0",
00052 "",
00053 ""
00054 };
00055
00056 static const char * right[16] =
00057 {
00058 "",
00059 "",
00060 "",
00061 "10" ,
00062 "",
00063 "010[2]" ,
00064 "",
00065 "210" ,
00066 "",
00067 "010" ,
00068 "",
00069 "10" ,
00070 "",
00071 "010[2]" ,
00072 "",
00073 ""
00074 };
00075
00076 bool reverse = ADirection==Backward || ADirection==Left;
00077
00078 const char * series =
00079 (ADirection==Left || ADirection==Right) ? right[AOrbit] : forward[AOrbit];
00080
00081 int length = strlen(series);
00082
00083
00084 if (ASelect && !isWholeCellMarked(ALastDart, AOrbit, AMarkNumber))
00085 {
00086 markOrbit(ALastDart, AOrbit, AMarkNumber);
00087 return ALastDart;
00088 }
00089
00090 if (!ASelect)
00091 unmarkOrbit(ALastDart, AOrbit, AMarkNumber);
00092
00093
00094 CDart * current = ALastDart;
00095 bool firstSubMove = false;
00096
00097 #define INFINITE (9)
00098
00099 for (int i=0, depth=0, freezeLevel=INFINITE; i<length; ++i)
00100 {
00101 char c = series[reverse ? length-i-1 : i];
00102
00103 if (c=='[' || c==']')
00104 {
00105 if (reverse ^ (c=='['))
00106 {
00107 ++depth;
00108 firstSubMove = true;
00109 }
00110 else
00111 {
00112 --depth;
00113
00114 if (depth<freezeLevel)
00115 freezeLevel = INFINITE;
00116
00117 assert(!firstSubMove);
00118 }
00119 }
00120 else
00121 {
00122 if (depth < freezeLevel)
00123 {
00124 assert(c=='0' || c=='1' || c=='2' || c=='3');
00125 int dim = c-'0';
00126
00127 if (isFree(current, dim))
00128 {
00129 if (firstSubMove)
00130 freezeLevel = depth;
00131 else
00132 return ALastDart;
00133 }
00134 else
00135 current = alpha(current, dim);
00136 }
00137
00138 firstSubMove = false;
00139 }
00140 }
00141
00142 #undef INFINITE
00143
00144
00145 if (ASelect)
00146 markOrbit(current, AOrbit, AMarkNumber);
00147 else
00148 setMark(current, AMarkNumber);
00149
00150 return current;
00151 }
00152
00153 CDart * CGMapGeneric::goAsFarAsPossible(TMovement ADirection, CDart * ALastDart,
00154 TOrbit AOrbit, int AMarkNumber,
00155 bool ASelect)
00156 {
00157 assert(ALastDart!=NULL);
00158 assert(AOrbit==ORBIT_03 || AOrbit==ORBIT_02 || AOrbit==ORBIT_023 ||
00159 AOrbit==ORBIT_01 || AOrbit==ORBIT_013 || AOrbit==ORBIT_012);
00160
00161 int treated = getNewMark();
00162
00163 CDart * current = ALastDart;
00164
00165 go(ADirection, current, AOrbit, AMarkNumber, ASelect);
00166
00167 while (!isMarked(current, treated))
00168 {
00169 setMark(current, treated);
00170 current = go(ADirection, current, AOrbit, AMarkNumber, ASelect);
00171 assert(current!=NULL);
00172 }
00173
00174 unmarkAll(treated);
00175 freeMark(treated);
00176
00177 return current;
00178 }
00179