Ceremonial PR: fix map gen #39
| @@ -111,6 +111,15 @@ export class Point { | |||||||
|     let dy = other.y - this.y; |     let dy = other.y - this.y; | ||||||
|     return Math.sqrt(dx * dx + dy * dy); |     return Math.sqrt(dx * dx + dy * dy); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   neighbors() : Point[] { | ||||||
|  |     return [ | ||||||
|  |       new Point(this.x, this.y-1), | ||||||
|  |       new Point(this.x-1, this.y), | ||||||
|  |       new Point(this.x, this.y+1), | ||||||
|  |       new Point(this.x+1, this.y), | ||||||
|  |     ]; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| export class Size { | export class Size { | ||||||
| @@ -264,19 +273,27 @@ export class Grid<T> { | |||||||
|     return new Grid(this.size, (xy) => cbCell(this.get(xy), xy)); |     return new Grid(this.size, (xy) => cbCell(this.get(xy), xy)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   #checkPosition(position: Point) { |   #invalidPosition(position: Point) : boolean { | ||||||
|     if ( |     return position.x < 0 || | ||||||
|       position.x < 0 || |  | ||||||
|       position.x >= this.size.w || |       position.x >= this.size.w || | ||||||
|       Math.floor(position.x) != position.x || |       Math.floor(position.x) != position.x || | ||||||
|       position.y < 0 || |       position.y < 0 || | ||||||
|       position.y >= this.size.h || |       position.y >= this.size.h || | ||||||
|       Math.floor(position.y) != position.y |       Math.floor(position.y) != position.y;; | ||||||
|     ) { |   } | ||||||
|  |   #checkPosition(position: Point) { | ||||||
|  |     if (this.#invalidPosition(position)) { | ||||||
|       throw new Error(`invalid position for ${this.size}: ${position}`); |       throw new Error(`invalid position for ${this.size}: ${position}`); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   maybeGet(position: Point): T | null { | ||||||
|  |     if (this.#invalidPosition(position)) { | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |     return this.#data[position.y][position.x]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   get(position: Point): T { |   get(position: Point): T { | ||||||
|     this.#checkPosition(position); |     this.#checkPosition(position); | ||||||
|     return this.#data[position.y][position.x]; |     return this.#data[position.y][position.x]; | ||||||
|   | |||||||
| @@ -105,6 +105,51 @@ export class LoadedNewMap { | |||||||
|   getZoneLabel(point: Point): string | null { |   getZoneLabel(point: Point): string | null { | ||||||
|     return this.#zoneLabels.get(point); |     return this.#zoneLabels.get(point); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   isConnected(): boolean { | ||||||
|  |     const size = this.#size; | ||||||
|  |     let reached = new Grid<boolean>(size, ()=>false); | ||||||
|  |  | ||||||
|  |     // find starting location | ||||||
|  |     const found: Point | null = (()=>{ | ||||||
|  |       for(let x = 0; x < size.w; x++) { | ||||||
|  |         for(let y = 0; y < size.w; y++) { | ||||||
|  |           const p = new Point(x, y) | ||||||
|  |           if (this.#architecture.get(p) == Architecture.Floor) { | ||||||
|  |             return p; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return null; | ||||||
|  |     })(); | ||||||
|  |     if (found === null) { | ||||||
|  |       // technically, all open floors on the map are indeed connected | ||||||
|  |       return true | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let stack : Point[] = [found]; | ||||||
|  |     reached.set(found, true); | ||||||
|  |     while (stack.length > 0) { | ||||||
|  |       const loc = stack.pop() as Point; | ||||||
|  |       for (var p of loc.neighbors()) { | ||||||
|  |         if ((this.#architecture.maybeGet(p) === Architecture.Floor) && !reached.get(p)) { | ||||||
|  |           reached.set(p, true); | ||||||
|  |           stack.push(p); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for(let x = 0; x < size.w; x++) { | ||||||
|  |       for(let y = 0; y < size.w; y++) { | ||||||
|  |         const p = new Point(x, y) | ||||||
|  |         if (this.#architecture.get(p) == Architecture.Floor && !reached.get(p)) { | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| export class CellView { | export class CellView { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user