mazegen.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. export const mazegen = (function() {
  2. function RouletteSelect(src) {
  3. const roll = Math.random() * src.length;
  4. let sum = 0;
  5. for (let i = 0; i < src.length; i++) {
  6. sum += 1.0;
  7. if (roll < sum) {
  8. const res = src[i];
  9. src = src.splice(i, 1);
  10. return res;
  11. }
  12. }
  13. }
  14. function _Key(x, y) {
  15. return x + '.' + y;
  16. }
  17. return {
  18. MazeGenerator: class {
  19. constructor(nodes) {
  20. this._nodes = nodes;
  21. this._visited = {};
  22. }
  23. *GenerateIteratively(nodeKey) {
  24. this._visited[nodeKey] = true;
  25. const node = this._nodes[nodeKey];
  26. node.metadata.render.visited = true;
  27. node.metadata.render.active = true;
  28. const neighbours = [...node.potentialEdges];
  29. while (neighbours.length > 0) {
  30. const ki = RouletteSelect(neighbours);
  31. if (!(ki in this._visited)) {
  32. node.metadata.render.active = true;
  33. const adjNode = this._nodes[ki];
  34. yield;
  35. node.edges.push(ki);
  36. adjNode.edges.push(nodeKey);
  37. node.metadata.render.active = false;
  38. yield* this.GenerateIteratively(ki);
  39. node.metadata.render.active = true;
  40. }
  41. }
  42. yield;
  43. node.metadata.render.active = false;
  44. }
  45. GenerateMaze(start) {
  46. this._ProcessNode(start);
  47. }
  48. _ProcessNode(nodeKey) {
  49. this._visited[nodeKey] = true;
  50. const node = this._nodes[nodeKey];
  51. const neighbours = [...node.potentialEdges];
  52. while (neighbours.length > 0) {
  53. const ki = RouletteSelect(neighbours);
  54. if (!(ki in this._visited)) {
  55. const adjNode = this._nodes[ki];
  56. node.edges.push(ki);
  57. adjNode.edges.push(nodeKey);
  58. this._ProcessNode(ki);
  59. }
  60. }
  61. }
  62. }
  63. };
  64. })();