mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-20 23:50:27 +00:00
Autoplay: split into several functions
This commit is contained in:
parent
4dfb77d727
commit
ab7d6c407e
@ -20,101 +20,7 @@ bool sameland(eLand ll, eLand ln) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cell *cellToTarget() {
|
||||
if (isCrossroads(cwt.at->land)) {
|
||||
for (cell *c: dcal) {
|
||||
if (c->land == laCamelot && c->wall == waNone) {
|
||||
printf("Trying to teleport into Camelot\n");
|
||||
items[itOrbTeleport] += 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cwt.at->land == laCamelot) {
|
||||
int oldDist = celldistAltRelative(cwt.at);
|
||||
if (oldDist > 3) {
|
||||
for (cell *c: dcal) {
|
||||
if (c->land == laCamelot) {
|
||||
int dist = celldistAltRelative(c);
|
||||
if (-1 <= dist && dist <= 1 && hrand(10) == 0) {
|
||||
printf("Trying to teleport near the round table (%d to %d)\n", oldDist, dist);
|
||||
items[itOrbTeleport] += 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dcal[hrand(isize(dcal))];
|
||||
}
|
||||
|
||||
/* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
|
||||
eLand l2;
|
||||
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
|
||||
return l2;
|
||||
}); */
|
||||
|
||||
void autoplay(int num_moves = 1000000000) {
|
||||
// drawMesh();
|
||||
// exit(0);
|
||||
|
||||
doAutoplay = true;
|
||||
|
||||
cheater = 1;
|
||||
eLand lland = laIce;
|
||||
eLand lland2 = laIce;
|
||||
int lcount = 0;
|
||||
int gcount = 0;
|
||||
int lastgold = 0;
|
||||
|
||||
// landlist = { laRuins, laTerracotta, laPrairie };
|
||||
|
||||
generateLandList(isLandIngame);
|
||||
|
||||
#ifndef NOSDL
|
||||
int lastdraw = 0;
|
||||
#endif
|
||||
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) {
|
||||
lastgold = gold();
|
||||
gcount = 0;
|
||||
}
|
||||
else gcount++;
|
||||
|
||||
if(false && sameland(lland, cwt.at->land)) lcount++;
|
||||
else {
|
||||
lcount = 0; lland2 = lland; lland = cwt.at->land;
|
||||
printf("%10dcc %5dt %5de %5d$ %5dK %5dgc %-30s H%d\n", cellcount, turncount, celldist(cwt.at), gold(), tkills(), gcount, dnameof(cwt.at->land).c_str(), hrand(1000000));
|
||||
fflush(stdout);
|
||||
#ifndef NOSDL
|
||||
if(int(SDL_GetTicks()) > lastdraw + 3000) {
|
||||
lastdraw = SDL_GetTicks();
|
||||
fullcenter();
|
||||
msgs.clear();
|
||||
popScreenAll();
|
||||
drawscreen();
|
||||
clearAnimations();
|
||||
}
|
||||
#endif
|
||||
//mainloop();
|
||||
}
|
||||
|
||||
/* if(gcount < 500) for(int i=1; i<isize(dcal); i++) {
|
||||
c2 = dcal[i];
|
||||
if(lcount >= 50 && !sameland(lland, c2->land) && !sameland(lland2, c2->land)) break;
|
||||
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
|
||||
} */
|
||||
|
||||
// Use a random cheat
|
||||
void randomCheat() {
|
||||
int croll = hrand(50);
|
||||
if (croll < 25) {
|
||||
eItem b = (eItem) hrand(ittypes);
|
||||
@ -217,11 +123,43 @@ void autoplay(int num_moves = 1000000000) {
|
||||
vid.monmode = hrand(4);
|
||||
printf("Set vid.monmode to %d: %s\n", vid.monmode, mdmodes[vid.monmode]);
|
||||
}
|
||||
}
|
||||
|
||||
cell *cellToTarget() {
|
||||
if (isCrossroads(cwt.at->land)) {
|
||||
for (cell *c: dcal) {
|
||||
if (c->land == laCamelot && c->wall == waNone) {
|
||||
printf("Trying to teleport into Camelot\n");
|
||||
items[itOrbTeleport] += 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(cwt.at->land == laCamelot) {
|
||||
int oldDist = celldistAltRelative(cwt.at);
|
||||
if (oldDist > 3) {
|
||||
for (cell *c: dcal) {
|
||||
if (c->land == laCamelot) {
|
||||
int dist = celldistAltRelative(c);
|
||||
if (-1 <= dist && dist <= 1 && hrand(10) == 0) {
|
||||
printf("Trying to teleport near the round table (%d to %d)\n", oldDist, dist);
|
||||
items[itOrbTeleport] += 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dcal[hrand(isize(dcal))];
|
||||
}
|
||||
|
||||
void randomMove()
|
||||
{
|
||||
// don't show warning dialogs
|
||||
items[itWarning] = 1;
|
||||
|
||||
// Make a random move
|
||||
int roll = hrand(50);
|
||||
if (roll == 0) {
|
||||
// drop dead orb
|
||||
@ -248,7 +186,6 @@ void autoplay(int num_moves = 1000000000) {
|
||||
}
|
||||
} else {
|
||||
printf("MOVE CONFUSED %d\n", d);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// try to use a ranged orb
|
||||
@ -257,8 +194,102 @@ void autoplay(int num_moves = 1000000000) {
|
||||
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) {
|
||||
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()
|
||||
{
|
||||
long long ienter = (long long) 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(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");
|
||||
@ -274,9 +305,11 @@ void autoplay(int num_moves = 1000000000) {
|
||||
printf("\n\n\n");
|
||||
}
|
||||
|
||||
if(hrand(5000) == 0 || (isGravityLand(cwt.at->land) && coastvalEdge(cwt.at) >= 100) || gcount > 2000 || cellcount >= 20000000) {
|
||||
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;
|
||||
*gcount = 0;
|
||||
cellcount = 0;
|
||||
activateSafety(autoplayLand ? autoplayLand : landlist[hrand(isize(landlist))]);
|
||||
if (cellcount < 0) {
|
||||
@ -289,86 +322,72 @@ void autoplay(int num_moves = 1000000000) {
|
||||
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;
|
||||
/* auto a3 = addHook(hooks_nextland, 100, [] (eLand l) {
|
||||
eLand l2;
|
||||
do { l2 = pick(laRuins, laTerracotta, laPrairie); } while(l2 == l);
|
||||
return l2;
|
||||
}); */
|
||||
|
||||
void autoplay(int num_moves = 1000000000) {
|
||||
// drawMesh();
|
||||
// exit(0);
|
||||
|
||||
doAutoplay = true;
|
||||
|
||||
cheater = 1;
|
||||
eLand lland = laIce;
|
||||
eLand lland2 = laIce;
|
||||
int lcount = 0;
|
||||
int gcount = 0;
|
||||
int lastgold = 0;
|
||||
|
||||
// landlist = { laRuins, laTerracotta, laPrairie };
|
||||
|
||||
generateLandList(isLandIngame);
|
||||
|
||||
#ifndef NOSDL
|
||||
int lastdraw = 0;
|
||||
#endif
|
||||
while(doAutoplay) {
|
||||
|
||||
if(gold() > lastgold) {
|
||||
lastgold = gold();
|
||||
gcount = 0;
|
||||
}
|
||||
else gcount++;
|
||||
|
||||
if(false && sameland(lland, cwt.at->land)) lcount++;
|
||||
else {
|
||||
lcount = 0; lland2 = lland; lland = cwt.at->land;
|
||||
printf("%10dcc %5dt %5de %5d$ %5dK %5dgc %-30s H%d\n", cellcount, turncount, celldist(cwt.at), gold(), tkills(), gcount, dnameof(cwt.at->land).c_str(), hrand(1000000));
|
||||
fflush(stdout);
|
||||
#ifndef NOSDL
|
||||
if(int(SDL_GetTicks()) > lastdraw + 3000) {
|
||||
lastdraw = SDL_GetTicks();
|
||||
fullcenter();
|
||||
msgs.clear();
|
||||
popScreenAll();
|
||||
drawscreen();
|
||||
clearAnimations();
|
||||
}
|
||||
#endif
|
||||
//mainloop();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/* if(gcount < 500) for(int i=1; i<isize(dcal); i++) {
|
||||
c2 = dcal[i];
|
||||
if(lcount >= 50 && !sameland(lland, c2->land) && !sameland(lland2, c2->land)) break;
|
||||
else if(lcount < 50 && c2->item && c2->item != itOrbSafety) break;
|
||||
} */
|
||||
|
||||
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;
|
||||
}
|
||||
randomCheat();
|
||||
randomMove();
|
||||
if(false) if(turncount % 5000 == 0) showAutoplayStats();
|
||||
resetIfNeeded(&gcount);
|
||||
noteUnusualSituations();
|
||||
stopIfBug();
|
||||
|
||||
if(turncount >= num_moves) return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user