private double maxscore(MachineState state, int maxDepth, int currentDepth)
     throws MoveDefinitionException, GoalDefinitionException, TransitionDefinitionException {
   if (playerResult.containsMemoizedState(state)) {
     return playerResult.getMemoizedState(state);
   }
   if (currentDepth == maxDepth || stateMachine.isTerminal(state)) {
     return Heuristic.getPlayerMobility(stateMachine, state, role);
   }
   List<Move> moves = stateMachine.getLegalMoves(state, role);
   double score = Double.MIN_VALUE;
   Collections.shuffle(moves);
   for (Move move : moves) {
     double result = minscore(move, state, maxDepth, currentDepth + 1);
     if (result > score) {
       score = result;
     }
   }
   playerResult.putMemoizedState(state, score);
   return score;
 }