grid.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. #ifndef __GRID_H
  2. #define __GRID_H
  3. #include "neighbors.h"
  4. #include "random.h"
  5. #include <algorithm>
  6. #include <unordered_set>
  7. #include <unordered_map>
  8. #include <limits>
  9. #include <iostream>
  10. namespace grid {
  11. typedef std::pair<unsigned int, unsigned int> pt;
  12. struct Map {
  13. unsigned int w;
  14. unsigned int h;
  15. std::vector<float> grid;
  16. std::vector<float> karma;
  17. std::unordered_set<pt> walkmap;
  18. std::unordered_set<pt> watermap;
  19. std::unordered_set<pt> floormap;
  20. std::unordered_set<pt> cornermap;
  21. std::unordered_set<pt> shoremap;
  22. std::unordered_set<pt> lakemap;
  23. std::unordered_set<pt> lowlands;
  24. struct genmaps_t {
  25. std::vector<pt> walkmap;
  26. std::vector<pt> watermap;
  27. std::vector<pt> floormap;
  28. std::vector<pt> cornermap;
  29. std::vector<pt> shoremap;
  30. std::vector<pt> lakemap;
  31. std::vector<pt> lowlands;
  32. std::unordered_set<pt> nogens;
  33. bool is_nogen(unsigned int x, unsigned int y) {
  34. return nogens.count(pt(x, y));
  35. }
  36. void add_nogen(unsigned int x, unsigned int y) {
  37. nogens.insert(pt(x, y));
  38. }
  39. void add_nogen_expand(neighbors::Neighbors& neigh,
  40. unsigned int x, unsigned int y, unsigned int depth) {
  41. pt xy(x, y);
  42. std::set<pt> ng;
  43. for (const auto& xy_ : neigh(xy)) {
  44. ng.insert(neigh.mk(xy_, xy));
  45. }
  46. std::set<pt> proc;
  47. nogens.insert(xy);
  48. proc.insert(xy);
  49. for (unsigned int i = 1; i < depth; ++i) {
  50. std::set<pt> ngtmp;
  51. for (const pt& z : ng) {
  52. if (proc.count(z) != 0)
  53. continue;
  54. proc.insert(z);
  55. for (const auto& xy_ : neigh(z)) {
  56. ngtmp.insert(neigh.mk(xy_, z));
  57. }
  58. }
  59. ng.insert(ngtmp.begin(), ngtmp.end());
  60. }
  61. nogens.insert(ng.begin(), ng.end());
  62. }
  63. bool _one_of(rnd::Generator& rng, const std::vector<pt>& map, pt& ret) const {
  64. if (map.empty())
  65. return false;
  66. for (unsigned int i = 0; i < 10; ++i) {
  67. ret = map[rng.n(map.size())];
  68. if (nogens.count(ret) != 0)
  69. continue;
  70. return true;
  71. }
  72. return false;
  73. }
  74. bool one_of_walk(rnd::Generator& rng, pt& ret) const {
  75. return _one_of(rng, walkmap, ret);
  76. }
  77. bool one_of_floor(rnd::Generator& rng, pt& ret) const {
  78. return _one_of(rng, floormap, ret);
  79. }
  80. bool one_of_corner(rnd::Generator& rng, pt& ret) const {
  81. return _one_of(rng, cornermap, ret);
  82. }
  83. bool one_of_shore(rnd::Generator& rng, pt& ret) const {
  84. return _one_of(rng, shoremap, ret);
  85. }
  86. bool one_of_water(rnd::Generator& rng, pt& ret) const {
  87. return _one_of(rng, watermap, ret);
  88. }
  89. bool one_of_lake(rnd::Generator& rng, pt& ret) const {
  90. return _one_of(rng, lakemap, ret);
  91. }
  92. bool one_of_lowlands(rnd::Generator& rng, pt& ret) const {
  93. return _one_of(rng, lowlands, ret);
  94. }
  95. template <typename T>
  96. genmaps_t(const T& g) {
  97. walkmap.assign(g.walkmap.begin(), g.walkmap.end());
  98. floormap.assign(g.floormap.begin(), g.floormap.end());
  99. cornermap.assign(g.cornermap.begin(), g.cornermap.end());
  100. shoremap.assign(g.shoremap.begin(), g.shoremap.end());
  101. watermap.assign(g.watermap.begin(), g.watermap.end());
  102. lakemap.assign(g.lakemap.begin(), g.lakemap.end());
  103. lowlands.assign(g.lowlands.begin(), g.lowlands.end());
  104. }
  105. template <typename T>
  106. genmaps_t(const genmaps_t& maps, const T& g) : genmaps_t(g) {
  107. nogens = maps.nogens;
  108. }
  109. void swap(genmaps_t&& maps) {
  110. walkmap.swap(maps.walkmap);
  111. floormap.swap(maps.floormap);
  112. cornermap.swap(maps.cornermap);
  113. shoremap.swap(maps.shoremap);
  114. watermap.swap(maps.watermap);
  115. lakemap.swap(maps.lakemap);
  116. lowlands.swap(maps.lowlands);
  117. nogens.swap(maps.nogens);
  118. }
  119. };
  120. void init(unsigned int _w, unsigned int _h) {
  121. w = _w;
  122. h = _h;
  123. grid.resize(w*h);
  124. karma.resize(w*h);
  125. walkmap.clear();
  126. watermap.clear();
  127. floormap.clear();
  128. cornermap.clear();
  129. shoremap.clear();
  130. lakemap.clear();
  131. lowlands.clear();
  132. for (size_t i = 0; i < w*h; ++i) {
  133. grid[i] = 10.0;
  134. karma[i] = 0.0;
  135. }
  136. }
  137. void clear() {
  138. init(w, h);
  139. }
  140. float& _get(unsigned int x, unsigned int y) {
  141. return grid[y*w+x];
  142. }
  143. float& _get(const pt& xy) {
  144. return grid[xy.second*w+xy.first];
  145. }
  146. float& get_karma(unsigned int x, unsigned int y) {
  147. return karma[y*w+x];
  148. }
  149. float get(unsigned int x, unsigned int y) const {
  150. return grid[y*w+x];
  151. }
  152. /*** *** *** *** *** ***/
  153. void subdivide_mapgen(rnd::Generator& rng,
  154. unsigned int a, unsigned int b,
  155. unsigned int c, unsigned int d, bool domid) {
  156. unsigned int x = ((c - a) / 2) + a;
  157. unsigned int y = ((d - b) / 2) + b;
  158. if ((a == x || c == x) &&
  159. (b == y || d == y))
  160. return;
  161. //int s = std::max(c-a, d-b);
  162. int step = 0;
  163. int s = 1;
  164. double mid;
  165. if (!domid) {
  166. mid = _get(x, y);
  167. } else {
  168. mid = _get(a, b) + _get(c, b) + _get(a, d) + _get(c, d);
  169. mid = (mid / 4.0) - step + rng.range(-s, s);
  170. _get(x, y) = mid;
  171. }
  172. double top = ((_get(a, b) + _get(c, b) + mid) / 3.0) - step + rng.range(-s, s);
  173. _get(x, b) = top;
  174. double bot = ((_get(a, d) + _get(c, d) + mid) / 3.0) - step + rng.range(-s, s);
  175. _get(x, d) = bot;
  176. double lef = ((_get(a, b) + _get(a, d) + mid) / 3.0) - step + rng.range(-s, s);
  177. _get(a, y) = lef;
  178. double rig = ((_get(c, b) + _get(c, d) + mid) / 3.0) - step + rng.range(-s, s);
  179. _get(c, y) = rig;
  180. subdivide_mapgen(rng, a, b, x, y, true);
  181. subdivide_mapgen(rng, x, b, c, y, true);
  182. subdivide_mapgen(rng, a, y, x, d, true);
  183. subdivide_mapgen(rng, x, y, c, d, true);
  184. }
  185. void normalize() {
  186. double avg = 0.0;
  187. double min = std::numeric_limits<double>::max();
  188. double max = std::numeric_limits<double>::min();
  189. for (double i : grid) {
  190. avg += i;
  191. }
  192. avg /= (w * h);
  193. for (float& i : grid) {
  194. i -= avg;
  195. if (i > max) max = i;
  196. else if (i < min) min = i;
  197. }
  198. double scale = (max - min) / 20.0;
  199. for (float& i : grid) {
  200. i = (i / scale);
  201. if (i > 10.0) i = 10.0;
  202. else if (i < -10.0) i = -10.0;
  203. }
  204. }
  205. void makegrid(rnd::Generator& rng) {
  206. _get((w-1)/2, (h-1)/2) = -10;
  207. subdivide_mapgen(rng, 0, 0, w - 1, h - 1, false);
  208. normalize();
  209. }
  210. template <typename PARAMS>
  211. void flow(neighbors::Neighbors& neigh, rnd::Generator& rng, const PARAMS& genparams,
  212. const pt& xy, std::unordered_set<pt>& out, double n) {
  213. if (n < genparams.flow_epsilon) {
  214. return;
  215. }
  216. if (out.count(xy) != 0)
  217. return;
  218. out.insert(xy);
  219. double v0 = _get(xy);
  220. std::vector< std::pair<double, pt> > l;
  221. double vtotal = 0.0;
  222. for (const auto& _xy_ : neigh(xy)) {
  223. auto xy_ = neigh.mk(_xy_, xy);
  224. double v = _get(xy_);
  225. if (out.count(xy_) == 0 && v <= v0) {
  226. l.push_back(std::make_pair(v, xy_));
  227. vtotal += v;
  228. }
  229. }
  230. if (l.size() == 0) {
  231. return;
  232. }
  233. for (auto& i : l) {
  234. flow(neigh, rng, genparams, i.second, out, n * (i.first / vtotal));
  235. }
  236. }
  237. template <typename PARAMS>
  238. void makeflow(neighbors::Neighbors& neigh,
  239. rnd::Generator& rng,
  240. const PARAMS& genparams,
  241. std::discrete_distribution<size_t>& ddist,
  242. std::unordered_set<pt>& gout,
  243. std::unordered_map<pt, unsigned int>& watr,
  244. double n, double q) {
  245. size_t index = ddist(rng.gen);
  246. unsigned int y = index / w;
  247. unsigned int x = index % w;
  248. std::unordered_set<pt> out;
  249. flow(neigh, rng, genparams, pt(x, y), out, n);
  250. for (const pt& xy : out) {
  251. watr[xy] += 1;
  252. float& i = _get(xy);
  253. i -= q;
  254. if (i < -10.0) i = -10.0;
  255. }
  256. gout.insert(out.begin(), out.end());
  257. }
  258. template <typename PARAMS>
  259. void makerivers(neighbors::Neighbors& neigh, rnd::Generator& rng, const PARAMS& genparams) {
  260. std::unordered_set<pt> gout;
  261. std::unordered_map<pt, unsigned int> watr;
  262. unsigned int N1 = grid.size() / genparams.flow_n_freq; //100;
  263. double N2 = genparams.flow_volume;
  264. double N3 = genparams.flow_erosion;
  265. {
  266. std::discrete_distribution<size_t> ddist;
  267. for (unsigned int i = 0; i < N1; i++) {
  268. if (i % genparams.flow_renorm_freq == 0) {
  269. std::vector<double> grid_norm;
  270. for (double v : grid) {
  271. grid_norm.push_back((v + 10.0) * genparams.flow_renorm_scale); //5);
  272. }
  273. ddist = std::discrete_distribution<size_t>(grid_norm.begin(), grid_norm.end());
  274. }
  275. makeflow(neigh, rng, genparams, ddist, gout, watr, N2, N3);
  276. }
  277. }
  278. double hmin = 10;
  279. unsigned int wmax = 0;
  280. for (const pt& xy : gout) {
  281. double h = _get(xy);
  282. auto tmp = watr.find(xy);
  283. unsigned int w = (tmp == watr.end() ? 0 : tmp->second);
  284. hmin = std::min(hmin, h);
  285. wmax = std::max(wmax, w);
  286. }
  287. double walk_threshold = std::max(genparams.walk_threshold, hmin);
  288. unsigned int lowlands_threshold = std::min(genparams.lowlands_threshold, wmax);
  289. for (const pt& xy : gout) {
  290. double h = _get(xy);
  291. auto tmp = watr.find(xy);
  292. unsigned int w = (tmp == watr.end() ? 0 : tmp->second);
  293. if (h <= walk_threshold) {
  294. walkmap.insert(xy);
  295. if (h <= hmin && w >= lowlands_threshold) {
  296. lowlands.insert(xy);
  297. }
  298. }
  299. }
  300. if (walkmap.empty() || lowlands.empty())
  301. throw std::runtime_error("Failed to generate map");
  302. ///
  303. std::vector< std::pair<unsigned int,pt> > watr_r;
  304. for (const auto& v : watr) {
  305. watr_r.push_back(std::make_pair(v.second, v.first));
  306. }
  307. std::sort(watr_r.begin(), watr_r.end());
  308. std::reverse(watr_r.begin(), watr_r.end());
  309. unsigned int pctwater = rng.gauss(genparams.water_quantile_mean, genparams.water_quantile_dev);
  310. if (pctwater <= 1) pctwater = 1;
  311. pctwater = watr_r.size() / pctwater;
  312. if (watr_r.size() > pctwater) {
  313. watr_r.resize(pctwater);
  314. }
  315. for (const auto& v : watr_r) {
  316. watermap.insert(v.second);
  317. }
  318. }
  319. template <typename PARAMS, typename FUNC>
  320. void flatten_pass(neighbors::Neighbors& neigh, const PARAMS& genparams, FUNC progressbar,
  321. size_t np_walk, size_t np_water) {
  322. std::unordered_set<pt> newwalkmap;
  323. auto* walkmap_p = &walkmap;
  324. size_t npass = std::max(np_walk, np_water);
  325. for (size_t np = 0; np < npass; ++np) {
  326. if (walkmap_p->size() > 2000)
  327. progressbar(" ..."_m);
  328. std::unordered_map<pt, size_t> nwalk;
  329. std::unordered_map<pt, size_t> nwater;
  330. for (const auto& xy : *walkmap_p) {
  331. bool iswater = watermap.count(xy);
  332. for (const auto& ij_ : neigh(xy)) {
  333. auto ij = neigh.mk(ij_, xy);
  334. // For all solid squares neighboring a walkable square,
  335. // count the number of neighbor walkable squares.
  336. if (np < np_walk && walkmap.count(ij) == 0)
  337. nwalk[ij]++;
  338. // For all dry squares neighboring a walkable water square,
  339. // count the number of neighbor walkable water squares.
  340. if (np < np_water && iswater && watermap.count(ij) == 0)
  341. nwater[ij]++;
  342. }
  343. }
  344. newwalkmap.clear();
  345. auto add_newwalkmap = [&](const pt& xy) {
  346. newwalkmap.insert(xy);
  347. for (const auto& ij_ : neigh(xy)) {
  348. auto ij = neigh.mk(ij_, xy);
  349. if (walkmap.count(ij))
  350. newwalkmap.insert(ij);
  351. }
  352. };
  353. for (const auto& z : nwalk) {
  354. if (genparams.flatten_walk_ng & (1 << z.second)) {
  355. walkmap.insert(z.first);
  356. add_newwalkmap(z.first);
  357. }
  358. }
  359. for (const auto& z : nwater) {
  360. if (genparams.flatten_water_ng & (1 << z.second)) {
  361. watermap.insert(z.first);
  362. walkmap.insert(z.first);
  363. add_newwalkmap(z.first);
  364. }
  365. }
  366. walkmap_p = &newwalkmap;
  367. }
  368. }
  369. template <typename PARAMS, typename FUNC>
  370. void unflow(neighbors::Neighbors& neigh, const PARAMS& genparams, FUNC progressbar, size_t npass) {
  371. std::unordered_set<pt> unwater;
  372. auto* watermap_p = &watermap;
  373. for (size_t np = 0; np < npass; ++np) {
  374. if (watermap_p->size() > 2000)
  375. progressbar(" ..."_m);
  376. unwater.clear();
  377. for (const pt& xy : *watermap_p) {
  378. unsigned int nwater = 0;
  379. for (const auto& xy_ : neigh(xy)) {
  380. if (watermap.count(neigh.mk(xy_, xy)) != 0)
  381. nwater++;
  382. }
  383. if (genparams.unflow_ng & (1 << nwater)) {
  384. unwater.insert(xy);
  385. }
  386. }
  387. for (const pt& xy : unwater) {
  388. watermap.erase(xy);
  389. }
  390. watermap_p = &unwater;
  391. }
  392. }
  393. template <typename PARAMS, typename FUNC>
  394. void flatten(neighbors::Neighbors& neigh, const PARAMS& genparams, FUNC progressbar) {
  395. {
  396. progressbar("Aging rock..."_m);
  397. flatten_pass(neigh, genparams, progressbar, genparams.nflatten_walk, genparams.nflatten_water);
  398. }
  399. {
  400. progressbar("Flowing water..."_m);
  401. unflow(neigh, genparams, progressbar, genparams.nunflow);
  402. }
  403. }
  404. void _set_maps(neighbors::Neighbors& neigh) {
  405. for (const pt& xy : walkmap) {
  406. if (watermap.count(xy) == 0) {
  407. floormap.insert(xy);
  408. for (const auto& v : neigh(xy)) {
  409. if (watermap.count(neigh.mk(v, xy)) != 0) {
  410. shoremap.insert(xy);
  411. break;
  412. }
  413. }
  414. }
  415. for (const auto& v : neigh(xy)) {
  416. if (walkmap.count(neigh.mk(v, xy)) == 0) {
  417. cornermap.insert(xy);
  418. break;
  419. }
  420. }
  421. }
  422. for (const pt& xy : watermap) {
  423. if (walkmap.count(xy) != 0) {
  424. lakemap.insert(xy);
  425. }
  426. }
  427. }
  428. template <typename PARAMS>
  429. void make_karma(rnd::Generator& rng, const PARAMS& genparams) {
  430. for (unsigned int y = 0; y < h; ++y) {
  431. for (unsigned int x = 0; x < w; ++x) {
  432. float& k = get_karma(x, y);
  433. if (y > 0 && x > 0) {
  434. k = ((get_karma(x-1, y) + get_karma(x, y-1) + get_karma(x-1, y-1)) / 3.0);
  435. }
  436. k += rng.gauss(genparams.karma_mean, genparams.karma_dev);
  437. k = std::min(std::max(k, -1.0f), 1.0f);
  438. }
  439. }
  440. }
  441. template <typename PARAMS, typename FUNC>
  442. void generate(neighbors::Neighbors& neigh,
  443. rnd::Generator& rng,
  444. const PARAMS& genparams,
  445. FUNC progressbar) {
  446. clear();
  447. {
  448. progressbar("Placing shiprock..."_m);
  449. makegrid(rng);
  450. }
  451. {
  452. progressbar("Placing water..."_m);
  453. makerivers(neigh, rng, genparams);
  454. }
  455. flatten(neigh, genparams, progressbar);
  456. for (const auto& xy : lakemap) {
  457. if (walkmap.count(xy) == 0)
  458. throw std::runtime_error("Sanity error 0.1.1");
  459. if (watermap.count(xy) == 0)
  460. throw std::runtime_error("Sanity error 0.1.2");
  461. }
  462. for (const auto& xy : shoremap) {
  463. if (walkmap.count(xy) == 0)
  464. throw std::runtime_error("Sanity error 0.1.3");
  465. }
  466. //
  467. {
  468. progressbar("Allotting karma..."_m);
  469. make_karma(rng, genparams);
  470. }
  471. {
  472. progressbar("Combining..."_m);
  473. set_maps(neigh);
  474. }
  475. }
  476. void set_maps(neighbors::Neighbors& neigh) {
  477. floormap.clear();
  478. shoremap.clear();
  479. cornermap.clear();
  480. lakemap.clear();
  481. _set_maps(neigh);
  482. for (const auto& xy : lakemap) {
  483. if (walkmap.count(xy) == 0)
  484. throw std::runtime_error("Sanity error 0.2.1");
  485. if (watermap.count(xy) == 0)
  486. throw std::runtime_error("Sanity error 0.2.2");
  487. }
  488. for (const auto& xy : shoremap) {
  489. if (walkmap.count(xy) == 0)
  490. throw std::runtime_error("Sanity error 0.2.3");
  491. }
  492. }
  493. /*** *** *** *** ***/
  494. void set_height(unsigned int x, unsigned int y, double h) {
  495. _get(x, y) = h;
  496. }
  497. double get_height(unsigned int x, unsigned int y) {
  498. return _get(x, y);
  499. }
  500. bool is_walk(unsigned int x, unsigned int y) const {
  501. return (walkmap.count(pt(x, y)) != 0);
  502. }
  503. bool is_water(unsigned int x, unsigned int y) const {
  504. return (watermap.count(pt(x, y)) != 0);
  505. }
  506. bool is_lake(unsigned int x, unsigned int y) const {
  507. return (lakemap.count(pt(x, y)) != 0);
  508. }
  509. bool is_floor(unsigned int x, unsigned int y) const {
  510. return (floormap.count(pt(x, y)) != 0);
  511. }
  512. bool is_corner(unsigned int x, unsigned int y) const {
  513. return (cornermap.count(pt(x, y)) != 0);
  514. }
  515. bool is_shore(unsigned int x, unsigned int y) const {
  516. return (shoremap.count(pt(x, y)) != 0);
  517. }
  518. bool is_lowlands(unsigned int x, unsigned int y) const {
  519. return (lowlands.count(pt(x, y)) != 0);
  520. }
  521. void _set_maps_of(neighbors::Neighbors& neigh, const std::set<pt>& affected) {
  522. for (const pt& xy : affected) {
  523. floormap.erase(xy);
  524. shoremap.erase(xy);
  525. cornermap.erase(xy);
  526. lakemap.erase(xy);
  527. if (walkmap.count(xy) == 0) {
  528. lowlands.erase(xy);
  529. continue;
  530. }
  531. if (watermap.count(xy) != 0) {
  532. lakemap.insert(xy);
  533. } else {
  534. floormap.insert(xy);
  535. }
  536. for (const auto& v_ : neigh(xy)) {
  537. auto v = neigh.mk(v_, xy);
  538. if (watermap.count(v) != 0 && walkmap.count(v) != 0) {
  539. shoremap.insert(xy);
  540. }
  541. if (walkmap.count(v) == 0) {
  542. cornermap.insert(xy);
  543. }
  544. }
  545. }
  546. }
  547. void set_walk_water(neighbors::Neighbors& neigh, unsigned int x, unsigned int y, bool walk, bool water) {
  548. pt tmp(x, y);
  549. if (walk) {
  550. walkmap.insert(tmp);
  551. } else {
  552. walkmap.erase(tmp);
  553. }
  554. if (water) {
  555. watermap.insert(tmp);
  556. } else {
  557. watermap.erase(tmp);
  558. }
  559. std::set<pt> affected;
  560. for (const auto& v : neigh(tmp)) {
  561. affected.insert(neigh.mk(v, tmp));
  562. }
  563. affected.insert(tmp);
  564. _set_maps_of(neigh, affected);
  565. }
  566. bool _one_of(rnd::Generator& rng, const std::unordered_set<pt>& s, pt& ret) {
  567. if (s.size() == 0)
  568. return false;
  569. size_t n = rng.n(s.size());
  570. auto i = s.begin();
  571. while (n > 0) {
  572. ++i;
  573. --n;
  574. }
  575. ret = *i;
  576. return true;
  577. }
  578. bool one_of_walk(rnd::Generator& rng, pt& ret) {
  579. return _one_of(rng, walkmap, ret);
  580. }
  581. bool one_of_floor(rnd::Generator& rng, pt& ret) {
  582. return _one_of(rng, floormap, ret);
  583. }
  584. bool one_of_corner(rnd::Generator& rng, pt& ret) {
  585. return _one_of(rng, cornermap, ret);
  586. }
  587. bool one_of_shore(rnd::Generator& rng, pt& ret) {
  588. return _one_of(rng, shoremap, ret);
  589. }
  590. bool one_of_water(rnd::Generator& rng, pt& ret) {
  591. return _one_of(rng, watermap, ret);
  592. }
  593. bool one_of_lake(rnd::Generator& rng, pt& ret) {
  594. return _one_of(rng, lakemap, ret);
  595. }
  596. bool one_of_lowlands(rnd::Generator& rng, pt& ret) {
  597. return _one_of(rng, lowlands, ret);
  598. }
  599. // Fake functions to adhere to a template interface.
  600. bool is_nogen(unsigned int x, unsigned int y) { return false; }
  601. void add_nogen(unsigned int x, unsigned int y) { }
  602. };
  603. }
  604. namespace serialize {
  605. template <>
  606. struct reader<grid::Map> {
  607. void read(Source& s, grid::Map& t) {
  608. serialize::read(s, t.w);
  609. serialize::read(s, t.h);
  610. serialize::read(s, t.grid);
  611. serialize::read(s, t.karma);
  612. serialize::read(s, t.walkmap);
  613. serialize::read(s, t.watermap);
  614. serialize::read(s, t.floormap);
  615. serialize::read(s, t.cornermap);
  616. serialize::read(s, t.shoremap);
  617. serialize::read(s, t.lakemap);
  618. serialize::read(s, t.lowlands);
  619. }
  620. };
  621. template <>
  622. struct writer<grid::Map> {
  623. void write(Sink& s, const grid::Map& t) {
  624. serialize::write(s, t.w);
  625. serialize::write(s, t.h);
  626. serialize::write(s, t.grid);
  627. serialize::write(s, t.karma);
  628. serialize::write(s, t.walkmap);
  629. serialize::write(s, t.watermap);
  630. serialize::write(s, t.floormap);
  631. serialize::write(s, t.cornermap);
  632. serialize::write(s, t.shoremap);
  633. serialize::write(s, t.lakemap);
  634. serialize::write(s, t.lowlands);
  635. }
  636. };
  637. }
  638. #endif