UNPKG

bingo-master

Version:

A Bingo game library implemented in TypeScript

155 lines (137 loc) 5.28 kB
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); }) } }