Updated HyperRogue sources to 7.4f.

This commit is contained in:
Zeno Rogue 2016-01-02 11:09:13 +01:00
parent 721461a5c5
commit 19055633b0
24 changed files with 24025 additions and 4041 deletions

View File

@ -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
View File

@ -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;
}

File diff suppressed because it is too large Load Diff

143
direntx.h Normal file
View 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_ */

8077
game.cpp

File diff suppressed because it is too large Load Diff

3455
graph.cpp

File diff suppressed because it is too large Load Diff

View File

@ -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
View File

@ -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
View 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);

View File

@ -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);

View File

@ -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++)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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", "", "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

File diff suppressed because it is too large Load Diff

53
mtrand.cpp Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1912
shmup.cpp Normal file

File diff suppressed because it is too large Load Diff