From 569d75103168677987f41e563f511bd7f3d4157a Mon Sep 17 00:00:00 2001 From: klangner Date: Tue, 3 Nov 2020 09:04:33 +0100 Subject: [PATCH] Added maze Fixed #28 --- README.md | 2 +- demo/src/lib.rs | 23 ++- demo/www/index.html | 1 + demo/www/index.js | 7 + docs/0.bootstrap.js | 6 +- docs/bootstrap.js | 2 +- docs/fa6c9d72e1d9a518ed31.module.wasm | Bin 0 -> 106269 bytes docs/index.html | 1 + src/filter/maze.rs | 217 ++++++++++++++++++++++++++ src/filter/mod.rs | 2 + 10 files changed, 251 insertions(+), 10 deletions(-) create mode 100644 docs/fa6c9d72e1d9a518ed31.module.wasm create mode 100644 src/filter/maze.rs diff --git a/README.md b/README.md index 1cc1766..a46a8ac 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ This library consists of different map filters which can be combined to create c * [x] Cull unreachable areas * [ ] Diffusion-Limited Aggregation (DLA) * [x] Drunkard's walk - * [ ] Maze + * [x] Maze * [x] Noise generator * [ ] Prefabs * [x] Room corridors nearest diff --git a/demo/src/lib.rs b/demo/src/lib.rs index 35097ea..5c59bf3 100644 --- a/demo/src/lib.rs +++ b/demo/src/lib.rs @@ -99,19 +99,32 @@ impl World { World::new(width, height, map) } + pub fn new_maze(width: u32, height: u32, seed: u32) -> World { + World::print_map_info(format!("Maze with the seed: {}", seed)); + let mut rng = StdRng::seed_from_u64(seed as u64); + let map = MapBuilder::new(width as usize, height as usize) + .with(MazeBuilder::new()) + .with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP)) + .with(DistantExit::new()) + .build_with_rng(&mut rng); + World::new(width, height, map) + } + pub fn new_random(width: u32, height: u32, seed: u32) -> World { let mut rng = rand::thread_rng(); let px = rng.gen::(); - if px < 0.2 { + if px < 1.0/6.0 { World::new_cellular_automata(width, height, seed) - } else if px < 0.4 { + } else if px < 2.0/6.0 { World::new_simple_rooms(width, height, seed) - } else if px < 0.6 { + } else if px < 3.0/6.0 { World::new_drunkard(width, height, seed) - } else if px < 0.8 { + } else if px < 4.0/6.0 { + World::new_bsp_rooms(width, height, seed) + } else if px < 5.0/6.0 { World::new_bsp_rooms(width, height, seed) } else { - World::new_bsp_interior(width, height, seed) + World::new_maze(width, height, seed) } } diff --git a/demo/www/index.html b/demo/www/index.html index 486667b..e3fc112 100644 --- a/demo/www/index.html +++ b/demo/www/index.html @@ -41,6 +41,7 @@ BSP Rooms BSP Interior Drunkard Walk + Maze Random Generator diff --git a/demo/www/index.js b/demo/www/index.js index 0e23819..de206f1 100644 --- a/demo/www/index.js +++ b/demo/www/index.js @@ -60,6 +60,12 @@ function newBspRooms() { requestAnimationFrame(renderLoop); } +function newMaze() { + var seed = Date.now(); + world = World.new_maze(GRID_COLS, GRID_ROWS, get_seed()); + requestAnimationFrame(renderLoop); +} + function newRandomGen() { var seed = Date.now(); world = World.new_random(GRID_COLS, GRID_ROWS, get_seed()); @@ -156,4 +162,5 @@ document.getElementById('simple-rooms-option').addEventListener('click', newSimp document.getElementById('bsp-rooms-option').addEventListener('click', newBspRooms); document.getElementById('drunkard-option').addEventListener('click', newDrunkard); document.getElementById('bsp-interior-option').addEventListener('click', newBspInterior); +document.getElementById('maze-option').addEventListener('click', newMaze); document.getElementById('random-option').addEventListener('click', newRandomGen); diff --git a/docs/0.bootstrap.js b/docs/0.bootstrap.js index 2d4e83c..4328fad 100644 --- a/docs/0.bootstrap.js +++ b/docs/0.bootstrap.js @@ -20,7 +20,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _map /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* WEBPACK VAR INJECTION */(function(module, global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Cell\", function() { return Cell; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Position\", function() { return Position; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"World\", function() { return World; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_object_drop_ref\", function() { return __wbindgen_object_drop_ref; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getRandomValues_3ac1b33c90b52596\", function() { return __wbg_getRandomValues_3ac1b33c90b52596; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_randomFillSync_6f956029658662ec\", function() { return __wbg_randomFillSync_6f956029658662ec; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_self_1c83eb4471d9eb9b\", function() { return __wbg_self_1c83eb4471d9eb9b; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_static_accessor_MODULE_abf5ae284bffdf45\", function() { return __wbg_static_accessor_MODULE_abf5ae284bffdf45; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_require_5b2b5b594d809d9f\", function() { return __wbg_require_5b2b5b594d809d9f; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_crypto_c12f14e810edcaa2\", function() { return __wbg_crypto_c12f14e810edcaa2; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_msCrypto_679be765111ba775\", function() { return __wbg_msCrypto_679be765111ba775; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_is_undefined\", function() { return __wbindgen_is_undefined; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getRandomValues_05a60bf171bfc2be\", function() { return __wbg_getRandomValues_05a60bf171bfc2be; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_instanceof_Window_adf3196bdc02b386\", function() { return __wbg_instanceof_Window_adf3196bdc02b386; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_document_6cc8d0b87c0a99b9\", function() { return __wbg_document_6cc8d0b87c0a99b9; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getElementById_0cb6ad9511b1efc0\", function() { return __wbg_getElementById_0cb6ad9511b1efc0; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_setinnerHTML_4ff235db1a3cb4d8\", function() { return __wbg_setinnerHTML_4ff235db1a3cb4d8; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_call_8e95613cc6524977\", function() { return __wbg_call_8e95613cc6524977; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_object_clone_ref\", function() { return __wbindgen_object_clone_ref; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_newnoargs_f3b8a801d5d4b079\", function() { return __wbg_newnoargs_f3b8a801d5d4b079; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_self_07b2f89e82ceb76d\", function() { return __wbg_self_07b2f89e82ceb76d; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_window_ba85d88572adc0dc\", function() { return __wbg_window_ba85d88572adc0dc; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_globalThis_b9277fc37e201fe5\", function() { return __wbg_globalThis_b9277fc37e201fe5; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_global_e16303fe83e1d57f\", function() { return __wbg_global_e16303fe83e1d57f; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_throw\", function() { return __wbindgen_throw; });\n/* harmony import */ var _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapgen_demo_bg.wasm */ \"../pkg/mapgen_demo_bg.wasm\");\n\n\nconst heap = new Array(32).fill(undefined);\n\nheap.push(undefined, null, true, false);\n\nfunction getObject(idx) { return heap[idx]; }\n\nlet heap_next = heap.length;\n\nfunction dropObject(idx) {\n if (idx < 36) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nconst lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;\n\nlet cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nlet cachegetUint8Memory0 = null;\nfunction getUint8Memory0() {\n if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"memory\"].buffer) {\n cachegetUint8Memory0 = new Uint8Array(_mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"memory\"].buffer);\n }\n return cachegetUint8Memory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));\n}\n\nfunction handleError(f) {\n return function () {\n try {\n return f.apply(this, arguments);\n\n } catch (e) {\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbindgen_exn_store\"](addHeapObject(e));\n }\n };\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n/**\n*/\nconst Cell = Object.freeze({ Floor:0,\"0\":\"Floor\",Wall:1,\"1\":\"Wall\", });\n/**\n*/\nclass Position {\n\n static __wrap(ptr) {\n const obj = Object.create(Position.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n free() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbg_position_free\"](ptr);\n }\n /**\n * @param {number} col\n * @param {number} row\n * @returns {Position}\n */\n static new(col, row) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_new\"](col, row);\n return Position.__wrap(ret);\n }\n /**\n * @returns {number}\n */\n col() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_col\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n row() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_row\"](this.ptr);\n return ret >>> 0;\n }\n}\n/**\n*/\nclass World {\n\n static __wrap(ptr) {\n const obj = Object.create(World.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n free() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbg_world_free\"](ptr);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_cellular_automata(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_cellular_automata\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_simple_rooms(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_simple_rooms\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_bsp_rooms(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_bsp_rooms\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_bsp_interior(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_bsp_interior\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_drunkard(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_drunkard\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_random(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_random\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @returns {number}\n */\n width() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_col\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n height() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_height\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n tiles() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_tiles\"](this.ptr);\n return ret;\n }\n /**\n * @returns {Position}\n */\n player_pos() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_player_pos\"](this.ptr);\n return Position.__wrap(ret);\n }\n /**\n * @returns {Position}\n */\n exit_pos() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_exit_pos\"](this.ptr);\n return Position.__wrap(ret);\n }\n}\n\nconst __wbindgen_object_drop_ref = function(arg0) {\n takeObject(arg0);\n};\n\nconst __wbg_getRandomValues_3ac1b33c90b52596 = function(arg0, arg1, arg2) {\n getObject(arg0).getRandomValues(getArrayU8FromWasm0(arg1, arg2));\n};\n\nconst __wbg_randomFillSync_6f956029658662ec = function(arg0, arg1, arg2) {\n getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2));\n};\n\nconst __wbg_self_1c83eb4471d9eb9b = handleError(function() {\n var ret = self.self;\n return addHeapObject(ret);\n});\n\nconst __wbg_static_accessor_MODULE_abf5ae284bffdf45 = function() {\n var ret = module;\n return addHeapObject(ret);\n};\n\nconst __wbg_require_5b2b5b594d809d9f = function(arg0, arg1, arg2) {\n var ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2));\n return addHeapObject(ret);\n};\n\nconst __wbg_crypto_c12f14e810edcaa2 = function(arg0) {\n var ret = getObject(arg0).crypto;\n return addHeapObject(ret);\n};\n\nconst __wbg_msCrypto_679be765111ba775 = function(arg0) {\n var ret = getObject(arg0).msCrypto;\n return addHeapObject(ret);\n};\n\nconst __wbindgen_is_undefined = function(arg0) {\n var ret = getObject(arg0) === undefined;\n return ret;\n};\n\nconst __wbg_getRandomValues_05a60bf171bfc2be = function(arg0) {\n var ret = getObject(arg0).getRandomValues;\n return addHeapObject(ret);\n};\n\nconst __wbg_instanceof_Window_adf3196bdc02b386 = function(arg0) {\n var ret = getObject(arg0) instanceof Window;\n return ret;\n};\n\nconst __wbg_document_6cc8d0b87c0a99b9 = function(arg0) {\n var ret = getObject(arg0).document;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n};\n\nconst __wbg_getElementById_0cb6ad9511b1efc0 = function(arg0, arg1, arg2) {\n var ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n};\n\nconst __wbg_setinnerHTML_4ff235db1a3cb4d8 = function(arg0, arg1, arg2) {\n getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);\n};\n\nconst __wbg_call_8e95613cc6524977 = handleError(function(arg0, arg1) {\n var ret = getObject(arg0).call(getObject(arg1));\n return addHeapObject(ret);\n});\n\nconst __wbindgen_object_clone_ref = function(arg0) {\n var ret = getObject(arg0);\n return addHeapObject(ret);\n};\n\nconst __wbg_newnoargs_f3b8a801d5d4b079 = function(arg0, arg1) {\n var ret = new Function(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n};\n\nconst __wbg_self_07b2f89e82ceb76d = handleError(function() {\n var ret = self.self;\n return addHeapObject(ret);\n});\n\nconst __wbg_window_ba85d88572adc0dc = handleError(function() {\n var ret = window.window;\n return addHeapObject(ret);\n});\n\nconst __wbg_globalThis_b9277fc37e201fe5 = handleError(function() {\n var ret = globalThis.globalThis;\n return addHeapObject(ret);\n});\n\nconst __wbg_global_e16303fe83e1d57f = handleError(function() {\n var ret = global.global;\n return addHeapObject(ret);\n});\n\nconst __wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n};\n\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../www/node_modules/webpack/buildin/harmony-module.js */ \"./node_modules/webpack/buildin/harmony-module.js\")(module), __webpack_require__(/*! ./../www/node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///../pkg/mapgen_demo_bg.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* WEBPACK VAR INJECTION */(function(module, global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Cell\", function() { return Cell; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Position\", function() { return Position; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"World\", function() { return World; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_object_drop_ref\", function() { return __wbindgen_object_drop_ref; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getRandomValues_3ac1b33c90b52596\", function() { return __wbg_getRandomValues_3ac1b33c90b52596; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_randomFillSync_6f956029658662ec\", function() { return __wbg_randomFillSync_6f956029658662ec; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_self_1c83eb4471d9eb9b\", function() { return __wbg_self_1c83eb4471d9eb9b; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_static_accessor_MODULE_abf5ae284bffdf45\", function() { return __wbg_static_accessor_MODULE_abf5ae284bffdf45; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_require_5b2b5b594d809d9f\", function() { return __wbg_require_5b2b5b594d809d9f; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_crypto_c12f14e810edcaa2\", function() { return __wbg_crypto_c12f14e810edcaa2; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_msCrypto_679be765111ba775\", function() { return __wbg_msCrypto_679be765111ba775; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_is_undefined\", function() { return __wbindgen_is_undefined; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getRandomValues_05a60bf171bfc2be\", function() { return __wbg_getRandomValues_05a60bf171bfc2be; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_instanceof_Window_adf3196bdc02b386\", function() { return __wbg_instanceof_Window_adf3196bdc02b386; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_document_6cc8d0b87c0a99b9\", function() { return __wbg_document_6cc8d0b87c0a99b9; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_getElementById_0cb6ad9511b1efc0\", function() { return __wbg_getElementById_0cb6ad9511b1efc0; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_setinnerHTML_4ff235db1a3cb4d8\", function() { return __wbg_setinnerHTML_4ff235db1a3cb4d8; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_call_8e95613cc6524977\", function() { return __wbg_call_8e95613cc6524977; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_object_clone_ref\", function() { return __wbindgen_object_clone_ref; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_newnoargs_f3b8a801d5d4b079\", function() { return __wbg_newnoargs_f3b8a801d5d4b079; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_self_07b2f89e82ceb76d\", function() { return __wbg_self_07b2f89e82ceb76d; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_window_ba85d88572adc0dc\", function() { return __wbg_window_ba85d88572adc0dc; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_globalThis_b9277fc37e201fe5\", function() { return __wbg_globalThis_b9277fc37e201fe5; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbg_global_e16303fe83e1d57f\", function() { return __wbg_global_e16303fe83e1d57f; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"__wbindgen_throw\", function() { return __wbindgen_throw; });\n/* harmony import */ var _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mapgen_demo_bg.wasm */ \"../pkg/mapgen_demo_bg.wasm\");\n\n\nconst heap = new Array(32).fill(undefined);\n\nheap.push(undefined, null, true, false);\n\nfunction getObject(idx) { return heap[idx]; }\n\nlet heap_next = heap.length;\n\nfunction dropObject(idx) {\n if (idx < 36) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nconst lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;\n\nlet cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nlet cachegetUint8Memory0 = null;\nfunction getUint8Memory0() {\n if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"memory\"].buffer) {\n cachegetUint8Memory0 = new Uint8Array(_mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"memory\"].buffer);\n }\n return cachegetUint8Memory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));\n}\n\nfunction handleError(f) {\n return function () {\n try {\n return f.apply(this, arguments);\n\n } catch (e) {\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbindgen_exn_store\"](addHeapObject(e));\n }\n };\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n/**\n*/\nconst Cell = Object.freeze({ Floor:0,\"0\":\"Floor\",Wall:1,\"1\":\"Wall\", });\n/**\n*/\nclass Position {\n\n static __wrap(ptr) {\n const obj = Object.create(Position.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n free() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbg_position_free\"](ptr);\n }\n /**\n * @param {number} col\n * @param {number} row\n * @returns {Position}\n */\n static new(col, row) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_new\"](col, row);\n return Position.__wrap(ret);\n }\n /**\n * @returns {number}\n */\n col() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_col\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n row() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_row\"](this.ptr);\n return ret >>> 0;\n }\n}\n/**\n*/\nclass World {\n\n static __wrap(ptr) {\n const obj = Object.create(World.prototype);\n obj.ptr = ptr;\n\n return obj;\n }\n\n free() {\n const ptr = this.ptr;\n this.ptr = 0;\n\n _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"__wbg_world_free\"](ptr);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_cellular_automata(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_cellular_automata\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_simple_rooms(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_simple_rooms\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_bsp_rooms(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_bsp_rooms\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_bsp_interior(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_bsp_interior\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_drunkard(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_drunkard\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_maze(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_maze\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @param {number} width\n * @param {number} height\n * @param {number} seed\n * @returns {World}\n */\n static new_random(width, height, seed) {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_new_random\"](width, height, seed);\n return World.__wrap(ret);\n }\n /**\n * @returns {number}\n */\n width() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"position_col\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n height() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_height\"](this.ptr);\n return ret >>> 0;\n }\n /**\n * @returns {number}\n */\n tiles() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_tiles\"](this.ptr);\n return ret;\n }\n /**\n * @returns {Position}\n */\n player_pos() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_player_pos\"](this.ptr);\n return Position.__wrap(ret);\n }\n /**\n * @returns {Position}\n */\n exit_pos() {\n var ret = _mapgen_demo_bg_wasm__WEBPACK_IMPORTED_MODULE_0__[\"world_exit_pos\"](this.ptr);\n return Position.__wrap(ret);\n }\n}\n\nconst __wbindgen_object_drop_ref = function(arg0) {\n takeObject(arg0);\n};\n\nconst __wbg_getRandomValues_3ac1b33c90b52596 = function(arg0, arg1, arg2) {\n getObject(arg0).getRandomValues(getArrayU8FromWasm0(arg1, arg2));\n};\n\nconst __wbg_randomFillSync_6f956029658662ec = function(arg0, arg1, arg2) {\n getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2));\n};\n\nconst __wbg_self_1c83eb4471d9eb9b = handleError(function() {\n var ret = self.self;\n return addHeapObject(ret);\n});\n\nconst __wbg_static_accessor_MODULE_abf5ae284bffdf45 = function() {\n var ret = module;\n return addHeapObject(ret);\n};\n\nconst __wbg_require_5b2b5b594d809d9f = function(arg0, arg1, arg2) {\n var ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2));\n return addHeapObject(ret);\n};\n\nconst __wbg_crypto_c12f14e810edcaa2 = function(arg0) {\n var ret = getObject(arg0).crypto;\n return addHeapObject(ret);\n};\n\nconst __wbg_msCrypto_679be765111ba775 = function(arg0) {\n var ret = getObject(arg0).msCrypto;\n return addHeapObject(ret);\n};\n\nconst __wbindgen_is_undefined = function(arg0) {\n var ret = getObject(arg0) === undefined;\n return ret;\n};\n\nconst __wbg_getRandomValues_05a60bf171bfc2be = function(arg0) {\n var ret = getObject(arg0).getRandomValues;\n return addHeapObject(ret);\n};\n\nconst __wbg_instanceof_Window_adf3196bdc02b386 = function(arg0) {\n var ret = getObject(arg0) instanceof Window;\n return ret;\n};\n\nconst __wbg_document_6cc8d0b87c0a99b9 = function(arg0) {\n var ret = getObject(arg0).document;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n};\n\nconst __wbg_getElementById_0cb6ad9511b1efc0 = function(arg0, arg1, arg2) {\n var ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n};\n\nconst __wbg_setinnerHTML_4ff235db1a3cb4d8 = function(arg0, arg1, arg2) {\n getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);\n};\n\nconst __wbg_call_8e95613cc6524977 = handleError(function(arg0, arg1) {\n var ret = getObject(arg0).call(getObject(arg1));\n return addHeapObject(ret);\n});\n\nconst __wbindgen_object_clone_ref = function(arg0) {\n var ret = getObject(arg0);\n return addHeapObject(ret);\n};\n\nconst __wbg_newnoargs_f3b8a801d5d4b079 = function(arg0, arg1) {\n var ret = new Function(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n};\n\nconst __wbg_self_07b2f89e82ceb76d = handleError(function() {\n var ret = self.self;\n return addHeapObject(ret);\n});\n\nconst __wbg_window_ba85d88572adc0dc = handleError(function() {\n var ret = window.window;\n return addHeapObject(ret);\n});\n\nconst __wbg_globalThis_b9277fc37e201fe5 = handleError(function() {\n var ret = globalThis.globalThis;\n return addHeapObject(ret);\n});\n\nconst __wbg_global_e16303fe83e1d57f = handleError(function() {\n var ret = global.global;\n return addHeapObject(ret);\n});\n\nconst __wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n};\n\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../www/node_modules/webpack/buildin/harmony-module.js */ \"./node_modules/webpack/buildin/harmony-module.js\")(module), __webpack_require__(/*! ./../www/node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///../pkg/mapgen_demo_bg.js?"); /***/ }), @@ -28,7 +28,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* WEBPACK VAR INJECTION */(f /*!**********************************!*\ !*** ../pkg/mapgen_demo_bg.wasm ***! \**********************************/ -/*! exports provided: memory, __wbg_world_free, __wbg_position_free, world_new_cellular_automata, world_new_simple_rooms, world_new_bsp_rooms, world_new_bsp_interior, world_new_drunkard, world_new_random, world_height, world_tiles, world_player_pos, world_exit_pos, position_new, position_col, position_row, world_width, __wbindgen_exn_store */ +/*! exports provided: memory, __wbg_world_free, __wbg_position_free, world_new_cellular_automata, world_new_simple_rooms, world_new_bsp_rooms, world_new_bsp_interior, world_new_drunkard, world_new_maze, world_new_random, world_height, world_tiles, world_player_pos, world_exit_pos, position_new, position_col, position_row, world_width, __wbindgen_exn_store */ /***/ (function(module, exports, __webpack_require__) { eval("\"use strict\";\n// Instantiate WebAssembly module\nvar wasmExports = __webpack_require__.w[module.i];\n__webpack_require__.r(exports);\n// export exports from WebAssembly module\nfor(var name in wasmExports) if(name != \"__webpack_init__\") exports[name] = wasmExports[name];\n// exec imports from WebAssembly module (for esm order)\n/* harmony import */ var m0 = __webpack_require__(/*! ./mapgen_demo_bg.js */ \"../pkg/mapgen_demo_bg.js\");\n\n\n// exec wasm module\nwasmExports[\"__webpack_init__\"]()\n\n//# sourceURL=webpack:///../pkg/mapgen_demo_bg.wasm?"); @@ -43,7 +43,7 @@ eval("\"use strict\";\n// Instantiate WebAssembly module\nvar wasmExports = __we /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var mapgen_demo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mapgen-demo */ \"../pkg/mapgen_demo.js\");\n/* harmony import */ var mapgen_demo_mapgen_demo_bg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! mapgen-demo/mapgen_demo_bg */ \"../pkg/mapgen_demo_bg.wasm\");\n\n\n\nconst CANVAS_SIZE = 750;\nconst GRID_COLS = 80;\nconst GRID_ROWS = 50;\nconst CELL_SIZE = CANVAS_SIZE/GRID_ROWS;\nconst TILE_SIZE = 39;\n\n// Init canvas\nconst canvas = document.getElementById(\"mapgen-canvas\");\ncanvas.height = CELL_SIZE * GRID_ROWS;\ncanvas.width = CELL_SIZE * GRID_COLS;\nconst ctx = canvas.getContext('2d');\n// Info box\nconst infoDiv = document.getElementById('map-info');\n// API to the WASM\nlet world = null;\n\n// Load tiles bitmap\nlet tiles_image = new Image();\ntiles_image.src = 'assets/tiles.png';\n\n// Take provided seed or generate new one\nfunction get_seed() {\n var seed_text = document.getElementById(\"seed\").value;\n if( seed_text.length > 0) {\n return Number(seed_text);\n } \n return Date.now();\n}\n\n// Map generators\nfunction newCellularAutomata() {\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_cellular_automata(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newSimpleRooms() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_simple_rooms(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newBspInterior() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_bsp_interior(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newDrunkard() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_drunkard(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newBspRooms() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_bsp_rooms(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newRandomGen() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_random(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nconst renderLoop = () => {\n // universe.tick();\n drawCells();\n requestAnimationFrame(renderLoop);\n};\n\nconst getIndex = (row, column) => {\n return row * GRID_COLS + column;\n};\n\nconst is_inner_wall = (tiles, col, row) => {\n for (let c = Math.max(col - 1, 0); c < Math.min(col + 2, GRID_COLS); c++) {\n for (let r = Math.max(row - 1, 0); r < Math.min(row + 2, GRID_ROWS); r++) {\n if ((c != col || r != row) && tiles[getIndex(r, c)] == mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"Cell\"].Floor) {\n return false;\n }\n }\n }\n\n return true;\n}\n\nconst draw_tile = (ctx, row, col, tile_type) => {\n var tile_x = 0;\n var tile_y = 0;\n if (tile_type == \"floor\") {\n tile_x = 3;\n tile_y = 2;\n } else if (tile_type == \"wall\") {\n tile_x = 0;\n tile_y = 3;\n } else if (tile_type == \"player\") {\n tile_x = 0;\n tile_y = 8;\n } else if (tile_type == \"exit\") {\n tile_x = 10;\n tile_y = 1;\n } else {\n tile_x = 18;\n tile_y = 0;\n }\n\n ctx.drawImage(\n tiles_image,\n tile_x * TILE_SIZE + 3,\n tile_y * TILE_SIZE + 3,\n TILE_SIZE - 3,\n TILE_SIZE - 3,\n col * CELL_SIZE,\n row * CELL_SIZE,\n CELL_SIZE,\n CELL_SIZE);\n\n}\n\nconst drawCells = () => {\n const tilesPtr = world.tiles();\n const tiles = new Uint8Array(mapgen_demo_mapgen_demo_bg__WEBPACK_IMPORTED_MODULE_1__[\"memory\"].buffer, tilesPtr, GRID_COLS * GRID_ROWS);\n\n // tiles\n for (let row = 0; row < GRID_ROWS; row++) {\n for (let col = 0; col < GRID_COLS; col++) {\n const idx = getIndex(row, col);\n if (tiles[idx] == mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"Cell\"].Floor) {\n draw_tile(ctx, row, col, \"floor\");\n } else if (is_inner_wall(tiles, col, row)){\n draw_tile(ctx, row, col, \"inner-wall\");\n } else {\n draw_tile(ctx, row, col, \"wall\");\n }\n }\n }\n\n // Player position\n let player = world.player_pos();\n draw_tile(ctx, player.row(), player.col(), \"player\");\n\n // Exit position\n let exit = world.exit_pos();\n draw_tile(ctx, exit.row(), exit.col(), \"exit\");\n};\n\nnewRandomGen();\n\n// Connect UI element\ndocument.getElementById('cellular-automata-option').addEventListener('click', newCellularAutomata);\ndocument.getElementById('simple-rooms-option').addEventListener('click', newSimpleRooms);\ndocument.getElementById('bsp-rooms-option').addEventListener('click', newBspRooms);\ndocument.getElementById('drunkard-option').addEventListener('click', newDrunkard);\ndocument.getElementById('bsp-interior-option').addEventListener('click', newBspInterior);\ndocument.getElementById('random-option').addEventListener('click', newRandomGen);\n\n\n//# sourceURL=webpack:///./index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var mapgen_demo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! mapgen-demo */ \"../pkg/mapgen_demo.js\");\n/* harmony import */ var mapgen_demo_mapgen_demo_bg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! mapgen-demo/mapgen_demo_bg */ \"../pkg/mapgen_demo_bg.wasm\");\n\n\n\nconst CANVAS_SIZE = 750;\nconst GRID_COLS = 80;\nconst GRID_ROWS = 50;\nconst CELL_SIZE = CANVAS_SIZE/GRID_ROWS;\nconst TILE_SIZE = 39;\n\n// Init canvas\nconst canvas = document.getElementById(\"mapgen-canvas\");\ncanvas.height = CELL_SIZE * GRID_ROWS;\ncanvas.width = CELL_SIZE * GRID_COLS;\nconst ctx = canvas.getContext('2d');\n// Info box\nconst infoDiv = document.getElementById('map-info');\n// API to the WASM\nlet world = null;\n\n// Load tiles bitmap\nlet tiles_image = new Image();\ntiles_image.src = 'assets/tiles.png';\n\n// Take provided seed or generate new one\nfunction get_seed() {\n var seed_text = document.getElementById(\"seed\").value;\n if( seed_text.length > 0) {\n return Number(seed_text);\n } \n return Date.now();\n}\n\n// Map generators\nfunction newCellularAutomata() {\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_cellular_automata(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newSimpleRooms() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_simple_rooms(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newBspInterior() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_bsp_interior(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newDrunkard() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_drunkard(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newBspRooms() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_bsp_rooms(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newMaze() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_maze(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nfunction newRandomGen() {\n var seed = Date.now();\n world = mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"World\"].new_random(GRID_COLS, GRID_ROWS, get_seed());\n requestAnimationFrame(renderLoop);\n}\n\nconst renderLoop = () => {\n // universe.tick();\n drawCells();\n requestAnimationFrame(renderLoop);\n};\n\nconst getIndex = (row, column) => {\n return row * GRID_COLS + column;\n};\n\nconst is_inner_wall = (tiles, col, row) => {\n for (let c = Math.max(col - 1, 0); c < Math.min(col + 2, GRID_COLS); c++) {\n for (let r = Math.max(row - 1, 0); r < Math.min(row + 2, GRID_ROWS); r++) {\n if ((c != col || r != row) && tiles[getIndex(r, c)] == mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"Cell\"].Floor) {\n return false;\n }\n }\n }\n\n return true;\n}\n\nconst draw_tile = (ctx, row, col, tile_type) => {\n var tile_x = 0;\n var tile_y = 0;\n if (tile_type == \"floor\") {\n tile_x = 3;\n tile_y = 2;\n } else if (tile_type == \"wall\") {\n tile_x = 0;\n tile_y = 3;\n } else if (tile_type == \"player\") {\n tile_x = 0;\n tile_y = 8;\n } else if (tile_type == \"exit\") {\n tile_x = 10;\n tile_y = 1;\n } else {\n tile_x = 18;\n tile_y = 0;\n }\n\n ctx.drawImage(\n tiles_image,\n tile_x * TILE_SIZE + 3,\n tile_y * TILE_SIZE + 3,\n TILE_SIZE - 3,\n TILE_SIZE - 3,\n col * CELL_SIZE,\n row * CELL_SIZE,\n CELL_SIZE,\n CELL_SIZE);\n\n}\n\nconst drawCells = () => {\n const tilesPtr = world.tiles();\n const tiles = new Uint8Array(mapgen_demo_mapgen_demo_bg__WEBPACK_IMPORTED_MODULE_1__[\"memory\"].buffer, tilesPtr, GRID_COLS * GRID_ROWS);\n\n // tiles\n for (let row = 0; row < GRID_ROWS; row++) {\n for (let col = 0; col < GRID_COLS; col++) {\n const idx = getIndex(row, col);\n if (tiles[idx] == mapgen_demo__WEBPACK_IMPORTED_MODULE_0__[\"Cell\"].Floor) {\n draw_tile(ctx, row, col, \"floor\");\n } else if (is_inner_wall(tiles, col, row)){\n draw_tile(ctx, row, col, \"inner-wall\");\n } else {\n draw_tile(ctx, row, col, \"wall\");\n }\n }\n }\n\n // Player position\n let player = world.player_pos();\n draw_tile(ctx, player.row(), player.col(), \"player\");\n\n // Exit position\n let exit = world.exit_pos();\n draw_tile(ctx, exit.row(), exit.col(), \"exit\");\n};\n\nnewRandomGen();\n\n// Connect UI element\ndocument.getElementById('cellular-automata-option').addEventListener('click', newCellularAutomata);\ndocument.getElementById('simple-rooms-option').addEventListener('click', newSimpleRooms);\ndocument.getElementById('bsp-rooms-option').addEventListener('click', newBspRooms);\ndocument.getElementById('drunkard-option').addEventListener('click', newDrunkard);\ndocument.getElementById('bsp-interior-option').addEventListener('click', newBspInterior);\ndocument.getElementById('maze-option').addEventListener('click', newMaze);\ndocument.getElementById('random-option').addEventListener('click', newRandomGen);\n\n\n//# sourceURL=webpack:///./index.js?"); /***/ }), diff --git a/docs/bootstrap.js b/docs/bootstrap.js index 7acec5e..3052c17 100644 --- a/docs/bootstrap.js +++ b/docs/bootstrap.js @@ -222,7 +222,7 @@ /******/ promises.push(installedWasmModuleData); /******/ else { /******/ var importObject = wasmImportObjects[wasmModuleId](); -/******/ var req = fetch(__webpack_require__.p + "" + {"../pkg/mapgen_demo_bg.wasm":"3bda724f23e860df0b9c"}[wasmModuleId] + ".module.wasm"); +/******/ var req = fetch(__webpack_require__.p + "" + {"../pkg/mapgen_demo_bg.wasm":"fa6c9d72e1d9a518ed31"}[wasmModuleId] + ".module.wasm"); /******/ var promise; /******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') { /******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) { diff --git a/docs/fa6c9d72e1d9a518ed31.module.wasm b/docs/fa6c9d72e1d9a518ed31.module.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d320f2952b9e398c8a6a2eef98cfc305e36bede6 GIT binary patch literal 106269 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html index 486667b..e3fc112 100644 --- a/docs/index.html +++ b/docs/index.html @@ -41,6 +41,7 @@ BSP Rooms BSP Interior Drunkard Walk + Maze Random Generator diff --git a/src/filter/maze.rs b/src/filter/maze.rs new file mode 100644 index 0000000..9931d00 --- /dev/null +++ b/src/filter/maze.rs @@ -0,0 +1,217 @@ +//! Example generator usage: +//! ``` +//! use rand::prelude::*; +//! use mapgen::{Map, MapFilter}; +//! use mapgen::filter::MazeBuilder; +//! +//! let mut rng = StdRng::seed_from_u64(100); +//! let gen = MazeBuilder::new(); +//! let map = gen.modify_map(&mut rng, &Map::new(80, 50)); +//! +//! assert_eq!(map.width, 80); +//! assert_eq!(map.height, 50); +//! ``` +//! + +use rand::prelude::*; +use crate::MapFilter; +use crate::{ + map::{Map, TileType}, + random::Rng +}; + + +pub struct MazeBuilder {} + +impl MapFilter for MazeBuilder { + fn modify_map(&self, rng: &mut StdRng, map: &Map) -> Map { + self.build(rng, map) + } +} + +impl MazeBuilder { + pub fn new() -> Box { + Box::new(MazeBuilder{}) + } + + #[allow(clippy::map_entry)] + fn build(&self, rng: &mut StdRng, map: &Map) -> Map { + let mut new_map = map.clone(); + let mut maze = Grid::new((map.width as i32/ 2)-2, (map.height as i32/ 2)-2, rng); + maze.generate_maze(&mut new_map); + new_map + } +} + +/* Maze code taken under MIT from https://github.com/cyucelen/mazeGenerator/ */ + +const TOP : usize = 0; +const RIGHT : usize = 1; +const BOTTOM : usize = 2; +const LEFT : usize = 3; + +#[derive(Copy, Clone)] +struct Cell { + row: i32, + column: i32, + walls: [bool; 4], + visited: bool, +} + +impl Cell { + fn new(row: i32, column: i32) -> Cell { + Cell{ + row, + column, + walls: [true, true, true, true], + visited: false + } + } + + fn remove_walls(&mut self, next : &mut Cell) { + let x = self.column - next.column; + let y = self.row - next.row; + + if x == 1 { + self.walls[LEFT] = false; + next.walls[RIGHT] = false; + } + else if x == -1 { + self.walls[RIGHT] = false; + next.walls[LEFT] = false; + } + else if y == 1 { + self.walls[TOP] = false; + next.walls[BOTTOM] = false; + } + else if y == -1 { + self.walls[BOTTOM] = false; + next.walls[TOP] = false; + } + } +} + +struct Grid<'a> { + width: i32, + height: i32, + cells: Vec, + backtrace: Vec, + current: usize, + rng : &'a mut StdRng +} + +impl<'a> Grid<'a> { + fn new(width: i32, height:i32, rng: &mut StdRng) -> Grid { + let mut grid = Grid{ + width, + height, + cells: Vec::new(), + backtrace: Vec::new(), + current: 0, + rng + }; + + for row in 0..height { + for column in 0..width { + grid.cells.push(Cell::new(row, column)); + } + } + + grid + } + + fn calculate_index(&self, row: i32, column: i32) -> i32 { + if row < 0 || column < 0 || column > self.width-1 || row > self.height-1 { + -1 + } else { + column + (row * self.width) + } + } + + fn get_available_neighbors(&self) -> Vec { + let mut neighbors : Vec = Vec::new(); + + let current_row = self.cells[self.current].row; + let current_column = self.cells[self.current].column; + + let neighbor_indices : [i32; 4] = [ + self.calculate_index(current_row -1, current_column), + self.calculate_index(current_row, current_column + 1), + self.calculate_index(current_row + 1, current_column), + self.calculate_index(current_row, current_column - 1) + ]; + + for i in neighbor_indices.iter() { + if *i != -1 && !self.cells[*i as usize].visited { + neighbors.push(*i as usize); + } + } + + neighbors + } + + fn find_next_cell(&mut self) -> Option { + let neighbors = self.get_available_neighbors(); + if !neighbors.is_empty() { + if neighbors.len() == 1 { + return Some(neighbors[0]); + } else { + return Some(neighbors[(self.rng.roll_dice(1, neighbors.len())-1) as usize]); + } + } + None + } + + fn generate_maze(&mut self, map: &mut Map) { + let mut i = 0; + loop { + self.cells[self.current].visited = true; + let next = self.find_next_cell(); + + match next { + Some(next) => { + self.cells[next].visited = true; + self.backtrace.push(self.current); + // __lower_part__ __higher_part_ + // / \ / \ + // --------cell1------ | cell2----------- + let (lower_part, higher_part) = + self.cells.split_at_mut(std::cmp::max(self.current, next)); + let cell1 = &mut lower_part[std::cmp::min(self.current, next)]; + let cell2 = &mut higher_part[0]; + cell1.remove_walls(cell2); + self.current = next; + } + None => { + if !self.backtrace.is_empty() { + self.current = self.backtrace[0]; + self.backtrace.remove(0); + } else { + break; + } + } + } + + if i % 50 == 0 { + self.copy_to_map(map); + } + i += 1; + } + } + + fn copy_to_map(&self, map: &mut Map) { + // Clear the map + for i in map.tiles.iter_mut() { *i = TileType::Wall; } + + for cell in self.cells.iter() { + let x = (cell.column as usize + 1) * 2; + let y = (cell.row as usize + 1) * 2; + + map.set_tile(x, y, TileType::Floor); + if !cell.walls[TOP] { map.set_tile(x, y-1, TileType::Floor) } + if !cell.walls[RIGHT] { map.set_tile(x+1, y, TileType::Floor) } + if !cell.walls[BOTTOM] { map.set_tile(x, y+1, TileType::Floor) } + if !cell.walls[LEFT] { map.set_tile(x-1, y, TileType::Floor) } + } + } +} \ No newline at end of file diff --git a/src/filter/mod.rs b/src/filter/mod.rs index ee3d553..0c191a6 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -7,6 +7,7 @@ pub mod cellular_automata; pub mod cull_unreachable; pub mod distant_exit; pub mod drunkard; +pub mod maze; pub mod noise_generator; pub mod simple_rooms; pub mod rooms_corridors_nearest; @@ -18,6 +19,7 @@ pub use cellular_automata::CellularAutomata; pub use cull_unreachable::CullUnreachable; pub use distant_exit::DistantExit; pub use drunkard::DrunkardsWalk; +pub use maze::MazeBuilder; pub use noise_generator::NoiseGenerator; pub use simple_rooms::SimpleRooms; pub use rooms_corridors_nearest::NearestCorridors;