public int findBestMove(Node currentNode, int best) {
    int turn = currentNode.getBoard().CurrentPlayer();

    // set the current value of the current node to compare with children node
    if (turn != player) currentNode.setValue(Float.POSITIVE_INFINITY);
    else currentNode.setValue(Float.NEGATIVE_INFINITY);

    // Check each pit on your side to find the best move. */
    for (int i = 0; i < 6; i++)
      if (currentNode.getBoard().validMove(i)) {
        try {
          MancalaGameState newBoard = currentNode.getBoard().copy();
          try {
            newBoard.play(i);
          } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }

          Node newNode = new Node(newBoard, currentNode.getDepth() + 1);

          newNode.setParent(currentNode);
          currentNode.setChild(newNode, i);

          // CUT OFF
          if (newNode.getBoard().checkEndGame() || (newNode.getDepth() >= cutoffDepth)) {

            RegressionState aState = new RegressionState(newNode.getBoard(), player);
            newNode.setValue(predictedValue(aState, weight));

          } else findBestMove(newNode, best);

          // alpha-beta pruning
          // AI = MAX
          // pick the child with larger value
          if (currentNode.getBoard().CurrentPlayer() == player) {
            if (currentNode.getChild(i) != null) {
              if (currentNode.getChild(i).getValue() > currentNode.getValue()) {
                currentNode.setValue(currentNode.getChild(i).getValue());
                best = i;
              }
            }
            currentNode.deleteChild(i);

            // alpha cut off if our value is greater than ANY
            // player/MIN parent value

            Node nodePtr = currentNode;
            while (nodePtr.getParent() != null) {
              nodePtr = nodePtr.getParent();
              if ((nodePtr.getBoard().CurrentPlayer != player)
                  && (currentNode.getValue() > nodePtr.getValue())) {
                nodePtr = null;
                return best;
              }
            }

            nodePtr = null;
          }

          // Player = MIN
          // pick the child with smaller value
          if (currentNode.getBoard().CurrentPlayer() != player) {
            if (currentNode.getChild(i) != null) {
              if (currentNode.getChild(i).getValue() < currentNode.getValue()) {
                currentNode.setValue(currentNode.getChild(i).getValue());
                best = i;
              }
            }
            currentNode.deleteChild(i);

            // beta cut off if our value is less than ANY
            // computer/MAX parent value
            Node nodePtr = currentNode;
            while (nodePtr.getParent() != null) {
              nodePtr = nodePtr.getParent();
              if ((nodePtr.getBoard().CurrentPlayer() == player)
                  && (currentNode.getValue() < nodePtr.getValue())) {
                nodePtr = null;
                return best;
              }
            }
            nodePtr = null;
          }
        } catch (java.lang.OutOfMemoryError e) {
          System.out.println("OUT OF MEM");
          return -1;
        }
      }
    return best; // return the best move
  }
  public void updateHistory(MancalaGameState gs) {

    RegressionState aState = new RegressionState(gs.copy(), player);
    gameHistory.add(aState);
  }