예제 #1
0
        /// <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]);
        }
예제 #2
0
        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());
        }
예제 #3
0
        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);
        }
예제 #4
0
        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));
        }
예제 #5
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);
        }
예제 #6
0
        /// <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];
                }
            }
        }
예제 #7
0
        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());
        }
예제 #8
0
파일: UCB1Tree.cs 프로젝트: pavadik/GameAI
        /// <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]);
        }
예제 #9
0
        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;
        }