text: const MapGen=function(){"use strict";function a(a){return Object.assign(Object.create(Object.getPrototypeOf(a)),a)}function b(a){return a.map(a=>a.road)}function c(a){return a.map(a=>[a.x,a.y,a.z])}function d(a){return a.map(a=>{const{vertices:b}=a;return a instanceof i?c([b.p1,b.p2,b.p3]):c([b.p1,b.p2,b.p3,b.p4])})}function e(a,c,e){const f=n.optMapGen(a,c,e),g=d(b(f));return g}class f{constructor(a,b,c){if(isNaN(a)||isNaN(b)||isNaN(c)||0>a||0>b||0>c)throw console.log(a,b,c),new Error("Wrong arguments for position");this.x=a,this.y=b,this.z=c}decrease(a){if(["x","y","z"].includes(a))return this[a]-=1,this;throw new Error("Expected x, y, or z chars")}increase(a){if(["x","y","z"].includes(a))return this[a]+=1,this;throw new Error("Expected x, y, or z chars")}}class g{constructor(a){if(isNaN(a)||0>a||Math.floor(a)!==a)throw new Error("3D Array size must be a positive integer");this.content=[],this.size=a;for(let b=0;b<Math.pow(a,3);++b)this.content.push(null)}get(a){if(!(a instanceof f))throw console.log(a),new Error("Expected 3D Pos as argument, got "+JSON.stringify(a));const{x:b,y:c,z:d}=a,e=this.size;if(0>b||0>c||0>d||b>=e||c>=e||d>=e)throw new Error("Pos out of map bounds");return this.content[b*e*e+c*e+d]}set(a,b){if(!(a instanceof f))throw console.log(a),new Error("Expected 3D Pos as argument, got "+JSON.stringify(a));const{x:c,y:d,z:e}=a,g=this.size;if(0>c||0>d||0>e||c>=g||d>=g||e>=g)throw new Error("Pos out of map bounds");this.content[c*g*g+d*g+e]=b}getSucc(a,b){if(!(a instanceof f&&[1,3,5,7].includes(b)))throw console.log(a,b),new Error("Bad args for getting succ");const{x:c,y:d,z:e}=a,g=this.size;if(0>c||0>d||0>e||c>=g||d>=g||e>=g)throw new Error("Pos out of map bounds");const h=g-1;let i;const j="x",k=(a,b,c,d)=>{try{return a?j:this.get(new f(b,c,d))}catch(a){return j}},l=0>c-1,m=c+1>h,n=0>d-1,o=0>d-2,p=d+1>h,q=d+1>h,r=0>e-1,s=e+1>h;switch(b){case 1:i={left:k(l,c-1,d,e),right:k(m,c+1,d,e),forward:k(s,c,d,e+1),upward:k(s||n,c,d-1,e+1)&&k(o||s,c,d-2,e+1),downward:k(p||s,c,d+1,e+1)&&k(q||s,c,d+2,e+1),above:k(n,c,d-1,e)&&k(o,c,d-2,e),under:k(p,c,d+1,e)&&k(q,c,d+2,e),underL:k(p||l,c-1,d+1,e)&&k(q||l,c-1,d+2,e),underR:k(p||m,c+1,d+1,e)&&k(q||m,c+1,d+2,e)};break;case 3:i={left:k(s,c,d,e+1),right:k(r,c,d,e-1),forward:k(m,c+1,d,e),upward:k(m||n,c+1,d-1,e)||k(o||m,c+1,d+2,e),downward:k(m||p,c+1,d+1,e)||k(q||m,c+1,d+2,e),above:k(n,c,d-1,e)||k(o,c,d+2,e),under:k(p,c,d+1,e)||k(q,c,d+2,e),underL:k(p||s,c,d+1,e+1)||k(q||s,c,d+2,e+1),underR:k(p||r,c,d+1,e-1)||k(q||r,c,d+2,e-1)};break;case 5:i={left:k(m,c+1,d,e),right:k(l,c-1,d,e),forward:k(r,c,d,e-1),upward:k(r||n,c,d-1,e-1)&&k(o||r,c,d+2,e-1),downward:k(r||p,c,d+1,e-1)&&k(q||r,c,d+2,e-1),above:k(n,c,d-1,e)&&k(o,c,d+2,e),under:k(p,c,d+1,e)&&k(q,c,d+2,e),underL:k(p||m,c+1,d+1,e)&&k(q||m,c+1,d+2,e),underR:k(p||l,c-1,d+1,e)&&k(q||l,c-1,d+2,e)};break;case 7:i={left:k(r,c,d,e-1),right:k(s,c,d,e+1),forward:k(l,c-1,d,e),upward:k(n||l,c-1,d-1,e)&&k(o||l,c-1,d+2,e),downward:k(p||l,c-1,d+1,e)&&k(q||l,c-1,d+2,e),above:k(n,c,d-1,e)&&k(o,c,d+2,e),under:k(p,c,d+1,e)&&k(q,c,d+2,e),underL:k(p||r,c,d+1,e-1)&&k(q||r,c,d+2,e-1),underR:k(p||s,c,d+1,e+1)&&k(q||s,c,d+2,e+1)};break;default:}return i}}class h{constructor(a){if(Math.floor(a)!==a)throw new Error("Maps can only have integer sizes");if(1>a)throw new Error("Map size must be positive and greater than zero");this.size={x:a,y:a,z:a},this.voxels=new g(a)}}class i{constructor(a,b,c){if(a instanceof f&&b instanceof f&&c instanceof f)this.vertices={p1:a,p2:b,p3:c};else throw console.log(a,b,c),new Error("Wrong arguments for creating triangle")}}class j{constructor(a,b,c,d){if(a instanceof f&&b instanceof f&&c instanceof f&&d instanceof f)this.vertices={p1:a,p2:b,p3:c,p4:d};else throw new Error("Wrong arguments for creating plane")}}class k{constructor(a){if(a instanceof f)this.pos=a;else throw new Error("Wrong arguments for creating voxel")}getVertices(){const{x:a,y:b,z:c}=this.pos;let d=new f(a,b,c),e=new f(a+1,b,c),g=new f(a+1,b,c+1),h=new f(a,b,c+1);return new j(d,e,g,h)}}class l{constructor(a,b){if(!(isNaN(a)&&isNaN(b))){if(1>a||8<a||a!=Math.floor(a))throw new Error("Unaccepted orientation argument for direction");if(0!==b&&-1!==b&&1!==b)throw new Error("Unaccepted climb argument for direction");this.orientation=a,this.climb=b}else throw new Error("Wrong parameter types for direction")}}class m{constructor(a,b,c){if(!(a instanceof k&&b instanceof l&&[1,3,5,7].includes(c)))throw console.log(a,b,c),new Error("Wrong parameter types for road");this.voxel=a,this.direction=b,this.road=m.createRoadPlane(a,b,c)}static createRoadPlane(a,b,c){if(!(a instanceof k&&b instanceof l&&[1,3,5,7].includes(c)))throw new Error("Wrong parameter types for road plane");const{orientation:d,climb:e}=b,f=a.getVertices(),{p1:g,p2:h,p3:m,p4:n}=f.vertices,o=d+c,p=9<o?o-9:o-1;switch(p){case 1:return-1===e?new j(g,h,m.increase("y"),n.increase("y")):0===e?new j(g,h,m,n):new j(g,h,m.decrease("y"),n.decrease("y"));break;case 2:if(0===e){if(1===c)return new i(g,h,m);if(3===c)return new i(m,n,g)}else throw new Error("Cannot create non-horizontal diagonal road segment");break;case 3:return-1===e?new j(g,h.increase("y"),m.increase("y"),n):0===e?new j(g,h,m,n):new j(g,h.decrease("y"),m.decrease("y"),n);break;case 4:if(0===e){if(3===c)return new i(n,g,h);if(5===c)return new i(m,n,h)}else throw new Error("Cannot create non-horizontal diagonal road segment");break;case 5:return-1===e?new j(g.increase("y"),h.increase("y"),m,n):0===e?new j(g,h,m,n):new j(g.decrease("y"),h.decrease("y"),m,n);break;case 6:if(0===e){if(5===c)return new i(g,m,n);if(7===c)return new i(h,m,g)}else throw new Error("Cannot create non-horizontal diagonal road segment");break;case 7:return-1===e?new j(g.increase("y"),h,m,n.increase("y")):0===e?new j(g,h,m,n):new j(g.decrease("y"),h,m,n.decrease("y"));break;case 8:if(0===e){if(7===c)return new i(n,h,m);if(1===c)return new i(g,n,h)}else throw new Error("Cannot create non-horizontal diagonal road segment");break;default:throw console.log(p,d,c),new Error("Invalid orientation for creating road plane");}}}class n{static optMapGen(a,b,c){function d(e,f,h,i){if(e.length==a)return e;const j=f.pos;g.set(j,l);const k=j.decrease("y"),o=j.increase("y");g.set(k,l),g.set(o,l);const p=g.getSucc(j,h),q=n.computeOptions(p,i,b,c);if(0<q.length){const a=n.shuffleArray(q);for(let b of a){const a=new m(f,b,h);g.set(j,a),e.push(a);const{currentVoxel:c,shape:i,currentDirection:k}=n.computeStepConsequences(b,h,j),l=d(e,c,k,i);if(!1!==l)return l;e.pop()}}return g.set(j,null),g.set(k,null),g.set(o,null),!1}const e=new h(a),g=e.voxels,i=Math.floor(a/2),j=new f(i,i,0),l="marked";let o=new k(j);return d([],o,1,"none")}static shuffleArray(a){const b=a.slice();for(let c=b.length-1;0<c;c--){const a=Math.floor(Math.random()*(c+1));[b[c],b[a]]=[b[a],b[c]]}return b}static getRandomInt(a,b){return Math.floor(Math.random()*(b-a))+a}static computeStepConsequences(b,c,d){const{climb:e,orientation:f}=b;let g,h;1===f?(g="square",h=1):2===f?(g="triangle",h=3):8===f?(g="triangle",h=7):void 0;let i=c-1+h;9<=i&&(i-=8);let j=a(d);switch(1===i?j.increase("z"):3===i?j.increase("x"):5===i?j.decrease("z"):7===i?j.decrease("x"):void 0,e){case 1:j.decrease("y");break;case-1:j.increase("y");break;default:}const l=new k(j);return{currentVoxel:l,shape:g,currentDirection:i}}static computeOptions(a,b,c,d){let e=[];const f=null===a.forward,g=null===a.downward,h=null===a.under,i=null===a.above,j=null===a.left,k=null===a.right,m=null===a.underL,n=null===a.underR,o=null===a.upward;return j&&k&&m&&h&&"square"===b&&e.push(new l(8,0)),k&&j&&n&&h&&"square"===b&&e.push(new l(2,0)),j&&k&&o&&f&&i&&(e=e.concat(Array(d).fill(new l(1,1)))),j&&k&&g&&h&&f&&(e=e.concat(Array(d).fill(new l(1,-1)))),j&&k&&f&&g&&h&&(e=e.concat(Array(c).fill(new l(1,0)))),e}}return{getMap:e,generateJSONMap:function(a,b,c){return JSON.stringify(e(a,b,c))}}}();