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 {
|
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;
|
||||||
|
@ -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")
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user