109 lines
No EOL
2.6 KiB
TypeScript
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;
|
|
}
|
|
}; |