UNPKG

bingo-master

Version:

A Bingo game library implemented in TypeScript

153 lines (136 loc) 4.96 kB
import { Tile } from "./types"; export class Board { readonly size: number; private data: number[][]; private map: Map<number, [row:number, col: number]>; private canceledRowsCount: number[]; private canceledColsCount: number[]; private canceledDignlsCount: number[]; private cancel_count: number; is_canceled: boolean[][]; constructor(size: number) { if (size < 2) { throw new Error("Board size must be greater then 1"); } this.size = size; this.data = Board.create(size); this.is_canceled = [] for (let i = 0; i < size; i++) { this.is_canceled[i] = [] for (let j = 0; j < size; j++) { this.is_canceled[i][j] = false; } } this.cancel_count = 0; this.map = new Map(); this.data.forEach((row, i) => { row.forEach((item, j) => { this.map.set(item, [i, j]); }) }); this.canceledRowsCount = new Array(size).fill(0); this.canceledColsCount = new Array(size).fill(0); this.canceledDignlsCount = new Array(2).fill(0); } private static create(size: number) : number[][] { // genrate size*size numbers from 1 to size*size let numbers: number[] = []; for(let i = 1; i <= size * size ; i++){ numbers[i - 1] = i; } // Arraging them in random order for(let i = 1; i < size * size; i++) { const randomIdx = Math.floor(Math.random() * (size * size)); const temp = numbers[i]; numbers[i] = numbers[randomIdx]; numbers[randomIdx] = temp; } const res:number[][] = []; for(let i = 0; i < size; i++) { res.push(numbers.slice(i * size, (i + 1) * size)); } return res; } public getData() : number[][] { return this.data; } public getCancelCount(): number { return this.cancel_count; } public getCanceldInfo(): string[] { const res: string[] = []; this.canceledRowsCount.forEach((count, i) => { if(count == this.size) { res.push("R_" + String(i)); } }); this.canceledColsCount.forEach((count, i) => { if(count == this.size) { res.push("C_" + String(i)); } }); this.canceledDignlsCount.forEach((count, i) => { if(count == this.size) { res.push("D_" + String(i)); } }); return res; } public cancelNumber(num: number): number { // the cheks are alredy done in Board class so it dosn't make any sence to chek them again or maybe i am wrong const value = this.map.get(num); if(value) { const [row, col] = value; this.is_canceled[row][col] = true; this.canceledRowsCount[row]++; this.canceledColsCount[col]++; if(this.canceledRowsCount[row] === this.size) this.cancel_count++; if(this.canceledColsCount[col] === this.size) this.cancel_count++; if(row === col){ this.canceledDignlsCount[0]++; if(this.canceledDignlsCount[0] === this.size) this.cancel_count++; } if((row + col) === (this.size - 1)){ this.canceledDignlsCount[1]++; if(this.canceledDignlsCount[1] === this.size) this.cancel_count++; } } return this.cancel_count; } public customInitialize(newBoard: number[][], newCanceles: number[]) : number { this.data = newBoard; newBoard.forEach((row, i) => { row.forEach((item, j) => { this.map.set(item, [i, j]); }); }); for (let i = 0; i < this.size; i++) { this.is_canceled[i] = [] for (let j = 0; j < this.size; j++) { this.is_canceled[i][j] = false; } } this.canceledRowsCount.fill(0) this.canceledColsCount.fill(0) this.canceledDignlsCount.fill(0) this.cancel_count = 0; newCanceles.forEach((cancel) => { this.cancelNumber(cancel) }) return this.cancel_count; } // create a function which will give detailed info about board public getBoardDetails() : Tile[][] { const res: Tile[][] = [] this.data.forEach((row, i) => { res[i] = [] row.forEach((item, j) => { res[i][j] = { value: item, isCanceled: this.is_canceled[i][j] } }); }); return res; } }