public static RandomSearch Create(string[] args) { Heuristic f; if (args.Length < 3) { throw new FormatException("Usage: random <depth> <evaluations> <...scoring function...>"); } List<string> scoring = new List<string>(args); List<int> parameters; scoring.RemoveRange(0, 2); try { f = Heuristic.parse(scoring); parameters = new List<string>(args).GetRange(0, 2).ConvertAll<int>(x => int.Parse(x)); } catch (FormatException excpt) { throw excpt; } return new RandomSearch(f, parameters[0], parameters[1]); }
public static Move minimax(Board startingPoint, int depth, Heuristic scoringFunction, out double score, Func<Board, bool> endCondition=null) { bool myTurn = startingPoint.Turn % 2 == 0; //Indicates that it's Minimax's turn. Move bestMove = null; List<Move> legalMoves = startingPoint.legalMoves; double[] bestScore = new double[legalMoves.Count]; //int val; Func<double, double, bool> comp = (x,y) => (x > y); if (depth == 0 || legalMoves.Count == 0 || (endCondition != null && endCondition(startingPoint))) { //If the root is currently myTurn, then the opponent generated this board; therefore send the negation of the score. Otherwise send the score. score = scoringFunction.evaluate(startingPoint) * (myTurn ? -1 : 1); return null; } if (!myTurn) { //If it's the opponent's turn, they will select for the minimal score. for (int i=0; i < bestScore.Length; i++) bestScore[i] = double.MaxValue; comp = (x, y) => (x < y); } else for (int i = 0; i < bestScore.Length; i++) bestScore[i] = double.MinValue; Parallel.For(0, legalMoves.Count, (x) => { Move m = legalMoves[x]; minimax(startingPoint.generate(m), depth - 1, scoringFunction, out bestScore[x]); }); //At this point bestscore[x] is the cumulative score of lower branches guaranteed by choosing the xth move. bestMove = legalMoves[0]; //Minimax finds the maximum of these scores, or the opponent finds the minimum of these scores. for (int i=1; i < bestScore.Length; i++) { if (comp(bestScore[i], bestScore[0])) { bestScore[0] = bestScore[i]; bestMove = legalMoves[i]; } } //If it's Minimax's turn, the opponent generated this board; therefore the score is subtracted. Otherwise the score is added. score = myTurn ? bestScore[0] - scoringFunction.evaluate(startingPoint) : bestScore[0] + scoringFunction.evaluate(startingPoint); if (startingPoint.Equals(Board.current)) { Array scores = bestScore.Set(); var best = new List<double>(bestScore).FindAll(x => x == bestScore[0]); RecordHistory.current.writeToFile("minimax.txt", "Diversity: " + scores.Length + " " + "BestScores: " + best.Count + Environment.NewLine); } return bestMove; }
/// <summary> /// Gets the greedy move based on the given function. Ignores Reserves to save computation. /// </summary> /// <param name="b"></param> /// <param name="scoringFunction"></param> /// <returns></returns> public static Move getGreedyMove(Board b, Heuristic scoringFunction) { Move bestMove = null; double bestScore = int.MinValue; foreach (Move m in b.legalMoves) { //if (m.moveType == Move.Type.RESERVE) continue; double temp = scoringFunction.evaluate(b.generate(m)); if (temp > bestScore) { bestScore = temp; bestMove = m; } } if (bestMove == null) { throw new Exception("GreedyMove returned a null move."); } return bestMove; }
public Greedy(Heuristic scoringFunction) { this.scoringFunction = scoringFunction; name = "Greedy " + scoringFunction.ToString(); }
public Greedy() { scoringFunction = Heuristic.Lead + Heuristic.WinLoss; name = "Greedy Delta"; }
public Minimax(int i, Heuristic f) : base("Minimax " + i + "(" + f.ToString() + ")") { treeDepth = i; scoringFunction = f; }
public RandomSearch(Heuristic f, int depth, int evaluations) { this.f = f; this.depth = depth; this.evaluations = evaluations; }
public Heuristic operate(string op, Heuristic rhs) { switch (op) { case "+": return this + rhs; case "-": return this - rhs; case "*": return this * rhs; case "/": return this / rhs; case "^": return this ^ rhs; case "delta": return this.delta(); default: throw new FormatException("Invalid operator"); } }
public static void Save(string name, Heuristic fn) { System.IO.File.AppendAllText(save, name + ":" + fn.ToString() + "\n"); }