001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package examples.gp.tictactoe;
011:
012: import org.jgap.gp.impl.*;
013: import org.jgap.gp.*;
014: import org.jgap.gp.function.*;
015:
016: /**
017: * Validates evolved nodes for the Tic Tac Toe problem.
018: *
019: * @author Klaus Meffert
020: * @since 3.2
021: */
022: public class GameNodeValidator implements INodeValidator {
023: /**
024: * Validates a_node in the context of a_chrom during evolution. Considers the
025: * recursion level (a_recursLevel), the type needed (a_type) for the node, the
026: * functions available (a_functionSet) and the depth of the whole chromosome
027: * needed (a_depth), and whether grow mode is used (a_grow is true) or not.
028: *
029: * @param a_chrom the chromosome that will contain the node, if valid (ignored
030: * in this implementation)
031: * @param a_node the node selected and to be validated
032: * @param a_rootNode the root node of a_node, may be null for top nodes
033: * @param a_tries number of times the validator has been called, useful for
034: * stopping by returning true if the number exceeds a limit
035: * @param a_num the chromosome's index in the individual of this chromosome
036: * @param a_recurseLevel level of recursion, i.e. the depth of a node
037: * @param a_type the return type of the node needed
038: * @param a_functionSet the array of available functions (ignored in this
039: * implementation)
040: * @param a_depth the allowed remaining depth of the program chromosome
041: * @param a_grow true: use grow mode, false: use full mode (ignored in this
042: * implementation)
043: * @param a_childIndex index of the child in the parent node to which it
044: * belongs (-1 if node is root node)
045: * @param a_fullProgram true: full program is available for evaluation
046: * @return true: node is valid; false: node is invalid
047: *
048: * @author Klaus Meffert
049: * @since 3.2
050: */
051: public boolean validate(ProgramChromosome a_chrom,
052: CommandGene a_node, CommandGene a_rootNode, int a_tries,
053: int a_num, int a_recurseLevel, Class a_type,
054: CommandGene[] a_functionSet, int a_depth, boolean a_grow,
055: int a_childIndex, boolean a_fullProgram) {
056: // Guard to avoid endless validation.
057: // ----------------------------------
058: if (a_tries > 10) {
059: return true;
060: }
061: if (a_fullProgram) {
062: return true;
063: }
064: // Chromosome 1.
065: // -------------
066: if (a_num == 1) {
067: // Program must start with a loop.
068: // -------------------------------
069: if (a_recurseLevel == 0 && a_node.getClass() != Loop.class) {
070: return false;
071: }
072: if (a_recurseLevel == 1
073: && a_node.getClass() != EvaluateBoard.class) {
074: return false;
075: }
076: }
077: // Chromosome 2.
078: // -------------
079: if (a_num == 2) {
080: // SubProgram needed as root
081: if (a_recurseLevel == 0
082: && a_node.getClass() != SubProgram.class) {
083: return false;
084: }
085: // SubProgram forbidden other than at beginning
086: // if (a_recurseLevel > 1 && a_node.getClass() == SubProgram.class) {
087: // return false;
088: // }
089: // EvaluateBoard forbidden other than under root node and as not-first
090: // child
091: if (a_recurseLevel > 1
092: && a_node.getClass() == EvaluateBoard.class
093: && a_childIndex > 0) {
094: return false;
095: }
096: if (a_recurseLevel == 1 && a_childIndex == 0
097: && a_node.getClass() != EvaluateBoard.class) {
098: return false;
099: }
100: if (a_rootNode != null
101: && a_rootNode.getClass() != SubProgram.class
102: && a_rootNode.getClass() != IfElse.class
103: && a_node.getClass() == IfElse.class
104: && a_childIndex <= 1) {
105: return false;
106: }
107: if (a_rootNode != null
108: && a_rootNode.getClass() != IfElse.class
109: && a_node.getClass() != Equals.class) {
110: return false;
111: }
112: // CountStones forbidden other than under SubProgram
113: // if ( (a_rootNode == null || a_rootNode.getClass() != SubProgram.class) &&
114: // a_node.getClass() == CountStones.class) {
115: // return false;
116: // }
117: // CountStones needed one under root
118: // if (a_recurseLevel == 1 && a_node.getClass() != CountStones.class) {
119: // return false;
120: // }
121: }
122: // Chromosome 3.
123: // -------------
124: if (a_num == 3) {
125: if (a_recurseLevel == 0
126: && a_node.getClass() != PutStone1.class) {
127: return false;
128: }
129: if (a_recurseLevel == 1
130: && a_node.getClass() != ReadTerminalIndexed.class) {
131: return false;
132: }
133: }
134: return true;
135: }
136: }
|