private static void SamegameIDAStarTest(string levelPath, int maxCost, int tableSize)//TODO Need a good heuristic for samegame { string[] levels = ReadSamegameLevels(levelPath); IPuzzleState[] states = new IPuzzleState[levels.Length]; int solvedLevels = 0; double totalScore = 0; for (int i = 0; i < states.Length; i++) { states[i] = new SamegameGameState(levels[i], null, null); IDAStarSearch idaStar = new IDAStarSearch(); Log("Level" + (i + 1) + ":\n" + states[i].PrettyPrint()); List <IPuzzleMove> solution = null; string moves = ""; while (!states[i].isTerminal()) { solution = idaStar.Solve(states[i], maxCost, tableSize, 100); if (solution.Count > 0) { moves += solution[0]; states[i].DoMove(solution[0]); } else { break; } } if (states[i].EndState()) { solvedLevels++; } totalScore += states[i].GetResult(); Log("Level " + (i + 1) + " solved: " + (states[i].EndState()) + " solution length:" + moves.Count() + " Score: " + states[i].GetResult()); Log("Moves: " + moves); Log("Solved " + solvedLevels + "/" + (i + 1)); Console.Write("\rSolved " + solvedLevels + "/" + (i + 1)); } Log("Total score: " + totalScore); }
private static void SamegameTest(double const_C, double const_D, int iterations, int restarts, string[] levels, uint seed, bool ucb1Tuned, bool rave, bool nodeRecycling, int memoryBudget) { uint threadIndex = GetThreadIndex(); Console.WriteLine("Thread " + threadIndex + " started"); MersenneTwister rnd = new MersenneTwister(seed + threadIndex); int currentLevelIndex = GetTaskIndex(threadIndex); Stopwatch stopwatch = new Stopwatch(); long stateInitTime; long solvingTime; int totalRollouts = 0; int totalNodes = 0; List <int> visitsList = new List <int>(); List <int> raveVisitsList = new List <int>(); double totalDepth = 0; int totalNodesEliminated = 0; int totalNodesNotExpanded = 0; while (currentLevelIndex >= 0) { ISPSimulationStrategy simulationStrategy = new SamegameTabuColorRandomStrategy(levels[currentLevelIndex], rnd); //Console.Write("\rRun " + (restartN + 1) + " of " + restarts + " "); stopwatch.Restart(); SamegameGameState s = new SamegameGameState(levels[currentLevelIndex], rnd, simulationStrategy); stopwatch.Stop(); stateInitTime = stopwatch.ElapsedMilliseconds; IPuzzleMove move; SamegameMCTSStrategy player = new SamegameMCTSStrategy(rnd, ucb1Tuned, rave, raveThreshold, nodeRecycling, memoryBudget, useNodeElimination, iterations, null, const_C, const_D); string moveString = string.Empty; List <IPuzzleMove> moveList = new List <IPuzzleMove>(); stopwatch.Restart(); while (!s.isTerminal()) { move = player.selectMove(s); moveList.Add(move); s.DoMove(move); totalRollouts += player.Mcts.IterationsExecuted; totalNodes += player.Mcts.NodeCount; totalNodesEliminated += player.Mcts.nodesEliminated; totalNodesNotExpanded += player.Mcts.nodesNotExpanded; visitsList.AddRange(player.Mcts.visits); raveVisitsList.AddRange(player.Mcts.raveVisits); totalDepth += player.Mcts.maxDepth; } stopwatch.Stop(); solvingTime = stopwatch.ElapsedMilliseconds; lock (taskLock) { if (s.GetScore() > scores[currentLevelIndex]) { scores[currentLevelIndex] = s.GetScore(); bestMoves[currentLevelIndex] = moveList; Log("Completed run " + taskTaken[currentLevelIndex] + "/" + restarts + " of level " + (currentLevelIndex + 1) + ". New top score found: " + scores[currentLevelIndex] + " - Init Time: " + TimeFormat(stateInitTime) + " - Solving Time: " + TimeFormat(solvingTime)); //PrintMoveList(currentLevelIndex, moveList); //PrintBestScore(); } else { Log("Completed run " + taskTaken[currentLevelIndex] + "/" + restarts + " of level " + (currentLevelIndex + 1) + " with score: " + s.GetScore() + " - Init Time: " + TimeFormat(stateInitTime) + " - Solving Time: " + TimeFormat(solvingTime)); } } currentLevelIndex = GetTaskIndex(threadIndex); } visitsList.Sort((x, y) => (x.CompareTo(y))); raveVisitsList.Sort((x, y) => (x.CompareTo(y))); double avgVisits = 0; foreach (int v in visitsList) { avgVisits += v; } double avgRaveVisits = 0; foreach (int v in raveVisitsList) { avgRaveVisits += v; } avgVisits /= visitsList.Count; avgRaveVisits /= raveVisitsList.Count; //Log("Solved " + solvedLevels + "/" + levels.Length); Log("Total iterations: " + totalRollouts); Log("Total nodes: " + totalNodes); Log("Nodes eliminated: " + totalNodesEliminated); Log("Nodes Not Expanded: " + totalNodesNotExpanded); Log("avg nodes:" + ((double)totalNodes) / levels.Length); Log("avg visits: " + avgVisits); Log("avg raveVisits: " + avgRaveVisits); Log("median visits: " + (visitsList.Count % 2 == 0 ? visitsList[visitsList.Count / 2] : (visitsList[visitsList.Count / 2] + visitsList[1 + visitsList.Count / 2]) / 2)); Log("median raveVisits: " + (raveVisitsList.Count % 2 == 0 ? raveVisitsList[raveVisitsList.Count / 2] : (raveVisitsList[raveVisitsList.Count / 2] + raveVisitsList[1 + raveVisitsList.Count / 2]) / 2)); Log("avg depth: " + totalDepth / levels.Length); }