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:
parent
b3e29d9e03
commit
117e2cb6f4
@ -1,5 +1,49 @@
|
||||
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 rot_plane(hyperpoint h) {
|
||||
@ -288,7 +332,12 @@ level rotplane(
|
||||
"!!!!!!!!!!!!!!!!"
|
||||
},
|
||||
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(
|
||||
@ -306,7 +355,15 @@ level longtrack(
|
||||
"gggggfffffggggggggggggggggggggggggggggggggggggggggggggggggggggGG"
|
||||
},
|
||||
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(
|
||||
@ -325,7 +382,11 @@ level geodesical(
|
||||
"bbbbbbbbbbbbbbbb",
|
||||
},
|
||||
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(
|
||||
@ -344,7 +405,11 @@ level geodesical4(
|
||||
"ffffffffffffffff",
|
||||
},
|
||||
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(
|
||||
@ -400,7 +465,11 @@ level rotwell(
|
||||
"!!!!!!!!!!!!!!!!"
|
||||
},
|
||||
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(
|
||||
@ -426,7 +495,14 @@ level labyrinth(
|
||||
"!!!!!!!!!!!!!!!!"
|
||||
},
|
||||
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;
|
||||
|
@ -391,6 +391,11 @@ void initialize() {
|
||||
|
||||
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("-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(); })
|
||||
+ addHook(hooks_configfile, 100, [] {
|
||||
param_f(aimspeed_key_x, "nilrider_key_x")
|
||||
|
@ -15,8 +15,8 @@ struct timestamp {
|
||||
ld t; /**< planning spline parameter */
|
||||
|
||||
flagtype collected_triangles; /**< a bitset which shows which triangles are collected */
|
||||
flagtype achievements; /**< a bitset which shows which achievements are complete */
|
||||
flagtype achflags; /**< a bitset which marks failed conducts, etc. */
|
||||
flagtype goals; /**< a bitset which shows which goals are complete */
|
||||
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 */
|
||||
void centerview(level*);
|
||||
@ -64,6 +64,23 @@ using xy_float = pair<ld, ld>;
|
||||
using xy_int = pair<int, int>;
|
||||
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 {
|
||||
string name;
|
||||
char hotkey;
|
||||
@ -77,8 +94,8 @@ struct level {
|
||||
|
||||
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) :
|
||||
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; }
|
||||
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), goals(g) { initialized = false; }
|
||||
|
||||
ld real_minx, real_miny, real_maxx, real_maxy;
|
||||
|
||||
@ -90,6 +107,7 @@ struct level {
|
||||
|
||||
vector<statue> statues;
|
||||
vector<triangledata> triangles;
|
||||
vector<goal> goals;
|
||||
|
||||
/** the texture data used for the ground */
|
||||
texture::texture_data *unil_texture;
|
||||
|
@ -1,8 +1,12 @@
|
||||
namespace nilrider {
|
||||
|
||||
bool nospeed = false;
|
||||
int goal_id = 0;
|
||||
ld solver_unit = .25;
|
||||
|
||||
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 {
|
||||
int id;
|
||||
@ -14,6 +18,7 @@ void level::solve() {
|
||||
struct vertex {
|
||||
int id;
|
||||
int x, y;
|
||||
flagtype collected;
|
||||
ld zval;
|
||||
hyperpoint where;
|
||||
bool goal;
|
||||
@ -21,7 +26,7 @@ void level::solve() {
|
||||
vector<edge> edges;
|
||||
};
|
||||
|
||||
map<pair<int, int>, int> xy_to_id;
|
||||
map<tuple<int, int, flagtype>, int> xy_to_id;
|
||||
vector<vertex> vertices;
|
||||
|
||||
auto getpt = [&] (int x, int y) {
|
||||
@ -30,22 +35,23 @@ void level::solve() {
|
||||
return p;
|
||||
};
|
||||
|
||||
auto get_id = [&] (int x, int y) {
|
||||
if(xy_to_id.count({x, y}))
|
||||
return xy_to_id[{x, y}];
|
||||
auto get_id = [&] (int x, int y, flagtype co) {
|
||||
if(xy_to_id.count({x, y, co}))
|
||||
return xy_to_id[{x, y, co}];
|
||||
else {
|
||||
int id = isize(vertices);
|
||||
xy_to_id[{x,y}] = id;
|
||||
xy_to_id[{x,y, co}] = id;
|
||||
vertices.emplace_back();
|
||||
auto& b = vertices.back();
|
||||
b.where = getpt(x, y);
|
||||
b.id = id;
|
||||
b.x = x; b.y = y;
|
||||
b.collected = co;
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
get_id(0, 0);
|
||||
get_id(0, 0, 0);
|
||||
transmatrix Rstart = gpushxto0(vertices[0].where);
|
||||
|
||||
for(int id=0; id<isize(vertices); id++) {
|
||||
@ -58,8 +64,15 @@ void level::solve() {
|
||||
|
||||
xy_float f0 = get_xy_f(point0);
|
||||
|
||||
char ch = mapchar(f0);
|
||||
v.goal = ch == '*';
|
||||
timestamp ts;
|
||||
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];
|
||||
|
||||
for(int dx=-2; dx<=2; dx++)
|
||||
@ -87,11 +100,9 @@ void level::solve() {
|
||||
hyperpoint rpoint = gpushxto0(point1) * point0;
|
||||
rpoint[2] -= rpoint[0] * rpoint[1] / 2;
|
||||
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);
|
||||
|
||||
println(hlog, "edge from ", id, " to ", e.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,6 +136,7 @@ void level::solve() {
|
||||
step++;
|
||||
|
||||
if(v.goal) {
|
||||
if(nospeed && z0 * eunit - v.zval > eunit) continue;
|
||||
println(hlog, "reached the goal in time ", t0);
|
||||
vector<hyperpoint> positions;
|
||||
while(id0 || z0) {
|
||||
|
@ -121,7 +121,7 @@ bool timestamp::tick(level *lev) {
|
||||
vel -= sin(slope) * gravity / tps;
|
||||
if(vel < 0) {
|
||||
vel = 0;
|
||||
return false;
|
||||
if(ovel == 0) return false;
|
||||
}
|
||||
|
||||
auto mvel = (vel + ovel) / 2;
|
||||
|
Loading…
Reference in New Issue
Block a user