mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
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
143
direntx.h
Normal file
143
direntx.h
Normal file
@ -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;
|
||||
}
|
||||
|
260
hyper.h
Normal file
260
hyper.h
Normal file
@ -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()) {
|
||||
|
1570
mapeditor.cpp
Normal file
1570
mapeditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
53
mtrand.cpp
Normal file
53
mtrand.cpp
Normal file
@ -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
|
||||
}
|
||||
|
158
mtrand.h
Normal file
158
mtrand.h
Normal file
@ -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
|
||||
|
455
patterngen.cpp
Normal file
455
patterngen.cpp
Normal file
@ -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
|
1053
patterns.cpp
Normal file
1053
patterns.cpp
Normal file
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
Block a user