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; 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; } };