const { astar , Graph } = require ( "javascript-astar" ) ; import { TileCoordinates , CreatureStats } from "@creature-chess/models" ; import { BoardState } from "@shoki/board" ; import { getTargetAttackPositions } from "./utils/getTargetAttackPositions" ; const createEmptyWeightGrid = ( { width , height } ) => { const grid = [ ] ; for ( let x = 0 ; x < width ; x ++ ) { const column = [ ] ; for ( let y = 0 ; y < height ; y ++ ) { column . push ( 1 ) ; } grid . push ( column ) ; } return grid ; } ; const createWeightGrid = ( start , board ) => { const grid = createEmptyWeightGrid ( board . size ) ; Object . entries ( board . piecePositions ) . forEach ( ( [ position , pieceId ] ) => { const [ x , y ] = position . split ( "," ) . map ( p => parseInt ( p , 10 ) ) ; if ( pieceId ) { grid [ x ] [ y ] = 0 ; } } ) ; grid [ start . x ] [ start . y ] = 1 ; return grid ; } ; type Path = { stepCount : number ; firstStep : TileCoordinates ; } ; const findPath = ( board , start , end ) : Path | null => { const weights = createWeightGrid ( start , board ) ; const graph = new Graph ( weights ) ; const startGraphItem = graph . grid [ start . x ] [ start . y ] ; const endGraphItem = graph . grid [ end . x ] [ end . y ] ; const path = astar . search ( graph , startGraphItem , endGraphItem ) ; const firstPathNode = path [ 0 ] ; if ( ! firstPathNode ) { return null ; } const firstStep = firstPathNode ; return { stepCount : path . length , firstStep } ; } ; const pathNotNull = ( path ) : path is Path => path !== null ; export const getNextPiecePosition = ( attackerPosition , attackerStats , targetPosition , board ) : TileCoordinates | null => { const { attackType : { range : attackRange } } = attackerStats ; const targetTiles = getTargetAttackPositions ( board , targetPosition , attackRange ) ; const paths = targetTiles . map ( pos => findPath ( board , attackerPosition , pos ) ) . filter ( pathNotNull ) ; if ( paths . length === 0 ) { return null ; } paths . sort ( ( a , b ) => a . stepCount - b . stepCount ) ; return paths [ 0 ] . firstStep ; } ;