mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	nilrider:: goal checking and goal solving and goals for all levels
This commit is contained in:
		| @@ -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; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue