import { List } from "immutable" ; import { Path } from "../types" ; import { KifuTreeNode } from "../kifuTreeNode" ; import { JumpTo , JumpMap } from "../jumpTo" ; export function traverseTree ( rootNode , callback ) { const stack = [ ] ; stack . push ( { path : List < number > ( ) , node : rootNode } ) ; while ( true ) { const currentNode = stack . pop ( ) ; if ( ! currentNode ) { break ; } callback ( currentNode . node , currentNode . path ) ; for ( let i = currentNode . node . children . size - 1 ; i >= 0 ; i -- ) { const node = currentNode . node . children . get ( i ) ! ; const path = currentNode . path . concat ( i ) ; stack . push ( { node , path } ) ; } } } export function buildJumpMap ( rootNode ) { const jumpMap = { } ; const seen = { } ; traverseTree ( rootNode , ( node , path ) => { const sfen = node . sfen ; const jumpTo = new JumpTo ( { node : node , path : path , } ) ; if ( seen [ sfen ] ) { if ( ! jumpMap [ sfen ] ) { jumpMap [ sfen ] = [ seen [ sfen ] ] ; } jumpMap [ sfen ] . push ( jumpTo ) ; } else { seen [ sfen ] = jumpTo ; } } ) ; return jumpMap ; } export function getNodesOnPath ( tree , path ) { const nodes = [ ] ; let currentNode = tree ; path . forEach ( ( num ) => { currentNode = currentNode . children . get ( num ) ! ; nodes . push ( currentNode ) ; } ) ; return nodes ; } export function getStringPathFromPath ( tree , path ) { return getNodesOnPath ( tree , path ) . map ( ( node ) => node . readableKifu ) ; } export function getPathFromStringPath ( tree , stringPath ) { const path = [ ] ; let currentNode = tree ; for ( let kifu of stringPath ) { const nextNodeIndex = currentNode . children . findIndex ( ( childNode ) => childNode . readableKifu === kifu ) ; if ( nextNodeIndex < 0 ) { break ; } const nextNode = currentNode . children . get ( nextNodeIndex ) ! ; path . push ( nextNodeIndex ) ; currentNode = nextNode ; } return List ( path ) ; } export function pathToKeyPath ( path ) { const keyPath = [ ] ; path . forEach ( ( num ) => { keyPath . push ( "children" ) ; keyPath . push ( num ) ; } ) ; return keyPath ; } export function findNodeByPath ( tree , path ) { if ( path . size === 0 ) { return tree ; } const nodes = getNodesOnPath ( tree , path ) ; return nodes [ nodes . length - 1 ] ; }