export default class SearchTree {
  static hash(state) {
    return JSON.stringify(state.data);
  }

  static makeStateData(...args) {
    return args;
  }

  static isTerminal(state) {
    return false;
  }

  generateTree(initialStateData) {
    this.states = new Map();
    this.generateStates(initialStateData);
  }

  printTree() {
    for (let [hash, state] of this.states) {
      console.log(`${hash} => ${state.descendents.map(state => this.constructor.hash(state)).join(' | ')}`);
    }
  }

  run(initialStateData) {
    this.generateTree(initialStateData);
    this.printTree();
  }

  generateDescendents(state, add) {
  }

  generateStates(stateData) {
    // Create a new state instance with the given state data
    let state = {
      descendents: [],
      data: stateData,
    };
    let hash = this.constructor.hash(state);

    // Record this state if it has not already been seen
    let existingState = this.states.get(hash);
    if (existingState) {
      return existingState;
    } else {
      this.states.set(hash, state);
    }

    // This is a terminal state, so abort
    if (this.constructor.isTerminal(state)) {
      return state;
    }

    let add = (...args) => {
      state.descendents.push(this.generateStates(this.constructor.makeStateData(...args)));
    };

    this.generateDescendents(state, add);

    return state;
  }
}

@@ -636,96 +636,90 @@
 %0A%0A  
-generateStates(stateData) %7B%0A    // Create a new state instance with the given 
+// Lookup or create the state from the provided state data%0A  getState(
 state
- d
+D
 ata
+) %7B
 %0A   
@@ -756,16 +756,39 @@
 ts: %5B%5D,%0A
+      expanded: false,%0A
       da
@@ -1061,25 +1061,294 @@
 state);%0A    
-%7D
+  return state;%0A    %7D%0A  %7D%0A%0A  generateStates(stateData) %7B%0A    let state = this.getState(stateData);%0A    if (state.expanded) %7B%0A      // This node has already been expanded, so ignore it%0A      return state;%0A    %7D%0A%0A    // Mark the node as expanded%0A    state.expanded = true;
 %0A%0A    // Thi

Refactor state lookup into a separate function