mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
Pattern-related functions moved from cells and mapeditor to pattern2s; three-color patterns
This commit is contained in:
parent
22535c919c
commit
9b2f9ecc14
395
cell.cpp
395
cell.cpp
@ -713,49 +713,6 @@ void verifycells(heptagon *at) {
|
|||||||
verifycell(at->c7);
|
verifycell(at->c7);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eupattern(cell *c) {
|
|
||||||
if(torus) return (decodeId(c->master)*2) % 3;
|
|
||||||
eucoord x, y;
|
|
||||||
decodeMaster(c->master, x, y);
|
|
||||||
short z = (short(y+2*x))%3;
|
|
||||||
z %= 3;
|
|
||||||
if(z<0) z += 3;
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ishept(cell *c) {
|
|
||||||
// EUCLIDEAN
|
|
||||||
if(euclid) return eupattern(c) == 0;
|
|
||||||
else return c->type != S6;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ishex1(cell *c) {
|
|
||||||
// EUCLIDEAN
|
|
||||||
if(euclid) return eupattern(c) == 1;
|
|
||||||
else return c->type != S6;
|
|
||||||
}
|
|
||||||
|
|
||||||
int val46(cell *c) {
|
|
||||||
return ctof(c) ? c->master->emeraldval :
|
|
||||||
((c->master->emeraldval & 1) ^ ((c->master->emeraldval & 2)>>1) ^ (c->spin(0)&1)) ? 8 : 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int emeraldval(cell *c) {
|
|
||||||
if(euclid) return eupattern(c);
|
|
||||||
if(a46) return val46(c);
|
|
||||||
if(sphere) return 0;
|
|
||||||
if(ctof(c))
|
|
||||||
return c->master->emeraldval >> 3;
|
|
||||||
else {
|
|
||||||
return emerald_hexagon(
|
|
||||||
emeraldval(createMov(c,0)),
|
|
||||||
emeraldval(createMov(c,2)),
|
|
||||||
emeraldval(createMov(c,4))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int eudist(short sx, short sy) {
|
int eudist(short sx, short sy) {
|
||||||
int z0 = abs(sx);
|
int z0 = abs(sx);
|
||||||
int z1 = abs(sy);
|
int z1 = abs(sy);
|
||||||
@ -836,202 +793,6 @@ int dirfromto(cell *cfrom, cell *cto) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// === FIFTYVALS ===
|
|
||||||
|
|
||||||
unsigned bitmajority(unsigned a, unsigned b, unsigned c) {
|
|
||||||
return (a&b) | ((a^b)&c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int eufifty(cell *c) {
|
|
||||||
eucoord x, y;
|
|
||||||
if(torus) {
|
|
||||||
if(c->land == laWildWest) return decodeId(c->master) % 37;
|
|
||||||
else return decodeId(c->master) % 27;
|
|
||||||
}
|
|
||||||
decodeMaster(c->master, x, y);
|
|
||||||
int ix = short(x) + 99999 + short(y);
|
|
||||||
int iy = short(y) + 99999;
|
|
||||||
if(c->land == laWildWest)
|
|
||||||
return (ix + iy * 26 + 28) % 37;
|
|
||||||
else {
|
|
||||||
ix += (iy/3) * 3;
|
|
||||||
iy %= 3; ix %= 9;
|
|
||||||
return iy * 9 + ix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int val38(cell *c) {
|
|
||||||
if(ctof(c)) return c->master->fiftyval;
|
|
||||||
else return 4 ^ c->master->fiftyval ^ (c->spin(0) & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fiftyval(cell *c) {
|
|
||||||
if(a38) return val38(c);
|
|
||||||
if(euclid) return eufifty(c) * 32;
|
|
||||||
if(sphere || S7>7 || S6>6) return 0;
|
|
||||||
if(ctof(c))
|
|
||||||
return c->master->fiftyval;
|
|
||||||
else {
|
|
||||||
return bitmajority(
|
|
||||||
fiftyval(createMov(c,0)),
|
|
||||||
fiftyval(createMov(c,2)),
|
|
||||||
fiftyval(createMov(c,4))) + 512;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cdist50(cell *c) {
|
|
||||||
if(sphere || S7>7 || S6>6) return 0;
|
|
||||||
if(euclid) {
|
|
||||||
if(c->land == laWildWest)
|
|
||||||
return "0123333332112332223322233211233333322"[eufifty(c)] - '0';
|
|
||||||
else return "012333321112322232222321123"[eufifty(c)] - '0';
|
|
||||||
}
|
|
||||||
if(c->type != 6) return cdist50(fiftyval(c));
|
|
||||||
int a0 = cdist50(createMov(c,0));
|
|
||||||
int a1 = cdist50(createMov(c,2));
|
|
||||||
int a2 = cdist50(createMov(c,4));
|
|
||||||
if(a0 == 0 || a1 == 0 || a2 == 0) return 1;
|
|
||||||
return a0+a1+a2-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
int land50(cell *c) {
|
|
||||||
if(c->type != 6) return land50(fiftyval(c));
|
|
||||||
else if(sphere || euclid) return 0;
|
|
||||||
else {
|
|
||||||
if(cdist50(createMov(c,0)) < 3) return land50(createMov(c,0));
|
|
||||||
if(cdist50(createMov(c,2)) < 3) return land50(createMov(c,2));
|
|
||||||
if(cdist50(createMov(c,4)) < 3) return land50(createMov(c,4));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int polara50(cell *c) {
|
|
||||||
if(c->type != 6) return polara50(fiftyval(c));
|
|
||||||
else if(sphere || euclid || S7>7 || S6>6) return 0;
|
|
||||||
else {
|
|
||||||
if(cdist50(createMov(c,0)) < 3) return polara50(createMov(c,0));
|
|
||||||
if(cdist50(createMov(c,2)) < 3) return polara50(createMov(c,2));
|
|
||||||
if(cdist50(createMov(c,4)) < 3) return polara50(createMov(c,4));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int polarb50(cell *c) {
|
|
||||||
if(euclid) return true;
|
|
||||||
if(c->type != 6) return polarb50(fiftyval(c));
|
|
||||||
else if(sphere || euclid || S7>7 || S6>6) return true;
|
|
||||||
else {
|
|
||||||
if(cdist50(createMov(c,0)) < 3) return polarb50(createMov(c,0));
|
|
||||||
if(cdist50(createMov(c,2)) < 3) return polarb50(createMov(c,2));
|
|
||||||
if(cdist50(createMov(c,4)) < 3) return polarb50(createMov(c,4));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int elhextable[28][3] = {
|
|
||||||
{0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1}
|
|
||||||
};
|
|
||||||
|
|
||||||
int fiftyval049(cell *c) {
|
|
||||||
if(c->type != 6 || euclid) return fiftyval(c) / 32;
|
|
||||||
else if(sphere) return 0;
|
|
||||||
else {
|
|
||||||
int a[3], qa=0;
|
|
||||||
int pa = polara50(c), pb = polarb50(c);
|
|
||||||
for(int i=0; i<6; i+=2) {
|
|
||||||
cell *c2 = c->mov[i];
|
|
||||||
if(polara50(c2) == pa && polarb50(c2) == pb)
|
|
||||||
a[qa++] = fiftyval049(c2);
|
|
||||||
}
|
|
||||||
// 0-1-2
|
|
||||||
sort(a, a+qa);
|
|
||||||
if(qa == 1) return 43+a[0]-1;
|
|
||||||
if(qa == 2 && a[1] == a[0]+7) return 36+a[0]-1;
|
|
||||||
if(qa == 2 && a[1] != a[0]+7) return 29+a[0]-1;
|
|
||||||
if(a[1] == 1 && a[2] == 7)
|
|
||||||
return 15 + 6;
|
|
||||||
if(a[2] >= 1 && a[2] <= 7)
|
|
||||||
return 15 + a[1]-1;
|
|
||||||
if(a[0] == 1 && a[1] == 7 && a[2] == 8)
|
|
||||||
return 22;
|
|
||||||
if(a[1] <= 7 && a[2] >= 8)
|
|
||||||
return 22 + a[1]-1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
{0,1,2} 15+0..15+6
|
|
||||||
{1,2,9},22+0..22+6
|
|
||||||
{1,9} 29+0..29+6
|
|
||||||
{1,8} 36+0..36+6
|
|
||||||
{1} 43+0..43+6
|
|
||||||
*/
|
|
||||||
|
|
||||||
// zebraval
|
|
||||||
|
|
||||||
int dir_truncated457(cell *c) {
|
|
||||||
int wset = 0;
|
|
||||||
for(int i=0; i<4; i++)
|
|
||||||
if(zebra40(createMov(c, i*2))&2) wset |= (1<<i);
|
|
||||||
if(wset == 0) return -8;
|
|
||||||
if(wset == 15) return -10;
|
|
||||||
if(wset == 3) return 1;
|
|
||||||
if(wset == 6) return 3;
|
|
||||||
if(wset == 12) return 5;
|
|
||||||
if(wset == 9) return 7;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int zebra40(cell *c) {
|
|
||||||
if(euclid) return eupattern(c);
|
|
||||||
else if(a46) return val46(c);
|
|
||||||
else if(ctof(c)) return (c->master->zebraval/10);
|
|
||||||
else if(a4) {
|
|
||||||
int ws = dir_truncated457(c);
|
|
||||||
if(ws < 0) return -ws;
|
|
||||||
return 16 + (ws/2);
|
|
||||||
}
|
|
||||||
else if(sphere) return 0;
|
|
||||||
else if(euclid) return eupattern(c);
|
|
||||||
else if(S3 == 4 && S7 == 6) {
|
|
||||||
return 8 + ((c->master->zebraval / 10 + c->spin(0))%2) * 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int ii[3], z;
|
|
||||||
ii[0] = (c->mov[0]->master->zebraval/10);
|
|
||||||
ii[1] = (c->mov[2]->master->zebraval/10);
|
|
||||||
ii[2] = (c->mov[4]->master->zebraval/10);
|
|
||||||
for(int r=0; r<2; r++)
|
|
||||||
if(ii[1] < ii[0] || ii[2] < ii[0])
|
|
||||||
z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z;
|
|
||||||
for(int i=0; i<28; i++)
|
|
||||||
if(zebratable6[i][0] == ii[0] && zebratable6[i][1] == ii[1] &&
|
|
||||||
zebratable6[i][2] == ii[2]) {
|
|
||||||
int ans = 16+i;
|
|
||||||
// if(ans >= 40) ans ^= 2;
|
|
||||||
// if(ans >= 4 && ans < 16) ans ^= 2;
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int zebra3(cell *c) {
|
|
||||||
if(c->type != 6) return (c->master->zebraval/10)/4;
|
|
||||||
else if(sphere || S7>7 || S6>6) return 0;
|
|
||||||
else {
|
|
||||||
int ii[3];
|
|
||||||
ii[0] = (c->mov[0]->master->zebraval/10)/4;
|
|
||||||
ii[1] = (c->mov[2]->master->zebraval/10)/4;
|
|
||||||
ii[2] = (c->mov[4]->master->zebraval/10)/4;
|
|
||||||
if(ii[0] == ii[1]) return ii[0];
|
|
||||||
if(ii[1] == ii[2]) return ii[1];
|
|
||||||
if(ii[2] == ii[0]) return ii[2];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RPV_MODULO 5
|
#define RPV_MODULO 5
|
||||||
|
|
||||||
#define RPV_RAND 0
|
#define RPV_RAND 0
|
||||||
@ -1345,76 +1106,6 @@ cell *heptatdir(cell *c, int d) {
|
|||||||
else return createMov(c, d);
|
else return createMov(c, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace fieldpattern {
|
|
||||||
|
|
||||||
pair<int, bool> fieldval(cell *c) {
|
|
||||||
if(ctof(c)) return make_pair(c->master->fieldval, false);
|
|
||||||
else return make_pair(btspin(c->master->fieldval, c->spin(0)), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fieldval_uniq(cell *c) {
|
|
||||||
if(sphere) {
|
|
||||||
if(ctof(c)) return c->master->fieldval;
|
|
||||||
else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval;
|
|
||||||
}
|
|
||||||
else if(torus) {
|
|
||||||
return decodeId(c->master);
|
|
||||||
}
|
|
||||||
else if(euclid) {
|
|
||||||
eucoord x, y;
|
|
||||||
decodeMaster(c->master, x, y);
|
|
||||||
int i = (short int)(x) * torusconfig::dx + (short int)(y) * torusconfig::dy;
|
|
||||||
i %= torusconfig::qty;
|
|
||||||
if(i<0) i += torusconfig::qty;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
if(ctof(c)) return c->master->fieldval/S7;
|
|
||||||
else {
|
|
||||||
int z = 0;
|
|
||||||
for(int u=0; u<S6; u+=2)
|
|
||||||
z = max(z, btspin(createMov(c, u)->master->fieldval, c->spin(u)));
|
|
||||||
return -1-z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int fieldval_uniq_rand(cell *c, int randval) {
|
|
||||||
if(sphere || torus || euclid)
|
|
||||||
// we do not care in these cases
|
|
||||||
return fieldval_uniq(c);
|
|
||||||
if(ctof(c)) return currfp.gmul(c->master->fieldval, randval)/7;
|
|
||||||
else {
|
|
||||||
int z = 0;
|
|
||||||
for(int u=0; u<6; u+=2)
|
|
||||||
z = max(z, btspin(currfp.gmul(createMov(c, u)->master->fieldval, randval), c->spin(u)));
|
|
||||||
return -1-z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int subpathid = currfp.matcode[currfp.strtomatrix("RRRPRRRRRPRRRP")];
|
|
||||||
int subpathorder = currfp.order(currfp.matrices[subpathid]);
|
|
||||||
|
|
||||||
pair<int, int> subval(cell *c, int _subpathid = subpathid, int _subpathorder = subpathorder) {
|
|
||||||
if(!ctof(c)) {
|
|
||||||
auto m = subval(createMov(c, 0));
|
|
||||||
for(int u=2; u<S6; u+=2)
|
|
||||||
m = min(m, subval(createMov(c, u)));
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pair<int, int> pbest, pcur;
|
|
||||||
pcur.first = c->master->fieldval;
|
|
||||||
pcur.second = 0;
|
|
||||||
pbest = pcur;
|
|
||||||
for(int i=0; i<_subpathorder; i++) {
|
|
||||||
pcur.first = currfp.gmul(pcur.first, _subpathid);
|
|
||||||
pcur.second++;
|
|
||||||
if(pcur < pbest) pbest = pcur;
|
|
||||||
}
|
|
||||||
return pbest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
int celldistance(cell *c1, cell *c2) {
|
int celldistance(cell *c1, cell *c2) {
|
||||||
int d = 0;
|
int d = 0;
|
||||||
|
|
||||||
@ -1509,89 +1200,3 @@ void clearCellMemory() {
|
|||||||
|
|
||||||
auto cellhooks = addHook(clearmemory, 500, clearCellMemory);
|
auto cellhooks = addHook(clearmemory, 500, clearCellMemory);
|
||||||
|
|
||||||
int getHemisphere(cell *c, int which) {
|
|
||||||
if(torus) return 0;
|
|
||||||
if(ctof(c)) {
|
|
||||||
int id = c->master->fiftyval;
|
|
||||||
if(S7 == 5) {
|
|
||||||
int hemitable[3][12] = {
|
|
||||||
{ 6, 3, 3, 3, 3, 3,-6,-3,-3,-3,-3,-3},
|
|
||||||
{ 6, 3, 6, 3, 0, 0,-6,-3,-6,-3, 0, 0},
|
|
||||||
{-3, 0, 3, 0,-6,-6, 3, 0,-3, 0, 6, 6}
|
|
||||||
};
|
|
||||||
return hemitable[which][id];
|
|
||||||
}
|
|
||||||
else if(S7 == 4) {
|
|
||||||
int hemitable[3][6] = {
|
|
||||||
{ 2, 2, 2,-1,-1,-1},
|
|
||||||
{ 2,-1, 2, 2,-1,-1},
|
|
||||||
{ 2,-1,-1, 2, 2,-1},
|
|
||||||
};
|
|
||||||
return hemitable[which][id];
|
|
||||||
}
|
|
||||||
else if(S7 == 3) {
|
|
||||||
int hemitable[3][4] = {
|
|
||||||
{ 2, 2,-1,-1},
|
|
||||||
{ 2,-1, 2,-1},
|
|
||||||
{ 2,-1,-1, 2},
|
|
||||||
};
|
|
||||||
return hemitable[which][id];
|
|
||||||
}
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int score = 0;
|
|
||||||
for(int i=0; i<6; i+=2)
|
|
||||||
score += getHemisphere(c->mov[i], which) * (c->mirror(i) ? -1 : 1);
|
|
||||||
return score/3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sphereinfo {
|
|
||||||
int id;
|
|
||||||
int dir;
|
|
||||||
bool reflect;
|
|
||||||
};
|
|
||||||
|
|
||||||
sphereinfo valsphere(cell *c) {
|
|
||||||
sphereinfo si;
|
|
||||||
if(ctof(c)) {
|
|
||||||
int d = c->master->fieldval;
|
|
||||||
si.id = (d < siblings[d]) ? 0 : 1;
|
|
||||||
for(int i=0; i<S7; i++) {
|
|
||||||
int di = c->master->move[i]->fieldval;
|
|
||||||
if(di == siblings[d]) si.dir = i;
|
|
||||||
}
|
|
||||||
si.reflect = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int ids = 0, tids = 0, td = 0;
|
|
||||||
for(int i=0; i<S3; i++) {
|
|
||||||
int d = c->mov[i*2]->master->fieldval;
|
|
||||||
ids |= (1<<d); tids += d;
|
|
||||||
}
|
|
||||||
for(int i=0; i<S3; i++) {
|
|
||||||
int d = c->mov[i*2]->master->fieldval;
|
|
||||||
if(ids & (1<<siblings[d])) td += d;
|
|
||||||
}
|
|
||||||
if(td) {
|
|
||||||
si.id = 4;
|
|
||||||
for(int i=0; i<S3; i++) {
|
|
||||||
int d = c->mov[i*2]->master->fieldval;
|
|
||||||
if(!(ids & (1<<siblings[d]))) si.dir = 2*i;
|
|
||||||
}
|
|
||||||
si.reflect = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
si.id = 8;
|
|
||||||
si.dir = 0; // whatever
|
|
||||||
sphereinfo si2 = valsphere(c->mov[0]);
|
|
||||||
int di = si2.dir - c->spin(0);
|
|
||||||
di %= S7;
|
|
||||||
if(di<0) di += S7;
|
|
||||||
si.reflect = di > S7/2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return si;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "heptagon.cpp"
|
#include "heptagon.cpp"
|
||||||
#include "language.cpp"
|
#include "language.cpp"
|
||||||
#include "cell.cpp"
|
#include "cell.cpp"
|
||||||
|
#include "pattern2.cpp"
|
||||||
#include "flags.cpp"
|
#include "flags.cpp"
|
||||||
#include "yendor.cpp"
|
#include "yendor.cpp"
|
||||||
#include "complex.cpp"
|
#include "complex.cpp"
|
||||||
|
18
game.cpp
18
game.cpp
@ -357,24 +357,6 @@ bool isWarped(cell *c) {
|
|||||||
return isWarped(c->land) || (!inmirrororwall(c->land) && (items[itOrb37] && c->cpdist <= 4));
|
return isWarped(c->land) || (!inmirrororwall(c->land) && (items[itOrb37] && c->cpdist <= 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns ishept in the normal tiling;
|
|
||||||
// in the 'pure heptagonal' tiling, returns true for a set of cells
|
|
||||||
// which roughly corresponds to the heptagons in the normal tiling
|
|
||||||
bool pseudohept(cell *c) {
|
|
||||||
if(nontruncated) {
|
|
||||||
if(sphere)
|
|
||||||
return
|
|
||||||
c->master == getDodecahedron(3) ||
|
|
||||||
c->master == getDodecahedron(5) ||
|
|
||||||
c->master == getDodecahedron(6);
|
|
||||||
if(S3 > 3)
|
|
||||||
return c->master->distance & 1;
|
|
||||||
int z = zebra40(c);
|
|
||||||
return z == 5 || z == 8 || z == 15;
|
|
||||||
}
|
|
||||||
else return ishept(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nonAdjacent(cell *c, cell *c2) {
|
bool nonAdjacent(cell *c, cell *c2) {
|
||||||
if(isWarped(c) && isWarped(c2) && !pseudohept(c) && !pseudohept(c2)) {
|
if(isWarped(c) && isWarped(c2) && !pseudohept(c) && !pseudohept(c2)) {
|
||||||
/* int i = neighborId(c, c2);
|
/* int i = neighborId(c, c2);
|
||||||
|
@ -79,8 +79,8 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
|
|||||||
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
|
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
|
||||||
h->zebraval = zebra_heptagon(parent->zebraval, d);
|
h->zebraval = zebra_heptagon(parent->zebraval, d);
|
||||||
h->fieldval = currfp.connections[fieldpattern::btspin(parent->fieldval, d)];
|
h->fieldval = currfp.connections[fieldpattern::btspin(parent->fieldval, d)];
|
||||||
if(a38)
|
if(a38)
|
||||||
h->fiftyval = (parent->fiftyval ^ d ^ 1) & 1;
|
h->fiftyval = fifty_38(parent->fiftyval, d);
|
||||||
else if(parent->s == hsOrigin)
|
else if(parent->s == hsOrigin)
|
||||||
h->fiftyval = firstfiftyval(d);
|
h->fiftyval = firstfiftyval(d);
|
||||||
else
|
else
|
||||||
|
19
hyper.h
19
hyper.h
@ -660,9 +660,12 @@ namespace mapeditor {
|
|||||||
extern int displaycodes;
|
extern int displaycodes;
|
||||||
int generateCanvas(cell *c);
|
int generateCanvas(cell *c);
|
||||||
void applyModelcell(cell *c);
|
void applyModelcell(cell *c);
|
||||||
int realpattern(cell *c);
|
|
||||||
|
int realpattern(cell *c, char w = whichPattern);
|
||||||
int patterndir(cell *c, char w = whichPattern);
|
int patterndir(cell *c, char w = whichPattern);
|
||||||
int subpattern(cell *c);
|
bool reflectPatternAt(cell *c, char p = whichPattern);
|
||||||
|
int subpattern(cell *c, char w = whichPattern);
|
||||||
|
|
||||||
extern cell *drawcell;
|
extern cell *drawcell;
|
||||||
void initdraw(cell *c);
|
void initdraw(cell *c);
|
||||||
void showMapEditor();
|
void showMapEditor();
|
||||||
@ -1823,6 +1826,7 @@ namespace windmap {
|
|||||||
static const int NOWINDBELOW = 8;
|
static const int NOWINDBELOW = 8;
|
||||||
static const int NOWINDFROM = 120;
|
static const int NOWINDFROM = 120;
|
||||||
|
|
||||||
|
int getId(cell *c);
|
||||||
int at(cell *c);
|
int at(cell *c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2100,6 +2104,7 @@ int polarb50(cell *c);
|
|||||||
|
|
||||||
bool isGravityLand(eLand l);
|
bool isGravityLand(eLand l);
|
||||||
bool isWarped(eLand l);
|
bool isWarped(eLand l);
|
||||||
|
bool isWarped(cell *c);
|
||||||
|
|
||||||
struct hrmap {
|
struct hrmap {
|
||||||
virtual heptagon *getOrigin() { return NULL; }
|
virtual heptagon *getOrigin() { return NULL; }
|
||||||
@ -2280,3 +2285,13 @@ void sdltogl(SDL_Surface *txt, struct glfont_t& f, int ch);
|
|||||||
void glcolor2(int color);
|
void glcolor2(int color);
|
||||||
|
|
||||||
void showStartMenu();
|
void showStartMenu();
|
||||||
|
|
||||||
|
bool polara50(int x);
|
||||||
|
int polara50(cell *c);
|
||||||
|
int fiftyval049(cell *c);
|
||||||
|
|
||||||
|
namespace fieldpattern {
|
||||||
|
pair<int, bool> fieldval(cell *c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int emeraldval(cell *c);
|
||||||
|
@ -1110,8 +1110,8 @@ int isLandValid(eLand l) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Graveyard pattern does not work on non-truncated weird geometries
|
// Graveyard pattern does not work on non-truncated weird geometries
|
||||||
if(l == laGraveyard && weirdhyperbolic && nontruncated)
|
if(l == laGraveyard)
|
||||||
return 0;
|
return geosupport_graveyard();
|
||||||
|
|
||||||
// Warped Coast does not work on non-truncated S3s (except standard heptagonal where we have to keep it)
|
// Warped Coast does not work on non-truncated S3s (except standard heptagonal where we have to keep it)
|
||||||
if(l == laWarpCoast && (S3==3) && nontruncated) {
|
if(l == laWarpCoast && (S3==3) && nontruncated) {
|
||||||
|
332
mapeditor.cpp
332
mapeditor.cpp
@ -315,190 +315,51 @@ namespace mapeditor {
|
|||||||
char whichShape = 0;
|
char whichShape = 0;
|
||||||
char whichCanvas = 0;
|
char whichCanvas = 0;
|
||||||
|
|
||||||
int nopattern(cell *c) {
|
bool symRotation, sym01, sym02, sym03;
|
||||||
if(isWarped(c) && !euclid) {
|
|
||||||
int u = ishept(c)?1:0;
|
int subpattern(int i, char w) {
|
||||||
int qhex = 0;
|
if(euclid) {
|
||||||
for(int v=0; v<c->type; v++) if(c->mov[v] && !isWarped(c->mov[v])) {
|
if(w == 'p')
|
||||||
u += 2;
|
return i;
|
||||||
if(!ishept(c->mov[v])) qhex++;
|
if(w == 'z' || w == 'f')
|
||||||
}
|
return (symRotation && (i<3)) ? 0 : i;
|
||||||
if(u == 8 && qhex == 2) return 12;
|
|
||||||
if(u == 2 && qhex == 1) return 8;
|
|
||||||
if(u == 6 && qhex == 2) return 10;
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
return ishept(c) ? 1 : ishex1(c) ? 2 : 0; // 0 to 1
|
|
||||||
}
|
|
||||||
|
|
||||||
bool reflectPatternAt(cell *c, char p = whichPattern) {
|
|
||||||
if(p == 'p' && sphere) return valsphere(c).reflect;
|
|
||||||
if(p == 'p' && polarb50(c)) return true;
|
|
||||||
if(p == 0) {
|
|
||||||
int np = nopattern(c);
|
|
||||||
if(np == 4) {
|
|
||||||
int d = patterndir(c);
|
|
||||||
return !isWarped(createMov(c, (d+1)%6));
|
|
||||||
}
|
|
||||||
if(np == 12) {
|
|
||||||
int d = patterndir(c);
|
|
||||||
return !isWarped(createMov(c, (d+1)%6));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int downdir(cell *c, cellfunction *cf = coastvalEdge) {
|
|
||||||
cell *c2 = chosenDown(c, 1, 1, cf);
|
|
||||||
if(!c2) return 0;
|
|
||||||
return neighborId(c, c2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int patterndir46(cell *c, int bits) {
|
|
||||||
if(ctof(c)) {
|
|
||||||
int b = c->master->emeraldval & bits;
|
|
||||||
return (b&1) ^ (b & 2 ? 1 : 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return ((c->mov[0]->master->emeraldval + c->spin(0)) & 1) ? 2 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int patterndir38(cell *c) {
|
if(a38 && w == 'p') {
|
||||||
if(ctof(c)) return c->master->fiftyval;
|
if(sym01 && i == 5) i = 4;
|
||||||
return 0;
|
if(symRotation && i < 4) i = 0;
|
||||||
}
|
return i;
|
||||||
|
|
||||||
int patterndir457(cell *c) {
|
|
||||||
if(!ctof(c)) {
|
|
||||||
int d = dir_truncated457(c);
|
|
||||||
if(d >= 0) return d;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for(int i=0; i<c->type; i++)
|
|
||||||
if((zebra40(createStep(c->master, i + S7/2)->c7)&2) == (zebra40(createStep(c->master, i + 1 + S7/2)->c7)&2))
|
|
||||||
return i;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int patterndir(cell *c, char w) {
|
if(w == 'z' || w == 'f' || w == 'p') {
|
||||||
if(w != 'H') {
|
if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
|
||||||
if(a46) return patterndir46(c, w == 'z' ? 3 : w == 'p' ? 2 : 1);
|
if(sym01 && (i&1)) i ^= 1;
|
||||||
if(a4) return patterndir457(c);
|
if(sym02 && (i&2)) i ^= 2;
|
||||||
if(a38) return patterndir38(c);
|
if(sym03 && (i&2)) i ^= 3;
|
||||||
if(sphere) return valsphere(c).dir;
|
}
|
||||||
}
|
|
||||||
switch(w) {
|
if(w == 'z' && symRotation) {
|
||||||
case 'z': {
|
if(a4 && !a46) {
|
||||||
int t = zebra40(c);
|
if(i >= 4 && i < 7) i -= 4;
|
||||||
|
|
||||||
if(euclid) return (t*4) % 6;
|
|
||||||
|
|
||||||
int t4 = t>>2, tcdir = 0;
|
|
||||||
|
|
||||||
if(nontruncated) tcdir = t^1;
|
|
||||||
|
|
||||||
else if(t4 == 10) tcdir = t-20;
|
|
||||||
else if(t4 >= 4 && t4 < 7) tcdir = 40 + (t&3);
|
|
||||||
else if(t4 >= 1 && t4 < 4) tcdir = t+12;
|
|
||||||
else if(t4 >= 7 && t4 < 10) tcdir = t-24;
|
|
||||||
|
|
||||||
for(int i=0; i<c->type; i++) if(c->mov[i] && zebra40(c->mov[i]) == tcdir)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
// printf("fail to fintd %d -> %d\n", t, tcdir);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'f': {
|
|
||||||
int t = emeraldval(c);
|
|
||||||
if(euclid) return 0;
|
|
||||||
int tcdir = 0, tbest = (t&3);
|
|
||||||
for(int i=0; i<c->type; i++) {
|
|
||||||
cell *c2 = c->mov[i];
|
|
||||||
if(c2) {
|
|
||||||
int t2 = emeraldval(c2);
|
|
||||||
if((t&3) == (t2&3) && t2 > tbest)
|
|
||||||
tbest = t2, tcdir = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tcdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'p': {
|
|
||||||
int tcdir = -1, tbest = -1;
|
|
||||||
int pa = polara50(c);
|
|
||||||
int pb = polarb50(c);
|
|
||||||
for(int i=0; i<c->type; i++) {
|
|
||||||
cell *c2 = c->mov[i];
|
|
||||||
if(c2 && polara50(c2) == pa && polarb50(c2) == pb) {
|
|
||||||
int t2 = fiftyval049(c2);
|
|
||||||
if(t2 > tbest) tbest = t2, tcdir = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tcdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'H':
|
|
||||||
return downdir(c);
|
|
||||||
|
|
||||||
case 0: {
|
|
||||||
if(euclid) return 0;
|
|
||||||
int u = nopattern(c);
|
|
||||||
|
|
||||||
if(u == 6) {
|
|
||||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 2 || u == 3 || u == 8) {
|
|
||||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,i)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 4 || u == 10) {
|
|
||||||
for(int i=0; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 6) {
|
|
||||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 5) {
|
|
||||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+3)%7)) && !isWarped(createMov(c,(i+4)%7)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 9) {
|
|
||||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+2)%7)) && !isWarped(createMov(c,(i+5)%7)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 11) {
|
|
||||||
for(int i=0; i<c->type; i++) if(isWarped(createMov(c,(i)%7)) && isWarped(createMov(c,(i+1)%7)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 12) {
|
|
||||||
for(int i=0; i<c->type; i+=2) if(isWarped(createMov(c,i)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u == 7) {
|
|
||||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+1)%7)) && !isWarped(createMov(c,(i+6)%7)))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(u < 2) return 0;
|
|
||||||
|
|
||||||
#if LOCAL
|
|
||||||
printf("unhandled: u=%d\n", u);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
else {
|
||||||
|
if(i >= 8 && i < 12) i -= 4;
|
||||||
|
if(i >= 12 && i < 16) i -= 8;
|
||||||
|
if(i >= 20 && i < 24) i -= 4;
|
||||||
|
if(i >= 24 && i < 28) i -= 8;
|
||||||
|
if(i >= 32 && i < 36) i -= 4;
|
||||||
|
if(i >= 36 && i < 40) i -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(w == 'p' && stdhyperbolic && symRotation && i >= 3)
|
||||||
|
i -= ((i/4-1) % 7) * 4;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int subpattern(cell *c, char w) {
|
||||||
|
return subpattern(realpattern(c, w), w);
|
||||||
}
|
}
|
||||||
|
|
||||||
string infix;
|
string infix;
|
||||||
@ -536,7 +397,6 @@ namespace mapeditor {
|
|||||||
|
|
||||||
cellwalker copysource;
|
cellwalker copysource;
|
||||||
|
|
||||||
bool symRotation, sym01, sym02, sym03;
|
|
||||||
int whichpart;
|
int whichpart;
|
||||||
|
|
||||||
const char *mapeditorhelp =
|
const char *mapeditorhelp =
|
||||||
@ -746,6 +606,8 @@ namespace mapeditor {
|
|||||||
dialog::addItem(XLAT("dark rainbow landscape"), 'd');
|
dialog::addItem(XLAT("dark rainbow landscape"), 'd');
|
||||||
dialog::addItem(XLAT("football"), 'F');
|
dialog::addItem(XLAT("football"), 'F');
|
||||||
|
|
||||||
|
dialog::addItem(XLAT("nice coloring"), 'T');
|
||||||
|
|
||||||
dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e');
|
dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e');
|
||||||
|
|
||||||
dialog::addSelItem(XLAT("four elements"), "palace", 'b');
|
dialog::addSelItem(XLAT("four elements"), "palace", 'b');
|
||||||
@ -970,99 +832,6 @@ namespace mapeditor {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int subpatternEmerald(int i) {
|
|
||||||
if(euclid) return (symRotation && (i<3)) ? 0 : i;
|
|
||||||
if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
|
|
||||||
if(sym01 && (i&1)) i ^= 1;
|
|
||||||
if(sym02 && (i&2)) i ^= 2;
|
|
||||||
if(sym03 && (i&2)) i ^= 3;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int subpatternZebra(int i) {
|
|
||||||
if(euclid) return (symRotation && (i<3)) ? 0 : i;
|
|
||||||
i = subpatternEmerald(i);
|
|
||||||
if(symRotation) {
|
|
||||||
if(a4 && !a46) {
|
|
||||||
if(i >= 4 && i < 7) i -= 4;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(i >= 8 && i < 12) i -= 4;
|
|
||||||
if(i >= 12 && i < 16) i -= 8;
|
|
||||||
if(i >= 20 && i < 24) i -= 4;
|
|
||||||
if(i >= 24 && i < 28) i -= 8;
|
|
||||||
if(i >= 32 && i < 36) i -= 4;
|
|
||||||
if(i >= 36 && i < 40) i -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int subpatternPalace(int i) {
|
|
||||||
if(euclid) return i;
|
|
||||||
i = subpatternEmerald(i);
|
|
||||||
if(symRotation && i >= 3) i -= ((i/4-1) % 7) * 4;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int subpattern(cell *c) {
|
|
||||||
switch(whichPattern) {
|
|
||||||
case 'z':
|
|
||||||
return subpatternZebra(zebra40(c)); // 4 to 43
|
|
||||||
case 'f':
|
|
||||||
return subpatternEmerald(emeraldval(c)); // 44 to 99
|
|
||||||
case 'p': {
|
|
||||||
if(a46) return subpatternEmerald(val46(c));
|
|
||||||
if(a38) return val38(c);
|
|
||||||
if(sphere) return subpatternEmerald(valsphere(c).id);
|
|
||||||
int i = fiftyval049(c);
|
|
||||||
i *= 4;
|
|
||||||
if(polara50(c)) i|=1;
|
|
||||||
if(polarb50(c)) i|=2;
|
|
||||||
return subpatternPalace(i);
|
|
||||||
}
|
|
||||||
case 'P':
|
|
||||||
return fiftyval(c);
|
|
||||||
case 'H':
|
|
||||||
case 'F':
|
|
||||||
return realpattern(c);
|
|
||||||
}
|
|
||||||
return nopattern(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int realpattern(cell *c) {
|
|
||||||
switch(whichPattern) {
|
|
||||||
case 'z':
|
|
||||||
return zebra40(c); // 4 to 43
|
|
||||||
case 'f':
|
|
||||||
return emeraldval(c); // 44 to 99
|
|
||||||
case 'p': {
|
|
||||||
if(a46) return val46(c);
|
|
||||||
if(a38) return val38(c);
|
|
||||||
if(sphere) return valsphere(c).id;
|
|
||||||
int i = fiftyval049(c);
|
|
||||||
i *= 4;
|
|
||||||
if(polara50(c)) i|=1;
|
|
||||||
if(polarb50(c)) i|=2;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
case 'H':
|
|
||||||
return towerval(c);
|
|
||||||
case 'F': {
|
|
||||||
if(euclid)
|
|
||||||
// use the torus ID
|
|
||||||
return fieldpattern::fieldval_uniq(c);
|
|
||||||
else if(nontruncated)
|
|
||||||
// use the actual field codes
|
|
||||||
return fieldpattern::fieldval(c).first;
|
|
||||||
else
|
|
||||||
// use the small numbers from windmap
|
|
||||||
return windmap::getId(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nopattern(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cellShapeGroup() {
|
int cellShapeGroup() {
|
||||||
if(whichPattern == 'f') return 4;
|
if(whichPattern == 'f') return 4;
|
||||||
if(whichPattern == 'p') return 5;
|
if(whichPattern == 'p') return 5;
|
||||||
@ -1085,17 +854,10 @@ namespace mapeditor {
|
|||||||
return subpattern(drawcell);
|
return subpattern(drawcell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int subpatternShape(int i) {
|
|
||||||
if(whichPattern == 'z') return subpatternZebra(i);
|
|
||||||
if(whichPattern == 'f') return subpatternEmerald(i);
|
|
||||||
if(whichPattern == 'p') return subpatternPalace(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool editingShape(int group, int id) {
|
bool editingShape(int group, int id) {
|
||||||
if(group != mapeditor::drawcellShapeGroup()) return false;
|
if(group != mapeditor::drawcellShapeGroup()) return false;
|
||||||
if(group < 3) return id == drawcellShapeID();
|
if(group < 3) return id == drawcellShapeID();
|
||||||
return subpatternShape(id) == subpattern(drawcell);
|
return subpattern(id, whichPattern) == subpattern(drawcell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void editCell(const pair<cellwalker, cellwalker>& where) {
|
void editCell(const pair<cellwalker, cellwalker>& where) {
|
||||||
@ -2055,7 +1817,13 @@ namespace mapeditor {
|
|||||||
return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
|
return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
|
||||||
}
|
}
|
||||||
if(whichCanvas == 'F') {
|
if(whichCanvas == 'F') {
|
||||||
return ishept(c) ? 0x202020 : 0xC0C0C0;
|
return pseudohept(c) ? 0x202020 : 0xC0C0C0;
|
||||||
|
}
|
||||||
|
if(whichCanvas == 'T') {
|
||||||
|
static unsigned int fcol[8] = { 0x800000, 0x008000, 0x000080, 0x404040,
|
||||||
|
0x800080, 0x008080, 0x808000, 0xD0D0D0 };
|
||||||
|
int fv = pattern_threecolor(c);
|
||||||
|
return fcol[fv&7];
|
||||||
}
|
}
|
||||||
return canvasback;
|
return canvasback;
|
||||||
}
|
}
|
||||||
|
700
pattern2.cpp
Normal file
700
pattern2.cpp
Normal file
@ -0,0 +1,700 @@
|
|||||||
|
// HyperRogue patterns: compute codes for actual cells
|
||||||
|
|
||||||
|
// Copyright (C) 2011-2017 Zeno Rogue, see 'hyper.cpp' for details
|
||||||
|
|
||||||
|
int eupattern(cell *c) {
|
||||||
|
if(torus) return (decodeId(c->master)*2) % 3;
|
||||||
|
eucoord x, y;
|
||||||
|
decodeMaster(c->master, x, y);
|
||||||
|
short z = (short(y+2*x))%3;
|
||||||
|
z %= 3;
|
||||||
|
if(z<0) z += 3;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ishept(cell *c) {
|
||||||
|
// EUCLIDEAN
|
||||||
|
if(euclid) return eupattern(c) == 0;
|
||||||
|
else return c->type != S6;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ishex1(cell *c) {
|
||||||
|
// EUCLIDEAN
|
||||||
|
if(euclid) return eupattern(c) == 1;
|
||||||
|
else return c->type != S6;
|
||||||
|
}
|
||||||
|
|
||||||
|
int val46(cell *c) {
|
||||||
|
return ctof(c) ? c->master->emeraldval :
|
||||||
|
((c->master->emeraldval & 1) ^ ((c->master->emeraldval & 2)>>1) ^ (c->spin(0)&1)) ? 8 : 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emeraldval(cell *c) {
|
||||||
|
if(euclid) return eupattern(c);
|
||||||
|
if(a46) return val46(c);
|
||||||
|
if(sphere) return 0;
|
||||||
|
if(ctof(c))
|
||||||
|
return c->master->emeraldval >> 3;
|
||||||
|
else {
|
||||||
|
return emerald_hexagon(
|
||||||
|
emeraldval(createMov(c,0)),
|
||||||
|
emeraldval(createMov(c,2)),
|
||||||
|
emeraldval(createMov(c,4))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === FIFTYVALS ===
|
||||||
|
|
||||||
|
unsigned bitmajority(unsigned a, unsigned b, unsigned c) {
|
||||||
|
return (a&b) | ((a^b)&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int eufifty(cell *c) {
|
||||||
|
eucoord x, y;
|
||||||
|
if(torus) {
|
||||||
|
if(c->land == laWildWest) return decodeId(c->master) % 37;
|
||||||
|
else return decodeId(c->master) % 27;
|
||||||
|
}
|
||||||
|
decodeMaster(c->master, x, y);
|
||||||
|
int ix = short(x) + 99999 + short(y);
|
||||||
|
int iy = short(y) + 99999;
|
||||||
|
if(c->land == laWildWest)
|
||||||
|
return (ix + iy * 26 + 28) % 37;
|
||||||
|
else {
|
||||||
|
ix += (iy/3) * 3;
|
||||||
|
iy %= 3; ix %= 9;
|
||||||
|
return iy * 9 + ix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int val38(cell *c) {
|
||||||
|
if(ctof(c)) return (c->master->fiftyval >> 1) & 3;
|
||||||
|
else return 4 ^ (c->master->fiftyval & 1) ^ (c->spin(0) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fiftyval(cell *c) {
|
||||||
|
if(a38) return val38(c);
|
||||||
|
if(euclid) return eufifty(c) * 32;
|
||||||
|
if(sphere || S7>7 || S6>6) return 0;
|
||||||
|
if(ctof(c))
|
||||||
|
return c->master->fiftyval;
|
||||||
|
else {
|
||||||
|
return bitmajority(
|
||||||
|
fiftyval(createMov(c,0)),
|
||||||
|
fiftyval(createMov(c,2)),
|
||||||
|
fiftyval(createMov(c,4))) + 512;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdist50(cell *c) {
|
||||||
|
if(sphere || S7>7 || S6>6) return 0;
|
||||||
|
if(euclid) {
|
||||||
|
if(c->land == laWildWest)
|
||||||
|
return "0123333332112332223322233211233333322"[eufifty(c)] - '0';
|
||||||
|
else return "012333321112322232222321123"[eufifty(c)] - '0';
|
||||||
|
}
|
||||||
|
if(c->type != 6) return cdist50(fiftyval(c));
|
||||||
|
int a0 = cdist50(createMov(c,0));
|
||||||
|
int a1 = cdist50(createMov(c,2));
|
||||||
|
int a2 = cdist50(createMov(c,4));
|
||||||
|
if(a0 == 0 || a1 == 0 || a2 == 0) return 1;
|
||||||
|
return a0+a1+a2-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int land50(cell *c) {
|
||||||
|
if(c->type != 6) return land50(fiftyval(c));
|
||||||
|
else if(sphere || euclid) return 0;
|
||||||
|
else {
|
||||||
|
if(cdist50(createMov(c,0)) < 3) return land50(createMov(c,0));
|
||||||
|
if(cdist50(createMov(c,2)) < 3) return land50(createMov(c,2));
|
||||||
|
if(cdist50(createMov(c,4)) < 3) return land50(createMov(c,4));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int polara50(cell *c) {
|
||||||
|
if(c->type != 6) return polara50(fiftyval(c));
|
||||||
|
else if(sphere || euclid || S7>7 || S6>6) return 0;
|
||||||
|
else {
|
||||||
|
if(cdist50(createMov(c,0)) < 3) return polara50(createMov(c,0));
|
||||||
|
if(cdist50(createMov(c,2)) < 3) return polara50(createMov(c,2));
|
||||||
|
if(cdist50(createMov(c,4)) < 3) return polara50(createMov(c,4));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int polarb50(cell *c) {
|
||||||
|
if(euclid) return true;
|
||||||
|
if(c->type != 6) return polarb50(fiftyval(c));
|
||||||
|
else if(sphere || euclid || S7>7 || S6>6) return true;
|
||||||
|
else {
|
||||||
|
if(cdist50(createMov(c,0)) < 3) return polarb50(createMov(c,0));
|
||||||
|
if(cdist50(createMov(c,2)) < 3) return polarb50(createMov(c,2));
|
||||||
|
if(cdist50(createMov(c,4)) < 3) return polarb50(createMov(c,4));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int elhextable[28][3] = {
|
||||||
|
{0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1}
|
||||||
|
};
|
||||||
|
|
||||||
|
int fiftyval049(cell *c) {
|
||||||
|
if(c->type != 6 || euclid) return fiftyval(c) / 32;
|
||||||
|
else if(sphere) return 0;
|
||||||
|
else {
|
||||||
|
int a[3], qa=0;
|
||||||
|
int pa = polara50(c), pb = polarb50(c);
|
||||||
|
for(int i=0; i<6; i+=2) {
|
||||||
|
cell *c2 = c->mov[i];
|
||||||
|
if(polara50(c2) == pa && polarb50(c2) == pb)
|
||||||
|
a[qa++] = fiftyval049(c2);
|
||||||
|
}
|
||||||
|
// 0-1-2
|
||||||
|
sort(a, a+qa);
|
||||||
|
if(qa == 1) return 43+a[0]-1;
|
||||||
|
if(qa == 2 && a[1] == a[0]+7) return 36+a[0]-1;
|
||||||
|
if(qa == 2 && a[1] != a[0]+7) return 29+a[0]-1;
|
||||||
|
if(a[1] == 1 && a[2] == 7)
|
||||||
|
return 15 + 6;
|
||||||
|
if(a[2] >= 1 && a[2] <= 7)
|
||||||
|
return 15 + a[1]-1;
|
||||||
|
if(a[0] == 1 && a[1] == 7 && a[2] == 8)
|
||||||
|
return 22;
|
||||||
|
if(a[1] <= 7 && a[2] >= 8)
|
||||||
|
return 22 + a[1]-1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{0,1,2} 15+0..15+6
|
||||||
|
{1,2,9},22+0..22+6
|
||||||
|
{1,9} 29+0..29+6
|
||||||
|
{1,8} 36+0..36+6
|
||||||
|
{1} 43+0..43+6
|
||||||
|
*/
|
||||||
|
|
||||||
|
// zebraval
|
||||||
|
|
||||||
|
int dir_truncated457(cell *c) {
|
||||||
|
int wset = 0;
|
||||||
|
for(int i=0; i<4; i++)
|
||||||
|
if(zebra40(createMov(c, i*2))&2) wset |= (1<<i);
|
||||||
|
if(wset == 0) return -8;
|
||||||
|
if(wset == 15) return -10;
|
||||||
|
if(wset == 3) return 1;
|
||||||
|
if(wset == 6) return 3;
|
||||||
|
if(wset == 12) return 5;
|
||||||
|
if(wset == 9) return 7;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zebra40(cell *c) {
|
||||||
|
if(euclid) return eupattern(c);
|
||||||
|
else if(a46) return val46(c);
|
||||||
|
else if(ctof(c)) return (c->master->zebraval/10);
|
||||||
|
else if(a4) {
|
||||||
|
int ws = dir_truncated457(c);
|
||||||
|
if(ws < 0) return -ws;
|
||||||
|
return 16 + (ws/2);
|
||||||
|
}
|
||||||
|
else if(sphere) return 0;
|
||||||
|
else if(euclid) return eupattern(c);
|
||||||
|
else if(S3 == 4 && S7 == 6) {
|
||||||
|
return 8 + ((c->master->zebraval / 10 + c->spin(0))%2) * 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int ii[3], z;
|
||||||
|
ii[0] = (c->mov[0]->master->zebraval/10);
|
||||||
|
ii[1] = (c->mov[2]->master->zebraval/10);
|
||||||
|
ii[2] = (c->mov[4]->master->zebraval/10);
|
||||||
|
for(int r=0; r<2; r++)
|
||||||
|
if(ii[1] < ii[0] || ii[2] < ii[0])
|
||||||
|
z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z;
|
||||||
|
for(int i=0; i<28; i++)
|
||||||
|
if(zebratable6[i][0] == ii[0] && zebratable6[i][1] == ii[1] &&
|
||||||
|
zebratable6[i][2] == ii[2]) {
|
||||||
|
int ans = 16+i;
|
||||||
|
// if(ans >= 40) ans ^= 2;
|
||||||
|
// if(ans >= 4 && ans < 16) ans ^= 2;
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int zebra3(cell *c) {
|
||||||
|
if(c->type != 6) return (c->master->zebraval/10)/4;
|
||||||
|
else if(sphere || S7>7 || S6>6) return 0;
|
||||||
|
else {
|
||||||
|
int ii[3];
|
||||||
|
ii[0] = (c->mov[0]->master->zebraval/10)/4;
|
||||||
|
ii[1] = (c->mov[2]->master->zebraval/10)/4;
|
||||||
|
ii[2] = (c->mov[4]->master->zebraval/10)/4;
|
||||||
|
if(ii[0] == ii[1]) return ii[0];
|
||||||
|
if(ii[1] == ii[2]) return ii[1];
|
||||||
|
if(ii[2] == ii[0]) return ii[2];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace fieldpattern {
|
||||||
|
|
||||||
|
pair<int, bool> fieldval(cell *c) {
|
||||||
|
if(ctof(c)) return make_pair(c->master->fieldval, false);
|
||||||
|
else return make_pair(btspin(c->master->fieldval, c->spin(0)), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fieldval_uniq(cell *c) {
|
||||||
|
if(sphere) {
|
||||||
|
if(ctof(c)) return c->master->fieldval;
|
||||||
|
else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval;
|
||||||
|
}
|
||||||
|
else if(torus) {
|
||||||
|
return decodeId(c->master);
|
||||||
|
}
|
||||||
|
else if(euclid) {
|
||||||
|
eucoord x, y;
|
||||||
|
decodeMaster(c->master, x, y);
|
||||||
|
int i = (short int)(x) * torusconfig::dx + (short int)(y) * torusconfig::dy;
|
||||||
|
i %= torusconfig::qty;
|
||||||
|
if(i<0) i += torusconfig::qty;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
if(ctof(c)) return c->master->fieldval/S7;
|
||||||
|
else {
|
||||||
|
int z = 0;
|
||||||
|
for(int u=0; u<S6; u+=2)
|
||||||
|
z = max(z, btspin(createMov(c, u)->master->fieldval, c->spin(u)));
|
||||||
|
return -1-z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fieldval_uniq_rand(cell *c, int randval) {
|
||||||
|
if(sphere || torus || euclid)
|
||||||
|
// we do not care in these cases
|
||||||
|
return fieldval_uniq(c);
|
||||||
|
if(ctof(c)) return currfp.gmul(c->master->fieldval, randval)/7;
|
||||||
|
else {
|
||||||
|
int z = 0;
|
||||||
|
for(int u=0; u<6; u+=2)
|
||||||
|
z = max(z, btspin(currfp.gmul(createMov(c, u)->master->fieldval, randval), c->spin(u)));
|
||||||
|
return -1-z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int subpathid = currfp.matcode[currfp.strtomatrix("RRRPRRRRRPRRRP")];
|
||||||
|
int subpathorder = currfp.order(currfp.matrices[subpathid]);
|
||||||
|
|
||||||
|
pair<int, int> subval(cell *c, int _subpathid = subpathid, int _subpathorder = subpathorder) {
|
||||||
|
if(!ctof(c)) {
|
||||||
|
auto m = subval(createMov(c, 0));
|
||||||
|
for(int u=2; u<S6; u+=2)
|
||||||
|
m = min(m, subval(createMov(c, u)));
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pair<int, int> pbest, pcur;
|
||||||
|
pcur.first = c->master->fieldval;
|
||||||
|
pcur.second = 0;
|
||||||
|
pbest = pcur;
|
||||||
|
for(int i=0; i<_subpathorder; i++) {
|
||||||
|
pcur.first = currfp.gmul(pcur.first, _subpathid);
|
||||||
|
pcur.second++;
|
||||||
|
if(pcur < pbest) pbest = pcur;
|
||||||
|
}
|
||||||
|
return pbest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int getHemisphere(cell *c, int which) {
|
||||||
|
if(torus) return 0;
|
||||||
|
if(ctof(c)) {
|
||||||
|
int id = c->master->fiftyval;
|
||||||
|
if(S7 == 5) {
|
||||||
|
int hemitable[3][12] = {
|
||||||
|
{ 6, 3, 3, 3, 3, 3,-6,-3,-3,-3,-3,-3},
|
||||||
|
{ 6, 3, 6, 3, 0, 0,-6,-3,-6,-3, 0, 0},
|
||||||
|
{-3, 0, 3, 0,-6,-6, 3, 0,-3, 0, 6, 6}
|
||||||
|
};
|
||||||
|
return hemitable[which][id];
|
||||||
|
}
|
||||||
|
else if(S7 == 4) {
|
||||||
|
int hemitable[3][6] = {
|
||||||
|
{ 2, 2, 2,-1,-1,-1},
|
||||||
|
{ 2,-1, 2, 2,-1,-1},
|
||||||
|
{ 2,-1,-1, 2, 2,-1},
|
||||||
|
};
|
||||||
|
return hemitable[which][id];
|
||||||
|
}
|
||||||
|
else if(S7 == 3) {
|
||||||
|
int hemitable[3][4] = {
|
||||||
|
{ 2, 2,-1,-1},
|
||||||
|
{ 2,-1, 2,-1},
|
||||||
|
{ 2,-1,-1, 2},
|
||||||
|
};
|
||||||
|
return hemitable[which][id];
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int score = 0;
|
||||||
|
for(int i=0; i<6; i+=2)
|
||||||
|
score += getHemisphere(c->mov[i], which) * (c->mirror(i) ? -1 : 1);
|
||||||
|
return score/3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sphereinfo {
|
||||||
|
int id;
|
||||||
|
int dir;
|
||||||
|
bool reflect;
|
||||||
|
};
|
||||||
|
|
||||||
|
sphereinfo valsphere(cell *c) {
|
||||||
|
sphereinfo si;
|
||||||
|
if(ctof(c)) {
|
||||||
|
int d = c->master->fieldval;
|
||||||
|
si.id = (d < siblings[d]) ? 0 : 1;
|
||||||
|
for(int i=0; i<S7; i++) {
|
||||||
|
int di = c->master->move[i]->fieldval;
|
||||||
|
if(di == siblings[d]) si.dir = i;
|
||||||
|
}
|
||||||
|
si.reflect = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int ids = 0, tids = 0, td = 0;
|
||||||
|
for(int i=0; i<S3; i++) {
|
||||||
|
int d = c->mov[i*2]->master->fieldval;
|
||||||
|
ids |= (1<<d); tids += d;
|
||||||
|
}
|
||||||
|
for(int i=0; i<S3; i++) {
|
||||||
|
int d = c->mov[i*2]->master->fieldval;
|
||||||
|
if(ids & (1<<siblings[d])) td += d;
|
||||||
|
}
|
||||||
|
if(td) {
|
||||||
|
si.id = 4;
|
||||||
|
for(int i=0; i<S3; i++) {
|
||||||
|
int d = c->mov[i*2]->master->fieldval;
|
||||||
|
if(!(ids & (1<<siblings[d]))) si.dir = 2*i;
|
||||||
|
}
|
||||||
|
si.reflect = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
si.id = 8;
|
||||||
|
si.dir = 0; // whatever
|
||||||
|
sphereinfo si2 = valsphere(c->mov[0]);
|
||||||
|
int di = si2.dir - c->spin(0);
|
||||||
|
di %= S7;
|
||||||
|
if(di<0) di += S7;
|
||||||
|
si.reflect = di > S7/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mapeditor {
|
||||||
|
|
||||||
|
int nopattern(cell *c) {
|
||||||
|
if(isWarped(c) && !euclid) {
|
||||||
|
int u = ishept(c)?1:0;
|
||||||
|
int qhex = 0;
|
||||||
|
for(int v=0; v<c->type; v++) if(c->mov[v] && !isWarped(c->mov[v])) {
|
||||||
|
u += 2;
|
||||||
|
if(!ishept(c->mov[v])) qhex++;
|
||||||
|
}
|
||||||
|
if(u == 8 && qhex == 2) return 12;
|
||||||
|
if(u == 2 && qhex == 1) return 8;
|
||||||
|
if(u == 6 && qhex == 2) return 10;
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
return ishept(c) ? 1 : ishex1(c) ? 2 : 0; // 0 to 1
|
||||||
|
}
|
||||||
|
|
||||||
|
int downdir(cell *c, cellfunction *cf = coastvalEdge) {
|
||||||
|
cell *c2 = chosenDown(c, 1, 1, cf);
|
||||||
|
if(!c2) return 0;
|
||||||
|
return neighborId(c, c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int realpattern(cell *c, char code) {
|
||||||
|
switch(code) {
|
||||||
|
case 'z':
|
||||||
|
return zebra40(c); // 4 to 43
|
||||||
|
case 'f':
|
||||||
|
return emeraldval(c); // 44 to 99
|
||||||
|
case 'p': {
|
||||||
|
if(a46) return val46(c);
|
||||||
|
if(a38) return val38(c);
|
||||||
|
if(sphere) return valsphere(c).id;
|
||||||
|
int i = fiftyval049(c);
|
||||||
|
i *= 4;
|
||||||
|
if(polara50(c)) i|=1;
|
||||||
|
if(polarb50(c)) i|=2;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
case 'H':
|
||||||
|
return towerval(c);
|
||||||
|
case 'F': {
|
||||||
|
if(euclid)
|
||||||
|
// use the torus ID
|
||||||
|
return fieldpattern::fieldval_uniq(c);
|
||||||
|
else if(nontruncated)
|
||||||
|
// use the actual field codes
|
||||||
|
return fieldpattern::fieldval(c).first;
|
||||||
|
else
|
||||||
|
// use the small numbers from windmap
|
||||||
|
return windmap::getId(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nopattern(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int patterndir46(cell *c, int bits) {
|
||||||
|
if(ctof(c)) {
|
||||||
|
int b = c->master->emeraldval & bits;
|
||||||
|
return (b&1) ^ (b & 2 ? 1 : 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ((c->mov[0]->master->emeraldval + c->spin(0)) & 1) ? 2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int patterndir38(cell *c) {
|
||||||
|
if(ctof(c)) return c->master->fiftyval | (c->master->fiftyval & 8 ? 0 : 2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int patterndir457(cell *c) {
|
||||||
|
if(!ctof(c)) {
|
||||||
|
int d = dir_truncated457(c);
|
||||||
|
if(d >= 0) return d;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(int i=0; i<c->type; i++)
|
||||||
|
if((zebra40(createStep(c->master, i + S7/2)->c7)&2) == (zebra40(createStep(c->master, i + 1 + S7/2)->c7)&2))
|
||||||
|
return i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reflectPatternAt(cell *c, char p) {
|
||||||
|
if(p == 'p' && sphere) return valsphere(c).reflect;
|
||||||
|
if(p == 'p' && polarb50(c)) return true;
|
||||||
|
if(p == 0) {
|
||||||
|
int np = nopattern(c);
|
||||||
|
if(np == 4) {
|
||||||
|
int d = patterndir(c);
|
||||||
|
return !isWarped(createMov(c, (d+1)%6));
|
||||||
|
}
|
||||||
|
if(np == 12) {
|
||||||
|
int d = patterndir(c);
|
||||||
|
return !isWarped(createMov(c, (d+1)%6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int patterndir(cell *c, char w) {
|
||||||
|
if(w != 'H') {
|
||||||
|
if(a46) return patterndir46(c, w == 'z' ? 3 : w == 'p' ? 2 : 1);
|
||||||
|
if(a4) return patterndir457(c);
|
||||||
|
if(a38) return patterndir38(c);
|
||||||
|
if(sphere) return valsphere(c).dir;
|
||||||
|
}
|
||||||
|
switch(w) {
|
||||||
|
case 'z': {
|
||||||
|
int t = zebra40(c);
|
||||||
|
|
||||||
|
if(euclid) return (t*4) % 6;
|
||||||
|
|
||||||
|
int t4 = t>>2, tcdir = 0;
|
||||||
|
|
||||||
|
if(nontruncated) tcdir = t^1;
|
||||||
|
|
||||||
|
else if(t4 == 10) tcdir = t-20;
|
||||||
|
else if(t4 >= 4 && t4 < 7) tcdir = 40 + (t&3);
|
||||||
|
else if(t4 >= 1 && t4 < 4) tcdir = t+12;
|
||||||
|
else if(t4 >= 7 && t4 < 10) tcdir = t-24;
|
||||||
|
|
||||||
|
for(int i=0; i<c->type; i++) if(c->mov[i] && zebra40(c->mov[i]) == tcdir)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
// printf("fail to fintd %d -> %d\n", t, tcdir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'f': {
|
||||||
|
int t = emeraldval(c);
|
||||||
|
if(euclid) return 0;
|
||||||
|
int tcdir = 0, tbest = (t&3);
|
||||||
|
for(int i=0; i<c->type; i++) {
|
||||||
|
cell *c2 = c->mov[i];
|
||||||
|
if(c2) {
|
||||||
|
int t2 = emeraldval(c2);
|
||||||
|
if((t&3) == (t2&3) && t2 > tbest)
|
||||||
|
tbest = t2, tcdir = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tcdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'p': {
|
||||||
|
int tcdir = -1, tbest = -1;
|
||||||
|
int pa = polara50(c);
|
||||||
|
int pb = polarb50(c);
|
||||||
|
for(int i=0; i<c->type; i++) {
|
||||||
|
cell *c2 = c->mov[i];
|
||||||
|
if(c2 && polara50(c2) == pa && polarb50(c2) == pb) {
|
||||||
|
int t2 = fiftyval049(c2);
|
||||||
|
if(t2 > tbest) tbest = t2, tcdir = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tcdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'H':
|
||||||
|
return downdir(c);
|
||||||
|
|
||||||
|
case 0: {
|
||||||
|
if(euclid) return 0;
|
||||||
|
int u = nopattern(c);
|
||||||
|
|
||||||
|
if(u == 6) {
|
||||||
|
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 2 || u == 3 || u == 8) {
|
||||||
|
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,i)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 4 || u == 10) {
|
||||||
|
for(int i=0; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 6) {
|
||||||
|
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 5) {
|
||||||
|
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+3)%7)) && !isWarped(createMov(c,(i+4)%7)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 9) {
|
||||||
|
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+2)%7)) && !isWarped(createMov(c,(i+5)%7)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 11) {
|
||||||
|
for(int i=0; i<c->type; i++) if(isWarped(createMov(c,(i)%7)) && isWarped(createMov(c,(i+1)%7)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 12) {
|
||||||
|
for(int i=0; i<c->type; i+=2) if(isWarped(createMov(c,i)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u == 7) {
|
||||||
|
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+1)%7)) && !isWarped(createMov(c,(i+6)%7)))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(u < 2) return 0;
|
||||||
|
|
||||||
|
#if LOCAL
|
||||||
|
printf("unhandled: u=%d\n", u);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int geosupport_threecolor() {
|
||||||
|
if(!nontruncated) {
|
||||||
|
if(S7 % 2) return 1;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if((S7 % 2 == 0) && (S3 == 3))
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int geosupport_graveyard() {
|
||||||
|
// always works in truncated geometries
|
||||||
|
if(!nontruncated) return 2;
|
||||||
|
|
||||||
|
// always works in patterns supporting three-color
|
||||||
|
return geosupport_threecolor();
|
||||||
|
}
|
||||||
|
|
||||||
|
int pattern_threecolor(cell *c) {
|
||||||
|
if(a38) {
|
||||||
|
int i = val38(c);
|
||||||
|
if(nontruncated) return i;
|
||||||
|
else return i < 4 ? 0 : (1+(i&1));
|
||||||
|
}
|
||||||
|
if(a46 && !nontruncated) {
|
||||||
|
int i = val46(c);
|
||||||
|
return i >> 2;
|
||||||
|
}
|
||||||
|
if(S7 == 4) {
|
||||||
|
int codesN[6] = {0,1,2,1,2,0};
|
||||||
|
if(nontruncated)
|
||||||
|
return codesN[c->master->fiftyval];
|
||||||
|
if(ctof(c))
|
||||||
|
return 0;
|
||||||
|
else for(int i=0; i<3; i++) {
|
||||||
|
cell *c2 = c->mov[i];
|
||||||
|
if(c2->master->fiftyval == 0)
|
||||||
|
return 1 + (c->spin(i)&1);
|
||||||
|
if(c2->master->fiftyval == 5)
|
||||||
|
return 2 - (c->spin(i)&1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(stdhyperbolic && nontruncated) {
|
||||||
|
int z = zebra40(c);
|
||||||
|
if(z == 5 || z == 8 || z == 15) return 0;
|
||||||
|
if(z == 10 || z == 12 || z == 7) return 2;
|
||||||
|
if(z == 6 || z == 9) return 3;
|
||||||
|
if(z == 14 || z == 11) return 4;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(S7 == 5 && nontruncated) {
|
||||||
|
const int codes[12] = {1, 2, 0, 3, 2, 0, 0, 1, 3, 1, 2, 3};
|
||||||
|
return codes[c->master->fiftyval];
|
||||||
|
}
|
||||||
|
if(S7 == 3 && nontruncated)
|
||||||
|
return c->master->fiftyval;
|
||||||
|
if(euclid) return eupattern(c);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns ishept in the normal tiling;
|
||||||
|
// in the 'pure heptagonal' tiling, returns true for a set of cells
|
||||||
|
// which roughly corresponds to the heptagons in the normal tiling
|
||||||
|
bool pseudohept(cell *c) {
|
||||||
|
if(nontruncated) {
|
||||||
|
if(bigsphere)
|
||||||
|
return
|
||||||
|
c->master == getDodecahedron(3) ||
|
||||||
|
c->master == getDodecahedron(5) ||
|
||||||
|
c->master == getDodecahedron(6);
|
||||||
|
if(S7 == 3)
|
||||||
|
return c->master == getDodecahedron(0);
|
||||||
|
else
|
||||||
|
return pattern_threecolor(c) == 0;
|
||||||
|
}
|
||||||
|
else return ishept(c);
|
||||||
|
}
|
||||||
|
|
19
patterns.cpp
19
patterns.cpp
@ -1,4 +1,4 @@
|
|||||||
// HyperRogue patterns
|
// HyperRogue patterns: tables to give codes to heptagons
|
||||||
|
|
||||||
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
|
// Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details
|
||||||
|
|
||||||
@ -1116,3 +1116,20 @@ int zebra_heptagon(int parent, int dir) {
|
|||||||
return zebratable[parent/10-4][(70+dir-(parent%10))%7];
|
return zebratable[parent/10-4][(70+dir-(parent%10))%7];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fifty_38(int f, int d) {
|
||||||
|
// This creates the 'p' pattern for the a38 geometry.
|
||||||
|
// Hexagons have codes 4 and 5, while octagons have 0, 1, 2.
|
||||||
|
|
||||||
|
// f&1 is which direction is the hexagon with code '4'
|
||||||
|
|
||||||
|
// c=((f>>1)&3) is 0, 1, or 2
|
||||||
|
int c = ((f>>1)&3);
|
||||||
|
|
||||||
|
// f&8: in which direction is c increasing by one
|
||||||
|
int step = (f&8) ? 1 : 2; if(d&1) step ^= 3;
|
||||||
|
|
||||||
|
return
|
||||||
|
((f ^ d ^ 1) & 1)
|
||||||
|
+ (((c + step) % 3) << 1)
|
||||||
|
+ (step==2?8:0);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user