Gravwell-Online/server/src/objects/Game.ts
2022-03-12 22:07:07 -06:00

109 lines
No EOL
2.6 KiB
TypeScript

import { determineDirection, FuelCard } from "common";
import { config, games, log } from "@/main";
import { promises as fs } from "fs";
import { Player } from "./Player";
import { Logger } from "tslog";
import { Deck } from "./Deck";
import path from "path";
export class Game {
readonly id: string;
readonly host: Player;
readonly log: Logger;
private _deck: Deck<FuelCard>;
private board: (Player|null)[];
private _players: Player[];
constructor(host: Player) {
// Setup the board
this.board = new Array(55).fill(null);
this.board[26] = null;
this.board[36] = null;
// Init the player data
this.host = host;
this._players = [ host ];
// Instantiate the deck
this.loadDeck();
this.id = Game.generateID(config.game.code_length);
this.log = log.getChildLogger({
name: this.id,
displayLoggerName: true,
});
};
/**
* Loads the deck from the data file which contains an array of card
* definitions.
*/
private async loadDeck() {
if (config.game.fuel_deck.type == "file:json") {
let cards = JSON.parse(
await fs.readFile(
path.join(process.cwd(), config.game.fuel_deck.location),
`utf-8`
)
);
this._deck = new Deck(cards);
} else {
throw new Error(`Unsupported data format for the cards: "${config.game.fuel_deck.type}"`)
}
};
/** The deck of the fuel cards */
get deck() { return this._deck; };
/** A list players of in the game */
get players() { return this._players; };
/**
* The algorithm to determine which direction the closest ship is, this
* uses an integer that can be multiplied by the player's fuel card
* magnitude in order to determine the delta for the board index.
*
* ---
*
* Possible Return Values:
* - `-1` = Away from the Warp Gate (towards the black hole)
* - `0` = Not moving
* - `1` = Towards the Warp Gate (away from the black hole)
*/
public movementDirection(player: Player): number {
let location = this.board.indexOf(player);
this.log.debug(`Calculating movement direction for ${player.name}`);
return determineDirection(this.board, location);
};
/**
* Generates a game code with the given length
*
* @param length The length of the code to generate
*/
public static generateID(length: number): string {
let code: string;
// Prevent erroneous codes from being generated
if (length <= 0) {
throw new Error("Can't code have a length <= 0");
};
// Generate a new code until we find one that isn't taken already.
do {
code = ``;
for (var i = 0; i < length; i++) {
code += Math.floor(Math.random() * 9);
};
} while (games.has(code));
return code;
}
};