bingo-master
Version:
A Bingo game library implemented in TypeScript
155 lines (137 loc) • 5.28 kB
text/typescript
import { Board } from "./Board";
import { Tile } from "./types";
export class Bingo {
readonly size: number;
readonly members_count: number;
private boards: Board[];
private canceled: Set<number>;
private cancel_counts: number[];
private is_gameover: boolean;
private winner: number | null;
constructor(size: number = 5, count: number = 2) {
if(size < 2) {
throw new Error("Bingo can not be played on board size less then 2")
}
if(count < 2 || count > size) {
throw new Error("numbers of members can only be in the range 2 to size of bord")
// because this dosen't make any sence to have too much players it will be completly unfair game
}
this.size = size;
this.members_count = count;
this.boards = [];
for (let i = 0; i < count; i++) {
this.boards[i] = new Board(size);
}
this.canceled = new Set<number>();
this.cancel_counts = new Array(count).fill(0);
this.is_gameover = false;
this.winner = null;
}
public getTurn() : number {
return this.canceled.size % this.members_count;
}
public getBoards() : number[][][] {
const res: number[][][] = [];
this.boards.forEach((board) => {
res.push(board.getData())
});
return res;
}
public getMyBoard(ind: number) : number[][] {
if(ind < 0 || ind >= this.members_count){
throw new Error("invalid index")
}
return this.boards[ind].getData();
}
public getMyCancelCount(ind: number) : number {
if(ind < 0 || ind >= this.members_count){
throw new Error("invalid index")
}
return this.boards[ind].getCancelCount();
}
public getMyCanceledInfo(ind: number) : string[] {
if(ind < 0 || ind >= this.members_count){
throw new Error("invalid index")
}
return this.boards[ind].getCanceldInfo();
}
public getMyBoardInfo(ind: number) : Tile[][] {
if(ind < 0 || ind > this.size) {
throw new Error("Invalid index...")
}
return this.boards[ind].getBoardDetails();
}
public getCanceled() : number[] {
return [...this.canceled];
}
public getCancelCounts() : number[] {
return this.cancel_counts;
}
public getWinner() : number | null {
return this.winner;
}
public cancelNumber(num: number, turn: number) {
if(this.is_gameover){
throw new Error("hey game is over, why don't you try a new game...")
}
if(turn != this.getTurn()){
throw new Error("Its not your turn...")
}
if(num <= 0 || num > this.size * this.size){
throw new Error("Invalid number, out of range")
}
if(this.canceled.has(num)){
throw new Error("Number already canceled")
}
this.boards.forEach((board, i)=> {
this.cancel_counts[i] = board.cancelNumber(num);
this.canceled.add(num);
})
if(this.cancel_counts[turn] >= this.size){
// you win the game
this.winner = turn;
this.is_gameover = true;
}
this.cancel_counts.forEach((count, i) => {
if(count >= this.size){
// somone else win by your move : i is the winner
this.winner = i;
this.is_gameover = true;
}
})
}
/**
* README BEFOR USING THIS FUNCTION
* This function is for suppose you want the numbers of your choice like
* you have build your own way of random arangement (but honestly i don't remond you to do that it will simply sounds unfair)
* another or the MAJOR REASON for the existance of this function is: suppose your server goes down and
* games are goin on and you have stored the game state in DB OR redis whatever now you want to reinitialize it
* then use this function (or now you are the boss so do wahtever you feel good )
*
*/
public customInitialize(newBoards: number[][][], newCanceles: number[]) {
if(newBoards.length < 0 || newBoards.length > this.members_count){
throw new Error("Invalid numbe of boards passed...")
}
if(newBoards[0].length != this.size){
throw new Error("Invalid board size...")
}
const set = new Set<number>;
newCanceles.forEach((cancel) => {
if(cancel < 0 || cancel > this.size * this.size){
throw new Error("Invalid number in cancels...")
}
if(set.has(cancel)){
throw new Error("Duplicate cancel numbers...")
}
set.add(cancel)
});
this.canceled.clear()
newCanceles.forEach((cancel) => {
this.canceled.add(cancel)
});
this.boards.forEach((board, i) => {
this.cancel_counts[i] = board.customInitialize(newBoards[i], newCanceles);
})
}
}