private Goal <int[], actionType> selectGoal(int[] state, int maxLevel, List <actionType> availableActions) { Goal <int[], actionType> newGoal = new Goal <int[], actionType>(-1, null, default(actionType), null, double.NegativeInfinity, null, null); double[][] values = new double[models.Length][]; for (int i = 0; i <= maxLevel; i++) { int[] thisState = stateTree.GetParentState(state, i); values[i] = models[i].value(thisState, availableActions); } // the default new goal will be the best lowest-level goal for (int i = 0; i < availableActions.Count(); i++) { if (values[0][i] > newGoal.value || newGoal == null) { int[] goalState = models[0].PredictNextState(state, availableActions.ElementAt(i)); /// might need to find best possible next state instead newGoal = new Goal <int[], actionType>(0, state, availableActions.ElementAt(i), goalState, values[0][i], stateComparer, actionComparer); } } // find the best action at any allowed level for (int l = Math.Max(minLevel, 1); l <= maxLevel; l++) { int[] thisState = stateTree.GetParentState(state, l); for (int i = 0; i < availableActions.Count(); i++) { int[] thisGoal = models[l].PredictNextState(thisState, availableActions.ElementAt(i)); if (thisGoal == null) { continue; } Goal <int[], actionType> candidateGoal = new Goal <int[], actionType>(l, thisState, availableActions.ElementAt(i), thisGoal, values[l][i], stateComparer, actionComparer); // check if the goal is allowed if ((currentGoal.goalState != null) && (l < currentGoal.level)) { int[] temp = stateTree.GetParentState(thisGoal, currentGoal.level - l); if (!stateComparer.Equals(temp, currentGoal.goalState)) { continue; } } else if ((currentGoal.goalState != null) && (l == currentGoal.level) && (candidateGoal.value < currentGoal.value)) { continue; } if (candidateGoal.value > newGoal.value) { if (l > 0 && values[l][i] <= 0)// { continue; } newGoal = candidateGoal; } } } return(newGoal); }