redone modecode

This commit is contained in:
Zeno Rogue 2020-08-02 02:04:18 +02:00
parent 44f359582c
commit 3505f17460
9 changed files with 343 additions and 279 deletions

View File

@ -739,7 +739,7 @@ enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSolNIH, gcNil, gcProdu
enum class eVariation { bitruncated, pure, goldberg, irregular, dual, untruncated, warped, unrectified };
typedef flagtype modecode_t;
typedef int modecode_t;
/** only the actual geometry */
struct geometryinfo1 {
@ -764,7 +764,6 @@ struct geometryinfo {
int vertex;
flagtype flags;
geometryinfo1 g;
modecode_t xcode;
std::array<int,2> distlimit; // bitrunc, non-bitrunc
eVariation default_variation;
};
@ -844,85 +843,85 @@ EX modecode_t no_code = 0x1;
/** list of available geometries */
EX vector<geometryinfo> ginf = {
{"{7,3}", "none", "{7,3} (standard HyperRogue map)", "HR", 7, 3, 0, giHyperb2, 0, {{7, 5}}, eVariation::bitruncated},
{"{6,3}", "none", "{6,3} (euclidean Hex grid)", "euclid", 6, 3, qOPTQ, giEuclid2, 0, {{7, 7}}, eVariation::bitruncated},
{"{5,3}", "none", "{5,3} (dodecahedron)", "sphere", 5, 3, qsSMALLB, giSphere2, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{5,3}", "elliptic", "elliptic geometry in {5,3}", "elliptic", 5, 3, qsNONORE, giSphere2, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{7,3}", "Zebra", "Zebra quotient", "Zebra", 7, 3, qsZEBRA, giHyperb2, 0x00400, {{7, 5}}, eVariation::bitruncated},
{"{7,3}", "field", "field quotient", "field", 7, 3, qsFIELD, giHyperb2, 0x00200, {{7, 5}}, eVariation::bitruncated},
{"{6,3}", "torus", "torus/Klein bottle/...", "torus", 6, 3, qsBQ|qDEPRECATED, giEuclid2, 0x00600, {{7, 7}}, eVariation::bitruncated},
{"{8,3}", "none", "{8,3} (like standard but with octagons)", "oct", 8, 3, 0, giHyperb2, 0x08000, {{6, 4}}, eVariation::bitruncated},
{"{5,4}", "none", "{5,4} (four pentagons)", "4x5", 5, 4, 0, giHyperb2, 0x08200, {{6, 4}}, eVariation::bitruncated},
{"{6,4}", "none", "{6,4} (four hexagons)", "4x6", 6, 4, 0, giHyperb2, 0x08400, {{5, 3}}, eVariation::bitruncated},
{"{7,4}", "none", "{7,4} (four heptagons)", "4x7", 7, 4, 0, giHyperb2, 0x08600, {{4, 3}}, eVariation::bitruncated},
{"{4,3}", "none", "{4,3} (cube)", "3x4", 4, 3, qsSMALLB, giSphere2, 0x10000, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{3,3}", "none", "{3,3} (tetrahedron)", "3x3", 3, 3, qsSMALLB, giSphere2, 0x10200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{4,4}", "none", "{4,4} (Euclidean square grid)", "4x4", 4, 4, qOPTQ, giEuclid2, 0x10400, {{7, 7}}, eVariation::bitruncated},
{"{4,3}", "elliptic", "elliptic geometry in {4,3}", "e3x4", 4, 3, qsNONORE, giSphere2, 0x10600, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{7,3}", "Klein", "Klein Quartic", "Klein", 7, 3, qsSMALL, giHyperb2, 0x18000, {{7, 5}}, eVariation::bitruncated},
{"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, giHyperb2, 0x18200, {{6, 4}}, eVariation::bitruncated},
{"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, giHyperb2, 0x18400, {{6, 4}}, eVariation::bitruncated},
{"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, giHyperb2, 0x18600, {{7, 5}}, eVariation::bitruncated},
{"binary","none", "variant of the binary tiling", "binary", 7, 3, qBINARY, giHyperb2, 0x48400, {{7, 5}}, eVariation::pure},
{"Arch", "none", "Archimedean", "A", 7, 3, qARCHI, giHyperb2, 0, {{7, 5}}, eVariation::pure},
{"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, giHyperb2, 0x20000, {{7, 5}}, eVariation::bitruncated},
{"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, giHyperb2, 0x20200, {{6, 4}}, eVariation::bitruncated},
{"{12,3}","M3", "Schmutz's M(3)", "M3", 12, 3, qsSMALL, giHyperb2, 0x20400, {{4, 2}}, eVariation::bitruncated},
{"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, giHyperb2, 0x20600, {{4, 2}}, eVariation::bitruncated},
{"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ|qCRYSTAL, giHyperb2, 0x28000, {{5, 3}}, eVariation::pure},
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, giSphere2, 0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"bin{4,4}", "none", "{4,4} on horospheres", "bin44", 9, 3, qBINARY, giHyperb3, 0x30000, {{7, 3}}, eVariation::pure},
{"{4,3,4}","none", "{4,3,4} cube tiling", "434", 6, 4, qOPTQ, giEuclid3, 0x30200, {{7, 5}}, eVariation::pure},
{"{5,3,3}","none", "{5,3,3} 120-cell", "533", 12, 3, qsSMALLB, giSphere3, 0x30400, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{5,3,3}", "elliptic","{5,3,3} 120-cell (elliptic space)", "e533", 12, 3, qsSMALLBE, giSphere3, 0x30600, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"rh{4,3,4}","none", "rhombic dodecahedral honeycomb", "rh434", 12, 3, qOPTQ, giEuclid3, 0x31000, {{7, 5}}, eVariation::pure},
{"2t{4,3,4}","none", "bitruncated cubic honeycomb", "2t434", 14, 3, qOPTQ, giEuclid3, 0x31200, {{7, 5}}, eVariation::pure},
{"{5,3,4}","none", "{5,3,4} hyperbolic honeycomb", "534", 12, 4, 0, giHyperb3, 0x31400, {{7, 2}}, eVariation::pure},
{"{4,3,5}","none", "{4,3,5} hyperbolic honeycomb", "435", 6, 5, 0, giHyperb3, 0x31600, {{7, 2}}, eVariation::pure},
{"{3,3,3}","none", "{3,3,3} 5-cell", "333", 4, 3, qsSMALLB, giSphere3, 0x38000, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,4}","none", "{3,3,4} 16-cell", "334", 4, 4, qsSMALLB, giSphere3, 0x38200, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,4}","elliptic","{3,3,4} 16-cell (elliptic space)", "e334", 4, 4, qsSMALLBE, giSphere3, 0x39200, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{4,3,3}","none", "{4,3,3} 8-cell", "433", 6, 4, qsSMALLB, giSphere3, 0x38400, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{4,3,3}","elliptic","{4,3,3} 8-cell (elliptic space)", "e433", 6, 4, qsSMALLBE, giSphere3, 0x39400, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,4,3}","none", "{3,4,3} 24-cell", "343", 8, 3, qsSMALLB, giSphere3, 0x38600, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,4,3}","elliptic","{3,4,3} 24-cell (elliptic space)", "e343", 8, 3, qsSMALLBE, giSphere3, 0x39600, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","none", "{3,3,5} 600-cell", "335", 4, 3, qsSMALLB, giSphere3, 0x41000, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","elliptic","{3,3,5} 600-cell (elliptic space)", "e335", 4, 3, qsSMALLBE, giSphere3, 0x41200, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"bin{3,6}", "none", "{3,6} on horospheres", "bin36", 8, 3, qBINARY, giHyperb3, 0x40000, {{7, 3}}, eVariation::pure},
{"bin-rect", "none", "rectangles on horospheres", "bin44/2", 7, 3, qBINARY, giHyperb3, 0x40200, {{7, 3}}, eVariation::pure},
{"bin{6,3}", "none", "{6,3} on horospheres", "bin63", 14, 3, qBINARY, giHyperb3, 0x40400, {{7, 3}}, eVariation::pure},
{"{4,3,5}","field", "{4,3,5} field quotient space", "f435", 6, 5, qsSMALLBF | qDEPRECATED, giHyperb3, 0x40600, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{5,3,4}","field", "{5,3,4} field quotient space", "f435", 12, 4, qsSMALLBF | qDEPRECATED, giHyperb3, 0x40800, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"binary4","none", "standard binary tiling", "binary4", 5, 3, qBINARY, giHyperb2, 0x41400, {{7, 5}}, eVariation::pure},
{"sol", "none", "Solv geometry", "sol", 8, 3, qBINARY|qSOL, giSolNIH, 0x41600, {{7, 5}}, eVariation::pure},
{"kd2", "none", "kite-and-dart", "kd2", 4, 3, qKITE, giEuclid2, 0x48000, {{7, 7}}, eVariation::pure},
{"kd3", "none", "kite-and-dart on horospheres", "kd3", 12, 3, qsBP, giHyperb3, 0x48200, {{7, 3}}, eVariation::pure},
{"nil", "none", "Nil geometry", "nil", 6, 3, qOPTQ, giNil, 0x48600, {{7, 5}}, eVariation::pure},
{"product","none", "product space", "product", 7, 3, qHYBRID, giProduct, 0x00000, {{7, 3}}, eVariation::pure},
{"twisted","none", "rotation space", "twisted", 7, 3, qHYBRID, giSL2, 0x00000, {{6, 4}}, eVariation::pure},
{"ternary","none", "standard ternary tiling", "ternary", 6, 3, qBINARY, giHyperb2, 0x48400, {{6, 4}}, eVariation::pure},
{"3x2", "none", "stretched hyperbolic", "3:2", 11, 3, qBINARY|qNIH, giSolNIH, 0x49000, {{6, 3}}, eVariation::pure},
{"3x1/2", "none", "stretched Solv", "3:1/2", 9, 3, (qBINARY|qSOL|qNIH), giSolNIH, 0x49200, {{7, 3}}, eVariation::pure},
{"{3,oo}", "none", "{3,∞} (infinite triangles)", "oox3", 3, OINF, qIDEAL, giHyperb2, 0x49400, {{7, 7}}, eVariation::pure},
{"{3,3,6}","none", "{3,3,6} hyperbolic honeycomb", "336", 4, 6, qIDEAL, giHyperb3, 0x49600, {{7, 2}}, eVariation::pure},
{"{3,4,4}","none", "{3,4,4} hyperbolic honeycomb", "344", 8, 4, qIDEAL, giHyperb3, 0x50000, {{7, 2}}, eVariation::pure},
{"{3,4,4}","Crystal", "4D crystal in H3", "Cryst3" , 8, 4, qIDEAL | qANYQ | qCRYSTAL, giHyperb3, 0x52000, {{7, 3}}, eVariation::pure},
{"cat", "cat", "Arnold's cat mapping torus", "cat", 12, 3, qBINARY | qSOL | qsBQ | qOPTQ, giSolNIH, 0x52200, {{6, 4}}, eVariation::pure},
{"file", "none", "load from file", "file", 7, 3, qEXPERIMENTAL, giEuclid2, 0, {{7, 5}}, eVariation::pure},
{"{4,oo}", "none", "{4,∞} (infinite squares)", "oox4", 4, OINF, qIDEAL, giHyperb2, 0x49400, {{5, 5}}, eVariation::pure},
{"{5,3,4}","Crystal", "6D crystal in H3", "Cryst6" , 12, 4, qANYQ | qCRYSTAL, giHyperb3, 0x52000, {{7, 3}}, eVariation::pure},
{"{5,3,5}","none", "{5,3,5} hyperbolic honeycomb", "535", 12, 5, 0, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{5,3,6}","none", "{5,3,6} hyperbolic honeycomb", "536", 12, 6, qIDEAL, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{5,3,5}","SWh", "{5,3,5} quotient", "535c", 12, 5, qsSMALLB | qANYQ, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{5,3,5}","SW", "Seifert-Weber space", "535s", 12, 5, qsSINGLE, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{5,3,3}","SW", "Poincaré homology sphere", "533s", 12, 3, qsSINGLE, giSphere3, no_code, {{7, 2}}, eVariation::pure},
{"{?,oo}", "none", "{3/4,∞} (infinite triangles and squares)", "ooxm", 3, OINF, qIDEAL | qINFMIXED, giHyperb2, no_code, {{6, 6}}, eVariation::pure},
{"{4,3,6}","none", "{4,3,6} hyperbolic honeycomb", "436", 6, 6, qIDEAL, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"?", "none", "fake", "", 0, 0, qRAYONLY, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{3,4,5}","none", "{3,4,5} hyperbolic honeycomb", "345", 8, 5, qIDEAL | qULTRA, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{3,5,3}","none", "{3,5,3} hyperbolic honeycomb", "353", 20, 5, 0, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{3,5,4}","none", "{3,5,4} hyperbolic honeycomb", "354", 20, 5, qIDEAL | qULTRA, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{3,5,5}","none", "{3,5,5} hyperbolic honeycomb", "355", 20, 5, qIDEAL | qULTRA, giHyperb3, no_code, {{7, 2}}, eVariation::pure},
{"{7,3}", "none", "{7,3} (standard HyperRogue map)", "HR", 7, 3, 0, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"{6,3}", "none", "{6,3} (euclidean Hex grid)", "euclid", 6, 3, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
{"{5,3}", "none", "{5,3} (dodecahedron)", "sphere", 5, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{5,3}", "elliptic", "elliptic geometry in {5,3}", "elliptic", 5, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{7,3}", "Zebra", "Zebra quotient", "Zebra", 7, 3, qsZEBRA, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"{7,3}", "field", "field quotient", "field", 7, 3, qsFIELD, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"{6,3}", "torus", "torus/Klein bottle/...", "torus", 6, 3, qsBQ|qDEPRECATED, giEuclid2, {{7, 7}}, eVariation::bitruncated},
{"{8,3}", "none", "{8,3} (like standard but with octagons)", "oct", 8, 3, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
{"{5,4}", "none", "{5,4} (four pentagons)", "4x5", 5, 4, 0, giHyperb2, {{6, 4}}, eVariation::bitruncated},
{"{6,4}", "none", "{6,4} (four hexagons)", "4x6", 6, 4, 0, giHyperb2, {{5, 3}}, eVariation::bitruncated},
{"{7,4}", "none", "{7,4} (four heptagons)", "4x7", 7, 4, 0, giHyperb2, {{4, 3}}, eVariation::bitruncated},
{"{4,3}", "none", "{4,3} (cube)", "3x4", 4, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{3,3}", "none", "{3,3} (tetrahedron)", "3x3", 3, 3, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{4,4}", "none", "{4,4} (Euclidean square grid)", "4x4", 4, 4, qOPTQ, giEuclid2, {{7, 7}}, eVariation::bitruncated},
{"{4,3}", "elliptic", "elliptic geometry in {4,3}", "e3x4", 4, 3, qsNONORE, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"{7,3}", "Klein", "Klein Quartic", "Klein", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"{8,3}", "Bolza", "Bolza Surface", "Bolza", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
{"{8,3}", "Bolza2", "Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, giHyperb2, {{6, 4}}, eVariation::bitruncated},
{"{7,3}", "minimal", "minimal quotient", "minimal", 7, 3, qsSMALLN, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"binary","none", "variant of the binary tiling", "binary", 7, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
{"Arch", "none", "Archimedean", "A", 7, 3, qARCHI, giHyperb2, {{7, 5}}, eVariation::pure},
{"{7,3}", "Macbeath", "Macbeath Surface", "Macbeath", 7, 3, qsSMALL, giHyperb2, {{7, 5}}, eVariation::bitruncated},
{"{5,4}", "Bring", "Bring's Surface", "Bring", 5, 4, qsSMALL, giHyperb2, {{6, 4}}, eVariation::bitruncated},
{"{12,3}","M3", "Schmutz's M(3)", "M3", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
{"{12,3}","M4", "Schmutz's M(4)", "M4", 12, 3, qsSMALL, giHyperb2, {{4, 2}}, eVariation::bitruncated},
{"{6,4}", "Crystal", "dimensional crystal", "Crystal", 6, 4, qANYQ|qCRYSTAL, giHyperb2, {{5, 3}}, eVariation::pure},
{"{3,4}", "none", "{3,4} (octahedron)", "4x3", 3, 4, qsSMALLB, giSphere2, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated},
{"bin{4,4}", "none", "{4,4} on horospheres", "bin44", 9, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
{"{4,3,4}","none", "{4,3,4} cube tiling", "434", 6, 4, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
{"{5,3,3}","none", "{5,3,3} 120-cell", "533", 12, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{5,3,3}", "elliptic","{5,3,3} 120-cell (elliptic space)", "e533", 12, 3, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"rh{4,3,4}","none", "rhombic dodecahedral honeycomb", "rh434", 12, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
{"2t{4,3,4}","none", "bitruncated cubic honeycomb", "2t434", 14, 3, qOPTQ, giEuclid3, {{7, 5}}, eVariation::pure},
{"{5,3,4}","none", "{5,3,4} hyperbolic honeycomb", "534", 12, 4, 0, giHyperb3, {{7, 2}}, eVariation::pure},
{"{4,3,5}","none", "{4,3,5} hyperbolic honeycomb", "435", 6, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,3,3}","none", "{3,3,3} 5-cell", "333", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,4}","none", "{3,3,4} 16-cell", "334", 4, 4, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,4}","elliptic","{3,3,4} 16-cell (elliptic space)", "e334", 4, 4, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{4,3,3}","none", "{4,3,3} 8-cell", "433", 6, 4, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{4,3,3}","elliptic","{4,3,3} 8-cell (elliptic space)", "e433", 6, 4, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,4,3}","none", "{3,4,3} 24-cell", "343", 8, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,4,3}","elliptic","{3,4,3} 24-cell (elliptic space)", "e343", 8, 3, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","none", "{3,3,5} 600-cell", "335", 4, 3, qsSMALLB, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{3,3,5}","elliptic","{3,3,5} 600-cell (elliptic space)", "e335", 4, 3, qsSMALLBE, giSphere3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"bin{3,6}", "none", "{3,6} on horospheres", "bin36", 8, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
{"bin-rect", "none", "rectangles on horospheres", "bin44/2", 7, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
{"bin{6,3}", "none", "{6,3} on horospheres", "bin63", 14, 3, qBINARY, giHyperb3, {{7, 3}}, eVariation::pure},
{"{4,3,5}","field", "{4,3,5} field quotient space", "f435", 6, 5, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"{5,3,4}","field", "{5,3,4} field quotient space", "f435", 12, 4, qsSMALLBF | qDEPRECATED, giHyperb3, {{SEE_ALL, SEE_ALL}}, eVariation::pure},
{"binary4","none", "standard binary tiling", "binary4", 5, 3, qBINARY, giHyperb2, {{7, 5}}, eVariation::pure},
{"sol", "none", "Solv geometry", "sol", 8, 3, qBINARY|qSOL, giSolNIH, {{7, 5}}, eVariation::pure},
{"kd2", "none", "kite-and-dart", "kd2", 4, 3, qKITE, giEuclid2, {{7, 7}}, eVariation::pure},
{"kd3", "none", "kite-and-dart on horospheres", "kd3", 12, 3, qsBP, giHyperb3, {{7, 3}}, eVariation::pure},
{"nil", "none", "Nil geometry", "nil", 6, 3, qOPTQ, giNil, {{7, 5}}, eVariation::pure},
{"product","none", "product space", "product", 7, 3, qHYBRID, giProduct, {{7, 3}}, eVariation::pure},
{"twisted","none", "rotation space", "twisted", 7, 3, qHYBRID, giSL2, {{6, 4}}, eVariation::pure},
{"ternary","none", "standard ternary tiling", "ternary", 6, 3, qBINARY, giHyperb2, {{6, 4}}, eVariation::pure},
{"3x2", "none", "stretched hyperbolic", "3:2", 11, 3, qBINARY|qNIH, giSolNIH, {{6, 3}}, eVariation::pure},
{"3x1/2", "none", "stretched Solv", "3:1/2", 9, 3, (qBINARY|qSOL|qNIH), giSolNIH, {{7, 3}}, eVariation::pure},
{"{3,oo}", "none", "{3,∞} (infinite triangles)", "oox3", 3, OINF, qIDEAL, giHyperb2, {{7, 7}}, eVariation::pure},
{"{3,3,6}","none", "{3,3,6} hyperbolic honeycomb", "336", 4, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,4,4}","none", "{3,4,4} hyperbolic honeycomb", "344", 8, 4, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,4,4}","Crystal", "4D crystal in H3", "Cryst3" , 8, 4, qIDEAL | qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
{"cat", "cat", "Arnold's cat mapping torus", "cat", 12, 3, qBINARY | qSOL | qsBQ | qOPTQ, giSolNIH, {{6, 4}}, eVariation::pure},
{"file", "none", "load from file", "file", 7, 3, qEXPERIMENTAL, giEuclid2, {{7, 5}}, eVariation::pure},
{"{4,oo}", "none", "{4,∞} (infinite squares)", "oox4", 4, OINF, qIDEAL, giHyperb2, {{5, 5}}, eVariation::pure},
{"{5,3,4}","Crystal", "6D crystal in H3", "Cryst6" , 12, 4, qANYQ | qCRYSTAL, giHyperb3, {{7, 3}}, eVariation::pure},
{"{5,3,5}","none", "{5,3,5} hyperbolic honeycomb", "535", 12, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
{"{5,3,6}","none", "{5,3,6} hyperbolic honeycomb", "536", 12, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
{"{5,3,5}","SWh", "{5,3,5} quotient", "535c", 12, 5, qsSMALLB | qANYQ, giHyperb3, {{7, 2}}, eVariation::pure},
{"{5,3,5}","SW", "Seifert-Weber space", "535s", 12, 5, qsSINGLE, giHyperb3, {{7, 2}}, eVariation::pure},
{"{5,3,3}","SW", "Poincaré homology sphere", "533s", 12, 3, qsSINGLE, giSphere3, {{7, 2}}, eVariation::pure},
{"{?,oo}", "none", "{3/4,∞} (infinite triangles and squares)", "ooxm", 3, OINF, qIDEAL | qINFMIXED, giHyperb2, {{6, 6}}, eVariation::pure},
{"{4,3,6}","none", "{4,3,6} hyperbolic honeycomb", "436", 6, 6, qIDEAL, giHyperb3, {{7, 2}}, eVariation::pure},
{"?", "none", "fake", "", 0, 0, qRAYONLY, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,4,5}","none", "{3,4,5} hyperbolic honeycomb", "345", 8, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,5,3}","none", "{3,5,3} hyperbolic honeycomb", "353", 20, 5, 0, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,5,4}","none", "{3,5,4} hyperbolic honeycomb", "354", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
{"{3,5,5}","none", "{3,5,5} hyperbolic honeycomb", "355", 20, 5, qIDEAL | qULTRA, giHyperb3, {{7, 2}}, eVariation::pure},
};
// bits: 9, 10, 15, 16, (reserved for later) 17, 18

View File

@ -518,8 +518,6 @@ void set_gfake(ld _around) {
check_cgi();
cgi.require_basics();
ginf[gFake].xcode = no_code;
if(currentmap) new hrmap_fake(currentmap);
}

View File

@ -134,9 +134,11 @@ struct fhstream : hstream {
};
struct shstream : hstream {
color_t vernum;
virtual color_t get_vernum() override { return vernum; }
string s;
int pos;
shstream(const string& t = "") : s(t) { pos = 0; }
shstream(const string& t = "") : s(t) { pos = 0; vernum = VERNUM_HEX; }
virtual void write_char(char c) { s += c; }
virtual char read_char() { if(pos == isize(s)) throw hstream_exception(); return s[pos++]; }
};
@ -402,6 +404,30 @@ template<class T> T deserialize(const string& s) {
}
#endif
EX string as_hexstring(string o) {
string res;
for(char x: o) {
char buf[4];
sprintf(buf, "%02X", (unsigned char)(x));
res += buf;
}
return res;
}
EX string from_hexstring(string o) {
string res;
for(int i=0; i<isize(o); i+=2) {
char buf[4];
buf[0] = o[i];
buf[1] = o[i+1];
buf[2] = 0;
int x;
sscanf(buf, "%02X", &x);
res += char(x);
}
return res;
}
EX string as_cstring(string o) {
string s = "string(\"";
for(char c: o)

View File

@ -433,10 +433,14 @@ EX int maxgold() {
return mg;
}
EX void updateHi(eItem it, int v) {
EX void updateHi_for_code(eItem it, int v, modecode_t xcode) {
if(!yendor::on)
if(v > hiitems[modecode()][it])
changes.value_set(hiitems[modecode()][it], v);
if(v > hiitems[xcode][it])
changes.value_set(hiitems[xcode][it], v);
}
EX void updateHi(eItem it, int v) {
updateHi_for_code(it, v, modecode());
}
EX void gainItem(eItem it) {

View File

@ -2,9 +2,9 @@
// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
#include "hyper.h"
#if CAP_LEGACY
namespace hr {
#if CAP_LEGACY
namespace shmup {
void scanchar(FILE *f, char& c) {
@ -143,6 +143,100 @@ void loadOldConfig(FILE *f) {
err=fscanf(f, "%d%d%d%d%lf\n", &vid.mobilecompasssize, &vid.aurastr, &vid.aurasmoothen, &vid.graphglyph, &jps);
vid.linewidth = jps;
}
#endif
// Identifiers for the current combinations of game modes
// These are recorded in the save file, so it is somewhat
// important that they do not change for already existing
// modes, as otherwise the scores would be lost.
// Unfortunately, the codes assigned when HyperRogue had
// just a few special modes did not really follow a specific
// rule, so this system has grown rather ugly as the
// number of special modes kept growing...
// mode codes for 'old' modes, from 0 to 255
int modecodetable[42][6] = {
{ 0, 38, 39, 40, 41, 42}, // softcore hyperbolic
{ 7, 43, 44, 45, 46, 47}, // hardcore hyperbolic
{ 2, 4, 9, 11, 48, 49}, // shmup hyperbolic
{ 13, 50, 51, 52, 53, 54}, // softcore heptagonal hyperbolic
{ 16, 55, 56, 57, 58, 59}, // hardcore heptagonal hyperbolic
{ 14, 15, 17, 18, 60, 61}, // shmup heptagonal hyperbolic
{ 1, 62, 63, 64, 65, 66}, // softcore euclidean
{ 8, 67, 68, 69, 70, 71}, // hardcore euclidean
{ 3, 5, 10, 12, 72, 73}, // shmup euclidean
{110,111,112,113,114,115}, // softcore spherical
{116,117,118,119,120,121}, // hardcore spherical
{122,123,124,125,126,127}, // shmup spherical
{128,129,130,131,132,133}, // softcore heptagonal spherical
{134,135,136,137,138,139}, // hardcore heptagonal spherical
{140,141,142,143,144,145}, // shmup heptagonal spherical
{146,147,148,149,150,151}, // softcore elliptic
{152,153,154,155,156,157}, // hardcore elliptic
{158,159,160,161,162,163}, // shmup elliptic
{164,165,166,167,168,169}, // softcore heptagonal elliptic
{170,171,172,173,174,175}, // hardcore heptagonal elliptic
{176,177,178,179,180,181}, // shmup heptagonal elliptic
{ 19, 74, 75, 76, 77, 78}, // softcore hyperbolic chaosmode
{ 26, 79, 80, 81, 82, 83}, // hardcore hyperbolic chaosmode
{ 21, 23, 28, 30, 84, 85}, // shmup hyperbolic chaosmode
{ 32, 86, 87, 88, 89, 90}, // softcore heptagonal hyperbolic chaosmode
{ 35, 91, 92, 93, 94, 95}, // hardcore heptagonal hyperbolic chaosmode
{ 33, 34, 36, 37, 96, 97}, // shmup heptagonal hyperbolic chaosmode
{ 20, 98, 99,100,101,102}, // softcore euclidean chaosmode
{ 27,103,104,105,106,107}, // hardcore euclidean chaosmode
{ 22, 24, 29, 31,108,109}, // shmup euclidean chaosmode
{182,183,184,185,186,187}, // softcore spherical chaosmode
{188,189,190,191,192,193}, // hardcore spherical chaosmode
{194,195,196,197,198,199}, // shmup spherical chaosmode
{200,201,202,203,204,205}, // softcore heptagonal spherical chaosmode
{206,207,208,209,210,211}, // hardcore heptagonal spherical chaosmode
{212,213,214,215,216,217}, // shmup heptagonal spherical chaosmode
{218,219,220,221,222,223}, // softcore elliptic chaosmode
{224,225,226,227,228,229}, // hardcore elliptic chaosmode
{230,231,232,233,234,235}, // shmup elliptic chaosmode
{236,237,238,239,240,241}, // softcore heptagonal elliptic chaosmode
{242,243,244,245,246,247}, // hardcore heptagonal elliptic chaosmode
{248,249,250,251,252,253}, // shmup heptagonal elliptic chaosmode
};
// unused codes: 6 (cheat/tampered), 25, 254, 255
EX modecode_t legacy_modecode() {
if(int(geometry) > 3 || int(variation) > 1) return UNKNOWN;
if(chaosmode > 1) return UNKNOWN;
// compute the old code
int xcode = 0;
if(shmup::on) xcode += 2;
else if(pureHardcore()) xcode ++;
if(euclid) xcode += 6;
else if(!BITRUNCATED) xcode += 3;
if(sphere) {
xcode += 9;
if(elliptic) xcode += 6;
}
if(chaosmode) xcode += 21;
int np = numplayers()-1; if(np<0 || np>5) np=5;
// bits: 0 to 7
modecode_t mct = modecodetable[xcode][np];
#if CAP_INV
if(inv::on) mct += (1<<11);
#endif
if(peace::on) mct += (1<<12);
#if CAP_TOUR
if(tour::on) mct += (1<<13);
#endif
if(numplayers() == 7) mct += (1<<14);
return mct;
}
}
#endif

View File

@ -366,9 +366,13 @@ EX namespace mapeditor {
}
}
#endif
}
EX }
namespace mapstream {
#if HDR
struct hstream;
#endif
EX namespace mapstream {
#if CAP_EDIT
std::map<cell*, int> cellids;
@ -427,7 +431,7 @@ namespace mapstream {
return dir;
}
void save_geometry(fhstream& f) {
EX void save_geometry(hstream& f) {
f.write(geometry);
char nbtype = char(variation);
f.write(nbtype);
@ -476,6 +480,10 @@ namespace mapstream {
if(hybri) {
hybrid::in_underlying_geometry([&] { save_geometry(f); });
}
if(fake::in()) {
f.write(fake::around);
fake::in_underlying_geometry([&] { save_geometry(f); });
}
if(bt::in())
f.write(vid.binary_width);
if(euc::in()) {
@ -485,7 +493,8 @@ namespace mapstream {
f.write(mine_adjacency_rule);
}
void load_geometry(fhstream& f) {
EX void load_geometry(hstream& f) {
auto vernum = f.get_vernum();
f.read(geometry);
char nbtype;
f.read(nbtype);
@ -497,7 +506,7 @@ namespace mapstream {
}
#endif
#if CAP_CRYSTAL
if(cryst && f.vernum >= 10504) {
if(cryst && vernum >= 10504) {
int sides;
f.read(sides);
#if CAP_CRYSTAL
@ -523,7 +532,7 @@ namespace mapstream {
auto& ge = fgeomextras[current_extra];
auto& id = ge.current_prime_id;
f.read(id);
if(f.vernum < 0xA80C) switch(ge.base) {
if(vernum < 0xA80C) switch(ge.base) {
case gNormal: id++; break;
case g45: id++; break;
case g46: id+=2; break;
@ -544,36 +553,43 @@ namespace mapstream {
}
}
#endif
if(geometry == gNil && f.vernum >= 0xA80C) {
if(geometry == gNil && vernum >= 0xA80C) {
f.read(S7);
f.read(nilv::nilperiod);
nilv::set_flags();
}
if(geometry == gArnoldCat && f.vernum >= 0xA80C) {
if(geometry == gArnoldCat && vernum >= 0xA80C) {
f.read(asonov::period_xy);
f.read(asonov::period_z);
asonov::set_flags();
}
if(geometry == gProduct && f.vernum >= 0xA80C) {
if(geometry == gProduct && vernum >= 0xA80C) {
f.read(hybrid::csteps);
if(f.vernum >= 0xA80D) f.read(product::cspin);
if(f.vernum >= 0xA833) f.read(product::cmirror);
if(vernum >= 0xA80D) f.read(product::cspin);
if(vernum >= 0xA833) f.read(product::cmirror);
}
if(geometry == gRotSpace && f.vernum >= 0xA833) {
if(geometry == gRotSpace && vernum >= 0xA833) {
f.read(hybrid::csteps);
}
if(hybri && f.vernum >= 0xA80C) {
if(hybri && vernum >= 0xA80C) {
auto g = geometry;
load_geometry(f);
set_geometry(g);
}
if(bt::in() && f.vernum >= 0xA80C)
if(fake::in()) {
ld ar;
f.read(ar);
fake::around = ar;
load_geometry(f);
fake::change_around();
}
if(bt::in() && vernum >= 0xA80C)
f.read(vid.binary_width);
if(euc::in() && f.vernum >= 0xA80D) {
if(euc::in() && vernum >= 0xA80D) {
f.read(euc::eu_input.user_axes);
f.read(euc::eu_input.twisted);
}
if(f.vernum >= 0xA810)
if(vernum >= 0xA810)
f.read(mine_adjacency_rule);
}
@ -917,9 +933,9 @@ namespace mapstream {
}
#endif
}
EX }
namespace mapeditor {
EX namespace mapeditor {
EX bool drawplayer = true;

View File

@ -1043,7 +1043,6 @@ EX namespace hybrid {
auto keep = ginf[g].menu_displayed_name;
ginf[g] = ginf[underlying];
ginf[g].menu_displayed_name = keep;
ginf[g].xcode = no_code;
if(g == gRotSpace) {
ginf[g].g = sph ? giSphere3 : giSL2;
ginf[g].tiling_name = "Iso(" + ginf[g].tiling_name + ")";

View File

@ -411,7 +411,7 @@ EX namespace scores {
/** \brief the amount of boxes reserved for each hr::score item */
#define MAXBOX 500
/** \brief currently used boxes in hr::score */
#define POSSCORE 387
#define POSSCORE 388
/** \brief a struct to keep local score from an earlier game */
struct score {
/** \brief version used */
@ -491,7 +491,7 @@ void applyBoxI(eItem it, bool f = false) {
fakebox[boxid] = f;
monsbox[boxid] = false;
if(loadingHi) {
updateHi(it, save.box[boxid++]);
updateHi_for_code(it, save.box[boxid++], saved_modecode);
}
else applyBox(items[it]);
}
@ -531,6 +531,8 @@ void applyBoxM(eMonster m, bool f = false) {
applyBox(kills[m]);
}
EX modecode_t saved_modecode;
/** \brief Call applyBox for all the required values. This will save the values if hr::scores::saving==true, load if hr::scores::loading==true, load into highscores if hr::scores::loadingHi==true */
EX void applyBoxes() {
invorb.clear();
@ -879,6 +881,8 @@ EX void applyBoxes() {
applyBoxM(moRusalka);
list_invorb();
applyBoxNum(saved_modecode, "modecode");
if(POSSCORE != boxid) printf("ERROR: %d boxes\n", boxid);
if(isize(invorb)) { println(hlog, "ERROR: Orbs not taken into account"); exit(1); }
}
@ -894,11 +898,13 @@ void loadBox() {
boxid = 0; loading = true; applyBoxes(); loading = false;
}
/** \brief load the current game values from save into the highscore tables */
void loadBoxHigh() {
const int MODECODE_BOX = 387;
modecode_t fill_modecode() {
dynamicval<int> sp1(multi::players, save.box[197]);
dynamicval<eGeometry> sp2(geometry, (eGeometry) save.box[116]);
if(among(geometry, gArchimedean, gProduct, gRotSpace, gArbitrary))
return 6; /* these would not be saved nor loaded correctly */
dynamicval<bool> sp3(shmup::on, save.box[119]);
dynamicval<int> sp4(chaosmode, save.box[196]);
dynamicval<eVariation> sp5(variation, (eVariation) save.box[186]);
@ -911,14 +917,22 @@ void loadBoxHigh() {
if(save.box[341]) variation = eVariation::goldberg;
if(save.box[344]) variation = eVariation::irregular;
if(multi::players < 1 || multi::players > MAXPLAYER)
if(multi::players < 0 || multi::players > MAXPLAYER)
return 6;
if(multi::players == 0)
multi::players = 1;
if(shmup::on && multi::players == 1) ;
else {
// have boxid
boxid = 0; loadingHi = true; applyBoxes(); loadingHi = false;
}
if(shmup::on && multi::players == 1 && boxid <= 258)
return 6; /* not sure why */
return modecode(2);
}
/** \brief load the current game values from save into the highscore tables */
void loadBoxHigh() {
saved_modecode = save.box[MODECODE_BOX];
boxid = 0; loadingHi = true; applyBoxes(); loadingHi = false;
}
EX }
@ -964,20 +978,18 @@ EX void saveStats(bool emergency IS(false)) {
if(tour::on) return;
#endif
if(randomPatternsMode) return;
if(dual::state) return;
if(arcm::in()) return;
if(arb::in()) return;
if(hybri) return;
if(daily::on) return;
if(peace::on) return;
if(dpgen::in) return;
if(experimental) return;
if(ginf[geometry].xcode == no_code) return;
if(INVERSE) return;
if(!gold()) return;
remove_emergency_save();
auto& xcode = scores::saved_modecode;
xcode = modecode();
FILE *f = fopen(scorefile, "at");
if(!f) {
@ -999,15 +1011,13 @@ EX void saveStats(bool emergency IS(false)) {
if((tactic::on || yendor::on) && !items[itOrbSafety] && !cheater) {
int t = (int) (timer - timerstart);
modecode_t xcode = modecode();
if(tactic::on) {
int score = items[treasureType(specialland)];
if(score) {
int c =
anticheat::certify(dnameof(specialland), turncount, t, (int) timerstart,
int(xcode)*999 + tactic::id + 256 * score + (xcode>>32)*7);
unsigned(xcode)*999 + tactic::id + 256 * score);
fprintf(f, "TACTICS %s %d %d %d %d %d %d %d %d date: %s\n", VER,
tactic::id, specialland, score, turncount, t, int(timerstart),
c, int(xcode), buf);
@ -1020,7 +1030,7 @@ EX void saveStats(bool emergency IS(false)) {
fprintf(f, "YENDOR %s %d %d %d %d %d %d %d %d date: %s\n", VER,
yendor::lastchallenge, items[itOrbYendor], yendor::won, turncount, t, int(timerstart),
anticheat::certify(yendor::won ? "WON" : "LOST", turncount, t, (int) timerstart,
int(xcode)*999 + yendor::lastchallenge + 256 * items[itOrbYendor] + (xcode>>32)*7),
unsigned(xcode)*999 + yendor::lastchallenge + 256 * items[itOrbYendor]),
int(xcode),
buf);
@ -1098,8 +1108,13 @@ EX void loadsave() {
bool tamper = false;
int coh = counthints();
while(!feof(f)) {
char buf[120];
if(fgets(buf, 120, f) == NULL) break;
char buf[12000];
if(fgets(buf, 12000, f) == NULL) break;
if(buf[0] == 'M' && buf[1] == 'O') {
string s = buf;
while(s != "" && s.back() < 32) s.pop_back();
load_modecode_line(s);
}
if(buf[0] == 'H' && buf[1] == 'y') {
if(fscanf(f, "%s", buf) <= 0) break;
sc.ver = buf;
@ -1115,6 +1130,8 @@ EX void loadsave() {
using namespace scores;
for(int i=0; i<boxid; i++) save.box[i] = sc.box[i];
for(int i=boxid; i<MAXBOX; i++) save.box[i] = 0, sc.box[i] = 0;
if(boxid <= MODECODE_BOX) save.box[MODECODE_BOX] = sc.box[MODECODE_BOX] = fill_modecode();
if(save.box[258] >= 0 && save.box[258] < coh) {
hints[save.box[258]].last = save.box[1];
@ -1209,6 +1226,11 @@ EX void loadsave() {
randomPatternsMode = false;
yendor::on = false;
tour::on = false;
shstream ss;
ss.s = meaning[sc.box[MODECODE_BOX]];
ss.read(ss.vernum);
mapstream::load_geometry(ss);
}
}
#endif

View File

@ -16,7 +16,8 @@ EX int hiitemsMax(eItem it) {
return mx;
}
EX modecode_t modecode();
/** 1 - just return UNKNOWN if id not assigned; 2 - assign without writing to file; 3 - assign with writing to file */
EX modecode_t modecode(int mode IS(3));
typedef vector<pair<int, string> > subscoreboard;
@ -788,7 +789,6 @@ EX namespace yendor {
if(yendor::on) {
changes.value_set(yendor::won, true);
if(!cheater) {
dynamicval<int> c(chaosmode, 0);
yendor::bestscore[modecode()][yendor::challenge] =
max(yendor::bestscore[modecode()][yendor::challenge], items[itOrbYendor]);
yendor::uploadScore();
@ -830,8 +830,8 @@ EX namespace tactic {
};
map<modecode_t, vector<scoredata>> scoreboard;
int chances(eLand l) {
if(modecode() != 0 && l != laCamelot) return 3;
EX int chances(eLand l, modecode_t xc IS(modecode())) {
if(xc != 0 && l != laCamelot) return 3;
for(auto& ti: land_tac)
if(ti.l == l)
return ti.tries;
@ -853,12 +853,12 @@ EX namespace tactic {
return hiitemsMax(treasureType(l)) * landMultiplier(l) >= 20;
}
EX void record(eLand land, int score, flagtype xc IS(modecode())) {
EX void record(eLand land, int score, modecode_t xc IS(modecode())) {
if(land >=0 && land < landtypes) {
for(int i=MAXTAC-1; i; i--) lsc[xc][land][i] = lsc[xc][land][i-1];
tactic::lsc[xc][land][0] = score;
}
int t = chances(land);
int t = chances(land, xc);
int csum = 0;
for(int i=0; i<t; i++) if(lsc[xc][land][i] > 0) csum += lsc[xc][land][i];
if(csum > recordsum[xc][land]) recordsum[xc][land] = csum;
@ -1029,160 +1029,66 @@ EX namespace tactic {
EX }
// Identifiers for the current combinations of game modes
// These are recorded in the save file, so it is somewhat
// important that they do not change for already existing
// modes, as otherwise the scores would be lost.
// Unfortunately, the codes assigned when HyperRogue had
// just a few special modes did not really follow a specific
// rule, so this system has grown rather ugly as the
// number of special modes kept growing...
map<string, modecode_t> code_for;
EX map<modecode_t, string> meaning;
// mode codes for 'old' modes, from 0 to 255
char xcheat;
int modecodetable[42][6] = {
{ 0, 38, 39, 40, 41, 42}, // softcore hyperbolic
{ 7, 43, 44, 45, 46, 47}, // hardcore hyperbolic
{ 2, 4, 9, 11, 48, 49}, // shmup hyperbolic
{ 13, 50, 51, 52, 53, 54}, // softcore heptagonal hyperbolic
{ 16, 55, 56, 57, 58, 59}, // hardcore heptagonal hyperbolic
{ 14, 15, 17, 18, 60, 61}, // shmup heptagonal hyperbolic
{ 1, 62, 63, 64, 65, 66}, // softcore euclidean
{ 8, 67, 68, 69, 70, 71}, // hardcore euclidean
{ 3, 5, 10, 12, 72, 73}, // shmup euclidean
{110,111,112,113,114,115}, // softcore spherical
{116,117,118,119,120,121}, // hardcore spherical
{122,123,124,125,126,127}, // shmup spherical
{128,129,130,131,132,133}, // softcore heptagonal spherical
{134,135,136,137,138,139}, // hardcore heptagonal spherical
{140,141,142,143,144,145}, // shmup heptagonal spherical
{146,147,148,149,150,151}, // softcore elliptic
{152,153,154,155,156,157}, // hardcore elliptic
{158,159,160,161,162,163}, // shmup elliptic
{164,165,166,167,168,169}, // softcore heptagonal elliptic
{170,171,172,173,174,175}, // hardcore heptagonal elliptic
{176,177,178,179,180,181}, // shmup heptagonal elliptic
{ 19, 74, 75, 76, 77, 78}, // softcore hyperbolic chaosmode
{ 26, 79, 80, 81, 82, 83}, // hardcore hyperbolic chaosmode
{ 21, 23, 28, 30, 84, 85}, // shmup hyperbolic chaosmode
{ 32, 86, 87, 88, 89, 90}, // softcore heptagonal hyperbolic chaosmode
{ 35, 91, 92, 93, 94, 95}, // hardcore heptagonal hyperbolic chaosmode
{ 33, 34, 36, 37, 96, 97}, // shmup heptagonal hyperbolic chaosmode
{ 20, 98, 99,100,101,102}, // softcore euclidean chaosmode
{ 27,103,104,105,106,107}, // hardcore euclidean chaosmode
{ 22, 24, 29, 31,108,109}, // shmup euclidean chaosmode
{182,183,184,185,186,187}, // softcore spherical chaosmode
{188,189,190,191,192,193}, // hardcore spherical chaosmode
{194,195,196,197,198,199}, // shmup spherical chaosmode
{200,201,202,203,204,205}, // softcore heptagonal spherical chaosmode
{206,207,208,209,210,211}, // hardcore heptagonal spherical chaosmode
{212,213,214,215,216,217}, // shmup heptagonal spherical chaosmode
{218,219,220,221,222,223}, // softcore elliptic chaosmode
{224,225,226,227,228,229}, // hardcore elliptic chaosmode
{230,231,232,233,234,235}, // shmup elliptic chaosmode
{236,237,238,239,240,241}, // softcore heptagonal elliptic chaosmode
{242,243,244,245,246,247}, // hardcore heptagonal elliptic chaosmode
{248,249,250,251,252,253}, // shmup heptagonal elliptic chaosmode
};
// unused codes: 6 (cheat/tampered), 25, 254, 255
void save_mode_data(hstream& f) {
mapstream::save_geometry(f);
if(yendor::on)
f.write<char>(0);
else
f.write<char>(chaosmode);
f.write<char>(shmup::on);
f.write<char>(inv::on);
f.write<char>(tour::on);
f.write<char>(peace::on);
f.write<char>(peace::otherpuzzles);
f.write<char>(peace::explore_other);
f.write<char>(multi::players);
f.write<char>(xcheat);
}
modecode_t modecode() {
// bit 61: product; 62: rotspace
if(hybri) return PIU(modecode()) | (1ll << (prod ? 61 : 62));
#if CAP_SAVE
if(anticheat::tampered || cheater || geometry >= gGUARD) return 6;
#endif
EX modecode_t modecode(int mode) {
modecode_t x = legacy_modecode();
if(x != UNKNOWN) return x;
// compute the old code
int xcode = 0;
xcheat = (cheater ? 1 : 0);
shstream ss;
ss.write(ss.vernum);
save_mode_data(ss);
if(code_for.count(ss.s)) return code_for[ss.s];
if(shmup::on) xcode += 2;
else if(pureHardcore()) xcode ++;
if(mode == 1) return UNKNOWN;
if(euclid) xcode += 6;
else if(!BITRUNCATED) xcode += 3;
modecode_t next = 100000;
while(meaning.count(next)) next++;
if(sphere) {
xcode += 9;
if(elliptic) xcode += 6;
}
meaning[next] = ss.s;
code_for[ss.s] = next;
if(chaosmode) xcode += 21;
if(mode == 2) return next;
int np = numplayers()-1; if(np<0 || np>5) np=5;
// bits: 0 to 7
modecode_t mct = modecodetable[xcode][np];
FILE *f = fopen(scorefile, "at");
string s = as_hexstring(ss.s);
fprintf(f, "MODE %d %s\n", next, s.c_str());
fclose(f);
// bits: 9, 10, 15, 16, 17, 18
mct += ginf[geometry].xcode;
#if CAP_INV
if(inv::on) mct += (1<<11);
#endif
if(peace::on) mct += (1<<12);
#if CAP_TOUR
if(tour::on) mct += (1<<13);
#endif
if(numplayers() == 7) mct += (1<<14);
return next;
}
// daily/Yendor/Tactics/standard are saved separately, but are using the same codes (Daily uses no code)
// randompattern never records its scores
// no specifics of the advanced configuration of torus/fieldquotient currently recorded
#if CAP_GP
if(GOLDBERG) {
mct += (1 << 19);
auto loc = gp::human_representation(gp::param);
mct += loc.first << 21; // 4 bits
mct += loc.second << 25; // 4 bits
}
#endif
#if CAP_IRR
if(IRREGULAR) {
mct += (1 << 20);
mct += irr::density_code() << 21; // 8 bits
}
#endif
if(DUAL) {
mct += (1 << 19);
mct += (1 << 20);
}
typedef long long ll;
// 32 bits [29..61) for geometry specifics
if(euclid && quotient) {
/* todo */
}
#if CAP_FIELD
if(geometry == gFieldQuotient) {
using namespace fieldpattern;
mct += ll(current_extra) << 29;
mct += ll(fgeomextras[current_extra].current_prime_id) << 37;
}
#endif
#if CAP_CRYSTAL
if(cryst) {
mct += ll(ginf[geometry].sides) << 29;
mct += ll(ginf[geometry].vertex) << 37;
}
#endif
#if CAP_ARCM
if(geometry == gArchimedean) {
unsigned res = 7;
for(char c: arcm::current.symbol) res = res * 157 + c;
mct += ll(res) << 29;
if(PURE) mct ^= (1<<29);
}
#endif
return mct;
EX void load_modecode_line(string s) {
int code = atoi(&s[5]);
int pos = 5;
while(s[pos] != ' ' && s[pos]) pos++;
if(!s[pos]) return;
pos++;
string t = from_hexstring(s.substr(pos));
code_for[t] = code;
meaning[code] = t;
}
EX namespace peace {