/// <summary> /// Return the move with the highest win-rate after performing in parallel the specified number of simulations on the game. /// </summary> /// <param name="game">The starting gamestate.</param> /// <param name="simulations">The number of simulations to perform.</param> public static TMove ParallelSearch(TGame game, int simulations) { TPlayer aiPlayer = game.CurrentPlayer; List <TMove> legalMoves = game.GetLegalMoves(); int count = legalMoves.Count; MoveStats[] moveStats = new MoveStats[count]; Parallel.For(0, simulations, () => RandomFactory.Create(), (i, loop, localRandom) => { int moveIndex = localRandom.Next(0, count); TGame copy = game.DeepCopy(); copy.DoMove(legalMoves[moveIndex]); while (!copy.IsGameOver()) { copy.DoMove( copy.GetLegalMoves().RandomItem(localRandom)); } Interlocked.Add(ref moveStats[moveIndex].executions, 1); if (copy.IsWinner(aiPlayer)) { Interlocked.Add(ref moveStats[moveIndex].victories, 1); } return(localRandom); }, x => { } ); int bestMoveFound = 0; double bestScoreFound = 0f; for (int i = 0; i < count; i++) { double score = moveStats[i].Score(); if (score > bestScoreFound) { bestScoreFound = score; bestMoveFound = i; } } //for (int i = 0; i < legalMoves.Count; i++) // Console.WriteLine("Move " + legalMoves[i] + " has " + moveStats[i].victories + " victories / " + moveStats[i].executions + " executions."); return(legalMoves[bestMoveFound]); }
public object Perform(StepContext ctx, object input) { var random = RandomFactory.Create(); return(CreateCellMatrix(ctx) .Fill(random, ctx.RandomFillPercent) .Smooth( ctx.SmoothSteps, ctx.MaxActiveNeighbors, ctx.NeighboursRadio ) .RemoveRegions(ctx.RemoveRegionsSize) .MakeBorders()); }
public static string GenerateRandomAlphaString(int length = 8) { const string alphabet = "abcdefghijklmnopqrstuvwxyz"; var r = RandomFactory.Create(); var handle = ""; for (var count = 0; count < length; count++) { var chosenCharIndex = r.Next(0, alphabet.Length); handle += alphabet[chosenCharIndex]; } return(handle); }
public void RandomFactoryCreatesSameSequencOfGeneratorsForSameSeed() { int seed = 42; var f0 = new RandomFactory(seed, 10, 2, 1, 10, 1, 1, 1); IRandomCallGenerator r01 = f0.Create(); IRandomCallGenerator r02 = f0.Create(); var f1 = new RandomFactory(seed, 10, 2, 1, 10, 1, 1, 1); IRandomCallGenerator r11 = f1.Create(); IRandomCallGenerator r12 = f1.Create(); Assert.AreEqual(r11.GenerateRandomCall(0), r01.GenerateRandomCall(0)); Assert.AreEqual(r11.GenerateRandomCall(50), r01.GenerateRandomCall(50)); Assert.AreNotEqual(r11.GenerateRandomCall(1120), r01.GenerateRandomCall(2203)); Assert.AreEqual(r11.GenerateRandomCall(55), r01.GenerateRandomCall(55)); Assert.AreEqual(r02.GenerateRandomCall(0), r12.GenerateRandomCall(0)); Assert.AreEqual(r02.GenerateRandomCall(10), r12.GenerateRandomCall(10)); Assert.AreEqual(r02.GenerateRandomCall(0), r12.GenerateRandomCall(0)); Assert.AreEqual(r02.GenerateRandomCall(10), r12.GenerateRandomCall(10)); Assert.AreNotEqual(r11.GenerateRandomCall(0), r12.GenerateRandomCall(0)); }
public void GraphWithSelfEdgesPUT07() { AdjacencyGraph adjacencyGraph; Random random; VertexAndEdgeProvider s0 = new VertexAndEdgeProvider(); adjacencyGraph = AdjacencyGraphFactory.CreateCyclicGraph(s0, false, 0); random = RandomFactory.Create(0); IPexChoiceRecorder choices = PexChoose.NewTest(); ((IPexChoiceSessionBuilder)(choices.NextSegment(2) .OnCall(0, "DepthFirstAlgorithmSearchTestNEW.GraphWithSelfEdgesPUT(AdjacencyGraph, Int32, Boolean)") )) .At(0, "Random object", (object)random); this.GraphWithSelfEdgesPUT(adjacencyGraph, 2, false); }
/// <summary> /// Shuffles elements of the sequence. /// </summary> /// <typeparam name="TSource">The type of elements in the <paramref name="source"/>.</typeparam> /// <param name="source">A sequence of values.</param> /// <returns>An <see cref="IEnumerable{T}"/> where each of its elements are in the input sequence.</returns> /// <exception cref="ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception> /// <remarks> /// This method is implemented by using deferred execution. The immediate return value is an object that stores all /// the information that is required to perform the action. /// </remarks> public static IEnumerable <TSource> Shuffle <TSource>(this IEnumerable <TSource> source) { Contract.Requires <ArgumentNullException>(source != null, nameof(source)); return(Iterator()); IEnumerable <TSource> Iterator() { var random = RandomFactory.Create(); var list = new List <TSource>(source); for (int i = 0, count = list.Count; i < count; ++i) { var n = i + random.Next(count - i); yield return(list[n]); list[n] = list[i]; } } }
public async Task <QuestionCardModel> GetRandomQuestionCardForGame(int gameId) { var query = from qc in context.QuestionCards join game in context.Games on qc.LanguageId equals game.LanguageId where qc.IsActive && game.GameId == gameId && (!qc.IsAdultContent || qc.IsAdultContent == game.ShowAdultContent) && !(from gr in context.GameRounds where gr.GameId == game.GameId select gr.QuestionCardId).Contains(qc.QuestionCardId) select new QuestionCardModel { IsAdultContent = qc.IsAdultContent, LanguageId = qc.LanguageId, NumberOfAnswers = qc.NumberOfAnswers, QuestionCardId = qc.QuestionCardId, Text = qc.Text }; var count = await query.CountAsync(); int index = RandomFactory.Create().Next(count); return(await query.Skip(index).FirstOrDefaultAsync()); }
/// <summary> /// Return the best Transition found after performing in parallel the specified number of simulations on the game. /// </summary> /// <param name="game">The initial gamestate from which to find the best move for the current player.</param> /// <param name="milliseconds">The length of time to run the search.</param> public static Transition ParallelSearch(TGame game, long milliseconds) { ConcurrentDictionary <long, Node> tree = new ConcurrentDictionary <long, Node>(); tree.TryAdd(game.Hash, new Node(game.CurrentPlayer)); Stopwatch sw = new Stopwatch(); sw.Start(); Parallel.For(0L, Int64.MaxValue, () => new ThreadLocalVars(RandomFactory.Create(), new List <Node>(50)), (i, loop, localVars) => { if (sw.ElapsedMilliseconds > milliseconds) { loop.Stop(); } TGame copy = game.DeepCopy(); localVars.path.Clear(); localVars.path.Add(tree[game.Hash]); while (!copy.IsGameOver()) { List <Transition> transitions = copy.GetLegalTransitions(); List <Transition> transitionsNoStats = new List <Transition>(); foreach (Transition transition in transitions) { if (!tree.ContainsKey(transition.Hash)) { transitionsNoStats.Add(transition); } } // SELECTION if (transitionsNoStats.Count == 0) { double bestScore = double.MinValue; int parentPlays = localVars.path[localVars.path.Count - 1].plays; double ucb1Score; int indexOfBestTransition = 0; for (int j = 0; j < transitions.Count; j++) { ucb1Score = tree[transitions[j].Hash].ParentUCBScore(parentPlays); if (ucb1Score > bestScore) { bestScore = ucb1Score; indexOfBestTransition = j; } } Transition bestTransition = transitions[indexOfBestTransition]; copy.Transition(bestTransition); localVars.path.Add(tree[bestTransition.Hash]); } // EXPANSION else { copy.Transition(transitionsNoStats.RandomItem(localVars.random)); Node n = new Node(copy.CurrentPlayer); if (tree.TryAdd(copy.Hash, n)) { localVars.path.Add(n); } else { localVars.path.Add(tree[copy.Hash]); } break; } } // ROLLOUT copy.Rollout(); // BACKPROP foreach (Node node in localVars.path) { Interlocked.Add(ref node.plays, 1); if (copy.IsWinner(node.player)) { Interlocked.Add(ref node.wins, 1); } } return(localVars); }, x => { } ); // Simulations are over. Pick the best move, then return it List <Transition> allTransitions = game.GetLegalTransitions(); int indexOfBestMoveFound = 0; double worstScoreFound = double.MaxValue; double score; //Console.WriteLine("Root: plays-{0} wins-{1} plyr-{2}", tree[game.GetHash()].plays, tree[game.GetHash()].wins, tree[game.GetHash()].player); for (int i = 0; i < allTransitions.Count; i++) { // Node n = tree[allTransitions[i].Hash]; //Console.WriteLine("Move {0}: plays-{1} wins-{2} plyr-{3}", i, n.plays, n.wins, n.player); // **NOTE** // The best move chosen is the move with gives the // opponent the least number of victories score = tree[allTransitions[i].Hash].CurrentPlayerScore(); if (score < worstScoreFound) { worstScoreFound = score; indexOfBestMoveFound = i; } } return(allTransitions[indexOfBestMoveFound]); }
private async Task StartSimulation() { if (Simulator.SongData == null) { MessageBox.Show("楽曲を選んでください"); return; } if (Simulator.Unit == null) { MessageBox.Show("ユニットを選んでください"); return; } if (Runs < 1 || Runs > 1000000) { MessageBox.Show("試行回数は1から1,000,000までである必要があります"); return; } Note[] pattern = null; if (UtilizeActualPattern) { pattern = await new PatternProvider().GetPattern(Simulator.Song, Simulator.SongData.Difficulty, Simulator.SongData.Notes); if (pattern == null) { MessageBox.Show($"{Simulator.Song.Title}({Simulator.SongData.Difficulty})の譜面データが見つかりませんでした。"); return; } } SimulationCompleted = false; var results = new ConcurrentBag <SimulationResult>(); await Task.Run(() => Parallel.For(1, Runs + 1, i => results.Add(Simulator.StartSimulation(RandomFactory.Create(), i, pattern == null ? null : new Queue <Note>(pattern))))); MaxScore = results.Max(x => x.Score); MaxScorePerNote = results.Max(x => x.ScorePerNote); MinScore = results.Min(x => x.Score); MinScorePerNote = results.Min(x => x.ScorePerNote); AverageScore = (int)results.Average(x => x.Score); AverageScorePerNote = (int)results.Average(x => x.ScorePerNote); ScoreDistribution = results.GroupBy(x => (int)Math.Floor(x.Score / 10000.0)).OrderBy(x => x.Key).ToDictionary(x => x.Key, x => (double)x.Count() / results.Count); StandardDeviation = Math.Round(Math.Sqrt(results.Sum(x => Math.Pow(x.Score - AverageScore, 2))) / results.Count); int idx = 1; var duration = results.First().Duration; ActualTriggerRatio = Simulator.Unit.Slots.ToDictionary(s => $"スロット{idx++}", s => s == null ? 0 : results.SelectMany(x => x.TriggeredSkills).Where(x => x.Who == s).Count() / (results.Count * Math.Floor((duration - 1.0) / s.Skill.Interval))); SimulationResults = results.OrderBy(x => x.Id).Take(100).ToList(); SelectedResult = SimulationResults[0]; SimulationCompleted = true; }