import { createTileData , Point , Tile , TileData } from './Components' ; export interface Grid { getWidth ( ) : number ; getHeight ( ) : number ; inBounds ( point ) : boolean ; get ( point ) : Tile ; isSolid ( point ) : boolean ; mutate ( point , data ) : void ; mutateTile ( tile ) : void ; mutateDefault ( point , solid ) : void ; output ( console ) : void ; getJson ( ) : string ; walkable ( point ) : boolean ; isEmpty ( point ) : boolean ; clone ( ) : Grid ; cloneNewSize ( width , height ) : Grid ; } /**
 * A square grid system that stores nodes in a matrix
 * Uses an x,y system where x corresponds to column of the matrix,
 * and y corresponds to the row of the matrix
 * Tile should be treated like graph nodes
 */ class RectGrid implements Grid { private readonly tiles : Tile [ ] [ ] ; private readonly width : number ; private readonly height : number ; param width param height constructor ( width , height ) { this . width = width ; this . height = height ; this . tiles = createEmptyGrid ( width , height ) ; } getWidth ( ) { return this . width ; } getHeight ( ) { return this . height ; } param point inBounds ( point ) { return point . x >= 0 && point . x < this . width && point . y >= 0 && point . y < this . height ; } param point get ( point ) { return { point : this . tiles [ point . y ] [ point . x ] . point , data : this . tiles [ point . y ] [ point . x ] . data } ; } param point param data mutate ( point , data ) { this . tiles [ point . y ] [ point . x ] . data = data ; } param tile mutateTile ( tile ) { this . tiles [ tile . point . y ] [ tile . point . x ] . data = tile . data ; } param point param solid mutateDefault ( point , solid ) { this . mutate ( point , createTileData ( solid ) ) ; } param console output ( console ) { for ( let y = 0 ; y < this . height ; y ++ ) { let str = '' ; for ( let x = 0 ; x < this . width ; x ++ ) { str += this . tiles [ y ] [ x ] . data . isSolid + ', ' ; } console . log ( str ) ; } } /**
     * Returns json of tiles
     */ getJson ( ) { return JSON . stringify ( this . tiles ) ; } param point walkable ( point ) { return ! this . tiles [ point . y ] [ point . x ] . data . isSolid ; } param point isSolid ( point ) { return this . tiles [ point . y ] [ point . x ] . data . isSolid ; } param point isEmpty ( point ) { const data = this . tiles [ point . y ] [ point . x ] . data ; return data . pathCost === 1 && ! data . isSolid ; } clone ( ) { const grid = new RectGrid ( this . width , this . height ) ; for ( let y = 0 ; y < grid . height ; y ++ ) { for ( let x = 0 ; x < grid . width ; x ++ ) { const point = { x : x , y : y } ; grid . mutateTile ( this . get ( point ) ) ; } } return grid ; } cloneNewSize ( width , height ) { const grid = new RectGrid ( width , height ) ; for ( let y = 0 ; y < grid . height ; y ++ ) { for ( let x = 0 ; x < grid . width ; x ++ ) { const point = { x : x , y : y } ; if ( this . inBounds ( point ) ) { grid . mutateTile ( this . get ( point ) ) ; } } } return grid ; } } /**
 * Creates a 2d matrix of empty nodes
 */ function createEmptyGrid ( width , height ) { const nodes = [ ] ; for ( let y = 0 ; y < height ; y ++ ) { const row = [ ] ; for ( let x = 0 ; x < width ; x ++ ) { row . push ( { point : { x : x , y : y } , data : createTileData ( false ) } ) ; } nodes . push ( row ) ; } return nodes ; } export default RectGrid ;