mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-24 13:27:17 +00:00
commit
d0c231b057
@ -9,7 +9,7 @@ namespace hr {
|
|||||||
bool doAutoplay;
|
bool doAutoplay;
|
||||||
eLand autoplayLand;
|
eLand autoplayLand;
|
||||||
|
|
||||||
namespace prairie { extern long long enter; }
|
namespace prairie { extern cell *enter; }
|
||||||
|
|
||||||
bool sameland(eLand ll, eLand ln) {
|
bool sameland(eLand ll, eLand ln) {
|
||||||
if(ln == laBarrier || ln == laOceanWall)
|
if(ln == laBarrier || ln == laOceanWall)
|
||||||
@ -20,6 +20,111 @@ bool sameland(eLand ll, eLand ln) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void randomCheat() {
|
||||||
|
int croll = hrand(50);
|
||||||
|
if (croll < 25) {
|
||||||
|
eItem b = (eItem) hrand(ittypes);
|
||||||
|
printf("Gain item: %s\n", iinf[b].name);
|
||||||
|
items[b] = (1 << hrand(11)) - 1;
|
||||||
|
items[itOrbYendor] &= 15;
|
||||||
|
reduceOrbPowers(); // in particlar, cancel out slaying+weakness, since the combination may confuse shadow
|
||||||
|
} else if (croll == 25) {
|
||||||
|
printf("Gain kills\n");
|
||||||
|
kills[hrand(motypes)] = (1 << hrand(11)) - 1;
|
||||||
|
} else if (croll == 26) {
|
||||||
|
printf("Princess soon\n");
|
||||||
|
princess::saved = true;
|
||||||
|
princess::everSaved = true;
|
||||||
|
items[itSavedPrincess]++;
|
||||||
|
items[itOrbLove] = 1;
|
||||||
|
items[itOrbTime] = 0;
|
||||||
|
} else if (croll == 27) {
|
||||||
|
printf("Gain allies\n");
|
||||||
|
forCellEx(cz, cwt.at)
|
||||||
|
if (!cz->monst)
|
||||||
|
cz->monst = pick(moMouse, moFriendlyGhost, moGolem, moTameBomberbird, moKnight);
|
||||||
|
} else if (croll == 28) {
|
||||||
|
printf("Place orbs with pickup effects\n");
|
||||||
|
forCellEx(cz, cwt.at)
|
||||||
|
if (!cz->item)
|
||||||
|
cz->item = pick(itOrbLife, itOrbFriend, itOrbSpeed, itOrbShield, itOrbChaos, itOrbPurity);
|
||||||
|
} else if (croll == 29) {
|
||||||
|
printf("Place fun walls\n");
|
||||||
|
forCellEx(cz, cwt.at)
|
||||||
|
if (!cz->wall && !cz->monst)
|
||||||
|
cz->wall = pick(waExplosiveBarrel, waBigStatue, waThumperOff, waBonfireOff, waCloud, waMirror);
|
||||||
|
} else if (croll == 30) {
|
||||||
|
cell *ct = dcal[hrand(isize(dcal))];
|
||||||
|
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
||||||
|
eWall hazard = pick(waRose, waFireTrap, waMineMine, waTrapdoor, waChasm, waCavewall);
|
||||||
|
printf("Spam a hazard: %s\n", winf[hazard].name);
|
||||||
|
ct->wall = hazard;
|
||||||
|
}
|
||||||
|
} else if (croll == 31 && !memory_saving_mode) {
|
||||||
|
//printf("Saving memory\n");
|
||||||
|
//memory_saving_mode = true;
|
||||||
|
//save_memory();
|
||||||
|
//memory_saving_mode = false;
|
||||||
|
} else if (croll == 33) {
|
||||||
|
cell *ct = dcal[hrand(isize(dcal))];
|
||||||
|
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
||||||
|
printf("Spam some slime\n");
|
||||||
|
ct->item = itNone;
|
||||||
|
ct->wall = hrand(2) ? waFloorA : waFloorB;
|
||||||
|
switch(hrand(4)) {
|
||||||
|
case 0: ct->monst = moSlime; break;
|
||||||
|
case 1: ct->item = itGreenStone; break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (croll == 37) {
|
||||||
|
cell *ct = dcal[hrand(isize(dcal))];
|
||||||
|
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
||||||
|
ct->monst = pick(moRagingBull, moTroll, moAcidBird, moMiner, moReptile, moVineBeast, moBug0, moBug1);
|
||||||
|
printf("Spam a monster: %s\n", minf[ct->monst].name);
|
||||||
|
}
|
||||||
|
// todo: dice
|
||||||
|
} else if (croll == 38) {
|
||||||
|
forCellEx(cz, cwt.at) {
|
||||||
|
if (cz->monst == moPrincessArmed) {
|
||||||
|
printf("Disarming a princess\n");
|
||||||
|
cz->monst = moPrincess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (croll == 39) {
|
||||||
|
//forCellEx(cz, cwt.at) {
|
||||||
|
// if (!cz->monst) {
|
||||||
|
// printf("Summoning an unarmed princess incorrectly\n");
|
||||||
|
// cz->monst = moPrincess;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
} else if (croll == 40) {
|
||||||
|
//forCellEx(cz, cwt.at) {
|
||||||
|
// if (!cz->monst) {
|
||||||
|
// printf("Summoning an armed princess incorrectly\n");
|
||||||
|
// cz->monst = moPrincessArmed;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
} else if (croll == 41) {
|
||||||
|
cell *ct = dcal[hrand(isize(dcal))];
|
||||||
|
if (among(ct->wall, waNone, waVinePlant, waFloorA, waFloorB, waTrapdoor, waChasm, waBigStatue)) {
|
||||||
|
// Set wparam on a cell where it shouldn't matter, so that if this wall is later converted
|
||||||
|
// to a walltype that does care by some code that assumes wparam was 0,
|
||||||
|
// we can find out if that causes bugs.
|
||||||
|
printf("Randomizing wparam on %s at %p\n", winf[ct->wall].name, (void *)ct);
|
||||||
|
ct->wparam = (unsigned char) hrand(256);
|
||||||
|
}
|
||||||
|
} else if (croll == 42) {
|
||||||
|
vid.wallmode = hrand(7);
|
||||||
|
printf("Set vid.wallmode to %d: %s\n", vid.wallmode, wdmodes[vid.wallmode]);
|
||||||
|
} else if (croll == 43) {
|
||||||
|
vid.monmode = hrand(4);
|
||||||
|
printf("Set vid.monmode to %d: %s\n", vid.monmode, mdmodes[vid.monmode]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cell *cellToTarget() {
|
cell *cellToTarget() {
|
||||||
if (isCrossroads(cwt.at->land)) {
|
if (isCrossroads(cwt.at->land)) {
|
||||||
for (cell *c: dcal) {
|
for (cell *c: dcal) {
|
||||||
@ -50,6 +155,175 @@ cell *cellToTarget() {
|
|||||||
return dcal[hrand(isize(dcal))];
|
return dcal[hrand(isize(dcal))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void randomMove()
|
||||||
|
{
|
||||||
|
// don't show warning dialogs
|
||||||
|
items[itWarning] = 1;
|
||||||
|
|
||||||
|
int roll = hrand(50);
|
||||||
|
if (roll == 0) {
|
||||||
|
// drop dead orb
|
||||||
|
bool res = movepcto(MD_DROP, 1);
|
||||||
|
printf("DROP: %d\n", res);
|
||||||
|
} else if (roll < 5) {
|
||||||
|
// skip turn
|
||||||
|
bool res = movepcto(MD_WAIT, 1);
|
||||||
|
printf("WAIT: %d\n", res);
|
||||||
|
} else if (roll < 42) {
|
||||||
|
// move to or attack a neighbor cell
|
||||||
|
int i = hrand(cwt.at->type);
|
||||||
|
cell *c2 = cwt.at->move(i);
|
||||||
|
cwt.spin = 0;
|
||||||
|
int d = neighborId(cwt.at, c2);
|
||||||
|
if (d >= 0) {
|
||||||
|
int subdir = (roll%2==0)?1:-1;
|
||||||
|
string c2info = dnameof(c2->wall) + "; " + dnameof(c2->monst) + "; " + dnameof(c2->item);
|
||||||
|
bool res = movepcto(d, subdir, false);
|
||||||
|
printf("MOVE %d [%s] sub %d: %d\n", d, c2info.c_str(), subdir, res);
|
||||||
|
if (!res && c2->monst) {
|
||||||
|
printf("clearing the monster (%s)\n", minf[c2->monst].name);
|
||||||
|
killMonster(c2, moNone);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("MOVE CONFUSED %d\n", d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try to use a ranged orb
|
||||||
|
cell *ct = cellToTarget();
|
||||||
|
eItem ti = targetRangedOrb(ct, roMouseForce);
|
||||||
|
const char *tm = (ti == eItem(-1)) ? "orb cannot be used (see message log)" : iinf[ti].name;
|
||||||
|
printf("TARGET %p: %s\n", (void*)ct, tm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void noteUnusualSituations()
|
||||||
|
{
|
||||||
|
if(cwt.at->monst && !isMultitile(cwt.at->monst)) {
|
||||||
|
// This is possible in multiple ways
|
||||||
|
printf("on a non-multitile monster: %s\n", minf[cwt.at->monst].name);
|
||||||
|
}
|
||||||
|
else if(isDie(cwt.at->wall)) {
|
||||||
|
// This is possible with aether + teleport
|
||||||
|
printf("on a wall-type die: %s\n", winf[cwt.at->wall].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAnythingWrong()
|
||||||
|
{
|
||||||
|
uintptr_t ienter = (uintptr_t) prairie::enter;
|
||||||
|
if(ienter && ienter < 100000) {
|
||||||
|
printf("ERROR: prairie::enter has incorrect value\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buggyGeneration || isize(buggycells)) {
|
||||||
|
println(hlog, "ERROR: buggy generation");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isIcyLand(cwt.at)) {
|
||||||
|
float heat = HEAT(cwt.at);
|
||||||
|
// Checking for extreme values as well as NaNs and infinities
|
||||||
|
if (!(-1e10 < heat && heat < 1e10)) {
|
||||||
|
printf("ERROR: Heat is out of expected range\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cwt.at->land == laCamelot) {
|
||||||
|
for(int i=0; i<isize(dcal); i++) {
|
||||||
|
cell *c = dcal[i];
|
||||||
|
if(c->land == laCamelot && celldistAltRelative(c) == 0 && c->wall != waRoundTable) {
|
||||||
|
printf("ERROR: The round table of camelot is interrupted by a cell of %s\n", winf[c->wall].name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<isize(dcal); i++) {
|
||||||
|
cell *c = dcal[i];
|
||||||
|
(void)isChild(c, NULL);
|
||||||
|
if(childbug) return true;
|
||||||
|
if(c->land == laNone) {
|
||||||
|
printf("ERROR: no-land found\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(c->item == itBuggy || c->item == itBuggy2) {
|
||||||
|
printf("ERROR: buggy item found\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!euclid && isPrincess(c->monst) && princess::getPrincessInfo(c) == nullptr) {
|
||||||
|
printf("ERROR: missing princess info\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(dice::on(c)) {
|
||||||
|
if(dice::data.count(c) == 0) {
|
||||||
|
c->item = itBuggy;
|
||||||
|
printf("ERROR: missing dice::data[%p]\n", (void *)c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(!dice::data[c].which) {
|
||||||
|
// we might get here instead if someone already tried to do data[c], which creates a new element out of nothing
|
||||||
|
c->item = itBuggy;
|
||||||
|
printf("ERROR: missing dice::data[%p].which\n", (void *)c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopIfBug()
|
||||||
|
{
|
||||||
|
if(isAnythingWrong()) {
|
||||||
|
if(noGUI) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kills[moPlayer] = 0;
|
||||||
|
canmove = true;
|
||||||
|
doAutoplay = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showAutoplayStats()
|
||||||
|
{
|
||||||
|
printf("cells travelled: %d\n", celldist(cwt.at));
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for(int i=0; i<ittypes; i++) if(items[i])
|
||||||
|
printf("%4dx %s\n", items[i], iinf[i].name);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for(int i=1; i<motypes; i++) if(kills[i])
|
||||||
|
printf("%4dx %s <%d>\n", kills[i], minf[i].name, i);
|
||||||
|
|
||||||
|
printf("\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetIfNeeded(int *gcount)
|
||||||
|
{
|
||||||
|
if(hrand(5000) == 0 || (isGravityLand(cwt.at->land) && coastvalEdge(cwt.at) >= 100) || *gcount > 2000 || cellcount >= 20000000) {
|
||||||
|
printf("RESET\n");
|
||||||
|
*gcount = 0;
|
||||||
|
cellcount = 0;
|
||||||
|
activateSafety(autoplayLand ? autoplayLand : landlist[hrand(isize(landlist))]);
|
||||||
|
if (cellcount < 0) {
|
||||||
|
//printf("How did cellcount become negative?\n");
|
||||||
|
cellcount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cwt.at->land == laWestWall && cwt.at->landparam >= 30) {
|
||||||
|
printf("Safety generated\n");
|
||||||
|
forCellEx(c2, cwt.at) c2->item = itOrbSafety;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
|
/* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
|
||||||
eLand l2;
|
eLand l2;
|
||||||
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
|
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
|
||||||
@ -77,13 +351,7 @@ void autoplay(int num_moves = 1000000000) {
|
|||||||
int lastdraw = 0;
|
int lastdraw = 0;
|
||||||
#endif
|
#endif
|
||||||
while(doAutoplay) {
|
while(doAutoplay) {
|
||||||
|
|
||||||
long long ienter = (long long) prairie::enter;
|
|
||||||
if(ienter && ienter < 100000) {
|
|
||||||
printf("ERROR: enter has incorrect value\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gold() > lastgold) {
|
if(gold() > lastgold) {
|
||||||
lastgold = gold();
|
lastgold = gold();
|
||||||
gcount = 0;
|
gcount = 0;
|
||||||
@ -114,261 +382,12 @@ void autoplay(int num_moves = 1000000000) {
|
|||||||
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
|
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
// Use a random cheat
|
randomCheat();
|
||||||
int croll = hrand(50);
|
randomMove();
|
||||||
if (croll < 25) {
|
if(false) if(turncount % 5000 == 0) showAutoplayStats();
|
||||||
eItem b = (eItem) hrand(ittypes);
|
resetIfNeeded(&gcount);
|
||||||
printf("Gain item: %s\n", iinf[b].name);
|
noteUnusualSituations();
|
||||||
items[b] = (1 << hrand(11)) - 1;
|
stopIfBug();
|
||||||
items[itOrbYendor] &= 15;
|
|
||||||
reduceOrbPowers(); // in particlar, cancel out slaying+weakness, since the combination may confuse shadow
|
|
||||||
} else if (croll == 25) {
|
|
||||||
printf("Gain kills\n");
|
|
||||||
kills[hrand(motypes)] = (1 << hrand(11)) - 1;
|
|
||||||
} else if (croll == 26) {
|
|
||||||
printf("Princess soon\n");
|
|
||||||
princess::saved = true;
|
|
||||||
princess::everSaved = true;
|
|
||||||
items[itSavedPrincess]++;
|
|
||||||
items[itOrbLove] = 1;
|
|
||||||
items[itOrbTime] = 0;
|
|
||||||
} else if (croll == 27) {
|
|
||||||
printf("Gain allies\n");
|
|
||||||
forCellEx(cz, cwt.at)
|
|
||||||
if (!cz->monst)
|
|
||||||
cz->monst = pick(moMouse, moFriendlyGhost, moGolem, moTameBomberbird, moKnight);
|
|
||||||
} else if (croll == 28) {
|
|
||||||
printf("Place orbs with pickup effects\n");
|
|
||||||
forCellEx(cz, cwt.at)
|
|
||||||
if (!cz->item)
|
|
||||||
cz->item = pick(itOrbLife, itOrbFriend, itOrbSpeed, itOrbShield, itOrbChaos, itOrbPurity);
|
|
||||||
} else if (croll == 29) {
|
|
||||||
printf("Place fun walls\n");
|
|
||||||
forCellEx(cz, cwt.at)
|
|
||||||
if (!cz->wall && !cz->monst)
|
|
||||||
cz->wall = pick(waExplosiveBarrel, waBigStatue, waThumperOff, waBonfireOff, waCloud, waMirror);
|
|
||||||
} else if (croll == 30) {
|
|
||||||
cell *ct = dcal[hrand(isize(dcal))];
|
|
||||||
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
|
||||||
eWall hazard = pick(waRose, waFireTrap, waMineMine, waTrapdoor, waChasm, waCavewall);
|
|
||||||
printf("Spam a hazard: %s\n", winf[hazard].name);
|
|
||||||
ct->wall = hazard;
|
|
||||||
}
|
|
||||||
} else if (croll == 31 && !memory_saving_mode) {
|
|
||||||
//printf("Saving memory\n");
|
|
||||||
//memory_saving_mode = true;
|
|
||||||
//save_memory();
|
|
||||||
//memory_saving_mode = false;
|
|
||||||
} else if (croll == 33) {
|
|
||||||
cell *ct = dcal[hrand(isize(dcal))];
|
|
||||||
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
|
||||||
printf("Spam some slime\n");
|
|
||||||
ct->item = itNone;
|
|
||||||
ct->wall = hrand(2) ? waFloorA : waFloorB;
|
|
||||||
switch(hrand(4)) {
|
|
||||||
case 0: ct->monst = moSlime; break;
|
|
||||||
case 1: ct->item = itGreenStone; break;
|
|
||||||
default: ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (croll == 37) {
|
|
||||||
cell *ct = dcal[hrand(isize(dcal))];
|
|
||||||
if (!isPlayerOn(ct) && !ct->monst && !ct->wall) {
|
|
||||||
ct->monst = pick(moRagingBull, moTroll, moAcidBird, moMiner, moReptile, moVineBeast, moBug0, moBug1);
|
|
||||||
printf("Spam a monster: %s\n", minf[ct->monst].name);
|
|
||||||
}
|
|
||||||
// todo: dice
|
|
||||||
} else if (croll == 38) {
|
|
||||||
forCellEx(cz, cwt.at) {
|
|
||||||
if (cz->monst == moPrincessArmed) {
|
|
||||||
printf("Disarming a princess\n");
|
|
||||||
cz->monst = moPrincess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (croll == 39) {
|
|
||||||
//forCellEx(cz, cwt.at) {
|
|
||||||
// if (!cz->monst) {
|
|
||||||
// printf("Summoning an unarmed princess incorrectly\n");
|
|
||||||
// cz->monst = moPrincess;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
} else if (croll == 40) {
|
|
||||||
//forCellEx(cz, cwt.at) {
|
|
||||||
// if (!cz->monst) {
|
|
||||||
// printf("Summoning an armed princess incorrectly\n");
|
|
||||||
// cz->monst = moPrincessArmed;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
} else if (croll == 41) {
|
|
||||||
cell *ct = dcal[hrand(isize(dcal))];
|
|
||||||
if (among(ct->wall, waNone, waVinePlant, waFloorA, waFloorB, waTrapdoor, waChasm, waBigStatue)) {
|
|
||||||
// Set wparam on a cell where it shouldn't matter, so that if this wall is later converted
|
|
||||||
// to a walltype that does care by some code that assumes wparam was 0,
|
|
||||||
// we can find out if that causes bugs.
|
|
||||||
printf("Randomizing wparam on %s at %p\n", winf[ct->wall].name, (void *)ct);
|
|
||||||
ct->wparam = (unsigned char) hrand(256);
|
|
||||||
}
|
|
||||||
} else if (croll == 42) {
|
|
||||||
vid.wallmode = hrand(7);
|
|
||||||
printf("Set vid.wallmode to %d: %s\n", vid.wallmode, wdmodes[vid.wallmode]);
|
|
||||||
} else if (croll == 43) {
|
|
||||||
vid.monmode = hrand(4);
|
|
||||||
printf("Set vid.monmode to %d: %s\n", vid.monmode, mdmodes[vid.monmode]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't show warning dialogs
|
|
||||||
items[itWarning] = 1;
|
|
||||||
|
|
||||||
// Make a random move
|
|
||||||
int roll = hrand(50);
|
|
||||||
if (roll == 0) {
|
|
||||||
// drop dead orb
|
|
||||||
bool res = movepcto(MD_DROP, 1);
|
|
||||||
printf("DROP: %d\n", res);
|
|
||||||
} else if (roll < 5) {
|
|
||||||
// skip turn
|
|
||||||
bool res = movepcto(MD_WAIT, 1);
|
|
||||||
printf("WAIT: %d\n", res);
|
|
||||||
} else if (roll < 42) {
|
|
||||||
// move to or attack a neighbor cell
|
|
||||||
int i = hrand(cwt.at->type);
|
|
||||||
cell *c2 = cwt.at->move(i);
|
|
||||||
cwt.spin = 0;
|
|
||||||
int d = neighborId(cwt.at, c2);
|
|
||||||
if (d >= 0) {
|
|
||||||
int subdir = (roll%2==0)?1:-1;
|
|
||||||
string c2info = dnameof(c2->wall) + "; " + dnameof(c2->monst) + "; " + dnameof(c2->item);
|
|
||||||
bool res = movepcto(d, subdir, false);
|
|
||||||
printf("MOVE %d [%s] sub %d: %d\n", d, c2info.c_str(), subdir, res);
|
|
||||||
if (!res && c2->monst) {
|
|
||||||
printf("clearing the monster (%s)\n", minf[c2->monst].name);
|
|
||||||
killMonster(c2, moNone);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("MOVE CONFUSED %d\n", d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// try to use a ranged orb
|
|
||||||
cell *ct = cellToTarget();
|
|
||||||
eItem ti = targetRangedOrb(ct, roMouseForce);
|
|
||||||
const char *tm = (ti == eItem(-1)) ? "orb cannot be used (see message log)" : iinf[ti].name;
|
|
||||||
printf("TARGET %p: %s\n", (void*)ct, tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(false) if(turncount % 5000 == 0) {
|
|
||||||
printf("cells travelled: %d\n", celldist(cwt.at));
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
for(int i=0; i<ittypes; i++) if(items[i])
|
|
||||||
printf("%4dx %s\n", items[i], iinf[i].name);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
for(int i=1; i<motypes; i++) if(kills[i])
|
|
||||||
printf("%4dx %s <%d>\n", kills[i], minf[i].name, i);
|
|
||||||
|
|
||||||
printf("\n\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hrand(5000) == 0 || (isGravityLand(cwt.at->land) && coastvalEdge(cwt.at) >= 100) || gcount > 2000 || cellcount >= 20000000) {
|
|
||||||
printf("RESET\n");
|
|
||||||
gcount = 0;
|
|
||||||
cellcount = 0;
|
|
||||||
activateSafety(autoplayLand ? autoplayLand : landlist[hrand(isize(landlist))]);
|
|
||||||
if (cellcount < 0) {
|
|
||||||
//printf("How did cellcount become negative?\n");
|
|
||||||
cellcount = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cwt.at->land == laWestWall && cwt.at->landparam >= 30) {
|
|
||||||
printf("Safety generated\n");
|
|
||||||
forCellEx(c2, cwt.at) c2->item = itOrbSafety;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isIcyLand(cwt.at)) {
|
|
||||||
float heat = HEAT(cwt.at);
|
|
||||||
// Checking for extreme values as well as NaNs and infinities
|
|
||||||
if (!(-1e10 < heat && heat < 1e10)) {
|
|
||||||
printf("Heat is out of expected range\n");
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cwt.at->land == laCamelot) {
|
|
||||||
for(int i=0; i<isize(dcal); i++) {
|
|
||||||
cell *c = dcal[i];
|
|
||||||
if(c->land == laCamelot && celldistAltRelative(c) == 0 && c->wall != waRoundTable) {
|
|
||||||
printf("The round table of camelot is interrupted by a cell of %s\n", winf[c->wall].name);
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cwt.at->monst && !isMultitile(cwt.at->monst)) {
|
|
||||||
printf("on a non-multitile monster: %s\n", minf[cwt.at->monst].name);
|
|
||||||
}
|
|
||||||
else if(isDie(cwt.at->wall)) {
|
|
||||||
printf("on a wall-type die: %s\n", winf[cwt.at->wall].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<isize(dcal); i++) {
|
|
||||||
cell *c = dcal[i];
|
|
||||||
if(isChild(c, NULL)) {
|
|
||||||
}
|
|
||||||
if(childbug) doAutoplay = false;
|
|
||||||
if(c->land == laNone) {
|
|
||||||
printf("no-land found\n");
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
if(c->item == itBuggy || c->item == itBuggy2) {
|
|
||||||
printf("buggy item found\n");
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
if(isPrincess(c->monst) && princess::getPrincessInfo(c) == nullptr) {
|
|
||||||
printf("missing princess info\n");
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
if(dice::on(c)) {
|
|
||||||
if(dice::data.count(c) == 0) {
|
|
||||||
c->item = itBuggy;
|
|
||||||
printf("missing dice::data[%p]\n", (void *)c);
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
else if(!dice::data[c].which) {
|
|
||||||
// we might get here instead if someone already tried to do data[c], which creates a new element out of nothing
|
|
||||||
c->item = itBuggy;
|
|
||||||
printf("missing dice::data[%p].which\n", (void *)c);
|
|
||||||
kills[moPlayer] = 0;
|
|
||||||
canmove = true;
|
|
||||||
doAutoplay = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buggyGeneration || isize(buggycells)) {
|
|
||||||
if(noGUI) {
|
|
||||||
printf("Fatal: buggy generation\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
println(hlog, "buggy generation");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(turncount >= num_moves) return;
|
if(turncount >= num_moves) return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user