1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-10-31 19:36:16 +00:00

nilrider:: goal checking and goal solving and goals for all levels

This commit is contained in:
Zeno Rogue 2022-05-03 22:08:17 +02:00
parent b3e29d9e03
commit 117e2cb6f4
5 changed files with 134 additions and 23 deletions

View File

@ -1,5 +1,49 @@
namespace nilrider { namespace nilrider {
bool all(checkerparam c) { return c.t->collected_triangles == Flag(isize(c.l->triangles))-1; }
goalchecker basic_check(ld time_limit, ld rev_limit) {
return [=] (checkerparam c) {
if(c.timer > time_limit || c.rev > rev_limit) return grFailed;
if(all(c)) return grSuccess;
return grNone;
};
}
goalchecker get_any(ld time_limit, ld rev_limit) {
return [=] (checkerparam c) {
if(c.timer > time_limit || c.rev > rev_limit) return grFailed;
if(c.t->collected_triangles) return grSuccess;
return grNone;
};
}
goalchecker get_ordered(ld time_limit, ld rev_limit) {
return [=] (checkerparam c) {
if(c.timer > time_limit || c.rev > rev_limit) return grFailed;
if(c.t->collected_triangles & (c.t->collected_triangles+1)) return grFailed;
if(all(c)) return grSuccess;
return grNone;
};
}
goalchecker yplus_check(ld time_limit, ld rev_limit) {
return [=] (checkerparam c) {
if(c.timer > time_limit || c.rev > rev_limit) return grFailed;
if(c.t->where[1] < 0) return grFailed;
if(all(c)) return grSuccess;
return grNone;
};
}
goalchecker fullstop_check(ld time_limit, ld rev_limit) {
return [=] (checkerparam c) {
if(c.timer > time_limit || c.rev > rev_limit) return grFailed;
if(all(c) && c.t->vel == 0) return grSuccess;
return grNone;
};
}
ld f_heisenberg0(hyperpoint h) { return 0; } ld f_heisenberg0(hyperpoint h) { return 0; }
ld rot_plane(hyperpoint h) { ld rot_plane(hyperpoint h) {
@ -288,7 +332,12 @@ level rotplane(
"!!!!!!!!!!!!!!!!" "!!!!!!!!!!!!!!!!"
}, },
6, 6, 6, 6,
rot_plane rot_plane,
{
// the solver[0.25] result is 36.92
goal{0x40FF40, "Collect all the triangles in below 60 seconds", basic_check(60, 999)},
goal{0xFFD500, "Collect all the triangles in below 38 seconds", basic_check(38, 999)}
}
); );
level longtrack( level longtrack(
@ -306,7 +355,15 @@ level longtrack(
"gggggfffffggggggggggggggggggggggggggggggggggggggggggggggggggggGG" "gggggfffffggggggggggggggggggggggggggggggggggggggggggggggggggggGG"
}, },
0, 5, 0, 5,
long_x long_x,
{
// the solver[0.25] result is 1:08.56 (reduced to 1:08.45 by removing some points)
goal{0xFFD500, "Collect the triangle in below 1:15", basic_check(75, 999)},
// the solver[0.25] + some manual modifications achieves 1:37.44
goal{0xFF4040, "Stop where the triangle is in below 1:45", fullstop_check(75, 999)},
// the solver[0.25] result is 1:45.52
goal{0x303030, "Reach the triangle without going on the right side of the road below 2:00", yplus_check(120, 999)},
}
); );
level geodesical( level geodesical(
@ -325,7 +382,11 @@ level geodesical(
"bbbbbbbbbbbbbbbb", "bbbbbbbbbbbbbbbb",
}, },
0, 6, 0, 6,
geodesics_0 geodesics_0,
{
// the solver[0.25] result is 26.10
goal{0xFFD500, "Collect both triangles in below 30 seconds", basic_check(30, 999)}
}
); );
level geodesical4( level geodesical4(
@ -344,7 +405,11 @@ level geodesical4(
"ffffffffffffffff", "ffffffffffffffff",
}, },
0, 5, 0, 5,
geodesics_at_4 geodesics_at_4,
{
// the solver[0.25] result is 32.04
goal{0xFFD500, "Collect the triangle in below 35 seconds", basic_check(35, 999)}
}
); );
level heisenberg0( level heisenberg0(
@ -400,7 +465,11 @@ level rotwell(
"!!!!!!!!!!!!!!!!" "!!!!!!!!!!!!!!!!"
}, },
8, 8, 8, 8,
f_rot_well f_rot_well,
{
// the solver[0.5] result is 1:19.54 (obtained using get_ordered)
goal{0xFFD500, "Collect all triangles below 1:25", basic_check(85, 999)}
}
); );
level labyrinth( level labyrinth(
@ -426,7 +495,14 @@ level labyrinth(
"!!!!!!!!!!!!!!!!" "!!!!!!!!!!!!!!!!"
}, },
8, 8, 8, 8,
rot_plane rot_plane,
{
// the solver[0.1] result is 1:03.53
// the solver[0.15] result is 1:06.58
// the solver[0.24] result is 1:08.54
// the solver[0.25] result is 1:22.09 (it goes north for some reason)
goal{0xFFD500, "Collect the triangle in below 1:15", basic_check(75, 999)}
}
); );
level *curlev = &rotplane; level *curlev = &rotplane;

View File

@ -391,6 +391,11 @@ void initialize() {
auto celldemo = arg::add3("-unilcycle", initialize) + arg::add3("-unilplan", [] { planning_mode = true; }) + arg::add3("-viewsim", [] { view_replay = true; }) auto celldemo = arg::add3("-unilcycle", initialize) + arg::add3("-unilplan", [] { planning_mode = true; }) + arg::add3("-viewsim", [] { view_replay = true; })
+ arg::add3("-oqc", [] { on_quit = popScreenAll; }) + arg::add3("-oqc", [] { on_quit = popScreenAll; })
+ arg::add3("-nilsolve-set", [] {
arg::shift(); solver_unit = arg::argf();
arg::shift(); nospeed = arg::argi();
arg::shift(); goal_id = arg::argi();
curlev->solve(); })
+ arg::add3("-nilsolve", [] { curlev->solve(); }) + arg::add3("-nilsolve", [] { curlev->solve(); })
+ addHook(hooks_configfile, 100, [] { + addHook(hooks_configfile, 100, [] {
param_f(aimspeed_key_x, "nilrider_key_x") param_f(aimspeed_key_x, "nilrider_key_x")

View File

@ -15,8 +15,8 @@ struct timestamp {
ld t; /**< planning spline parameter */ ld t; /**< planning spline parameter */
flagtype collected_triangles; /**< a bitset which shows which triangles are collected */ flagtype collected_triangles; /**< a bitset which shows which triangles are collected */
flagtype achievements; /**< a bitset which shows which achievements are complete */ flagtype goals; /**< a bitset which shows which goals are complete */
flagtype achflags; /**< a bitset which marks failed conducts, etc. */ flagtype failed; /**< a bitset which shows which goals are failed */
bool tick(level*);/**< one tick of the simulation -- returns false if the unicycle has stopped or crashed */ bool tick(level*);/**< one tick of the simulation -- returns false if the unicycle has stopped or crashed */
void centerview(level*); void centerview(level*);
@ -64,6 +64,23 @@ using xy_float = pair<ld, ld>;
using xy_int = pair<int, int>; using xy_int = pair<int, int>;
inline xy_int pfloor(xy_int p) { return {floor(p.first), floor(p.second)}; } inline xy_int pfloor(xy_int p) { return {floor(p.first), floor(p.second)}; }
enum eGoalResult { grNone, grSuccess, grFailed };
struct checkerparam {
timestamp *t;
level *l;
ld timer;
int rev;
};
using goalchecker = std::function<eGoalResult(checkerparam)>;
struct goal {
color_t color;
string desc;
goalchecker check;
};
struct level { struct level {
string name; string name;
char hotkey; char hotkey;
@ -77,8 +94,8 @@ struct level {
bool initialized; bool initialized;
level(string name, char hotkey, flagtype flags, string longdesc, ld minx, ld miny, ld maxx, ld maxy, const vector<string>& mt, ld sx, ld sy, const std::function<ld(hyperpoint h)>& surf) : level(string name, char hotkey, flagtype flags, string longdesc, ld minx, ld miny, ld maxx, ld maxy, const vector<string>& mt, ld sx, ld sy, const std::function<ld(hyperpoint h)>& surf, vector<goal> g) :
name(name), hotkey(hotkey), longdesc(longdesc), flags(flags), minx(minx), miny(miny), maxx(maxx), maxy(maxy), map_tiles(mt), startx(sx), starty(sy), surface(surf) { initialized = false; } name(name), hotkey(hotkey), longdesc(longdesc), flags(flags), minx(minx), miny(miny), maxx(maxx), maxy(maxy), map_tiles(mt), startx(sx), starty(sy), surface(surf), goals(g) { initialized = false; }
ld real_minx, real_miny, real_maxx, real_maxy; ld real_minx, real_miny, real_maxx, real_maxy;
@ -90,6 +107,7 @@ struct level {
vector<statue> statues; vector<statue> statues;
vector<triangledata> triangles; vector<triangledata> triangles;
vector<goal> goals;
/** the texture data used for the ground */ /** the texture data used for the ground */
texture::texture_data *unil_texture; texture::texture_data *unil_texture;

View File

@ -1,8 +1,12 @@
namespace nilrider { namespace nilrider {
bool nospeed = false;
int goal_id = 0;
ld solver_unit = .25;
void level::solve() { void level::solve() {
ld xunit = .25, yunit = .25, eunit = xunit * yunit / 2; ld xunit = solver_unit, yunit = solver_unit, eunit = xunit * yunit / 2;
struct edge { struct edge {
int id; int id;
@ -14,6 +18,7 @@ void level::solve() {
struct vertex { struct vertex {
int id; int id;
int x, y; int x, y;
flagtype collected;
ld zval; ld zval;
hyperpoint where; hyperpoint where;
bool goal; bool goal;
@ -21,7 +26,7 @@ void level::solve() {
vector<edge> edges; vector<edge> edges;
}; };
map<pair<int, int>, int> xy_to_id; map<tuple<int, int, flagtype>, int> xy_to_id;
vector<vertex> vertices; vector<vertex> vertices;
auto getpt = [&] (int x, int y) { auto getpt = [&] (int x, int y) {
@ -30,22 +35,23 @@ void level::solve() {
return p; return p;
}; };
auto get_id = [&] (int x, int y) { auto get_id = [&] (int x, int y, flagtype co) {
if(xy_to_id.count({x, y})) if(xy_to_id.count({x, y, co}))
return xy_to_id[{x, y}]; return xy_to_id[{x, y, co}];
else { else {
int id = isize(vertices); int id = isize(vertices);
xy_to_id[{x,y}] = id; xy_to_id[{x,y, co}] = id;
vertices.emplace_back(); vertices.emplace_back();
auto& b = vertices.back(); auto& b = vertices.back();
b.where = getpt(x, y); b.where = getpt(x, y);
b.id = id; b.id = id;
b.x = x; b.y = y; b.x = x; b.y = y;
b.collected = co;
return id; return id;
} }
}; };
get_id(0, 0); get_id(0, 0, 0);
transmatrix Rstart = gpushxto0(vertices[0].where); transmatrix Rstart = gpushxto0(vertices[0].where);
for(int id=0; id<isize(vertices); id++) { for(int id=0; id<isize(vertices); id++) {
@ -58,8 +64,15 @@ void level::solve() {
xy_float f0 = get_xy_f(point0); xy_float f0 = get_xy_f(point0);
char ch = mapchar(f0); timestamp ts;
v.goal = ch == '*'; ts.where = point0;
ts.collected_triangles = v.collected;
ts.collect(this);
checkerparam p {&ts, this, 0, 0};
auto res = goals[goal_id].check(p);
if(res == grFailed) continue;
v.goal = res == grSuccess;
v.zval = (Rstart * point0)[2]; v.zval = (Rstart * point0)[2];
for(int dx=-2; dx<=2; dx++) for(int dx=-2; dx<=2; dx++)
@ -87,11 +100,9 @@ void level::solve() {
hyperpoint rpoint = gpushxto0(point1) * point0; hyperpoint rpoint = gpushxto0(point1) * point0;
rpoint[2] -= rpoint[0] * rpoint[1] / 2; rpoint[2] -= rpoint[0] * rpoint[1] / 2;
e.length = hypot_d(3, rpoint); e.length = hypot_d(3, rpoint);
e.id = get_id(x1, y1); e.id = get_id(x1, y1, ts.collected_triangles);
vertices[id].edges.push_back(e); vertices[id].edges.push_back(e);
println(hlog, "edge from ", id, " to ", e.id);
} }
} }
@ -125,6 +136,7 @@ void level::solve() {
step++; step++;
if(v.goal) { if(v.goal) {
if(nospeed && z0 * eunit - v.zval > eunit) continue;
println(hlog, "reached the goal in time ", t0); println(hlog, "reached the goal in time ", t0);
vector<hyperpoint> positions; vector<hyperpoint> positions;
while(id0 || z0) { while(id0 || z0) {

View File

@ -121,7 +121,7 @@ bool timestamp::tick(level *lev) {
vel -= sin(slope) * gravity / tps; vel -= sin(slope) * gravity / tps;
if(vel < 0) { if(vel < 0) {
vel = 0; vel = 0;
return false; if(ovel == 0) return false;
} }
auto mvel = (vel + ovel) / 2; auto mvel = (vel + ovel) / 2;