2023-03-04 00:25:54 +00:00
|
|
|
import { Player } from "./player.js";
|
2023-03-03 17:34:15 +00:00
|
|
|
|
2023-03-17 10:42:11 +00:00
|
|
|
// In standard Risk, this is 5
|
|
|
|
const _REINFORCEMENT_MULTIPLIER = 1;
|
|
|
|
|
2023-03-03 17:34:15 +00:00
|
|
|
const WAITING = 0;
|
|
|
|
const PRE_GAME = 1;
|
|
|
|
const PLAYING = 2;
|
|
|
|
|
|
|
|
export class Game {
|
|
|
|
constructor() {
|
|
|
|
this.us = null;
|
|
|
|
this.players = {};
|
|
|
|
this.state = WAITING;
|
2023-04-30 17:42:52 +00:00
|
|
|
this.contendedRegion = null;
|
2023-03-17 10:42:11 +00:00
|
|
|
|
|
|
|
this.allPlaced = false;
|
2023-03-03 17:34:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isWaiting() {
|
|
|
|
return this.state === WAITING;
|
|
|
|
}
|
|
|
|
|
|
|
|
isPregame() {
|
|
|
|
return this.state === PRE_GAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
isPlaying() {
|
|
|
|
return this.state === PLAYING;
|
|
|
|
}
|
|
|
|
|
|
|
|
incrementState() {
|
|
|
|
this.state += 1;
|
2023-03-04 00:25:54 +00:00
|
|
|
|
|
|
|
const event = new CustomEvent("gameStateUpdate", {
|
|
|
|
detail: { newState: this.state },
|
|
|
|
});
|
|
|
|
document.dispatchEvent(event);
|
2023-03-03 17:34:15 +00:00
|
|
|
}
|
|
|
|
|
2023-03-05 17:19:37 +00:00
|
|
|
playerCount() {
|
|
|
|
return Object.values(this.players).length;
|
|
|
|
}
|
|
|
|
|
2023-03-03 17:34:15 +00:00
|
|
|
currentPlayer() {
|
|
|
|
return Object.values(this.players).filter((p) => p.isPlaying)[0];
|
|
|
|
}
|
|
|
|
|
2023-03-13 14:52:14 +00:00
|
|
|
addPlayer(id, is_us, rsa_key, paillier_key) {
|
2023-03-03 17:34:15 +00:00
|
|
|
let is_new = this.players[id] === undefined;
|
|
|
|
|
|
|
|
if (this.isWaiting()) {
|
2023-03-13 14:52:14 +00:00
|
|
|
this.players[id] = new Player(id, is_us, rsa_key, paillier_key);
|
2023-03-04 00:25:54 +00:00
|
|
|
if (is_us) {
|
2023-03-03 17:34:15 +00:00
|
|
|
this.us = this.players[id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_new) {
|
|
|
|
const event = new CustomEvent("addPlayer");
|
|
|
|
document.dispatchEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
return is_new;
|
|
|
|
}
|
|
|
|
|
|
|
|
removePlayer(id) {
|
|
|
|
if (this.players[id] !== undefined) {
|
|
|
|
const event = new CustomEvent("removePlayer");
|
|
|
|
document.dispatchEvent(event);
|
|
|
|
delete this.players[id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
keepAlive(id) {
|
|
|
|
if (id !== this.us.id) {
|
|
|
|
this.players[id].resetTimeout(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setReady(id, ready) {
|
2023-03-04 00:25:54 +00:00
|
|
|
this.players[id].ready = ready;
|
|
|
|
|
|
|
|
const event = new CustomEvent("updatePlayer");
|
|
|
|
document.dispatchEvent(event);
|
2023-03-03 17:34:15 +00:00
|
|
|
|
|
|
|
if (this._allPlayersReady()) {
|
|
|
|
this.incrementState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_allPlayersReady() {
|
|
|
|
for (let player of Object.values(this.players)) {
|
2023-03-04 00:25:54 +00:00
|
|
|
if (!player.ready) {
|
2023-03-03 17:34:15 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2023-03-17 10:42:11 +00:00
|
|
|
|
|
|
|
reinforcementsRemaining() {
|
|
|
|
if (this.allPlaced) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
_REINFORCEMENT_MULTIPLIER * (10 - this.playerCount()) -
|
|
|
|
this.us.totalStrength
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
allReinforcementsPlaced() {
|
|
|
|
if (this.allPlaced) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
let totalStrength = Object.values(this.players).reduce(
|
|
|
|
(counter, player) => counter + player.totalStrength,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
|
|
|
|
this.allPlaced =
|
|
|
|
totalStrength >=
|
|
|
|
this.playerCount() *
|
|
|
|
_REINFORCEMENT_MULTIPLIER *
|
|
|
|
(10 - this.playerCount());
|
|
|
|
return this.allPlaced;
|
|
|
|
}
|
|
|
|
}
|
2023-03-03 17:34:15 +00:00
|
|
|
}
|