Updated HyperRogue sources to 7.4f.
This commit is contained in:
parent
721461a5c5
commit
19055633b0
149
achievement.cpp
149
achievement.cpp
|
@ -1,4 +1,4 @@
|
|||
#define NUMLEADER 26
|
||||
#define NUMLEADER 40
|
||||
|
||||
#define SCORE_UNKNOWN (-1)
|
||||
#define NO_SCORE_YET (-2)
|
||||
|
@ -8,11 +8,21 @@ int currentscore[NUMLEADER];
|
|||
const char* leadernames[NUMLEADER] = {
|
||||
"Score", "Diamonds", "Gold", "Spice", "Rubies", "Elixirs",
|
||||
"Shards", "Totems", "Daisies", "Statues", "Feathers", "Sapphires",
|
||||
"Hyperstones", "Time to Win", "Turns to Win",
|
||||
"Time to 10 Hyperstones-62", "Turns to 10 Hyperstones-62", "Orbs of Yendor",
|
||||
"Hyperstones", "Time to Win-71", "Turns to Win-71",
|
||||
"Time to 10 Hyperstones-73", "Turns to 10 Hyperstones-73", "Orbs of Yendor",
|
||||
"Fern Flowers",
|
||||
"Royal Jellies", "Powerstones", "Silver", "Wine", "Emeralds", "Grimoires",
|
||||
"Holy Grails"
|
||||
"Holy Grails", "Red Gems", "Pirate Treasures",
|
||||
"Shmup Score", "Shmup Time to Win", "Shmup Knife to Win",
|
||||
"Bomberbird Eggs", // 31
|
||||
"Ambers", // 32
|
||||
"Pearls", // 33
|
||||
"Hypersian Rugs", // 34
|
||||
"Garnets", // 35
|
||||
"Princess Challenge", // 36
|
||||
"Ivory Figurines", // 37
|
||||
"Elemental Gems", // 38
|
||||
"Onyxes" // 39
|
||||
};
|
||||
|
||||
bool haveLeaderboard(int id);
|
||||
|
@ -23,9 +33,11 @@ string achievementMessage[3];
|
|||
int achievementTimer;
|
||||
// vector<string> achievementsReceived;
|
||||
|
||||
void achievement_log(const char* s, bool euclideanAchievement) {
|
||||
void achievement_log(const char* s, bool euclideanAchievement, bool shmupAchievement) {
|
||||
if(cheater) return;
|
||||
if(euclid != euclideanAchievement) return;
|
||||
if(shmup::on != shmupAchievement) return;
|
||||
if(randomPatternsMode) return;
|
||||
|
||||
for(int i=0; i<size(achievementsReceived); i++)
|
||||
if(achievementsReceived[i] == s) return;
|
||||
|
@ -47,19 +59,21 @@ void achievement_log(const char* s, bool euclideanAchievement) {
|
|||
}
|
||||
|
||||
#ifdef STEAM
|
||||
void improveItemScores();
|
||||
#include "hypersteam.cpp"
|
||||
#else
|
||||
#ifndef ANDROID
|
||||
void achievement_init() {}
|
||||
void achievement_close() {}
|
||||
void achievement_gain(const char* s, bool euclideanAchievement) {
|
||||
achievement_log(s, euclideanAchievement);
|
||||
void achievement_gain(const char* s, bool euclideanAchievement, bool shmupAchievement) {
|
||||
achievement_log(s, euclideanAchievement, shmupAchievement);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void achievement_collection(eItem it, int prevgold, int newgold) {
|
||||
if(cheater) return;
|
||||
if(randomPatternsMode) return;
|
||||
int q = items[it];
|
||||
|
||||
if(q == 1) {
|
||||
|
@ -82,6 +96,17 @@ void achievement_collection(eItem it, int prevgold, int newgold) {
|
|||
if(it == itEmerald) achievement_gain("EMERALD1");
|
||||
if(it == itSilver) achievement_gain("SILVER1");
|
||||
if(it == itGrimoire) achievement_gain("GRIMOIRE1");
|
||||
if(it == itRedGem) achievement_gain("REDGEM1");
|
||||
if(it == itPirate) achievement_gain("PIRATE1");
|
||||
if(it == itCoast) achievement_gain("COAST1");
|
||||
// if(it == itWhirlpool) achievement_gain("WHIRL1");
|
||||
if(it == itBombEgg) achievement_gain("MINE1");
|
||||
if(it == itPalace) achievement_gain("RUG1");
|
||||
if(it == itFjord) achievement_gain("GARNET1");
|
||||
|
||||
if(it == itEdge) achievement_gain("TOWER1");
|
||||
if(it == itElemental) achievement_gain("ELEMENT1");
|
||||
if(it == itZebra) achievement_gain("ZEBRA1");
|
||||
}
|
||||
|
||||
// 32
|
||||
|
@ -111,6 +136,17 @@ void achievement_collection(eItem it, int prevgold, int newgold) {
|
|||
if(it == itEmerald) achievement_gain("EMERALD2");
|
||||
if(it == itSilver) achievement_gain("SILVER2");
|
||||
if(it == itGrimoire) achievement_gain("GRIMOIRE2");
|
||||
if(it == itRedGem) achievement_gain("REDGEM2");
|
||||
if(it == itPirate) achievement_gain("PIRATE2");
|
||||
if(it == itCoast) achievement_gain("COAST2");
|
||||
if(it == itWhirlpool) achievement_gain("WHIRL2");
|
||||
if(it == itBombEgg) achievement_gain("MINE2");
|
||||
if(it == itPalace) achievement_gain("RUG2");
|
||||
if(it == itFjord) achievement_gain("GARNET2");
|
||||
|
||||
if(it == itEdge) achievement_gain("TOWER2");
|
||||
if(it == itElemental) achievement_gain("ELEMENT2");
|
||||
if(it == itZebra) achievement_gain("ZEBRA2");
|
||||
}
|
||||
|
||||
if(q == 25) {
|
||||
|
@ -133,6 +169,17 @@ void achievement_collection(eItem it, int prevgold, int newgold) {
|
|||
if(it == itEmerald) achievement_gain("EMERALD3");
|
||||
if(it == itSilver) achievement_gain("SILVER3");
|
||||
if(it == itGrimoire) achievement_gain("GRIMOIRE3");
|
||||
if(it == itRedGem) achievement_gain("REDGEM3");
|
||||
if(it == itPirate) achievement_gain("PIRATE3");
|
||||
if(it == itCoast) achievement_gain("COAST3");
|
||||
if(it == itWhirlpool) achievement_gain("WHIRL3");
|
||||
if(it == itBombEgg) achievement_gain("MINE3");
|
||||
if(it == itPalace) achievement_gain("RUG3");
|
||||
if(it == itFjord) achievement_gain("GARNET3");
|
||||
|
||||
if(it == itEdge) achievement_gain("TOWER3");
|
||||
if(it == itElemental) achievement_gain("ELEMENT3");
|
||||
if(it == itZebra) achievement_gain("ZEBRA3");
|
||||
}
|
||||
|
||||
if(q == 50) {
|
||||
|
@ -155,14 +202,30 @@ void achievement_collection(eItem it, int prevgold, int newgold) {
|
|||
if(it == itEmerald) achievement_gain("EMERALD4");
|
||||
if(it == itSilver) achievement_gain("SILVER4");
|
||||
if(it == itGrimoire) achievement_gain("GRIMOIRE4");
|
||||
if(it == itRedGem) achievement_gain("REDGEM4");
|
||||
if(it == itPirate) achievement_gain("PIRATE4");
|
||||
if(it == itCoast) achievement_gain("COAST4");
|
||||
if(it == itWhirlpool) achievement_gain("WHIRL4");
|
||||
if(it == itBombEgg) achievement_gain("MINE4");
|
||||
if(it == itPalace) achievement_gain("RUG4");
|
||||
if(it == itFjord) achievement_gain("GARNET4");
|
||||
|
||||
if(it == itEdge) achievement_gain("TOWER4");
|
||||
if(it == itElemental) achievement_gain("ELEMENT4");
|
||||
if(it == itZebra) achievement_gain("ZEBRA4");
|
||||
}
|
||||
|
||||
if(it == itOrbYendor)
|
||||
if(it == itOrbYendor) {
|
||||
achievement_gain("YENDOR2");
|
||||
if(pureHardcore()) achievement_gain("HARDCORE");
|
||||
if(shmup::on) achievement_gain("SHMUP", false, true);
|
||||
}
|
||||
}
|
||||
|
||||
void achievement_count(const string& s, int current, int prev) {
|
||||
if(cheater) return;
|
||||
if(shmup::on) return;
|
||||
if(randomPatternsMode) return;
|
||||
if(s == "GOLEM" && current >= 5)
|
||||
achievement_gain("GOLEM2");
|
||||
if(s == "GOLEM" && current >= 10)
|
||||
|
@ -204,6 +267,7 @@ int specific_what = 0;
|
|||
|
||||
void improve_score(int i, eItem what) {
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(haveLeaderboard(i)) updateHi(what, currentscore[i]);
|
||||
if(items[what] && haveLeaderboard(i)) {
|
||||
if(items[what] > currentscore[i] && currentscore[i] != SCORE_UNKNOWN) {
|
||||
specific_improved++; specific_what = what;
|
||||
|
@ -215,14 +279,16 @@ void improve_score(int i, eItem what) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void achievement_final(bool really_final) {
|
||||
void achievement_score(int cat, int number) {
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(cheater) return;
|
||||
if(euclid) return;
|
||||
int total_improved = 0;
|
||||
specific_improved = 0;
|
||||
specific_what = 0;
|
||||
|
||||
if(randomPatternsMode) return;
|
||||
upload_score(cat, number);
|
||||
#endif
|
||||
}
|
||||
|
||||
void improveItemScores() {
|
||||
for(int i=1; i<=12; i++) improve_score(i, eItem(i));
|
||||
improve_score(17, itOrbYendor);
|
||||
improve_score(18, itFernFlower);
|
||||
|
@ -233,14 +299,39 @@ void achievement_final(bool really_final) {
|
|||
improve_score(23, itEmerald);
|
||||
improve_score(24, itGrimoire);
|
||||
improve_score(25, itHolyGrail);
|
||||
improve_score(26, itRedGem);
|
||||
improve_score(27, itPirate);
|
||||
improve_score(31, itBombEgg);
|
||||
improve_score(32, itCoast);
|
||||
improve_score(33, itWhirlpool);
|
||||
improve_score(34, itPalace);
|
||||
improve_score(35, itFjord);
|
||||
|
||||
improve_score(37, itEdge);
|
||||
improve_score(38, itElemental);
|
||||
improve_score(39, itZebra);
|
||||
}
|
||||
|
||||
void achievement_final(bool really_final) {
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(cheater) return;
|
||||
if(euclid) return;
|
||||
if(randomPatternsMode) return;
|
||||
int total_improved = 0;
|
||||
specific_improved = 0;
|
||||
specific_what = 0;
|
||||
|
||||
if(!shmup::on) improveItemScores();
|
||||
|
||||
int sid = shmup::on ? 28 : 0;
|
||||
|
||||
int tg = gold();
|
||||
if(tg && haveLeaderboard(0)) {
|
||||
if(tg > currentscore[0] && currentscore[0] != SCORE_UNKNOWN) {
|
||||
if(currentscore[0] < 0) total_improved += 2;
|
||||
total_improved++; currentscore[0] = tg;
|
||||
if(tg && haveLeaderboard(sid)) {
|
||||
if(tg > currentscore[sid] && currentscore[sid] != SCORE_UNKNOWN) {
|
||||
if(currentscore[sid] < 0) total_improved += 2;
|
||||
total_improved++; currentscore[sid] = tg;
|
||||
}
|
||||
upload_score(0, tg);
|
||||
upload_score(sid, tg);
|
||||
}
|
||||
|
||||
if(total_improved >= 2) {
|
||||
|
@ -264,11 +355,13 @@ void achievement_victory(bool hyper) {
|
|||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(cheater) return;
|
||||
if(euclid) return;
|
||||
if(randomPatternsMode) return;
|
||||
if(hyper && shmup::on) return;
|
||||
|
||||
int t = savetime + time(NULL) - timerstart;
|
||||
|
||||
int ih1 = hyper ? 15 : 13;
|
||||
int ih2 = hyper ? 16 : 14;
|
||||
int ih1 = hyper ? 15 : shmup::on ? 29 : 13;
|
||||
int ih2 = hyper ? 16 : shmup::on ? 30 : 14;
|
||||
|
||||
int improved = 0;
|
||||
if(currentscore[ih1] == NO_SCORE_YET || currentscore[ih2] == NO_SCORE_YET)
|
||||
|
@ -291,12 +384,20 @@ void achievement_victory(bool hyper) {
|
|||
addMessage(XLAT("This has been recorded in the " LEADERFULL "."));
|
||||
addMessage(XLAT("The faster you get here, the better you are!"));
|
||||
}
|
||||
else if(improved >= 3)
|
||||
addMessage(XLAT("You have improved both your real time and turn count. Congratulations!"));
|
||||
else if(improved >= 3) {
|
||||
if(shmup::on)
|
||||
addMessage(XLAT("You have improved both your real time and knife count. Congratulations!"));
|
||||
else
|
||||
addMessage(XLAT("You have improved both your real time and turn count. Congratulations!"));
|
||||
}
|
||||
else if(improved == 1)
|
||||
addMessage(XLAT("You have used less real time than ever before. Congratulations!"));
|
||||
else if(improved == 2)
|
||||
addMessage(XLAT("You have used less turns than ever before. Congratulations!"));
|
||||
else if(improved == 2) {
|
||||
if(shmup::on)
|
||||
addMessage(XLAT("You have used less knives than ever before. Congratulations!"));
|
||||
else
|
||||
addMessage(XLAT("You have used less turns than ever before. Congratulations!"));
|
||||
}
|
||||
}
|
||||
|
||||
upload_score(ih1, t);
|
||||
|
|
282
cell.cpp
282
cell.cpp
|
@ -4,6 +4,7 @@
|
|||
// cells the game is played on
|
||||
|
||||
int fix6(int a) { return (a+96)% 6; }
|
||||
int fix7(int a) { return (a+84)% 7; }
|
||||
|
||||
struct cell : gcell {
|
||||
char type; // 6 for hexagons, 7 for heptagons
|
||||
|
@ -12,6 +13,8 @@ struct cell : gcell {
|
|||
cell *mov[7]; // meaning very similar to heptagon::move
|
||||
};
|
||||
|
||||
int fixdir(int a, cell *c) { a %= c->type; if(a<0) a += c->type; return a; }
|
||||
|
||||
int cellcount = 0;
|
||||
|
||||
void initcell(cell *c); // from game.cpp
|
||||
|
@ -116,6 +119,16 @@ cell *createMov(cell *c, int d) {
|
|||
return c->mov[d];
|
||||
}
|
||||
|
||||
cell *createMovR(cell *c, int d) {
|
||||
d %= 42; d += 42; d %= c->type;
|
||||
return createMov(c, d);
|
||||
}
|
||||
|
||||
cell *getMovR(cell *c, int d) {
|
||||
d %= 42; d += 42; d %= c->type;
|
||||
return c->mov[d];
|
||||
}
|
||||
|
||||
// similar to heptspin from heptagon.cpp
|
||||
struct cellwalker {
|
||||
cell *c;
|
||||
|
@ -132,6 +145,10 @@ bool cwstepcreates(cellwalker& cw) {
|
|||
return cw.c->mov[cw.spin] == NULL;
|
||||
}
|
||||
|
||||
cell *cwpeek(cellwalker cw, int dir) {
|
||||
return createMov(cw.c, (cw.spin+42+dir) % cw.c->type);
|
||||
}
|
||||
|
||||
void cwstep(cellwalker& cw) {
|
||||
createMov(cw.c, cw.spin);
|
||||
int nspin = cw.c->spn[cw.spin];
|
||||
|
@ -188,7 +205,9 @@ cell*& euclideanAtCreate(eucoord x, eucoord y) {
|
|||
void initcells() {
|
||||
|
||||
origin.s = hsOrigin;
|
||||
origin.fjordval = 98;
|
||||
origin.emeraldval = 98;
|
||||
origin.zebraval = 40;
|
||||
origin.fiftyval = 0;
|
||||
for(int i=0; i<7; i++) origin.move[i] = NULL;
|
||||
origin.alt = NULL;
|
||||
origin.distance = 0;
|
||||
|
@ -197,7 +216,7 @@ void initcells() {
|
|||
else
|
||||
origin.c7 = newCell(7, &origin);
|
||||
|
||||
// origin.fjordval =
|
||||
// origin.emeraldval =
|
||||
}
|
||||
|
||||
#define DEBMEM(x) // { x fflush(stdout); }
|
||||
|
@ -287,9 +306,26 @@ bool ishept(cell *c) {
|
|||
else return c->type == 7;
|
||||
}
|
||||
|
||||
bool ishex1(cell *c) {
|
||||
// EUCLIDEAN
|
||||
if(euclid) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
short z = (short(y+2*x))%3;
|
||||
if(z<0) z += 3;
|
||||
return z == 1;
|
||||
}
|
||||
else return c->type == 7;
|
||||
}
|
||||
|
||||
void clearMemory() {
|
||||
extern void clearGameMemory();
|
||||
clearGameMemory();
|
||||
if(shmup::on) shmup::clearMemory();
|
||||
cleargraphmemory();
|
||||
#ifndef MOBILE
|
||||
mapeditor::clearModelCells();
|
||||
#endif
|
||||
// EUCLIDEAN
|
||||
if(euclid) {
|
||||
for(int y=0; y<256; y++) for(int x=0; x<256; x++)
|
||||
|
@ -307,15 +343,15 @@ void clearMemory() {
|
|||
DEBMEM ( printf("ok\n"); )
|
||||
}
|
||||
|
||||
int fjordval(cell *c) {
|
||||
int emeraldval(cell *c) {
|
||||
if(euclid) return 0;
|
||||
if(c->type == 7)
|
||||
return c->master->fjordval >> 3;
|
||||
return c->master->emeraldval >> 3;
|
||||
else {
|
||||
return fjord_hexagon(
|
||||
fjordval(createMov(c,0)),
|
||||
fjordval(createMov(c,2)),
|
||||
fjordval(createMov(c,4))
|
||||
return emerald_hexagon(
|
||||
emeraldval(createMov(c,0)),
|
||||
emeraldval(createMov(c,2)),
|
||||
emeraldval(createMov(c,4))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -348,6 +384,8 @@ int celldist(cell *c) {
|
|||
#define ALTDIST_BOUNDARY 99999
|
||||
#define ALTDIST_UNKNOWN 99998
|
||||
|
||||
#define ALTDIST_ERROR 90000
|
||||
|
||||
// defined in 'game'
|
||||
int euclidAlt(short x, short y);
|
||||
|
||||
|
@ -373,3 +411,231 @@ int celldistAlt(cell *c) {
|
|||
|
||||
#define GRAIL_FOUND 0x4000
|
||||
#define GRAIL_RADIUS_MASK 0x3FFF
|
||||
|
||||
int dirfromto(cell *cfrom, cell *cto) {
|
||||
for(int i=0; i<cfrom->type; i++) if(cfrom->mov[i] == cto) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// === FIFTYVALS ===
|
||||
|
||||
unsigned bitmajority(unsigned a, unsigned b, unsigned c) {
|
||||
return (a&b) | ((a^b)&c);
|
||||
}
|
||||
|
||||
int fiftyval(cell *c) {
|
||||
if(euclid) return 0;
|
||||
if(c->type == 7)
|
||||
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(euclid) {
|
||||
eucoord x, y;
|
||||
decodeMaster(c->master, x, y);
|
||||
int ix = short(x) + 99999 + short(y);
|
||||
int iy = short(y) + 99999;
|
||||
char palacemap[3][10] = {
|
||||
"012333321",
|
||||
"112322232",
|
||||
"222321123"
|
||||
};
|
||||
ix += (iy/3) * 3;
|
||||
iy %= 3; ix %= 9;
|
||||
return palacemap[iy][ix] - '0';
|
||||
}
|
||||
if(c->type == 7) 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 == 7) return land50(fiftyval(c));
|
||||
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 == 7) return polara50(fiftyval(c));
|
||||
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 == 7) return polarb50(fiftyval(c));
|
||||
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 == 7) return fiftyval(c) / 32;
|
||||
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 zebra40(cell *c) {
|
||||
if(c->type == 7) return (c->master->zebraval/10);
|
||||
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 == 7) return (c->master->zebraval/10)/4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
bool randpattern(cell *c, int rval) {
|
||||
int i, sw=0;
|
||||
switch(rval & 3) {
|
||||
case 0:
|
||||
return rand() < rval;
|
||||
case 1:
|
||||
i = zebra40(c);
|
||||
if(i&1) { if(rval&4) sw^=1; i &= ~1; }
|
||||
if(i&2) { if(rval&8) sw^=1; i &= ~2; }
|
||||
i >>= 2;
|
||||
i--; i /= 3;
|
||||
if(rval & (16<<i)) sw^=1;
|
||||
return sw;
|
||||
case 2:
|
||||
i = emeraldval(c);
|
||||
if(i&1) { if(rval&4) sw^=1; i &= ~1; }
|
||||
if(i&2) { if(rval&8) sw^=1; i &= ~2; }
|
||||
if(rval & (16<<i)) sw^=1;
|
||||
return sw;
|
||||
case 3:
|
||||
if(polara50(c)) { if(rval&4) sw^=1; }
|
||||
if(polarb50(c)) { if(rval&8) sw^=1; }
|
||||
int i = fiftyval049(c); i += 6; i /= 7;
|
||||
if(rval & (16<<i)) sw^=1;
|
||||
return sw;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int randpatternCode(cell *c, int rval) {
|
||||
switch(rval & 3) {
|
||||
case 1:
|
||||
return zebra40(c);
|
||||
case 2:
|
||||
return emeraldval(c);
|
||||
case 3:
|
||||
return fiftyval049(c) + (polara50(c)?50:0) + (polarb50(c)?1000:0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RANDITER 31
|
||||
|
||||
char rpm_memoize[3][256][RANDITER+1];
|
||||
|
||||
void clearMemoRPM() {
|
||||
for(int a=0; a<3; a++) for(int b=0; b<256; b++) for(int i=0; i<RANDITER+1; i++)
|
||||
rpm_memoize[a][b][i] = 2;
|
||||
}
|
||||
|
||||
extern int randompattern[landtypes];
|
||||
|
||||
bool randpatternMajority(cell *c, int ival, int iterations) {
|
||||
int rval = 0;
|
||||
if(ival == 0) rval = randompattern[laCaves];
|
||||
if(ival == 1) rval = randompattern[laLivefjord];
|
||||
if(ival == 2) rval = randompattern[laEmerald];
|
||||
if((rval&3) == 0) return randpattern(c, rval);
|
||||
int code = randpatternCode(c, rval);
|
||||
char& memo(rpm_memoize[ival][code][iterations]);
|
||||
if(memo < 2) return memo;
|
||||
int z = 0;
|
||||
if(iterations) for(int i=0; i<c->type; i++) {
|
||||
if(randpatternMajority(createMov(c,i), ival, iterations-1))
|
||||
z++;
|
||||
else
|
||||
z--;
|
||||
}
|
||||
if(z!=0) memo = (z>0);
|
||||
else memo = randpattern(c, rval);
|
||||
// printf("%p] rval = %X code = %d iterations = %d result = %d\n", c, rval, code, iterations, memo);
|
||||
return memo;
|
||||
}
|
||||
|
|
749
classes.cpp
749
classes.cpp
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* DIRENT.H (formerly DIRLIB.H)
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is a part of the mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within the package.
|
||||
*
|
||||
*/
|
||||
#ifndef _DIRENT_H_
|
||||
#define _DIRENT_H_
|
||||
|
||||
/* All the headers include this file. */
|
||||
#include <_mingw.h>
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dirent
|
||||
{
|
||||
long d_ino; /* Always zero. */
|
||||
unsigned short d_reclen; /* Always zero. */
|
||||
unsigned short d_namlen; /* Length of name in d_name. */
|
||||
|
||||
/* The following exactly mimic the layout of _finddata_t ...
|
||||
*/
|
||||
unsigned d_type; /* File attributes */
|
||||
time_t d_time_create;
|
||||
time_t d_time_access; /* always midnight local time */
|
||||
time_t d_time_write;
|
||||
_fsize_t d_size;
|
||||
/*
|
||||
* ...so that we may map a union of _finddata_t at the
|
||||
* location of d_type (corresponding to _finddata_t.attrib),
|
||||
* and thus map this directly to the _findfirst/_findnext
|
||||
* returned field.
|
||||
*/
|
||||
char d_name[FILENAME_MAX]; /* File name. */
|
||||
};
|
||||
|
||||
/*
|
||||
* This opaque data type represents the private structure
|
||||
* through which a directory stream is referenced.
|
||||
*/
|
||||
typedef union __dirstream_t DIR;
|
||||
|
||||
DIR* __cdecl __MINGW_NOTHROW opendir (const char*);
|
||||
struct dirent* __cdecl __MINGW_NOTHROW readdir (DIR*);
|
||||
int __cdecl __MINGW_NOTHROW closedir (DIR*);
|
||||
void __cdecl __MINGW_NOTHROW rewinddir (DIR*);
|
||||
long __cdecl __MINGW_NOTHROW telldir (DIR*);
|
||||
void __cdecl __MINGW_NOTHROW seekdir (DIR*, long);
|
||||
|
||||
|
||||
/* wide char versions */
|
||||
|
||||
struct _wdirent
|
||||
{
|
||||
long d_ino; /* Always zero. */
|
||||
unsigned short d_reclen; /* Always zero. */
|
||||
unsigned short d_namlen; /* Length of name in d_name. */
|
||||
|
||||
/* The following exactly mimic the layout of _wfinddata_t ...
|
||||
*/
|
||||
unsigned d_type; /* File attributes */
|
||||
time_t d_time_create; /* -1 for FAT file systems */
|
||||
time_t d_time_access; /* -1 for FAT file systems */
|
||||
time_t d_time_write;
|
||||
_fsize_t d_size;
|
||||
/*
|
||||
* ...so that we may map a union of _wfinddata_t at the
|
||||
* location of d_type (corresponding to _wfinddata_t.attrib),
|
||||
* and thus map this directly to the _wfindfirst/_wfindnext
|
||||
* returned field.
|
||||
*/
|
||||
wchar_t d_name[FILENAME_MAX]; /* File name. */
|
||||
};
|
||||
|
||||
/*
|
||||
* This opaque data type represents the private structure
|
||||
* through which a wide directory stream is referenced.
|
||||
*/
|
||||
typedef union __wdirstream_t _WDIR;
|
||||
|
||||
_WDIR* __cdecl __MINGW_NOTHROW _wopendir (const wchar_t*);
|
||||
struct _wdirent* __cdecl __MINGW_NOTHROW _wreaddir (_WDIR*);
|
||||
int __cdecl __MINGW_NOTHROW _wclosedir (_WDIR*);
|
||||
void __cdecl __MINGW_NOTHROW _wrewinddir (_WDIR*);
|
||||
long __cdecl __MINGW_NOTHROW _wtelldir (_WDIR*);
|
||||
void __cdecl __MINGW_NOTHROW _wseekdir (_WDIR*, long);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_BSD_SOURCE) || defined(_WIN32)
|
||||
/*
|
||||
* BSD-ish systems define manifest constants for the d_type field;
|
||||
* although probably only DT_REG and DT_DIR are useful on Win32, we
|
||||
* try to map them as best we can from the _finddata.attrib field.
|
||||
*
|
||||
* The relevant Microsoft manifest values are:
|
||||
*
|
||||
* _A_NORMAL (0x0000) normal file: best fit for DT_REG
|
||||
* _A_RDONLY (0x0001) read-only: no BSD d_type equivalent
|
||||
* _A_HIDDEN (0x0002) hidden entity: no BSD equivalent
|
||||
* _A_SYSTEM (0x0004) system entity: no BSD equivalent
|
||||
* _A_VOLID (0x0008) volume label: no BSD equivalent
|
||||
* _A_SUBDIR (0x0010) directory: best fit for DT_DIR
|
||||
* _A_ARCH (0x0020) "dirty": no BSD equivalent
|
||||
*
|
||||
* Thus, we may immediately define:
|
||||
*/
|
||||
#define DT_REG _A_NORMAL
|
||||
#define DT_DIR _A_SUBDIR
|
||||
|
||||
/* The remaining BSD d_type manifest values have no Win32 equivalents;
|
||||
* we will define them artificially, and then we will ensure that our
|
||||
* opendir()/readdir() implementation will never assign them; (we will
|
||||
* substitute DT_UNKNOWN, but it would be unwise to simply make these
|
||||
* equivalent to that, since an application is likely to simply check
|
||||
* for d_type equal to any one of these defined types, and thus could
|
||||
* mistakenly identify DT_UNKNOWN as being of the tested type):
|
||||
*/
|
||||
#define DT_BLK (((_A_SUBDIR) << 4) | DT_UNKNOWN)
|
||||
#define DT_CHR (((_A_SUBDIR) << 5) | DT_UNKNOWN)
|
||||
#define DT_FIFO (((_A_SUBDIR) << 6) | DT_UNKNOWN)
|
||||
#define DT_LNK (((_A_SUBDIR) << 7) | DT_UNKNOWN)
|
||||
#define DT_SOCK (((_A_SUBDIR) << 8) | DT_UNKNOWN)
|
||||
|
||||
/* No file system entity can ever be simultaneously a volume label
|
||||
* and a directory; we will exploit this to unambiguously define:
|
||||
*/
|
||||
#define DT_UNKNOWN (_A_VOLID | _A_SUBDIR)
|
||||
|
||||
#endif /* _BSD_SOURCE */
|
||||
#endif /* ! RC_INVOKED */
|
||||
|
||||
#endif /* !defined _DIRENT_H_ */
|
30
heptagon.cpp
30
heptagon.cpp
|
@ -25,13 +25,19 @@ struct heptagon {
|
|||
heptagon* move[7];
|
||||
// distance from the origin
|
||||
short distance;
|
||||
// fjord/wineyard generator
|
||||
short fjordval;
|
||||
heptagon*& modmove(int i) { return move[fixrot(i)]; }
|
||||
unsigned char& gspin(int i) { return spin[fixrot(i)]; }
|
||||
// emerald/wineyard generator
|
||||
short emeraldval;
|
||||
// fifty generator
|
||||
short fiftyval;
|
||||
// zebra generator (1B actually)
|
||||
short zebraval;
|
||||
// central cell
|
||||
cell *c7;
|
||||
// associated generator of alternate structure, for Camelot and horocycles
|
||||
heptagon *alt;
|
||||
// functions
|
||||
heptagon*& modmove(int i) { return move[fixrot(i)]; }
|
||||
unsigned char& gspin(int i) { return spin[fixrot(i)]; }
|
||||
};
|
||||
|
||||
// the automaton is used to generate each heptagon in an unique way
|
||||
|
@ -65,14 +71,20 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
|
|||
parent->move[d] = h; parent->spin[d] = pard;
|
||||
if(parent->c7) {
|
||||
h->c7 = newCell(7, h);
|
||||
h->fjordval = fjord_heptagon(parent->fjordval, d);
|
||||
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
|
||||
h->zebraval = zebra_heptagon(parent->zebraval, d);
|
||||
if(parent == &origin)
|
||||
h->fiftyval = fiftytable[0][d];
|
||||
else
|
||||
h->fiftyval = nextfiftyval(parent->fiftyval, parent->move[0]->fiftyval, d);
|
||||
}
|
||||
else {
|
||||
h->c7 = NULL;
|
||||
h->fjordval = 0;
|
||||
h->emeraldval = 0;
|
||||
h->fiftyval = 0;
|
||||
}
|
||||
//generateFjordval(parent);
|
||||
//generateFjordval(h);
|
||||
//generateEmeraldval(parent);
|
||||
//generateEmeraldval(h);
|
||||
if(pard == 0) {
|
||||
if(parent->s == hsOrigin) h->distance = 2;
|
||||
else if(h->spin[0] == 5)
|
||||
|
@ -92,7 +104,7 @@ void addSpin(heptagon *h, int d, heptagon *from, int rot, int spin) {
|
|||
h->spin[d] = fixrot(from->spin[rot] + spin);
|
||||
h->move[d]->move[fixrot(from->spin[rot] + spin)] = h;
|
||||
h->move[d]->spin[fixrot(from->spin[rot] + spin)] = d;
|
||||
//generateFjordval(h->move[d]); generateFjordval(h);
|
||||
//generateEmeraldval(h->move[d]); generateEmeraldval(h);
|
||||
}
|
||||
|
||||
heptagon *createStep(heptagon *h, int d) {
|
||||
|
|
128
hyper.cpp
128
hyper.cpp
|
@ -19,9 +19,9 @@
|
|||
#define ISANDROID 0
|
||||
#define ISMOBILE 0
|
||||
#define ISIOS 0
|
||||
#define VER "6.6"
|
||||
#define VERNUM 6600
|
||||
#define VERNUM_HEX 0x6600
|
||||
#define VER "7.4h"
|
||||
#define VERNUM 7480
|
||||
#define VERNUM_HEX 0x7480
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
|
@ -40,13 +40,27 @@ using namespace std;
|
|||
|
||||
const char *scorefile = "hyperrogue.log";
|
||||
const char *conffile = "hyperrogue.ini";
|
||||
|
||||
string levelfile = "hyperrogue.lev";
|
||||
string picfile = "hyperrogue.pic";
|
||||
|
||||
const char *loadlevel = NULL;
|
||||
const char *musicfile = "";
|
||||
|
||||
typedef long double ld;
|
||||
|
||||
template<class T> int size(T& x) {return x.size(); }
|
||||
string its(int i) { char buf[64]; sprintf(buf, "%d", i); return buf; }
|
||||
string cts(char c) { char buf[8]; buf[0] = c; buf[1] = 0; return buf; }
|
||||
string llts(long long i) {
|
||||
// sprintf does not work on Windows IIRC
|
||||
if(i < 0) return "-" + llts(-i);
|
||||
if(i < 10) return its(i);
|
||||
return llts(i/10) + its(i%10);
|
||||
}
|
||||
string fts(float x) { char buf[64]; sprintf(buf, "%4.2f", x); return buf; }
|
||||
string fts4(float x) { char buf[64]; sprintf(buf, "%6.4f", x); return buf; }
|
||||
string itsh(int i) {static char buf[16]; sprintf(buf, "%03X", i); return buf; }
|
||||
|
||||
#undef DEBT
|
||||
void DEBT(const char *buf) {
|
||||
|
@ -60,7 +74,7 @@ int clWidth, clHeight, clFont;
|
|||
string commandline;
|
||||
|
||||
#include "hyperpoint.cpp"
|
||||
#include "fjordgen.cpp"
|
||||
#include "patterns.cpp"
|
||||
#include "heptagon.cpp"
|
||||
#include "classes.cpp"
|
||||
#include "language.cpp"
|
||||
|
@ -69,22 +83,31 @@ string commandline;
|
|||
#define NOLICENSE
|
||||
#endif
|
||||
|
||||
#include "achievement.h"
|
||||
#include "hyper.h"
|
||||
|
||||
#include "cell.cpp"
|
||||
#include "game.cpp"
|
||||
|
||||
// #include "patterngen.cpp"
|
||||
|
||||
#include "geometry.cpp"
|
||||
|
||||
#include "polygons.cpp"
|
||||
|
||||
#ifndef MOBILE
|
||||
#include "mapeditor.cpp"
|
||||
#endif
|
||||
|
||||
#include "graph.cpp"
|
||||
|
||||
#include "achievement.cpp"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
bool switchEuclid = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
printf("HyperRogue by Zeno Rogue <zeno@attnam.com>, version "VER"\n");
|
||||
|
||||
#ifndef NOLICENSE
|
||||
printf("released under GNU General Public License version 2 and thus\n");
|
||||
printf("comes with absolutely no warranty; see COPYING for details\n");
|
||||
|
@ -94,6 +117,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// printf("cell size = %d\n", int(sizeof(cell)));
|
||||
srand(time(NULL));
|
||||
shrand(time(NULL));
|
||||
|
||||
#ifdef FHS
|
||||
char sbuf[640], cbuf[640];
|
||||
|
@ -102,18 +126,51 @@ int main(int argc, char **argv) {
|
|||
snprintf(cbuf, 640, "%s/.%s", getenv("HOME"), conffile); conffile = cbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
for(int i=1; i<argc; i++) {
|
||||
if(strcmp(argv[i], "-c") == 0 && i != argc-1) {conffile = argv[i+1]; i++;}
|
||||
else if(strcmp(argv[i], "-s") == 0 && i != argc-1) {scorefile = argv[i+1]; i++;}
|
||||
else if(strcmp(argv[i], "-m") == 0 && i != argc-1) {musicfile = argv[i+1]; i++;}
|
||||
else if(strcmp(argv[i], "-lev") == 0 && i != argc-1) {levelfile = argv[i+1]; i++;}
|
||||
else if(strcmp(argv[i], "-pic") == 0 && i != argc-1) {picfile = argv[i+1]; i++;}
|
||||
else if(strcmp(argv[i], "-load") == 0 && i != argc-1) {loadlevel = argv[i+1]; i++;}
|
||||
// else if(strcmp(argv[i], "-P") == 0 && i != argc-1) {par = atoi(argv[i+1]); i++;}
|
||||
else if(strcmp(argv[i], "-W") == 0 && i != argc-1) {
|
||||
for(int l=2; l<landtypes; l++) if(strstr(linf[l].name, argv[i+1]) != NULL)
|
||||
for(int l=0; l<landtypes; l++) if(strstr(linf[l].name, argv[i+1]) != NULL) {
|
||||
firstland = euclidland = eLand(l);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if(strcmp(argv[i], "-E") == 0) {
|
||||
switchEuclid = true;
|
||||
else if(strcmp(argv[i], "-L") == 0) {
|
||||
printf("Treasures:\n");
|
||||
for(int i=1; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_TREASURE)
|
||||
printf(" %s\n", iinf[i].name);
|
||||
printf("\n");
|
||||
printf("Orbs:\n");
|
||||
for(int i=1; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_ORB)
|
||||
printf(" %s\n", iinf[i].name);
|
||||
printf("\n");
|
||||
printf("Other items:\n");
|
||||
for(int i=1; i<ittypes; i++)
|
||||
if(itemclass(eItem(i)) == IC_OTHER)
|
||||
printf(" %s\n", iinf[i].name);
|
||||
printf("\n");
|
||||
printf("Monsters:\n");
|
||||
for(int i=1; i<motypes; i++)
|
||||
printf(" %s\n", minf[i].name);
|
||||
printf("\n");
|
||||
printf("Lands:\n");
|
||||
for(int i=1; i<landtypes; i++)
|
||||
printf(" %s\n", linf[i].name);
|
||||
printf("\n");
|
||||
printf("Walls:\n");
|
||||
for(int i=0; i<walltypes; i++)
|
||||
printf(" %s\n", winf[i].name);
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
else if(strcmp(argv[i], "-f") == 0) { commandline += "f"; }
|
||||
else if(strcmp(argv[i], "-w") == 0) { commandline += "w"; }
|
||||
|
@ -121,6 +178,10 @@ int main(int argc, char **argv) {
|
|||
else if(strcmp(argv[i], "-a") == 0) { commandline += "a"; }
|
||||
else if(strcmp(argv[i], "-p") == 0) { commandline += "p"; }
|
||||
else if(strcmp(argv[i], "-o") == 0) { commandline += "o"; }
|
||||
else if(strcmp(argv[i], "-E") == 0) { commandline += "E"; }
|
||||
else if(strcmp(argv[i], "-S") == 0) { commandline += "S"; }
|
||||
else if(strcmp(argv[i], "-H") == 0) { commandline += "H"; }
|
||||
else if(strcmp(argv[i], "-P") == 0) { commandline += "P"; }
|
||||
else if(strcmp(argv[i], "-r") == 0) {
|
||||
i++;
|
||||
sscanf(argv[i], "%dx%dx%d", &clWidth, &clHeight, &clFont);
|
||||
|
@ -135,6 +196,8 @@ int main(int argc, char **argv) {
|
|||
printf(" -c FILE - use the specified configuration file\n");
|
||||
printf(" -s FILE - use the specified highscore file\n");
|
||||
printf(" -m FILE - use the specified soundtrack (music)\n");
|
||||
printf(" -lev FILE - use the specified filename for the map editor (without loading)\n");
|
||||
printf(" -load FILE - use the specified filename for the map editor\n");
|
||||
printf(" --version, -v - show the version number\n");
|
||||
printf(" --help, -h - show the commandline options\n");
|
||||
printf(" -f, -w - start in the fullscreen or windowed mode\n");
|
||||
|
@ -142,7 +205,11 @@ int main(int argc, char **argv) {
|
|||
printf(" -r WxHxF - use the given resolution and font size\n");
|
||||
printf(" -o - switch the OpenGL mode on or off\n");
|
||||
printf(" -W LAND - start in the given land (cheat)\n");
|
||||
printf(" -E - start in Euclidean\n");
|
||||
printf(" -E - switch Euclidean\n");
|
||||
printf(" -S - switch Shmup\n");
|
||||
printf(" -P - switch Shmup number of players\n");
|
||||
printf(" -H - switch Hardcore\n");
|
||||
printf(" -L - list of features\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
|
@ -159,7 +226,11 @@ int main(int argc, char **argv) {
|
|||
display(T2);
|
||||
display(T*T2); */
|
||||
|
||||
eLand f = firstland;
|
||||
|
||||
// initlanguage();
|
||||
initgraph();
|
||||
loadsave();
|
||||
initcells();
|
||||
/* for(int uu=9; uu >= 0; uu--) {
|
||||
printf("uu=%d\n", uu);
|
||||
|
@ -167,34 +238,45 @@ int main(int argc, char **argv) {
|
|||
restartGame();
|
||||
} */
|
||||
|
||||
eLand f = firstland;
|
||||
|
||||
loadsave();
|
||||
#ifdef BUILDZEBRA
|
||||
firstland = laCanvas;
|
||||
shmup::on = false;
|
||||
#endif
|
||||
initgame();
|
||||
#ifdef BUILDZEBRA
|
||||
zebraPattern();
|
||||
#endif
|
||||
|
||||
restoreGolems(items[itOrbLife]); items[itOrbLife] = 0;
|
||||
if(!shmup::on) {
|
||||
restoreGolems(items[itOrbLife], moGolem); items[itOrbLife] = 0;
|
||||
restoreGolems(items[itOrbFriend], moTameBomberbird); items[itOrbFriend] = 0;
|
||||
restoreGolems(kills[moPrincessMoved], moPrincess, princess::saveHP); kills[moPrincessMoved] = 0;
|
||||
restoreGolems(kills[moPrincessArmedMoved], moPrincessArmed, princess::saveArmedHP); kills[moPrincessArmedMoved] = 0;
|
||||
}
|
||||
|
||||
firstland = f;
|
||||
|
||||
// verifyHell();
|
||||
// exit(1);
|
||||
|
||||
initgraph();
|
||||
|
||||
int t1 = SDL_GetTicks();
|
||||
|
||||
if(switchEuclid) restartGameSwitchEuclid();
|
||||
|
||||
// if(switchEuclid) restartGame('e');
|
||||
|
||||
if(loadlevel) mapstream::loadMap(loadlevel);
|
||||
|
||||
mainloop();
|
||||
|
||||
achievement_final(!items[itOrbSafety]);
|
||||
SDL_Quit();
|
||||
|
||||
saveStats();
|
||||
int msec = SDL_GetTicks() - t1;
|
||||
printf("frame : %f ms (%f fps)\n", 1.*msec/frames, 1000.*frames/msec);
|
||||
offscreen.clear();
|
||||
clearMemory();
|
||||
cleargraph();
|
||||
|
||||
achievement_close();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
// definitions
|
||||
|
||||
// disable this if you have no access to SDL_gfx
|
||||
#ifndef STEAM
|
||||
#define GFX
|
||||
#endif
|
||||
|
||||
#define GL
|
||||
|
||||
#ifdef NOGFX
|
||||
#undef GFX
|
||||
#endif
|
||||
|
||||
// scale the Euclidean
|
||||
#define EUCSCALE 2.3
|
||||
|
||||
// disable this if you have no access to SDL_mixer
|
||||
#ifndef MOBILE
|
||||
#define AUDIO
|
||||
#endif
|
||||
|
||||
#define NUMWITCH 7
|
||||
|
||||
// achievements
|
||||
|
||||
// initialize the achievement system.
|
||||
void achievement_init();
|
||||
|
||||
// close the achievement system.
|
||||
void achievement_close();
|
||||
|
||||
// gain the achievement with the given name.
|
||||
// Only awarded if euclid equals euclideanAchievement.
|
||||
void achievement_gain(const char*, bool euclideanAchievement = false, bool shmupAchievement = false);
|
||||
|
||||
// gain the achievement for collecting a number of 'it'.
|
||||
void achievement_collection(eItem it, int prevgold, int newgold);
|
||||
|
||||
// this is used for 'counting' achievements, such as kill 10
|
||||
// monsters at the same time.
|
||||
void achievement_count(const string& s, int current, int prev);
|
||||
|
||||
// scores for special challenges
|
||||
void achievement_score(int cat, int score);
|
||||
|
||||
// gain the victory achievements. Set 'hyper' to true for
|
||||
// the Hyperstone victory, and false for the Orb of Yendor victory.
|
||||
void achievement_victory(bool hyper);
|
||||
|
||||
// gain the final achievements. Called with really=false whenever the user
|
||||
// looks at their score, and really=true when the game really ends.
|
||||
void achievement_final(bool really);
|
||||
|
||||
// display the last achievement gained.
|
||||
void achievement_display();
|
||||
|
||||
// achievements received this game
|
||||
vector<string> achievementsReceived;
|
||||
|
||||
// game forward declarations
|
||||
|
||||
bool isCrossroads(eLand l);
|
||||
enum orbAction { roMouse, roKeyboard, roCheck, roMouseForce };
|
||||
void moveItem (cell *from, cell *to, bool activateYendor);
|
||||
void uncoverMines(cell *c, int lev);
|
||||
bool survivesMine(eMonster m);
|
||||
void killMonster(cell *c);
|
||||
void toggleGates(cell *ct, eWall type, int rad);
|
||||
bool destroyHalfvine(cell *c, eWall newwall = waNone, int tval = 6);
|
||||
void buildCrossroads2(cell *c);
|
||||
void createBugArmy(cell *c);
|
||||
heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special=0);
|
||||
void generateAlts(heptagon *h);
|
||||
void whirlGenerate(cell *wto);
|
||||
void setdist(cell *c, int d, cell *from);
|
||||
void checkOnYendorPath();
|
||||
void killThePlayerAt(eMonster m, cell *c);
|
||||
bool collectItem(cell *c2, bool telekinesis = false);
|
||||
void castLightningBolt(struct cellwalker lig);
|
||||
bool movepcto(int d, int subdir = 1, bool checkonly = false);
|
||||
void stabbingAttack(cell *mf, cell *mt, eMonster who = moNone);
|
||||
bool earthMove(cell *from, int dir);
|
||||
void messageKill(eMonster killer, eMonster victim);
|
||||
void moveMonster(cell *ct, cell *cf);
|
||||
int palaceHP();
|
||||
|
||||
void createMirrors(cell *c, int dir, eMonster type);
|
||||
void createMirages(cell *c, int dir, eMonster type);
|
||||
|
||||
int neighborId(cell *c1, cell *c2);
|
||||
|
||||
struct movedir { int d; int subdir; };
|
||||
inline bool movepcto(const movedir& md) { return movepcto(md.d, md.subdir); }
|
||||
|
||||
void activateActiv(cell *c, bool msg);
|
||||
|
||||
// shmup
|
||||
|
||||
namespace shmup {
|
||||
extern bool on;
|
||||
extern bool safety;
|
||||
extern int curtime;
|
||||
extern int players, cpid;
|
||||
void clearMemory();
|
||||
void init();
|
||||
void teleported();
|
||||
extern struct monster* mousetarget;
|
||||
extern eItem targetRangedOrb(orbAction a);
|
||||
void degradeDemons();
|
||||
void killThePlayer(eMonster m);
|
||||
void killThePlayer(eMonster m, int i);
|
||||
void visibleFor(int t);
|
||||
|
||||
void shmupDrownPlayers(cell *c);
|
||||
|
||||
cell *playerpos(int i);
|
||||
|
||||
bool playerInBoat(int i);
|
||||
|
||||
#define MAXBUTTON 64
|
||||
#define MAXAXE 16
|
||||
#define MAXHAT 4
|
||||
|
||||
struct config {
|
||||
int players;
|
||||
int subconfig;
|
||||
int setwhat;
|
||||
char keyaction[512];
|
||||
char joyaction[8][MAXBUTTON];
|
||||
char axeaction[8][MAXAXE];
|
||||
char hataction[8][MAXHAT][4];
|
||||
};
|
||||
}
|
||||
|
||||
// graph
|
||||
|
||||
void showMissionScreen();
|
||||
|
||||
void restartGraph();
|
||||
void resetmusic();
|
||||
|
||||
void cleargraphmemory();
|
||||
|
||||
void drawFlash(cell* c);
|
||||
|
||||
void drawLightning();
|
||||
void drawSafety();
|
||||
void restartGraph();
|
||||
void movepckeydir(int);
|
||||
|
||||
void centerpc(ld aspd);
|
||||
|
||||
void displayStat(int y, const string& name, const string& val, char mkey);
|
||||
void displayButton(int x, int y, const string& name, int key, int align, int rad = 0);
|
||||
void displayColorButton(int x, int y, const string& name, int key, int align, int rad, int color, int color2 = 0);
|
||||
inline string ONOFF(bool b) { return XLAT(b ? "ON" : "OFF"); }
|
||||
int darkened(int c);
|
||||
extern int getcstat;
|
||||
bool displaychr(int x, int y, int shift, int size, char chr, int col);
|
||||
bool displayfr(int x, int y, int b, int size, const string &s, int color, int align);
|
||||
void saveHighQualityShot();
|
||||
|
||||
bool outofmap(hyperpoint h);
|
||||
void getcoord(const hyperpoint& H, int& x, int& y, int &shift);
|
||||
void drawline(const hyperpoint& H1, int x1, int y1, int s1, const hyperpoint& H2, int x2, int y2, int col);
|
||||
void drawline(const hyperpoint& H1, const hyperpoint& H2, int col);
|
||||
|
||||
string ifMousing(string key, string s);
|
||||
|
||||
void saveConfig();
|
||||
|
||||
extern hyperpoint mouseh;
|
||||
|
||||
extern int webdisplay;
|
||||
|
||||
extern bool GL_initialized;
|
||||
extern hyperpoint ccenter;
|
||||
extern ld crad;
|
||||
|
||||
extern bool mousepressed, anyshiftclick;
|
||||
extern string help;
|
||||
|
||||
extern int lalpha;
|
||||
|
||||
struct videopar {
|
||||
ld scale, eye, alpha, aspeed;
|
||||
bool full;
|
||||
bool goteyes;
|
||||
bool quick;
|
||||
bool darkhepta;
|
||||
bool shifttarget;
|
||||
|
||||
int xres, yres, framelimit;
|
||||
|
||||
int xscr, yscr;
|
||||
|
||||
// paramaters calculated from the above
|
||||
int xcenter, ycenter;
|
||||
int radius;
|
||||
ld alphax, beta;
|
||||
|
||||
int fsize;
|
||||
int flashtime;
|
||||
|
||||
int wallmode, monmode, axes;
|
||||
|
||||
// for OpenGL
|
||||
float scrdist;
|
||||
|
||||
bool usingGL;
|
||||
bool usingAA;
|
||||
|
||||
int joyvalue, joyvalue2, joypanthreshold;
|
||||
float joypanspeed;
|
||||
|
||||
bool female;
|
||||
bool samegender; // same gender for the Princess?
|
||||
int language;
|
||||
|
||||
int skincolor, haircolor, dresscolor, swordcolor;
|
||||
int killreduction;
|
||||
|
||||
shmup::config scfg;
|
||||
};
|
||||
|
||||
extern videopar vid;
|
||||
|
||||
enum emtype {emNormal, emHelp,
|
||||
emMenu,
|
||||
emVisual1, emVisual2,
|
||||
emChangeMode, emCustomizeChar,
|
||||
emQuit, emDraw, emScores, emPickEuclidean,
|
||||
emPickScores,
|
||||
emShmupConfig,
|
||||
emMapEditor,
|
||||
emPatternPicker,
|
||||
emOverview
|
||||
};
|
||||
|
||||
extern emtype cmode, lastmode;
|
||||
|
||||
extern transmatrix View; // current rotation, relative to viewctr
|
||||
extern transmatrix cwtV; // player-relative view
|
||||
|
||||
extern cell *mouseover, *mouseover2;
|
||||
|
||||
extern struct SDL_Surface *s;
|
||||
|
||||
namespace mapeditor {
|
||||
extern bool drawplayer;
|
||||
extern char whichPattern;
|
||||
int generateCanvas(cell *c);
|
||||
void clearModelCells();
|
||||
void applyModelcell(cell *c);
|
||||
int realpattern(cell *c);
|
||||
int patterndir(cell *c, char w = whichPattern);
|
||||
}
|
||||
|
||||
void selectEyeGL(int ed);
|
||||
void selectEyeMask(int ed);
|
|
@ -99,6 +99,8 @@ struct transmatrix {
|
|||
// identity matrix
|
||||
transmatrix Id = {{{1,0,0}, {0,1,0}, {0,0,1}}};
|
||||
|
||||
transmatrix Mirror = {{{1,0,0}, {0,-1,0}, {0,0,1}}};
|
||||
|
||||
hyperpoint operator * (const transmatrix& T, const hyperpoint& H) {
|
||||
hyperpoint z;
|
||||
for(int i=0; i<3; i++) {
|
||||
|
@ -141,6 +143,10 @@ transmatrix xpush(ld alpha) {
|
|||
return T;
|
||||
}
|
||||
|
||||
double inverse_sinh(ld z) {
|
||||
return log(z+sqrt(1+z*z));
|
||||
}
|
||||
|
||||
// push alpha units vertically
|
||||
transmatrix ypush(ld alpha) {
|
||||
if(euclid) return eupush(0, alpha);
|
||||
|
@ -205,8 +211,22 @@ transmatrix rgpushxto0(hyperpoint H) {
|
|||
// fix the matrix T so that it is indeed an isometry
|
||||
// (without using this, imprecision could accumulate)
|
||||
|
||||
void display(const transmatrix& T);
|
||||
|
||||
void fixmatrix(transmatrix& T) {
|
||||
for(int x=0; x<3; x++) for(int y=0; y<=x; y++) {
|
||||
if(euclid) {
|
||||
for(int x=0; x<2; x++) for(int y=0; y<=x; y++) {
|
||||
ld dp = 0;
|
||||
for(int z=0; z<2; z++) dp += T[z][x] * T[z][y];
|
||||
|
||||
if(y == x) dp = 1 - sqrt(1/dp);
|
||||
|
||||
for(int z=0; z<2; z++) T[z][x] -= dp * T[z][y];
|
||||
}
|
||||
for(int x=0; x<2; x++) T[2][x] = 0;
|
||||
T[2][2] = 1;
|
||||
}
|
||||
else for(int x=0; x<3; x++) for(int y=0; y<=x; y++) {
|
||||
ld dp = 0;
|
||||
for(int z=0; z<3; z++) dp += T[z][x] * T[z][y] * sig(z);
|
||||
|
||||
|
|
51
langen.cpp
51
langen.cpp
|
@ -12,7 +12,7 @@ using namespace std;
|
|||
|
||||
template<class T> int size(T x) { return x.size(); }
|
||||
|
||||
#define NUMLAN 5
|
||||
#define NUMLAN 6
|
||||
|
||||
// language generator
|
||||
|
||||
|
@ -40,7 +40,7 @@ void addutftoset(set<string>& s, string& w) {
|
|||
//printf("%s\n", w.c_str());
|
||||
while(i < size(w)) {
|
||||
|
||||
if(w[i] < 0) {
|
||||
if(((signed char)(w[i])) < 0) {
|
||||
string z = w.substr(i, 2);
|
||||
// printf("Insert: %s [%02x%02x]\n", z.c_str(), w[i], w[i+1]);
|
||||
s.insert(w.substr(i, 2));
|
||||
|
@ -126,6 +126,9 @@ int main() {
|
|||
|
||||
nothe.insert("R'Lyeh");
|
||||
plural.insert("Crossroads");
|
||||
plural.insert("Crossroads II");
|
||||
plural.insert("Crossroads III");
|
||||
plural.insert("Elemental Planes");
|
||||
|
||||
#define S(a,b) d[1].add(a,b);
|
||||
#define N(a,b,c,d,e,f) \
|
||||
|
@ -155,6 +158,13 @@ int main() {
|
|||
{noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = f; nouns[4].add(a,n);}
|
||||
#include "language-ru.cpp"
|
||||
#undef N
|
||||
#undef S
|
||||
|
||||
#define S(a,b) d[5].add(a,b);
|
||||
#define N(a,b,c,d,e) \
|
||||
{noun n; n.genus = b; n.nom = c; n.nomp = d; n.acc = e; n.abl = e; nouns[5].add(a,n);}
|
||||
#include "language-de.cpp"
|
||||
#undef N
|
||||
#undef S
|
||||
|
||||
// verify
|
||||
|
@ -167,7 +177,7 @@ int main() {
|
|||
string mis = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(d[i].count(*x) == 0)
|
||||
mis += d[i]["EN"];
|
||||
if(mis != "")
|
||||
if(mis != "" && mis != "DE")
|
||||
printf("#warning Missing [%s]: %s\n", mis.c_str(), escape(*x, "?"));
|
||||
}
|
||||
|
||||
|
@ -181,7 +191,7 @@ int main() {
|
|||
string mis = "";
|
||||
for(int i=1; i<NUMLAN; i++) if(nouns[i].count(*x) == 0)
|
||||
mis += d[i]["EN"];
|
||||
if(mis != "")
|
||||
if(mis != "" && mis != "DE")
|
||||
printf("#warning Missing [%s]: %s\n", mis.c_str(), escape(*x, "?"));
|
||||
}
|
||||
|
||||
|
@ -221,6 +231,39 @@ int main() {
|
|||
for(int i=0; i<c; i++) printf("\"%s\",", vchars[i].c_str());
|
||||
printf("};\n");
|
||||
printf("//javastring = \"%s\";\n", javastring.c_str());
|
||||
|
||||
for(int i=1; i<NUMLAN; i++)
|
||||
for(map<string,string>::iterator it = d[i].m.begin(); it != d[i].m.end(); it++)
|
||||
s.insert(it->first);
|
||||
|
||||
printf("\n//statistics\n");
|
||||
for(map<string, string>::iterator it = d[1].m.begin(); it != d[1].m.end(); it++)
|
||||
d[0][it->first] = it->first;
|
||||
for(map<string, noun>::iterator it = nouns[1].m.begin(); it != nouns[1].m.end(); it++) {
|
||||
noun n = it->second;
|
||||
n.nom = n.nomp = n.acc = n.abl = it->first;
|
||||
nouns[0][it->first] = n;
|
||||
}
|
||||
|
||||
printf("// total: %5d nouns, %5d sentences\n", int(nouns[1].m.size()), int(d[1].m.size()));
|
||||
|
||||
for(int i=0; i<NUMLAN; i++) {
|
||||
int bnouns = 0;
|
||||
int dict = 0;
|
||||
|
||||
for(map<string, string>::iterator it = d[i].m.begin(); it != d[i].m.end(); it++)
|
||||
dict += it->second.size();
|
||||
for(map<string, noun>::iterator it = nouns[i].m.begin(); it != nouns[i].m.end(); it++) {
|
||||
noun& n = it->second;
|
||||
bnouns += n.nom.size();
|
||||
bnouns += n.nomp.size();
|
||||
bnouns += n.acc.size();
|
||||
bnouns += n.abl.size();
|
||||
}
|
||||
|
||||
printf("// %s: %5dB nouns, %5dB sentences\n",
|
||||
d[i]["EN"].c_str(), bnouns, dict);
|
||||
}
|
||||
|
||||
set<string> allsent;
|
||||
for(map<string, string>::iterator it = d[1].m.begin(); it != d[1].m.end(); it++)
|
||||
|
|
1277
language-cz.cpp
1277
language-cz.cpp
File diff suppressed because it is too large
Load Diff
2029
language-de.cpp
2029
language-de.cpp
File diff suppressed because it is too large
Load Diff
1306
language-pl.cpp
1306
language-pl.cpp
File diff suppressed because it is too large
Load Diff
1289
language-ru.cpp
1289
language-ru.cpp
File diff suppressed because it is too large
Load Diff
1296
language-tr.cpp
1296
language-tr.cpp
File diff suppressed because it is too large
Load Diff
109
language.cpp
109
language.cpp
|
@ -1,6 +1,6 @@
|
|||
// #define CHECKTRANS
|
||||
|
||||
#define NUMLAN 5
|
||||
#define NUMLAN 6
|
||||
|
||||
#define GEN_M 0
|
||||
#define GEN_F 1
|
||||
|
@ -17,10 +17,17 @@ struct stringpar {
|
|||
stringpar(eItem i) { v= iinf[i].name; }
|
||||
};
|
||||
|
||||
const char *dnameof(eMonster m) { return minf[m].name; }
|
||||
const char *dnameof(eLand l) { return linf[l].name; }
|
||||
const char *dnameof(eWall w) { return winf[w].name; }
|
||||
const char *dnameof(eItem i) { return iinf[i].name; }
|
||||
|
||||
void rep(string& pattern, string what, string to) {
|
||||
size_t at = pattern.find(what);
|
||||
if(at != string::npos)
|
||||
pattern = pattern.replace(at, what.size(), to);
|
||||
while(true) {
|
||||
size_t at = pattern.find(what);
|
||||
if(at == string::npos) break;
|
||||
pattern = pattern.replace(at, what.size(), to);
|
||||
}
|
||||
}
|
||||
|
||||
typedef unsigned hashcode;
|
||||
|
@ -84,13 +91,18 @@ string choose4(int g, string a, string b, string c, string d) {
|
|||
}
|
||||
|
||||
int playergender();
|
||||
int princessgender();
|
||||
int lang();
|
||||
|
||||
#include <set>
|
||||
set<string> warnshown;
|
||||
|
||||
void basicrep(string& x) {
|
||||
|
||||
const sentence *s = findInHashTable(x, all_sentences);
|
||||
if(!s) {
|
||||
if(!s && !warnshown.count(x)) {
|
||||
printf("WARNING: no translations for '%s'\n", x.c_str());
|
||||
warnshown.insert(x);
|
||||
}
|
||||
|
||||
int l = lang();
|
||||
|
@ -114,25 +126,6 @@ void basicrep(string& x) {
|
|||
void parrep(string& x, string w, stringpar p) {
|
||||
int l = lang();
|
||||
const fullnoun *N = findInHashTable(p.v, all_nouns);
|
||||
if(l == 0) {
|
||||
// proper names (R'Lyeh)
|
||||
if(N && (N->english_grammar_flags & 1)) {
|
||||
rep(x,"%"+w,p.v);
|
||||
rep(x,"%the"+w, p.v);
|
||||
rep(x,"%The"+w, p.v);
|
||||
}
|
||||
else {
|
||||
rep(x,"%"+w,p.v);
|
||||
rep(x,"%the"+w, "the " + p.v);
|
||||
rep(x,"%The"+w, "The " + p.v);
|
||||
}
|
||||
// plural names (Crossroads)
|
||||
if(N && (N->english_grammar_flags & 2))
|
||||
rep(x,"%s"+w, "");
|
||||
else
|
||||
rep(x,"%s"+w, "s");
|
||||
return;
|
||||
}
|
||||
if(l == 1) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[0].nom);
|
||||
|
@ -140,11 +133,13 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%a"+w, N->n[0].acc);
|
||||
rep(x, "%abl"+w, N->n[0].abl);
|
||||
rep(x, "%ł"+w, choose3(N->n[0].genus, "ł", "ła", "ło"));
|
||||
rep(x, "%łem"+w, choose3(N->n[0].genus, "łem", "łam", "łom"));
|
||||
rep(x, "%ął"+w, choose3(N->n[0].genus, "ął", "ęła", "ęło"));
|
||||
rep(x, "%ya"+w, choose3(N->n[0].genus, "y", "a", "e"));
|
||||
rep(x, "%yą"+w, choose4(N->n[0].genus, "ego", "ą", "e", "y"));
|
||||
rep(x, "%oa"+w, choose3(N->n[0].genus, "", "a", "o"));
|
||||
rep(x, "%ymą"+w, choose3(N->n[0].genus, "ym", "ą", "ym"));
|
||||
rep(x, "%go"+w, choose3(N->n[0].genus, "go", "ją", "je"));
|
||||
}
|
||||
else {
|
||||
rep(x,"%"+w, p.v);
|
||||
|
@ -154,7 +149,7 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%ł"+w, choose3(0, "ł", "ła", "ło"));
|
||||
}
|
||||
}
|
||||
if(lang() == 2) {
|
||||
if(l == 2) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[1].nom);
|
||||
rep(x, "%P"+w, N->n[1].nomp);
|
||||
|
@ -168,7 +163,7 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%abl"+w, p.v);
|
||||
}
|
||||
}
|
||||
if(lang() == 3) {
|
||||
if(l == 3) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[2].nom);
|
||||
rep(x, "%P"+w, N->n[2].nomp);
|
||||
|
@ -179,6 +174,8 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%el"+w, choose3(N->n[2].genus, "el", "la", "lo"));
|
||||
rep(x, "%ůj"+w, choose4(N->n[2].genus, "ého", "ou", "é", "ůj"));
|
||||
rep(x, "%ým"+w, choose3(N->n[2].genus, "ým", "ou", "ým"));
|
||||
rep(x, "%ho"+w, choose3(N->n[2].genus, "ho", "ji", "ho"));
|
||||
|
||||
if(p.v == "Mirror Image")
|
||||
rep(x, "%s"+w, "se");
|
||||
if(p.v == "Mirage")
|
||||
|
@ -191,7 +188,7 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%abl"+w, p.v);
|
||||
}
|
||||
}
|
||||
if(lang() == 4) {
|
||||
if(l == 4) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[3].nom);
|
||||
rep(x, "%P"+w, N->n[3].nomp);
|
||||
|
@ -199,6 +196,7 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%abl"+w, N->n[3].abl);
|
||||
rep(x, "%E"+w, choose3(N->n[3].genus, "", "а", "о"));
|
||||
rep(x, "%A"+w, choose3(N->n[3].genus, "ый", "ая", "ое"));
|
||||
rep(x, "%c"+w, choose3(N->n[3].genus, "ся", "ась", ""));
|
||||
}
|
||||
else {
|
||||
rep(x,"%"+w,p.v);
|
||||
|
@ -207,6 +205,46 @@ void parrep(string& x, string w, stringpar p) {
|
|||
rep(x, "%abl"+w, p.v);
|
||||
}
|
||||
}
|
||||
if(l == 5) {
|
||||
if(N) {
|
||||
rep(x, "%"+w, N->n[4].nom);
|
||||
rep(x, "%P"+w, N->n[4].nomp);
|
||||
rep(x, "%a"+w, N->n[4].acc);
|
||||
rep(x, "%abl"+w, N->n[4].abl);
|
||||
rep(x, "%Der"+w, choose3(N->n[4].genus, "Der", "Die", "Das"));
|
||||
rep(x, "%der"+w, choose3(N->n[4].genus, "der", "die", "das"));
|
||||
rep(x, "%den"+w, choose3(N->n[4].genus, "den", "die", "das"));
|
||||
}
|
||||
else {
|
||||
rep(x,"%"+w,p.v);
|
||||
rep(x, "%P"+w, p.v);
|
||||
rep(x, "%a"+w, p.v);
|
||||
rep(x, "%abl"+w, p.v);
|
||||
rep(x, "%Der"+w, "The");
|
||||
rep(x, "%der"+w, "the");
|
||||
rep(x, "%den"+w, "the");
|
||||
}
|
||||
}
|
||||
if(true) {
|
||||
// proper names (R'Lyeh)
|
||||
rep(x,"%"+w,p.v);
|
||||
if(N && (N->english_grammar_flags & 1)) {
|
||||
rep(x,"%the"+w, p.v);
|
||||
rep(x,"%The"+w, p.v);
|
||||
}
|
||||
else {
|
||||
rep(x,"%the"+w, "the " + p.v);
|
||||
rep(x,"%The"+w, "The " + p.v);
|
||||
rep(x,"%him"+w, princessgender() ? "her" : "him");
|
||||
rep(x,"%his"+w, princessgender() ? "her" : "his");
|
||||
}
|
||||
// plural names (Crossroads)
|
||||
if(N && (N->english_grammar_flags & 2))
|
||||
rep(x,"%s"+w, "");
|
||||
else
|
||||
rep(x,"%s"+w, "s");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void postrep(string& s) {
|
||||
|
@ -230,6 +268,23 @@ string XLAT(string x, stringpar p1, stringpar p2) {
|
|||
postrep(x);
|
||||
return x;
|
||||
}
|
||||
string XLAT(string x, stringpar p1, stringpar p2, stringpar p3) {
|
||||
basicrep(x);
|
||||
parrep(x,"1",p1.v);
|
||||
parrep(x,"2",p2.v);
|
||||
parrep(x,"3",p2.v);
|
||||
postrep(x);
|
||||
return x;
|
||||
}
|
||||
string XLAT(string x, stringpar p1, stringpar p2, stringpar p3, stringpar p4) {
|
||||
basicrep(x);
|
||||
parrep(x,"1",p1.v);
|
||||
parrep(x,"2",p2.v);
|
||||
parrep(x,"3",p2.v);
|
||||
parrep(x,"4",p2.v);
|
||||
postrep(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
string XLATN(string x) {
|
||||
if(lang()) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
|||
|
||||
|
||||
// mtrand.cpp, see include file mtrand.h for information
|
||||
|
||||
#include "mtrand.h"
|
||||
// non-inline function definitions and static member definitions cannot
|
||||
// reside in header file because of the risk of multiple declarations
|
||||
|
||||
// initialization of static private members
|
||||
unsigned long MTRand_int32::state[n] = {0x0UL};
|
||||
int MTRand_int32::p = 0;
|
||||
bool MTRand_int32::init = false;
|
||||
|
||||
void MTRand_int32::gen_state() { // generate new state vector
|
||||
for (int i = 0; i < (n - m); ++i)
|
||||
state[i] = state[i + m] ^ twiddle(state[i], state[i + 1]);
|
||||
for (int i = n - m; i < (n - 1); ++i)
|
||||
state[i] = state[i + m - n] ^ twiddle(state[i], state[i + 1]);
|
||||
state[n - 1] = state[m - 1] ^ twiddle(state[n - 1], state[0]);
|
||||
p = 0; // reset position
|
||||
}
|
||||
|
||||
void MTRand_int32::seed(unsigned long s) { // init by 32 bit seed
|
||||
state[0] = s & 0xFFFFFFFFUL; // for > 32 bit machines
|
||||
for (int i = 1; i < n; ++i) {
|
||||
state[i] = 1812433253UL * (state[i - 1] ^ (state[i - 1] >> 30)) + i;
|
||||
// see Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier
|
||||
// in the previous versions, MSBs of the seed affect only MSBs of the array state
|
||||
// 2002/01/09 modified by Makoto Matsumoto
|
||||
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
|
||||
}
|
||||
p = n; // force gen_state() to be called for next random number
|
||||
}
|
||||
|
||||
void MTRand_int32::seed(const unsigned long* array, int size) { // init by array
|
||||
seed(19650218UL);
|
||||
int i = 1, j = 0;
|
||||
for (int k = ((n > size) ? n : size); k; --k) {
|
||||
state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1664525UL))
|
||||
+ array[j] + j; // non linear
|
||||
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
|
||||
++j; j %= size;
|
||||
if ((++i) == n) { state[0] = state[n - 1]; i = 1; }
|
||||
}
|
||||
for (int k = n - 1; k; --k) {
|
||||
state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1566083941UL)) - i;
|
||||
state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines
|
||||
if ((++i) == n) { state[0] = state[n - 1]; i = 1; }
|
||||
}
|
||||
state[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array
|
||||
p = n; // force gen_state() to be called for next random number
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
|
||||
|
||||
// mtrand.h
|
||||
// C++ include file for MT19937, with initialization improved 2002/1/26.
|
||||
// Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
// Ported to C++ by Jasper Bedaux 2003/1/1 (see http://www.bedaux.net/mtrand/).
|
||||
// The generators returning floating point numbers are based on
|
||||
// a version by Isaku Wada, 2002/01/09
|
||||
//
|
||||
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The names of its contributors may not be used to endorse or promote
|
||||
// products derived from this software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Any feedback is very welcome.
|
||||
// http://www.math.keio.ac.jp/matumoto/emt.html
|
||||
// email: matumoto@math.keio.ac.jp
|
||||
//
|
||||
// Feedback about the C++ port should be sent to Jasper Bedaux,
|
||||
// see http://www.bedaux.net/mtrand/ for e-mail address and info.
|
||||
|
||||
#ifndef MTRAND_H
|
||||
#define MTRAND_H
|
||||
|
||||
class MTRand_int32 { // Mersenne Twister random number generator
|
||||
public:
|
||||
// default constructor: uses default seed only if this is the first instance
|
||||
MTRand_int32() { if (!init) seed(5489UL); init = true; }
|
||||
// constructor with 32 bit int as seed
|
||||
MTRand_int32(unsigned long s) { seed(s); init = true; }
|
||||
// constructor with array of size 32 bit ints as seed
|
||||
MTRand_int32(const unsigned long* array, int size) { seed(array, size); init = true; }
|
||||
// the two seed functions
|
||||
void seed(unsigned long); // seed with 32 bit integer
|
||||
void seed(const unsigned long*, int size); // seed with array
|
||||
// overload operator() to make this a generator (functor)
|
||||
unsigned long operator()() { return rand_int32(); }
|
||||
// 2007-02-11: made the destructor virtual; thanks "double more" for pointing this out
|
||||
virtual ~MTRand_int32() {} // destructor
|
||||
protected: // used by derived classes, otherwise not accessible; use the ()-operator
|
||||
unsigned long rand_int32(); // generate 32 bit random integer
|
||||
private:
|
||||
static const int n = 624, m = 397; // compile time constants
|
||||
// the variables below are static (no duplicates can exist)
|
||||
static unsigned long state[n]; // state vector array
|
||||
static int p; // position in state array
|
||||
static bool init; // true if init function is called
|
||||
// private functions used to generate the pseudo random numbers
|
||||
unsigned long twiddle(unsigned long, unsigned long); // used by gen_state()
|
||||
void gen_state(); // generate new state
|
||||
// make copy constructor and assignment operator unavailable, they don't make sense
|
||||
MTRand_int32(const MTRand_int32&); // copy constructor not defined
|
||||
void operator=(const MTRand_int32&); // assignment operator not defined
|
||||
};
|
||||
|
||||
// inline for speed, must therefore reside in header file
|
||||
inline unsigned long MTRand_int32::twiddle(unsigned long u, unsigned long v) {
|
||||
return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1)
|
||||
^ ((v & 1UL) * 0x9908B0DFUL);
|
||||
// 2013-07-22: line above modified for performance according to http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/Ierymenko.html
|
||||
// thanks Vitaliy FEOKTISTOV for pointing this out
|
||||
}
|
||||
|
||||
inline unsigned long MTRand_int32::rand_int32() { // generate 32 bit random int
|
||||
if (p == n) gen_state(); // new state vector needed
|
||||
// gen_state() is split off to be non-inline, because it is only called once
|
||||
// in every 624 calls and otherwise irand() would become too big to get inlined
|
||||
unsigned long x = state[p++];
|
||||
x ^= (x >> 11);
|
||||
x ^= (x << 7) & 0x9D2C5680UL;
|
||||
x ^= (x << 15) & 0xEFC60000UL;
|
||||
return x ^ (x >> 18);
|
||||
}
|
||||
|
||||
// generates double floating point numbers in the half-open interval [0, 1)
|
||||
class MTRand : public MTRand_int32 {
|
||||
public:
|
||||
MTRand() : MTRand_int32() {}
|
||||
MTRand(unsigned long seed) : MTRand_int32(seed) {}
|
||||
MTRand(const unsigned long* seed, int size) : MTRand_int32(seed, size) {}
|
||||
~MTRand() {}
|
||||
double operator()() {
|
||||
return static_cast<double>(rand_int32()) * (1. / 4294967296.); } // divided by 2^32
|
||||
private:
|
||||
MTRand(const MTRand&); // copy constructor not defined
|
||||
void operator=(const MTRand&); // assignment operator not defined
|
||||
};
|
||||
|
||||
// generates double floating point numbers in the closed interval [0, 1]
|
||||
class MTRand_closed : public MTRand_int32 {
|
||||
public:
|
||||
MTRand_closed() : MTRand_int32() {}
|
||||
MTRand_closed(unsigned long seed) : MTRand_int32(seed) {}
|
||||
MTRand_closed(const unsigned long* seed, int size) : MTRand_int32(seed, size) {}
|
||||
~MTRand_closed() {}
|
||||
double operator()() {
|
||||
return static_cast<double>(rand_int32()) * (1. / 4294967295.); } // divided by 2^32 - 1
|
||||
private:
|
||||
MTRand_closed(const MTRand_closed&); // copy constructor not defined
|
||||
void operator=(const MTRand_closed&); // assignment operator not defined
|
||||
};
|
||||
|
||||
// generates double floating point numbers in the open interval (0, 1)
|
||||
class MTRand_open : public MTRand_int32 {
|
||||
public:
|
||||
MTRand_open() : MTRand_int32() {}
|
||||
MTRand_open(unsigned long seed) : MTRand_int32(seed) {}
|
||||
MTRand_open(const unsigned long* seed, int size) : MTRand_int32(seed, size) {}
|
||||
~MTRand_open() {}
|
||||
double operator()() {
|
||||
return (static_cast<double>(rand_int32()) + .5) * (1. / 4294967296.); } // divided by 2^32
|
||||
private:
|
||||
MTRand_open(const MTRand_open&); // copy constructor not defined
|
||||
void operator=(const MTRand_open&); // assignment operator not defined
|
||||
};
|
||||
|
||||
// generates 53 bit resolution doubles in the half-open interval [0, 1)
|
||||
class MTRand53 : public MTRand_int32 {
|
||||
public:
|
||||
MTRand53() : MTRand_int32() {}
|
||||
MTRand53(unsigned long seed) : MTRand_int32(seed) {}
|
||||
MTRand53(const unsigned long* seed, int size) : MTRand_int32(seed, size) {}
|
||||
~MTRand53() {}
|
||||
double operator()() {
|
||||
return (static_cast<double>(rand_int32() >> 5) * 67108864. +
|
||||
static_cast<double>(rand_int32() >> 6)) * (1. / 9007199254740992.); }
|
||||
private:
|
||||
MTRand53(const MTRand53&); // copy constructor not defined
|
||||
void operator=(const MTRand53&); // assignment operator not defined
|
||||
};
|
||||
|
||||
#endif // MTRAND_H
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
void spill50(cell *c, eWall w, int r) {
|
||||
c->wall = w;
|
||||
if(r) for(int i=0; i<c->type; i++) spill50(createMov(c, i), w, r-1);
|
||||
}
|
||||
|
||||
int style = 3;
|
||||
|
||||
struct state50 {
|
||||
bool polarity1;
|
||||
bool polarity2;
|
||||
int color, color2, wc2;
|
||||
};
|
||||
|
||||
void progress(cell *c, state50 s);
|
||||
|
||||
#include <map>
|
||||
|
||||
map<cell*, state50> map50;
|
||||
|
||||
void initPatternFifty(cell *c) {
|
||||
state50 s;
|
||||
s.polarity1 = 0;
|
||||
s.polarity2 = 0;
|
||||
s.color = 0;
|
||||
s.color2 = 1;
|
||||
s.wc2 = 0;
|
||||
map50[c] = s;
|
||||
}
|
||||
|
||||
int par;
|
||||
|
||||
int haverule[1<<24][8];
|
||||
|
||||
void saveCode(heptagon *H1, int d, heptagon *H2) {
|
||||
|
||||
/*
|
||||
if(!H1 || !H2) return;
|
||||
if(H1->move[d] != H2) exit(1);
|
||||
|
||||
int h1 = H1->fiftyval;
|
||||
int h2 = H2->fiftyval;
|
||||
|
||||
if(!h1 || !h2) return;
|
||||
|
||||
if(haverule[h1][d] && haverule[h1][d] != h2) {
|
||||
printf("rule conflict: %06x, %d, %06x/%06x\n",
|
||||
h1, d, h2, haverule[h1][d]);
|
||||
// exit(1);
|
||||
}
|
||||
|
||||
if(!haverule[h1][d]) {
|
||||
haverule[h1][d] = h2;
|
||||
|
||||
printf("RULE50(0x%06x, %d, 0x%06x)\n", h1, d, h2);
|
||||
} */
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void saveCode(cell *c) {
|
||||
|
||||
/* heptagon *hept = c->master;
|
||||
|
||||
if(hept != &origin)
|
||||
saveCode(hept->move[0], hept->spin[0], hept); */
|
||||
|
||||
bool allcodes = c->master->fiftyval >= 0;
|
||||
|
||||
for(int i=0; i<7; i++)
|
||||
if(c->master->move[i] && c->master->move[i]->fiftyval >= 0) ;
|
||||
else allcodes = false;
|
||||
|
||||
if(allcodes) {
|
||||
printf("RULE50(0x%03x", c->master->fiftyval);
|
||||
int rulebase = 0;
|
||||
for(int i=0; i<7; i++)
|
||||
if(c->master->move[i]->fiftyval < c->master->move[rulebase]->fiftyval)
|
||||
rulebase = i;
|
||||
for(int i=0; i<7; i++) printf(", 0x%03x", c->master->move[(rulebase+i)%7]->fiftyval);
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
// hept->fiftyused = true;
|
||||
}
|
||||
|
||||
void encode(cell *c, state50 s, int mod, int spn) {
|
||||
/*int i = 0;
|
||||
i *= 16; i += s.color;
|
||||
i *= 16; i += s.color2;
|
||||
i *= 16; i += s.polarity1;
|
||||
i *= 16; i += s.polarity2;
|
||||
i *= 16; i += mod;
|
||||
i *= 16; i += spn;
|
||||
if(c->master->fiftyval) { printf("multiply 50val\n"); exit(1); }
|
||||
c->master->fiftyval = i; c->master->fiftyused = false; */
|
||||
|
||||
c->master->fiftyval =
|
||||
s.color + s.polarity1 * 8 + s.polarity2 * 16 + mod * 32;
|
||||
// s.color * 16 + (s.polarity1 ? 128 : 0) + (s.polarity2 ? 256 :0) + mod;
|
||||
|
||||
saveCode(c);
|
||||
for(int i=0; i<7; i++)
|
||||
saveCode(createStep(c->master, i)->c7);
|
||||
|
||||
/* for(int i=0; i<7; i++) if(c->master->move[i]) {
|
||||
saveCode(c->master, i, c->master->move[i]);
|
||||
saveCode(c->master->move[i], c->master->spin[i], c->master);
|
||||
} */
|
||||
}
|
||||
|
||||
eWall colorwalls[4] = {waCIsland, waCIsland2, waMineOpen, waDeadfloor };
|
||||
|
||||
void patternFiftyAt(cell *c) {
|
||||
if(!map50.count(c)) return;
|
||||
|
||||
state50 s = map50[c];
|
||||
|
||||
// c->wall = waCIsland;
|
||||
|
||||
// if(c->heat > ii) return;
|
||||
|
||||
// printf("pfifty %p\n", c);
|
||||
|
||||
if(style == 1 && s.polarity2) {
|
||||
spill50(c, waCamelot, 3);
|
||||
spill50(c, waNone, 2);
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cellwalker cw(c, i);
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
cwspin(cw, 4); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
cwspin(cw, 3); // 6
|
||||
cwstep(cw); cw.c->wall = waFloorA; cwstep(cw);
|
||||
cwspin(cw, 1);
|
||||
cwstep(cw); cw.c->wall = waFloorA; cwstep(cw);
|
||||
}
|
||||
}
|
||||
|
||||
/*switch(ii) {
|
||||
case 0:
|
||||
spill50(c, waNone, 3);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
spill50(c, waNone, 3);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
spill50(c, waNone, 3);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
spill50(c, waNone, 3);
|
||||
break;
|
||||
} */
|
||||
|
||||
if(style == 2) {
|
||||
spill50(c, waCavefloor, 2);
|
||||
spill50(c, waFloorA, 1);
|
||||
}
|
||||
|
||||
if(style == 3) {
|
||||
spill50(c, colorwalls[s.color], 3);
|
||||
// c->item = itGold;
|
||||
// if(s.polarity2) return;
|
||||
}
|
||||
|
||||
encode(c, s, 0, 0);
|
||||
|
||||
int sgn = s.polarity2 ? 1 : -1;
|
||||
int sgn1 = s.polarity1 ? 1 : -1;
|
||||
|
||||
int col2 = s.color2, sw = s.wc2;
|
||||
|
||||
while(col2 != 7-s.color) {
|
||||
sw += (s.polarity1?1:-1); sw %= 7;
|
||||
while(true) { col2++; col2 &= 7; if(col2 != s.color) break; }
|
||||
}
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cellwalker cw(c, sw);
|
||||
cwspin(cw, sgn1 * i);
|
||||
cwstep(cw);
|
||||
cwspin(cw, sgn*4);
|
||||
cwstep(cw);
|
||||
if(cw.spin < 0 || cw.spin >= 7 || cw.c->type != 7) exit(1);
|
||||
encode(cw.c, s, 1+i, cw.spin);
|
||||
}
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cellwalker cw(c, sw);
|
||||
cwspin(cw, sgn1 * i);
|
||||
cwstep(cw);
|
||||
cwspin(cw, 3);
|
||||
cwstep(cw);
|
||||
cwspin(cw, 3);
|
||||
cwstep(cw);
|
||||
if(cw.spin < 0 || cw.spin >= 7 || cw.c->type != 7) exit(1);
|
||||
encode(cw.c, s, 8+i, cw.spin);
|
||||
}
|
||||
|
||||
// c->heat = s.color +
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cellwalker cw(c, s.wc2);
|
||||
cwspin(cw, sgn1 * i);
|
||||
cwstep(cw);
|
||||
if(style == 0) cw.c->wall = waCamelot;
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, sgn*4); //6
|
||||
cwstep(cw); if(style == 0) cw.c->wall = waFloorA;
|
||||
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, sgn*4); //7
|
||||
cwstep(cw); if(style == 0) cw.c->wall = waFloorA;
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, 3); //6
|
||||
cwstep(cw); if(style == 0) cw.c->wall = waFloorA;
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, 3); //6
|
||||
cwstep(cw); if(style == 0) cw.c->wall = waFloorA;
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, sgn*3); //7
|
||||
cwstep(cw); if(style == 0) cw.c->wall = waCamelot;
|
||||
// cw.c->item = itSilver;
|
||||
cwspin(cw, sgn*2); //6
|
||||
cwstep(cw); // cw.c->item = itGold;
|
||||
// setdist(cw.c, 8, NULL);
|
||||
state50 s2 = s; s2.polarity1 = !s.polarity1;
|
||||
s2.wc2 = (cw.spin + sgn1 * i + sgn + 42) % 7;
|
||||
progress(cw.c, s2);
|
||||
// printf("heat set %f\n", cw.c->heat);
|
||||
}
|
||||
|
||||
int newcol = s.color2;
|
||||
|
||||
// if(s.polarity2) return;
|
||||
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cellwalker cw(c, s.wc2);
|
||||
cwspin(cw, sgn1 * i);
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, 3); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, sgn*4); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, sgn*2); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, 3); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, sgn*3); // 7
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// cw.c->item = itDiamond;
|
||||
cwspin(cw, sgn*4); // 6
|
||||
cwstep(cw); // cw.c->item = itSilver;
|
||||
// setdist(cw.c, 8, NULL);
|
||||
state50 s2 = s;
|
||||
s2.polarity2 = !s.polarity2;
|
||||
if(s.polarity2) s2.polarity1 = !s.polarity1;
|
||||
s2.color2 = s2.color;
|
||||
s2.color = newcol;
|
||||
s2.wc2 = cw.spin;
|
||||
progress(cw.c, s2);
|
||||
while(true) { newcol++; newcol &= 7; if(newcol != s2.color && newcol != s.color) break; }
|
||||
// printf("heat set %f\n", cw.c->heat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void progress(cell *c, state50 s) {
|
||||
|
||||
while(s.wc2) {
|
||||
s.wc2 += (s.polarity1?1:-1); s.wc2 %= 7;
|
||||
while(true) { s.color2++; s.color2 &= 7; if(s.color2 != s.color) break; }
|
||||
}
|
||||
|
||||
if(map50.count(c)) {
|
||||
state50 s2 = map50[c];
|
||||
if(s2.polarity1 != s.polarity1 || s2.polarity2 != s.polarity2) {
|
||||
printf("Polarity mismatch!\n");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
if(s2.color != s.color || s2.color2 != s.color2 || s2.wc2 != s.wc2)
|
||||
printf("%d:%d color= %dv%d color2= %dv%d wc2= %dv%d\n",
|
||||
s.polarity1, s.polarity2,
|
||||
s.color, s2.color,
|
||||
s.color2, s2.color2,
|
||||
s.wc2, s2.wc2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
map50[c] = s;
|
||||
if(c->mpdist <= 7)
|
||||
patternFiftyAt(c);
|
||||
}
|
||||
|
||||
long long Q; int qconflict;
|
||||
|
||||
string allconflict;
|
||||
|
||||
void setzebra(cellwalker cwb, int it, int type, string pathcode, int xmods) {
|
||||
// printf("spin=%d type=%d\n", cwb.spin, type);
|
||||
|
||||
if(cwb.spin != 1 && cwb.spin != 3 && cwb.spin != 5) {
|
||||
printf("S WRONG SPIN %d\n", cwb.spin);
|
||||
exit(1);
|
||||
}
|
||||
if(type < 0 || type > 3) {
|
||||
printf("S WRONG TYPE %d\n", type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cwb.c->tmp = cwb.spin + 16 * type;
|
||||
}
|
||||
|
||||
void zebra(cellwalker cwb, int it, int type, string pathcode, int xmods) {
|
||||
if(!it) return;
|
||||
if(cwb.spin != 1 && cwb.spin != 3 && cwb.spin != 5) {
|
||||
printf("WRONG SPIN %d\n", cwb.spin);
|
||||
exit(1);
|
||||
}
|
||||
if(type < 0 || type > 3) {
|
||||
printf("WRONG TYPE %d\n", type);
|
||||
exit(1);
|
||||
}
|
||||
// printf("%p+%d = 0%s\n", cwb.c, cwb.spin, pathcode.c_str());
|
||||
bool redraw = false;
|
||||
// int qval = Q + 99;
|
||||
// redraw = cwb.c->heat == qval;
|
||||
// cwb.c->heat = qval;
|
||||
eWall w = colorwalls[type];
|
||||
cwb.c->wall = w;
|
||||
for(int i=0; i<6; i+=2) {
|
||||
cellwalker cw = cwb;
|
||||
cwspin(cw, i);
|
||||
cw.c->heat = 4 + type + 4 * 9;
|
||||
cwstep(cw); cwspin(cw, 3); cw.c->wall = w;
|
||||
int i0 = i; if(type&2 && i0) i0 = 6-i0; i0 /= 2;
|
||||
cw.c->heat = 4 + type + 4 * (3+i0);
|
||||
cwstep(cw); cwspin(cw, 3); cw.c->wall = w;
|
||||
cw.c->heat = 4 + type + 4 * i0;
|
||||
cwstep(cw); cwspin(cw, 3); cw.c->wall = w;
|
||||
cw.c->heat = 4 + type + 4 * (6+i0);
|
||||
cwstep(cw); cwspin(cw, -3);
|
||||
cwstep(cw); cwspin(cw, -3);
|
||||
cwstep(cw); cwspin(cw, -3);
|
||||
cwstep(cw); cwspin(cw, -i);
|
||||
cwspin(cw, 0);
|
||||
setzebra(cw, it-1, type ^ 1, pathcode +'+'+char('A'+i)+char('0'+type), xmods*2);
|
||||
}
|
||||
|
||||
for(int i=0; i<6; i+=2) {
|
||||
cellwalker cw = cwb;
|
||||
cwspin(cw, (type&2)?-i:i);
|
||||
cwstep(cw); cwspin(cw, 3);
|
||||
cwstep(cw); cwspin(cw, 5);
|
||||
if(xmods < 2) {
|
||||
if(cw.c->item && cw.c->item != (1+i) && redraw && i==0) {
|
||||
qconflict++;
|
||||
// allconflict += pathcode; allconflict += "-";
|
||||
// cwb.c->item = itPalace;
|
||||
// printf("Conflict at %p\n", cwb.c);
|
||||
}
|
||||
// cw.c->item = eItem(1 + i);
|
||||
// cw.c->heat = 4 + type + 4 * (i/2);
|
||||
}
|
||||
cwstep(cw); cwspin(cw, 1);
|
||||
if(type < 2) {
|
||||
// cwspin(cw, i);
|
||||
cwspin(cw, i);
|
||||
}
|
||||
else {
|
||||
cwspin(cw, -i);
|
||||
}
|
||||
// cwspin(cw, ((Q >> (4*type)) & 12));
|
||||
setzebra(cw, it-1, 2^type, pathcode + '+'+char('a'+i)+char('0'+type), xmods+1);
|
||||
}
|
||||
}
|
||||
|
||||
void zebraPattern() {
|
||||
// int bqc = 99;
|
||||
|
||||
/* for(Q=0; Q<65536; Q++) {
|
||||
if((Q & (Q>>1)) & 0x5555) continue;
|
||||
qconflict = false;
|
||||
cellwalker cw(cwt);
|
||||
cwstep(cw); cwspin(cw, 1);
|
||||
qconflict = 0;
|
||||
allconflict = "";
|
||||
zebra(cw, 3, 0, "");
|
||||
if(qconflict < bqc) bqc = qconflict;
|
||||
// if(qconflict == bqc)
|
||||
printf("%X - X-%sX\n", Q, allconflict.c_str());
|
||||
}
|
||||
|
||||
Q = 0xFFFB; */
|
||||
|
||||
cellwalker cw(cwt);
|
||||
cwstep(cw); cwspin(cw, 1);
|
||||
setzebra(cw, 7, 0, "", -999);
|
||||
// cw.c->
|
||||
// printf("Conflicts: %d\n", qconflict);
|
||||
}
|
||||
|
||||
int bspin(heptagon *h) {
|
||||
vector<int> xv;
|
||||
xv.push_back(999);
|
||||
int besti = -1;
|
||||
for(int i=0; i<7; i++) {
|
||||
vector<int> yv;
|
||||
for(int j=0; j<7; j++) yv.push_back(int(h->move[(i+j)%7]->c7->heat+.1));
|
||||
if(yv < xv) xv = yv, besti = i;
|
||||
}
|
||||
return besti;
|
||||
}
|
||||
|
||||
void buildAutomatonRule(heptagon *h) {
|
||||
if(!h->c7->heat) return;
|
||||
for(int i=0; i<7; i++) if(!h->move[i]) return;
|
||||
for(int i=0; i<7; i++) for(int j=0; j<7; j++)
|
||||
if(!h->move[i]->move[j] || !h->move[i]->move[j]->c7->heat)
|
||||
return;
|
||||
int bi = bspin(h);
|
||||
printf("RULEZEBRA(%2d", int(h->c7->heat+.1));
|
||||
for(int j=0; j<7; j++) {
|
||||
heptagon *h2 = h->move[(bi+j)%7];
|
||||
int bi2 = bspin(h2);
|
||||
printf(", %2d%d", int(h2->c7->heat+.1), fix7(bi2 - h->spin[(bi+j)%7]));
|
||||
}
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
void buildAutomatonRule(cell *c) {
|
||||
if(c->type == 7)
|
||||
buildAutomatonRule(c->master);
|
||||
else {
|
||||
int ii[3];
|
||||
for(int i=0; i<6; i+=2) if(!c->mov[i] || !c->mov[i]->heat || c->mov[i]->type != 7) return;
|
||||
for(int i=0; i<6; i+=2) ii[i/2] = int(c->mov[i]->heat);
|
||||
int z;
|
||||
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;
|
||||
printf("RULEZEBRA6(%d,%d,%d,%d)\n", int(c->heat), int(ii[0]), int(ii[1]), int(ii[2]));
|
||||
}
|
||||
}
|
||||
|
||||
// #define BUILDZEBRA
|
File diff suppressed because it is too large
Load Diff
2213
polygons.cpp
2213
polygons.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue