public Engine(EngineParameters userParams) { currentEngineParams = userParams; }
public void BuildProgram( int populationSize, int crossoverPercentage, double mutationPercentage, int ElitismPercentage, int tourneySize, Action <string> currentStatusCallback, string dealerUpcardRankToUse) { displayGenerationCallback = currentStatusCallback; dealerUpcardRank = dealerUpcardRankToUse; // just some values, leave the rest as defaults var engineParams = new EngineParameters() { CrossoverRate = crossoverPercentage / 100F, ElitismRate = ElitismPercentage / 100F, IsLowerFitnessBetter = false, MutationRate = mutationPercentage / 100F, PopulationSize = populationSize, TourneySize = tourneySize }; // create the engine. each tree (and node within the tree) will return a bool. // we also indicate the type of our problem state data (used by terminal functions and stateful functions) var engine = new Engine <bool, ProblemState>(engineParams); // no constants for this problem // no variables for this solution - we can't pass in information about our hand // via boolean variables, so we do it via some terminal functions instead // for a boolean tree, we use the standard operators engine.AddFunction((a, b) => a || b, "Or"); engine.AddFunction((a, b, c) => a || b || c, "Or3"); engine.AddFunction((a, b) => a && b, "And"); engine.AddFunction((a, b, c) => a && b && c, "And3"); engine.AddFunction((a) => !a, "Not"); // then add functions to indicate a strategy engine.AddStatefulFunction(HitIf, "HitIf"); engine.AddStatefulFunction(StandIf, "StandIf"); engine.AddStatefulFunction(DoubleIf, "DoubleIf"); engine.AddStatefulFunction(SplitIf, "SplitIf"); // terminal functions to look at game state // first, player holding ace? engine.AddTerminalFunction(HasAce, "HasAce"); engine.AddTerminalFunction(HasPair, "HasPair"); // player hand totals engine.AddTerminalFunction(HandVal4, "Has4"); engine.AddTerminalFunction(HandVal5, "Has5"); engine.AddTerminalFunction(HandVal6, "Has6"); engine.AddTerminalFunction(HandVal7, "Has7"); engine.AddTerminalFunction(HandVal8, "Has8"); engine.AddTerminalFunction(HandVal9, "Has9"); engine.AddTerminalFunction(HandVal10, "Has10"); engine.AddTerminalFunction(HandVal11, "Has11"); engine.AddTerminalFunction(HandVal12, "Has12"); engine.AddTerminalFunction(HandVal13, "Has13"); engine.AddTerminalFunction(HandVal14, "Has14"); engine.AddTerminalFunction(HandVal15, "Has15"); engine.AddTerminalFunction(HandVal16, "Has16"); engine.AddTerminalFunction(HandVal17, "Has17"); engine.AddTerminalFunction(HandVal18, "Has18"); engine.AddTerminalFunction(HandVal19, "Has19"); engine.AddTerminalFunction(HandVal20, "Has20"); // num cards held engine.AddTerminalFunction(Holding2Cards, "Hold2"); engine.AddTerminalFunction(Holding3Cards, "Hold3"); // pass a fitness evaluation function and run engine.AddFitnessFunction((t) => EvaluateCandidate(t)); // and add something so we can track the progress engine.AddProgressFunction((t) => PerGenerationCallback(t)); BestSolution = engine.FindBestSolution(); }