final List<ProgramExtensionTemplate> opcodeSet = getContext()
.getFunctions().findOpcodes(types, getContext(),
includeTerminal, includeFunction);
// choose a random opcode
final ProgramExtensionTemplate temp = generateRandomOpcode(rnd,
opcodeSet);
if (temp == null) {
throw new EACompileError(
"Trying to generate a random opcode when no opcodes exist.");
}
// create the child nodes
final int childNodeCount = temp.getChildNodeCount();
final ProgramNode[] children = new ProgramNode[childNodeCount];
if (temp.getNodeType().isOperator() && children.length >= 2) {
// for an operator of size 2 or greater make sure all children are
// the same time
final List<ValueType> childTypes = temp.getParams().get(0)
.determineArgumentTypes(types);
final ValueType selectedType = childTypes.get(rnd
.nextInt(childTypes.size()));
childTypes.clear();
childTypes.add(selectedType);
// now create the children of a common type
for (int i = 0; i < children.length; i++) {
children[i] = createNode(rnd, program, depthRemaining - 1,
childTypes);
}
} else {
// otherwise, let the children have their own types
for (int i = 0; i < children.length; i++) {
final List<ValueType> childTypes = temp.getParams().get(i)
.determineArgumentTypes(types);
children[i] = createNode(rnd, program, depthRemaining - 1,
childTypes);
}
}
// now actually create the node
final ProgramNode result = new ProgramNode(program, temp, children);
temp.randomize(rnd, types, result, getMinConst(), getMaxConst());
return result;
}