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 0000000..d320f29 Binary files /dev/null and b/docs/fa6c9d72e1d9a518ed31.module.wasm differ 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;