Program: 84023
Project: 84023
Buggy source:
@SuppressWarnings("String_Node_Str") private ActionValuePair MT(SearchNode n,int gamma,int depth) throws InvalidActionException, IllegalStateException {
  checkedNodes++;
  if (DEBUG)   GraphVizPrinter.setState(n.gameState);
  if (depth > 4) {
    if (times_up())     throw new IllegalStateException("String_Node_Str");
  }
  populateFromTable(n);
  ActionValuePair bestAction=new ActionValuePair(null,0);
  if (depth == 0 || n.gameState.getStatus() != Status.Ongoing) {
    leafNodes++;
    if (n.f_minus == LOSE && n.f_plus == WIN) {
      bestAction.value=(int)n.gameState.heuristic();
    }
 else     if (n.f_plus == WIN) {
      bestAction.value=n.f_minus;
    }
 else {
      bestAction.value=n.f_plus;
    }
    if (DEBUG)     GraphVizPrinter.setRelation(n.gameState,bestAction.value,n.gameState.getParentState());
  }
 else {
    bestAction.value=n.maxnode ? LOSE : WIN;
    List<ActionValuePair> actions=buildAVPList(n.gameState.getActions());
    int[] depthsToSearch;
    if (depth > 4) {
      depthsToSearch=new int[2];
      depthsToSearch[0]=depth - 2;
      depthsToSearch[1]=depth;
    }
 else {
      depthsToSearch=new int[1];
      depthsToSearch[0]=depth;
    }
    for (int i=0; i < depthsToSearch.length; i++) {
      loopsHit++;
      for (      ActionValuePair avp : actions) {
        actionsChecked++;
        if (n.maxnode) {
          if (bestAction.value >= gamma)           break;
        }
 else {
          if (bestAction.value < gamma)           break;
        }
        State childState=avp.action.applyTo(n.gameState);
        SearchNode c=new SearchNode();
        c.gameState=childState;
        c.maxnode=!n.maxnode;
        c.depth=depthsToSearch[i];
        populateFromTable(c);
        int currentBound=n.maxnode ? c.f_plus : c.f_minus;
        ActionValuePair bestChildAction;
        if ((n.maxnode && currentBound >= gamma) || (!n.maxnode && currentBound < gamma)) {
          bestChildAction=MT(c,gamma,depthsToSearch[i] - 1);
        }
 else {
          bestChildAction=new ActionValuePair(null,currentBound);
        }
        bestChildAction.action=avp.action;
        avp.value=bestChildAction.value;
        if (n.maxnode)         bestAction=maxAVP(bestAction,bestChildAction);
 else         bestAction=minAVP(bestAction,bestChildAction);
      }
      if (depthsToSearch.length > 1 && i == 0) {
        if (n.maxnode) {
          Collections.sort(actions,Collections.reverseOrder());
        }
 else {
          Collections.sort(actions);
        }
      }
    }
    if (DEBUG)     GraphVizPrinter.setRelation(n.gameState,bestAction.value,n.gameState.getParentState(),gamma - 1,gamma);
  }
  if (bestAction.value >= gamma) {
    n.f_minus=bestAction.value;
    n.type=EntryType.LOWERBOUND;
  }
 else {
    n.f_plus=bestAction.value;
    n.type=EntryType.UPPERBOUND;
  }
  n.bestAction=bestAction.action;
  n.depth=depth;
  saveToTable(n);
  return bestAction;
}

Fixed version (ground truth):
@SuppressWarnings("String_Node_Str") private ActionValuePair MT(SearchNode n,int gamma,int depth,int iter) throws InvalidActionException, IllegalStateException {
  checkedNodes++;
  if (DEBUG)   GraphVizPrinter.setState(n.gameState);
  if (depth > 4) {
    if (times_up())     throw new IllegalStateException("String_Node_Str");
  }
  populateFromTable(n);
  ActionValuePair bestAction=new ActionValuePair(null,0);
  if (depth == 0 || n.gameState.getStatus() != Status.Ongoing) {
    leafNodes++;
    if (n.f_minus == LOSE && n.f_plus == WIN) {
      bestAction.value=(int)n.gameState.heuristic();
      int a=1;
    }
 else     if (n.f_plus == WIN) {
      bestAction.value=n.f_minus;
    }
 else {
      bestAction.value=n.f_plus;
    }
    if (DEBUG)     GraphVizPrinter.setRelation(n.gameState,bestAction.value,n.gameState.getParentState(),iter);
  }
 else {
    List<ActionValuePair> actions=buildAVPList(n.gameState.getActions(),n.bestAction);
    int[] depthsToSearch;
    if (depth > 4) {
      depthsToSearch=new int[2];
      depthsToSearch[0]=depth - 2;
      depthsToSearch[1]=depth;
    }
 else {
      depthsToSearch=new int[1];
      depthsToSearch[0]=depth;
    }
    for (int i=0; i < depthsToSearch.length; i++) {
      loopsHit++;
      bestAction.value=n.maxnode ? LOSE : WIN;
      for (      ActionValuePair avp : actions) {
        actionsChecked++;
        if (n.maxnode) {
          if (bestAction.value >= gamma)           break;
        }
 else {
          if (bestAction.value < gamma)           break;
        }
        State childState=avp.action.applyTo(n.gameState);
        SearchNode c=new SearchNode();
        c.gameState=childState;
        c.maxnode=!n.maxnode;
        c.depth=depthsToSearch[i];
        populateFromTable(c);
        int currentBound=n.maxnode ? c.f_plus : c.f_minus;
        ActionValuePair bestChildAction;
        if ((n.maxnode && currentBound >= gamma) || (!n.maxnode && currentBound < gamma)) {
          bestChildAction=MT(c,gamma,depthsToSearch[i] - 1,iter);
        }
 else {
          bestChildAction=new ActionValuePair(null,currentBound);
        }
        bestChildAction.action=avp.action;
        avp.value=bestChildAction.value;
        if (n.maxnode)         bestAction=maxAVP(bestAction,bestChildAction);
 else         bestAction=minAVP(bestAction,bestChildAction);
      }
      if (depthsToSearch.length > 1 && i == 0) {
        if (n.maxnode) {
          Collections.sort(actions,Collections.reverseOrder());
        }
 else {
          Collections.sort(actions);
        }
      }
    }
    if (DEBUG)     GraphVizPrinter.setRelation(n.gameState,bestAction.value,n.gameState.getParentState(),gamma - 1,gamma,iter);
  }
  if (bestAction.value >= gamma) {
    n.f_minus=bestAction.value;
    n.type=EntryType.LOWERBOUND;
  }
 else {
    n.f_plus=bestAction.value;
    n.type=EntryType.UPPERBOUND;
  }
  n.bestAction=bestAction.action;
  n.depth=depth;
  saveToTable(n);
  return bestAction;
}