Grid.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import GridError from "../../errors/graph/layering/grid/GridError.js";
  2. /**
  3. * Стека для укладка графа на двумерной плоскости
  4. */
  5. export class Grid<TElement> {
  6. /**
  7. * Ячейки сетки, которые могут хранить в себе элементы
  8. * @protected
  9. */
  10. protected readonly _cells: (TElement | undefined)[][];
  11. /**
  12. * Количество элементов в каждой из строк сетки
  13. * @private
  14. */
  15. private readonly width: number;
  16. /**
  17. * Количество элементов в каждом из столбцов сетки
  18. * @private
  19. */
  20. private readonly height: number;
  21. public constructor(width: number, height: number) {
  22. this.width = width;
  23. this.height = height;
  24. this._cells = Array.from({ length: height }, () => new Array(width));
  25. }
  26. public set(row: number, col: number, value: TElement) : this {
  27. this.validate(row, col);
  28. if(row >= this._cells.length)
  29. this._cells.length = row + 1;
  30. if(this._cells[row] === undefined)
  31. this._cells[row] = [];
  32. const r = this._cells[row]!;
  33. if(col >= r.length)
  34. r.length = col + 1;
  35. r[col] = value;
  36. return this;
  37. }
  38. public get(row: number, col: number) : TElement | undefined {
  39. this.validate(row, col);
  40. return this._cells[row]![col];
  41. }
  42. public delete(row: number, col: number) : this {
  43. this.validate(row, col);
  44. const r = this._cells[row];
  45. if(!r)
  46. return this;
  47. delete r[col];
  48. return this;
  49. }
  50. public isEmpty(row: number, col: number) : boolean {
  51. this.validate(row, col);
  52. const r = this._cells[row];
  53. if(!r)
  54. return true;
  55. return r[col] === undefined;
  56. }
  57. public getSize(): { width: number; height: number } {
  58. return { width: this.width, height: this.height };
  59. }
  60. protected validate(row: number, col: number) : void {
  61. if(row < 0 || row >= this._cells.length)
  62. throw new GridError(`Row index is out of bounds [0, ${this._cells.length - 1}]: ${row}`);
  63. const r = this._cells[row]!;
  64. if(col < 0 || col >= r.length)
  65. throw new GridError(`Column index is out of bounds [0, ${r.length - 1}]: ${row}`);
  66. }
  67. }