Пример #1
0
 internal SplitNode(SplitNode parent, char pos)
 {
     this.splitter = default(T);
     this.root     = parent.root;
     this.position = parent.position + pos;
     this.left     = null;
     this.right    = null;
 }
Пример #2
0
 internal SplitNode()
 {
     this.splitter = default(T);
     this.root     = this;
     this.position = "";
     this.left     = null;
     this.right    = null;
 }
Пример #3
0
        /// <summary>Process the specified task.
        /// The game will execute the desired task and all effects coupled either
        /// directly or indirectly in synchronous manner.
        ///
        /// Call <see cref="Controller.Options(bool)"/> on the <see cref="CurrentPlayer"/>
        /// instance for tasks which are accepted as arguments.
        /// After this method returns, check <see cref="Controller.Options(bool)"/>
        /// again until only <see cref="EndTurnTask"/> remains, which will
        /// start the turn of <see cref="CurrentOpponent"/>.
        /// </summary>
        /// <param name="gameTask">The game task to execute.</param>
        public void Process(PlayerTask gameTask)
        {
            // start with no splits ...
            Splits = new List <Game>();

            Log(LogLevel.INFO, BlockType.PLAY, "Game", gameTask.FullPrint());

            // clear last power history
            PowerHistory.Last.Clear();

            // make sure that we only use task for this game ...
            gameTask.Game = this;
            gameTask.Process();

            // add enchantment and buff tag changes
            if (History)
            {
                Enchants.ForEach(p =>
                                 p.Effects.Keys.ToList().ForEach(t =>
                                                                 IdEntityDic.Values.ToList().ForEach(o =>
                                                                                                     PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t])))));

                foreach (var controller in _players)
                {
                    controller.Hero.Enchants.ForEach(p =>
                                                     p.Effects.Keys.ToList().ForEach(t =>
                                                                                     PowerHistory.Add(PowerHistoryBuilder.TagChange(Game.CurrentPlayer.Hero.Id, t, Game.CurrentPlayer.Hero[t]))));

                    //CurrentPlayer.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled());
                    //CurrentPlayer.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled());
                    //CurrentOpponent.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled());
                    //CurrentOpponent.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled());

                    controller.ControlledZones.Where(z => z != null).ToList().ForEach(z =>
                                                                                      z.Enchants.ForEach(p =>
                                                                                                         p.Effects.Keys.ToList().ForEach(t =>
                                                                                                                                         z.GetAll.ForEach(o =>
                                                                                                                                                          PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t]))))));
                }

                Characters.ForEach(c =>
                                   c.Enchants.ForEach(p =>
                                                      p.Effects.Keys.ToList().ForEach(t =>
                                                                                      PowerHistory.Add(PowerHistoryBuilder.TagChange(c.Id, t, c[t])))));
            }

            if (Splitting)
            {
                var finalSplits = SplitNode.GetSolutions(this, 10, 10000);
                Dump("Split", $"found {finalSplits.Count} final splits of {finalSplits.Sum(p => p.SameState + 1)}!");
                finalSplits.GroupBy(p => p.SameState)
                .Select(i => new { Word = i.Key, Count = i.Count() })
                .ToList().ForEach(p => Dump("Split", $" {p.Count},  with {p.Word} same states"));
                FinalSplits = finalSplits;
            }
        }
Пример #4
0
 internal SplitNode FindCommonAncestorWith(SplitNode other)
 {
     return(root.FindNode(this.position, other.position, 0));
 }
Пример #5
0
        /// <summary>
        /// Based on algorithm MinSFA from POPL14.
        /// </summary>
        void ComputeSplitHistory()
        {
            var fa = autom;

            if (!fa.isDeterministic)
            {
                throw new AutomataException(AutomataExceptionKind.AutomatonIsNondeterministic);
            }

            this.initialFinalBlock             = new Block(fa.GetFinalStates());
            this.initialNonfinalBlock          = new Block(fa.GetNonFinalStates());
            this.initialFinalNode              = new SplitNode();
            this.initialNonfinalNode           = new SplitNode();
            splithistory[initialFinalBlock]    = this.initialFinalNode;
            splithistory[initialNonfinalBlock] = this.initialNonfinalNode;

            foreach (var q in fa.GetFinalStates())
            {
                Blocks[q] = initialFinalBlock;
            }
            foreach (var q in fa.GetNonFinalStates())
            {
                Blocks[q] = initialNonfinalBlock;
            }

            var W  = new BlockStack();
            var W1 = new BlockStack();

            if (initialNonfinalBlock.Count < initialFinalBlock.Count)
            {
                W1.Push(initialNonfinalBlock);
            }
            else
            {
                W1.Push(initialFinalBlock);
            }

            Func <T, T, T> MkDiff = (x, y) => solver.MkAnd(x, solver.MkNot(y));

            //use breath first search wrt new elements

            while (!W1.IsEmpty)
            {
                var tmp = W;
                W  = W1;
                W1 = tmp;

                while (!W.IsEmpty)
                {
                    var B = W.Pop();

                    var Bcopy = new List <int>(B);             //make a copy of B for iterating over its elemenents
                    var Gamma = new Dictionary <int, T>();     //joined conditions leading to B from states leading to B
                    foreach (var q in Bcopy)
                    {
                        foreach (var move in fa.GetMovesTo(q))      //moves leading to q
                        {
                            if (Blocks[move.SourceState].Count > 1) //singleton blocks cannot be further split
                            {
                                if (Gamma.ContainsKey(move.SourceState))
                                {
                                    Gamma[move.SourceState] = solver.MkOr(Gamma[move.SourceState], move.Label);
                                }
                                else
                                {
                                    Gamma[move.SourceState] = move.Label;
                                }
                            }
                        }
                    }

                    //if x is not in Gamma.Keys then return False else return Gamma[q]
                    //this way initial (_,B)-splitting is not required
                    Func <int, T> GAMMA = (x) =>
                    {
                        T pred;
                        if (Gamma.TryGetValue(x, out pred))
                        {
                            return(pred);
                        }
                        else
                        {
                            return(solver.False);
                        }
                    };

                    var relevant2 = new HashSet <Block>();
                    foreach (var q in Gamma.Keys)
                    {
                        if (Blocks[q].Count > 1)
                        {
                            relevant2.Add(Blocks[q]); //collect the relevant blocks
                        }
                    }
                    var relevantList = new List <Block>(relevant2);

                    //only relevant blocks are potentially split
                    while (relevantList.Count > 0)
                    {
                        var P = relevantList[0];
                        relevantList.RemoveAt(0);

                        var PE = P.GetEnumerator();
                        PE.MoveNext();

                        var  P1         = new Block();
                        bool splitFound = false;

                        //psi may be false here
                        T psi = GAMMA(PE.Current);
                        P1.Add(PE.Current); //note that PE has at least 2 elements

                        #region compute P1 as the new sub-block of P
                        while (PE.MoveNext())
                        {
                            var q   = PE.Current;
                            var phi = GAMMA(q);

                            if (splitFound)
                            {
                                var psi_and_phi = solver.MkAnd(psi, phi);
                                if (solver.IsSatisfiable(psi_and_phi))
                                {
                                    psi = psi_and_phi;
                                    P1.Add(q);
                                }
                            }
                            else
                            {
                                var psi_min_phi = MkDiff(psi, phi);
                                if (solver.IsSatisfiable(psi_min_phi))
                                {
                                    psi        = psi_min_phi;
                                    splitFound = true;
                                }
                                else // [[psi]] is subset of [[phi]]
                                {
                                    var phi_min_psi = MkDiff(phi, psi);
                                    if (!solver.IsSatisfiable(phi_min_psi))
                                    {
                                        // [[phi]] is subset of [[psi]]
                                        P1.Add(q); //psi and phi are equivalent
                                    }
                                    else
                                    {
                                        //there is some a: q --a--> B and p --a--> compl(B)
                                        P1.Clear();
                                        P1.Add(q);
                                        psi        = phi_min_psi;
                                        splitFound = true;
                                    }
                                }
                            }
                        }
                        #endregion

                        #region split P
                        //if P1.Count == P.Count then nothing was split
                        if (P1.Count < P.Count)
                        {
                            var node = splithistory[P];
                            node.Split(psi);
                            //which one is left or right does not matter
                            splithistory[P]  = node.left;
                            splithistory[P1] = node.right;

                            foreach (var p in P1)
                            {
                                P.Remove(p);
                                Blocks[p] = P1;
                            }

                            if (W.Contains(P) || W1.Contains(P))
                            {
                                W1.Push(P1);
                            }
                            else if (P.Count <= P1.Count)
                            {
                                W1.Push(P);
                            }
                            else
                            {
                                W1.Push(P1);
                            }

                            if (P.Count > 1)
                            {
                                relevantList.Add(P);
                            }
                            if (P1.Count > 1)
                            {
                                relevantList.Add(P1);
                            }
                        }
                        #endregion
                    }
                }
            }
        }
Пример #6
0
 internal void Split(T splitter)
 {
     this.splitter = splitter;
     this.left     = new SplitNode(this, 'l');
     this.right    = new SplitNode(this, 'r');
 }
Пример #7
0
        public static Graph THINGS()
        {
            /*
             * Sizes
             * - EC3: 80
             * - EC4: 110
             * - SNG-3: 70
             * - SNG-4: 90
             * - SNG-5: 110
             * In:
             * - 0:00:00, EC3(C), EC3(C)
             * - 0:05:00,  SNG-4
             * - 0:12:00,  EC3, EC4
             * - 0:30:00,  EC4
             * - 1:00:00,  SNG-3, SNG-3
             * - 1:10:00,  SNG-5
             * Out:
             * - 0:20:00,  EC3
             * - 0:25:00,  SNG-4
             * - 0:29:00,  EC4, EC3
             * - 0:45:00,  EC3, EC4
             * - 1:55:00,  SNG-5, SNG-3
             * - 2:10:00,  SNG-3
             *
             * Cleaning (C):
             * - EC3: 32
             * - EC4: 47
             * - SNG-3: 27
             * - SNG-4: 35
             * - SNG-5: 42
             *
             * Insepction (I):
             * - EC3: 32
             * - EC4: 47
             * - SNG-3: 27
             * - SNG-4: 35
             * - SNG-5: 42
             */
            var graph = new Graph();

            Func <int, int> hours   = (int h) => h * 3600;
            Func <int, int> minutes = (int m) => m * 60;
            Func <int, int> seconds = (int s) => s;

            Func <int, int, int> track2secs      = (int t, int s) => t * 60 + s * 30;
            Func <int, int>      turnaround2secs = (int c) => c * 30;

            /*
             *  - 0:00:00, EC3(C), EC3(C)
             *  - 0:05:00,  SNG4
             *  - 0:12:00,  EC3, EC4
             *  - 0:30:00,  EC4
             *  - 1:00:00,  SNG3, SNG3
             *  - 1:10:00,  SNG5
             */
            var ar1 = new ArrivalNode("(1,2)", 0);
            var ar2 = new ArrivalNode("(3)", minutes(5));
            var ar3 = new ArrivalNode("(4, 5)", minutes(12));
            var ar4 = new ArrivalNode("(6)", minutes(30));
            var ar5 = new ArrivalNode("(7, 8)", hours(1));
            var ar6 = new ArrivalNode("(9)", hours(1) + minutes(10));

            /*
             * Out:
             *  - 0:50:00,  EC3
             *  - 0:25:00,  SNG-4
             *  - 0:29:00,  EC4, EC3
             *  - 0:45:00,  EC3, EC4
             *  - 1:55:00,  SNG-5, SNG-3
             *  - 2:10:00,  SNG-3
             */
            var dep1 = new DepartureNode("(1)", minutes(60));
            var dep2 = new DepartureNode("(3)", minutes(25));
            var dep3 = new DepartureNode("(5,2)", minutes(69));
            var dep4 = new DepartureNode("(4, 6)", minutes(45));
            var dep5 = new DepartureNode("(9, 7)", hours(1) + minutes(55));
            var dep6 = new DepartureNode("(8)", hours(2) + minutes(10));


            {
                Node m12P1      = new MovementNode("(1, 2) to P1", track2secs(2, 1));
                Node s12        = new SplitNode("(1, 2) -> (1), (2)", minutes(2) + 30);
                Node m1p7       = new MovementNode("(1) to P7", track2secs(3, 2));
                Node service1p7 = new ServiceNode("(1) insepction", minutes(32));
                Node service2p7 = new ServiceNode("(1) insepction", minutes(32));
                Node m2p7       = new MovementNode("(2) to P7", track2secs(3, 2));
                ar1.AddSuccessor(m12P1);

                m12P1 += s12;
                s12   += m1p7;
                s12   += m2p7;
                m1p7  += m2p7;

                m1p7 += service1p7;
                m2p7 += service2p7;

                Node m1p4 = new MovementNode("(1) to P4", track2secs(5, 4));
                Node m2p4 = new MovementNode("(2) to P4", track2secs(5, 4));

                service1p7 += m1p4;
                service2p7 += m2p4;

                m1p4.AddSuccessor(dep1);
                m2p4.AddSuccessor(dep6);
            }

            graph.ArrivalNodes.Add(ar1);
            graph.ArrivalNodes.Add(ar2);
            graph.ArrivalNodes.Add(ar3);
            graph.ArrivalNodes.Add(ar4);
            graph.ArrivalNodes.Add(ar5);
            graph.ArrivalNodes.Add(ar6);

            graph.DepartureNodes.Add(dep1);
            graph.DepartureNodes.Add(dep2);
            graph.DepartureNodes.Add(dep3);
            graph.DepartureNodes.Add(dep4);
            graph.DepartureNodes.Add(dep5);
            graph.DepartureNodes.Add(dep6);

            graph.Propagate();

            return(graph);
        }
Пример #8
0
        public static Graph Create()
        {
            var graph = new Graph();

            Func <int, int> hours   = (int h) => h * 3600;
            Func <int, int> minutes = (int m) => m * 60;
            Func <int, int> seconds = (int s) => s;

            Func <int, int, int> track2secs      = (int t, int s) => t * 60 + s * 30;
            Func <int, int>      turnaround2secs = (int c) => c * 30;

            Debug.Assert(track2secs(2, 1) == minutes(2) + seconds(30));
            Debug.Assert(turnaround2secs(4) == minutes(2));

            var ar1  = new ArrivalNode("(1,2)", 0);
            var ar2  = new ArrivalNode("(3)", minutes(2) + 30);
            var arm1 = new MovementNode("(1, 2) to T3", track2secs(2, 1));


            var split12 = new SplitNode("(1, 2) to (1), (2)", minutes(2));

            var m2 = new MovementNode("(2) to T2", track2secs(2, 1));
            var s1 = new ServiceNode("(2) on T2", minutes(34));


            var m3 = new MovementNode("(1) to T4", track2secs(2, 1));



            var p3a = new ParkingNode("(1) P3");
            var p3b = new ParkingNode("(2) P3");

            var arm2a = new MovementNode("(3) to T3", track2secs(2, 1));
            var arm2b = new TurnAroundNode(turnaround2secs(4));
            var arm2c = new MovementNode("(3) to T1", track2secs(2, 1));

            var m4 = new MovementNode("(2) to G", track2secs(3, 2));



            var m5a = new MovementNode("(1) to T3", track2secs(2, 1));
            var m5b = new TurnAroundNode(turnaround2secs(3));
            var m5c = new MovementNode("(1) to T2", track2secs(2, 1));


            var s2 = new ServiceNode("(1) on T2", minutes(34));

            var m6 = new MovementNode("(1) to T1", track2secs(3, 2));

            var m7 = new SplitNode("(3) (1) to (3, 1)", minutes(3));


            var m8a = new MovementNode("(3, 1) to T4", track2secs(3, 2));
            var m8b = new TurnAroundNode(turnaround2secs(7));
            var m8c = new MovementNode("(3, 1) to G", track2secs(3, 2));

            var dep1 = new DepartureNode("(2)", minutes(90));
            var dep2 = new DepartureNode("(3, 1)", hours(2));


            ar1.AddSuccessor(arm1);
            ar2.AddSuccessor(arm2a);
            split12.AddSuccessor(m2);
            split12.AddSuccessor(m3);

            split12.AddSuccessor(p3a);
            split12.AddSuccessor(p3b);


            p3a.AddSuccessor(m2);
            p3b.AddSuccessor(m3);
            m2.AddSuccessor(s1);
            m2.AddSuccessor(m3);
            arm1.AddSuccessor(split12);
            arm2a.AddSuccessor(arm2b);
            arm2b.AddSuccessor(arm2c);
            s1.AddSuccessor(m4);
            m4.AddSuccessor(dep1);
            m3.AddSuccessor(m5a);
            m5a.AddSuccessor(m5b);
            m5b.AddSuccessor(m5c);
            m5c.AddSuccessor(s2);
            s2.AddSuccessor(m6);
            m6.AddSuccessor(m7);
            arm2c.AddSuccessor(m7);
            m7.AddSuccessor(m8a);
            m8a.AddSuccessor(m8b);
            m8b.AddSuccessor(m8c);
            m8c.AddSuccessor(dep2);



            // Other
            graph.ArrivalNodes.Add(ar1);
            graph.ArrivalNodes.Add(ar2);
            graph.DepartureNodes.Add(dep1);
            graph.DepartureNodes.Add(dep2);

            graph.Propagate();
            return(graph);
        }