create basic win popup

This commit is contained in:
evanpelle
2024-09-16 11:51:24 -07:00
parent 2f626bcc39
commit 534d97abb3
15 changed files with 287 additions and 27 deletions
+1
View File
@@ -142,6 +142,7 @@ export interface Game {
neighbors(cell: Cell | Tile): Tile[]
width(): number
height(): number
numLandTiles(): number
forEachTile(fn: (tile: Tile) => void): void
executions(): ExecutionView[]
terraNullius(): TerraNullius
+5
View File
@@ -294,12 +294,14 @@ export class GameImpl implements MutableGame {
private execs: Execution[] = []
private _width: number
private _height: number
private _numLandTiles: number
_terraNullius: TerraNulliusImpl
constructor(terrainMap: TerrainMap, private eventBus: EventBus, private _config: Config) {
this._terraNullius = new TerraNulliusImpl(this)
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);
@@ -309,6 +311,9 @@ export class GameImpl implements MutableGame {
}
}
}
numLandTiles(): number {
return this._numLandTiles
}
hasPlayer(id: PlayerID): boolean {
return this._players.has(id)
}
+4 -2
View File
@@ -2,7 +2,7 @@ import {Cell, TerrainType} from './Game';
import binAsString from "!!binary-loader!../../resources/TopoWorldMap.bin";
export class TerrainMap {
constructor(public readonly tiles: Terrain[][]) { }
constructor(public readonly tiles: Terrain[][], public readonly numLandTiles: number) { }
terrain(cell: Cell): Terrain {
return this.tiles[cell.x][cell.y]
@@ -45,6 +45,7 @@ export async function loadTerrainMap(): Promise<TerrainMap> {
}
const terrain: Terrain[][] = Array(width).fill(null).map(() => Array(height).fill(null));
let numLand = 0
// Start from the 5th byte (index 4) when processing terrain data
for (let x = 0; x < width; x++) {
@@ -58,6 +59,7 @@ export async function loadTerrainMap(): Promise<TerrainMap> {
let type: TerrainType = null
let land = false
if (isLand) {
numLand++
land = true
if (magnitude < 10) {
type = TerrainType.Plains
@@ -82,7 +84,7 @@ export async function loadTerrainMap(): Promise<TerrainMap> {
}
}
return new TerrainMap(terrain);
return new TerrainMap(terrain, numLand);
}
function logBinaryAsAscii(data: string, length: number = 8) {
+1
View File
@@ -26,6 +26,7 @@ export function getGameEnv(): GameEnv {
export interface Config {
theme(): Theme;
percentageTilesOwnedToWin(): number
turnIntervalMs(): number
gameCreationRate(): number
lobbyLifetime(): number
+3
View File
@@ -7,6 +7,9 @@ import {pastelTheme} from "./PastelTheme";
export class DefaultConfig implements Config {
percentageTilesOwnedToWin(): number {
return 80
}
boatMaxNumber(): number {
return 3
}
+3
View File
@@ -2,6 +2,9 @@ import {GameID} from "../Schemas";
import {DefaultConfig} from "./DefaultConfig";
export const devConfig = new class extends DefaultConfig {
percentageTilesOwnedToWin(): number {
return 80
}
numSpawnPhaseTurns(): number {
return 40
}
+47
View File
@@ -0,0 +1,47 @@
import {EventBus, GameEvent} from "../EventBus"
import {Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../Game"
export class WinEvent implements GameEvent {
constructor(public readonly winner: Player) { }
}
export class WinCheckExecution implements Execution {
private active = true
private mg: MutableGame
constructor(private eventBus: EventBus) {
}
init(mg: MutableGame, ticks: number) {
this.mg = mg
}
tick(ticks: number) {
if (ticks % 10 != 0) {
return
}
const sorted = this.mg.players().sort((a, b) => b.numTilesOwned() - a.numTilesOwned())
if (sorted.length == 0) {
return
}
const max = sorted[0]
if (max.numTilesOwned() / this.mg.numLandTiles() * 100 > this.mg.config().percentageTilesOwnedToWin()) {
this.eventBus.emit(new WinEvent(max))
this.active = false
}
}
owner(): MutablePlayer {
return null
}
isActive(): boolean {
return this.active
}
activeDuringSpawnPhase(): boolean {
return false
}
}