created path finding web worker

This commit is contained in:
Evan
2024-11-28 12:25:34 -08:00
parent 2216c34c41
commit 3e4f4e42cf
24 changed files with 643 additions and 306 deletions
+18 -5
View File
@@ -131,7 +131,21 @@ export class PlayerInfo {
) { }
}
export interface Tile {
export interface SearchNode {
cost(): number;
cell(): Cell
}
export interface TerrainMap {
terrain(cell: Cell): TerrainTile
neighbors(terrainTile: TerrainTile): TerrainTile[]
}
export interface TerrainTile extends SearchNode {
terrainType(): TerrainType
}
export interface Tile extends SearchNode {
isLand(): boolean
isShore(): boolean
isOceanShore(): boolean
@@ -150,8 +164,6 @@ export interface Tile {
neighbors(): Tile[]
neighborsWrapped(): Tile[]
onShore(): boolean
x(): number
y(): number
}
export interface Unit {
@@ -279,7 +291,7 @@ export interface Game {
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void
units(...types: UnitType[]): Unit[]
unitInfo(type: UnitType): UnitInfo
searchMap(): SharedArrayBuffer
terrainMap(): TerrainMap
}
export interface MutableGame extends Game {
@@ -325,4 +337,5 @@ export class TargetPlayerEvent implements GameEvent {
export class EmojiMessageEvent implements GameEvent {
constructor(public readonly message: EmojiMessage) { }
}
}
+10 -12
View File
@@ -2,7 +2,7 @@ import { info } from "console";
import { Config } from "../configuration/Config";
import { EventBus } from "../EventBus";
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Unit, UnitEvent as UnitEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance, AllianceExpiredEvent, Nation, UnitType, UnitInfo } from "./Game";
import { TerrainMap } from "./TerrainMapLoader";
import { TerrainMapImpl } from "./TerrainMapLoader";
import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
import { TileImpl } from "./TileImpl";
@@ -12,7 +12,7 @@ import { ClientID } from "../Schemas";
import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay";
import { UnitImpl } from "./UnitImpl";
export function createGame(terrainMap: TerrainMap, eventBus: EventBus, config: Config): Game {
export function createGame(terrainMap: TerrainMapImpl, eventBus: EventBus, config: Config): Game {
return new GameImpl(terrainMap, eventBus, config)
}
@@ -34,26 +34,24 @@ export class GameImpl implements MutableGame {
private _height: number
private _numLandTiles: number
_terraNullius: TerraNulliusImpl
private _searchMap: SharedArrayBuffer
allianceRequests: AllianceRequestImpl[] = []
alliances_: AllianceImpl[] = []
constructor(terrainMap: TerrainMap, public eventBus: EventBus, private _config: Config) {
constructor(private _terrainMap: TerrainMapImpl, public eventBus: EventBus, private _config: Config) {
this._terraNullius = new TerraNulliusImpl(this)
this._width = terrainMap.width();
this._height = terrainMap.height();
this._numLandTiles = terrainMap.numLandTiles
this._searchMap = terrainMap.searchBuffer
this._width = _terrainMap.width();
this._height = _terrainMap.height();
this._numLandTiles = _terrainMap.numLandTiles
this.map = new Array(this._width);
for (let x = 0; x < this._width; x++) {
this.map[x] = new Array(this._height);
for (let y = 0; y < this._height; y++) {
let cell = new Cell(x, y);
this.map[x][y] = new TileImpl(this, this._terraNullius, cell, terrainMap.terrain(cell));
this.map[x][y] = new TileImpl(this, this._terraNullius, cell, _terrainMap.terrain(cell));
}
}
this.nations_ = terrainMap.nationMap.nations
this.nations_ = _terrainMap.nationMap.nations
.map(n => new Nation(
n.name,
new Cell(n.coordinates[0], n.coordinates[1]),
@@ -396,8 +394,8 @@ export class GameImpl implements MutableGame {
this.eventBus.emit(new AllianceExpiredEvent(alliance.requestor(), alliance.recipient()))
}
public searchMap(): SharedArrayBuffer {
return this._searchMap
public terrainMap(): TerrainMapImpl {
return this._terrainMap
}
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void {
+57 -23
View File
@@ -1,4 +1,4 @@
import { Cell, GameMap, TerrainType } from './Game';
import { Cell, GameMap, SearchNode, TerrainMap, TerrainTile, TerrainType } from './Game';
import europeBin from "!!binary-loader!../../../resources/maps/Europe.bin";
import europeInfo from "../../../resources/maps/Europe.json"
@@ -13,7 +13,7 @@ const maps = new Map()
.set(GameMap.Europe, { bin: europeBin, info: europeInfo })
.set(GameMap.Mena, { bin: menaBin, info: menaInfo });
const loadedMaps = new Map<GameMap, TerrainMap>()
const loadedMaps = new Map<GameMap, TerrainMapImpl>()
export interface NationMap {
name: string;
@@ -29,15 +29,57 @@ export interface Nation {
}
export class TerrainMap {
export class TerrainTileImpl implements TerrainTile {
public shoreline: boolean = false
public magnitude: number = 0
public ocean = false
public land = false
private _neighbors: TerrainTile[] | null = null
constructor(public type: TerrainType, private _cell: Cell) { }
terrainType(): TerrainType {
return this.type
}
cost(): number {
return this.magnitude < 10 ? 2 : 1
}
cell(): Cell {
return this._cell
}
initNeighbors(map: TerrainMapImpl): TerrainTile[] {
if (this._neighbors === null) {
const positions = [
{ x: this._cell.x - 1, y: this._cell.y }, // Left
{ x: this._cell.x + 1, y: this._cell.y }, // Right
{ x: this._cell.x, y: this._cell.y - 1 }, // Up
{ x: this._cell.x, y: this._cell.y + 1 } // Down
];
this._neighbors = positions
.filter(pos => pos.x >= 0 && pos.x < map.width() &&
pos.y >= 0 && pos.y < map.height())
.map(pos => map.terrain(new Cell(pos.x, pos.y)));
}
return this._neighbors;
}
}
export class TerrainMapImpl implements TerrainMap {
constructor(
public readonly tiles: Terrain[][],
public readonly tiles: TerrainTileImpl[][],
public readonly numLandTiles: number,
public readonly nationMap: NationMap,
public searchBuffer: SharedArrayBuffer
) { }
terrain(cell: Cell): Terrain {
neighbors(terrainTile: TerrainTile): TerrainTile[] {
return (terrainTile as TerrainTileImpl).initNeighbors(this);
}
terrain(cell: Cell): TerrainTileImpl {
return this.tiles[cell.x][cell.y]
}
@@ -50,15 +92,7 @@ export class TerrainMap {
}
}
export class Terrain {
public shoreline: boolean = false
public magnitude: number = 0
public ocean = false
public land = false
constructor(public type: TerrainType) { }
}
export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
export async function loadTerrainMap(map: GameMap): Promise<TerrainMapImpl> {
if (loadedMaps.has(map)) {
return loadedMaps.get(map)
}
@@ -83,7 +117,7 @@ export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
throw new Error(`Invalid data: buffer size ${fileData.length} incorrect for ${width}x${height} terrain plus 4 bytes for dimensions.`);
}
const terrain: Terrain[][] = Array(width).fill(null).map(() => Array(height).fill(null));
const terrain: TerrainTileImpl[][] = Array(width).fill(null).map(() => Array(height).fill(null));
let numLand = 0
// Start from the 5th byte (index 4) when processing terrain data
@@ -115,19 +149,19 @@ export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
}
}
terrain[x][y] = new Terrain(type);
terrain[x][y] = new TerrainTileImpl(type, new Cell(x, y));
terrain[x][y].shoreline = shoreline;
terrain[x][y].magnitude = magnitude;
terrain[x][y].ocean = ocean
terrain[x][y].land = land
}
}
const encoder = new TextEncoder();
const encoded = encoder.encode(fileData);
const buffer = new SharedArrayBuffer(encoded.length);
const view = new Uint8Array(buffer);
view.set(encoded)
const m = new TerrainMap(terrain, numLand, mapData.info, buffer);
// const encoder = new TextEncoder();
// const encoded = encoder.encode(fileData);
// const buffer = new SharedArrayBuffer(encoded.length);
// const view = new Uint8Array(buffer);
// view.set(encoded)
const m = new TerrainMapImpl(terrain, numLand, mapData.info);
loadedMaps.set(map, m)
return m
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { TerrainMap } from "./TerrainMapLoader";
import { TerrainMapImpl } from "./TerrainMapLoader";
export enum SearchMapTileType {
Land,
Shore,
+7 -3
View File
@@ -1,5 +1,5 @@
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer } from "./Game";
import { Terrain } from "./TerrainMapLoader";
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, SearchNode, TerrainTile } from "./Game";
import { TerrainTileImpl } from "./TerrainMapLoader";
import { GameImpl } from "./GameImpl";
import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
@@ -14,7 +14,7 @@ export class TileImpl implements Tile {
private readonly gs: GameImpl,
public _owner: PlayerImpl | TerraNulliusImpl,
private readonly _cell: Cell,
private readonly _terrain: Terrain
private readonly _terrain: TerrainTileImpl
) { }
neighborsWrapped(): Tile[] {
@@ -108,4 +108,8 @@ export class TileImpl implements Tile {
}
return this._neighbors;
}
cost(): number {
return this.magnitude() < 10 ? 2 : 1
};
}