import GridError from "../../errors/graph/layering/grid/GridError.js"; /** * Стека для укладка графа на двумерной плоскости */ export class Grid { /** * Ячейки сетки, которые могут хранить в себе элементы * @protected */ protected readonly _cells: (TElement | undefined)[][]; /** * Количество элементов в каждой из строк сетки * @private */ private readonly width: number; /** * Количество элементов в каждом из столбцов сетки * @private */ private readonly height: number; public constructor(width: number, height: number) { this.width = width; this.height = height; this._cells = Array.from({ length: height }, () => new Array(width)); } public set(row: number, col: number, value: TElement) : this { this.validate(row, col); if(row >= this._cells.length) this._cells.length = row + 1; if(this._cells[row] === undefined) this._cells[row] = []; const r = this._cells[row]!; if(col >= r.length) r.length = col + 1; r[col] = value; return this; } public get(row: number, col: number) : TElement | undefined { this.validate(row, col); return this._cells[row]![col]; } public delete(row: number, col: number) : this { this.validate(row, col); const r = this._cells[row]; if(!r) return this; delete r[col]; return this; } public isEmpty(row: number, col: number) : boolean { this.validate(row, col); const r = this._cells[row]; if(!r) return true; return r[col] === undefined; } public getSize(): { width: number; height: number } { return { width: this.width, height: this.height }; } protected validate(row: number, col: number) : void { if(row < 0 || row >= this._cells.length) throw new GridError(`Row index is out of bounds [0, ${this._cells.length - 1}]: ${row}`); const r = this._cells[row]!; if(col < 0 || col >= r.length) throw new GridError(`Column index is out of bounds [0, ${r.length - 1}]: ${row}`); } }