/// <summary> /// Generates the next boardstate or returns false if unable /// </summary> private Board generate(ExactChromosome max, Board b) { MovesTaken++; Debug.Assert(b.Turn % 2 == 0); int i = b.Turn / 2; if (max.moves.Count <= i) { max.moves.Add(null); } if (max.moves[i] == null || !max.moves[i].isLegal(b)) { illegals++; max.moves[i] = getExactMove(b); if (max.moves[i] == null) { return null; } } max.boardState[i] = hash(b); return b.generate(max.moves[i]); }
public override void takeTurn() { RecordHistory.current.record(); AForge.Genetic.Population ga = new AForge.Genetic.Population(popSize, new ExactChromosome(depth), fit, new AForge.Genetic.RankSelection(), random); bool tempRecord = GameController.recording; GameController.recording = false; int i = 0; while (fit.timesEvaluated < evaluations) { //Getting an index out of range exception here when using RouletteWheelSelection (16 rounds in, seed 100) ga.RunEpoch(); RecordHistory.current.plot(i + "," + ga.FitnessMax + Environment.NewLine); if ((GameController.turn % 5 == 0) && (i == 0 || i == generations / 2 || i == generations - 1)) { List<double> fitnesses = ga.getFitnesses(); List<double> parents = ga.getParentFitnesses(); List<string> snap = new List<string>(); for (int j = 0; j < fitnesses.Count; j++) snap.Add(fitnesses[j].ToString() + "," + parents[j].ToString()); RecordHistory.current.snapshot(snap); } i++; } lastBestChromosome = ga.BestChromosome as ExactChromosome; fit.timesEvaluated = 0; GameController.recording = tempRecord; fit.Evaluate(lastBestChromosome); Move m = lastBestChromosome.moves[0]; if (m == null) { m = Move.getRandomMove(); throw new NullReferenceException("ExactGene couldn't find a random move."); } CONSOLE.Overwrite(12, "Illegals: " + fit.Illegals); CONSOLE.Overwrite(13, "Moves: " + fit.MovesTaken); takeAction(m); RecordHistory.current.record(this + " took move " + m); }
/// <summary> /// Evaluates a chromosome against Greedy /// </summary> private double score(ExactChromosome max) { Board current = Board.current; Board next; Move nextMove; Move pred = null; //Predicted move next turn for Greedy double score = 0; int i = 0; while (current.Turn < depth) { if (predictWin(current, pred)) break; next = generate(max, current); if (next == null) break; score += scoringFunction.evaluate(next); i++; current = next; if (predictWin(current, pred)) break; //Do the "Generate-next-move" loop for greedy nextMove = Greedy.getGreedyMove(current, greedy); if (i == 1) pred = nextMove; if (nextMove != null) { current = current.generate(nextMove); } else { break; } } if (max.parentFitness > 0 && score > max.parentFitness) { ExactChromosome.crossOverImprovements += 1; } else if (max.parentFitness < 0 && score > -max.parentFitness) { ExactChromosome.mutationImprovements += 1; } return score / i; }