public void StateConstruction()
		{
			var blueHand = new PlayHand(new[]
			                            	{
			                            		new PlayCard(CardInfo.CardPool["Squall"]),
			                            		new PlayCard(CardInfo.CardPool["Krysta"]),
			                            		new PlayCard(CardInfo.CardPool["Wendigo"]),
			                            		new PlayCard(CardInfo.CardPool["Behemoth"]),
			                            		new PlayCard(CardInfo.CardPool["Tonberry"]),
			                            	}, true);
			var redHand = new PlayHand(new[]
			                           	{
			                           		new PlayCard(CardInfo.CardPool["Torama"]),
			                           		new PlayCard(CardInfo.CardPool["Gerogero"]),
			                           		new PlayCard(CardInfo.CardPool["Buel"]),
			                           		new PlayCard(CardInfo.CardPool["Bomb"]),
			                           		new PlayCard(CardInfo.CardPool["Diablos"]),
			                           	}, false);
			var state = new State(new PlayField(), RuleModifier.None, blueHand, redHand, true);

			Assert.That(state.bluePoints, Is.EqualTo(5));
			state.bluePoints--;
			Assert.That(state.bluePoints, Is.EqualTo(4));
			State clone = state.Clone();
			Assert.That(clone.bluePoints, Is.EqualTo(4));
			clone.bluePoints--;
			Assert.That(state.bluePoints, Is.EqualTo(4));
			Assert.That(clone.bluePoints, Is.EqualTo(3));
		}
Example #2
0
        public QuestState(Quest quest, State state = null)
        {
            this.quest = quest;

            createNew     = state == null;
            OriginalState = state ?? State.Dumb;
            Action        = QuestStateProcessAction.None;
            ModifiedState = OriginalState.Clone();

            InitializeComponent();

            Customize();
        }
Example #3
0
        private void OnStartup(object sender, StartupEventArgs e)
        {
            var stateProvider = new StateProvider();

            _state = stateProvider.Load();
            _model = new MainModel(_state.Clone());
            var main = new MainWindow
            {
                DataContext = _model
            };

            main.Show();
        }
Example #4
0
            public object Clone()
            {
                State clone = new State();

                clone.attribute = (Attribute)attribute.Clone();

                if (next != null)
                {
                    clone.next = (State)next.Clone();
                }

                return(clone);
            }
        private void VisitSwitchBlock(BoundSwitchStatement node)
        {
            var initialState    = State.Clone();
            var reachableLabels = node.DecisionDag.ReachableLabels;

            foreach (var section in node.SwitchSections)
            {
                foreach (var label in section.SwitchLabels)
                {
                    if (reachableLabels.Contains(label.Label) || label.HasErrors ||
                        label == node.DefaultLabel && node.Expression.ConstantValue == null && IsTraditionalSwitch(node))
                    {
                        SetState(initialState.Clone());
                    }
                    else
                    {
                        SetUnreachable();
                    }

                    VisitPattern(label.Pattern);
                    SetState(StateWhenTrue);
                    if (label.WhenClause != null)
                    {
                        VisitCondition(label.WhenClause);
                        SetState(StateWhenTrue);
                    }

                    PendingBranches.Add(new PendingBranch(label, this.State, label.Label));
                }
            }

            // visit switch sections
            var afterSwitchState = UnreachableState();
            var switchSections   = node.SwitchSections;
            var iLastSection     = (switchSections.Length - 1);

            for (var iSection = 0; iSection <= iLastSection; iSection++)
            {
                VisitSwitchSection(switchSections[iSection], iSection == iLastSection);
                // Even though it is illegal for the end of a switch section to be reachable, in erroneous
                // code it may be reachable.  We treat that as an implicit break (branch to afterSwitchState).
                Join(ref afterSwitchState, ref this.State);
            }

            if (reachableLabels.Contains(node.BreakLabel) || node.DefaultLabel == null && IsTraditionalSwitch(node))
            {
                Join(ref afterSwitchState, ref initialState);
            }

            ResolveBreaks(afterSwitchState, node.BreakLabel);
        }
Example #6
0
        public IPath NewPath(Action <GraphicsState> configureState)
        {
            _finishPathIfNeeded();

            var state = State.Clone();

            configureState(state);

            var path = new Path(_contentStream, state);

            CurrentPath = path;

            return(path);
        }
Example #7
0
        private void TransitingProcessBehavior()
        {
            IMessageMetadataEnvelop        processingEnvelop = null;
            IReadOnlyCollection <ICommand> producedCommands  = null;
            IActorRef processingMessageSender = null;

            Receive <IMessageMetadataEnvelop>(messageEnvelop =>
            {
                _log.Debug("Transiting process by {@message}", messageEnvelop);

                processingEnvelop       = messageEnvelop;
                processingMessageSender = Sender;
                var pendingState        = (TState)State.Clone();
                Behavior.Become(() => AwaitingTransitionConfirmationBehavior(pendingState), nameof(AwaitingTransitionConfirmationBehavior));
                Process.Transit(pendingState, messageEnvelop.Message)
                .PipeTo(Self);
            });

            void AwaitingTransitionConfirmationBehavior(TState pendingState)
            {
                Receive <IReadOnlyCollection <ICommand> >(transitionResult =>
                {
                    _log.Debug("Process was transited, new state is {@state}", pendingState);
                    producedCommands = transitionResult;
                    var cmd          = new SaveStateCommand <TState>(Id,
                                                                     pendingState,
                                                                     GetMessageId(processingEnvelop));
                    //will reply back with CommandExecuted
                    _stateAggregateActor.Tell(new MessageMetadataEnvelop <SaveStateCommand <TState> >(cmd, processingEnvelop.Metadata));
                });
                Receive <AggregateActor.CommandExecuted>(c =>
                {
                    State = pendingState;
                    processingMessageSender.Tell(new ProcessTransited(producedCommands, processingEnvelop.Metadata,
                                                                      _producedCommand,
                                                                      State));
                    _log.Debug("Process dispatched {count} commands {@commands}", producedCommands?.Count ?? 0, producedCommands);

                    Behavior.Become(AwaitingMessageBehavior, nameof(AwaitingMessageBehavior));
                    pendingState            = null;
                    processingMessageSender = null;
                    processingEnvelop       = null;
                    producedCommands        = null;
                });

                Receive <Status.Failure>(f => FinishWithError(processingEnvelop, processingMessageSender, f.Cause));

                StashingMessagesToProcessBehavior("process is waiting for transition confirmation");
            }
        }
Example #8
0
 /// <summary>Moves the object. Gravity needs to be positive (gets reverted within the method).</summary>
 public void ApplyThrust(
     Thrust thrust,
     double gravity,
     ZeroDegreesDirection zeroDegreesDirection = ZeroDegreesDirection.Top)
 {
     StateHistory.Add(State.Clone());
     State.XSpeed += Trigonometry.GetHorizontalSpeedFraction(thrust.Rotation, zeroDegreesDirection) * thrust.Power;
     State.YSpeed += Trigonometry.GetVerticalSpeedFraction(thrust.Rotation, zeroDegreesDirection) * thrust.Power -
                     gravity;
     State.Power    = thrust.Power;
     State.X       += State.XSpeed;
     State.Y       += State.YSpeed;
     State.Rotation = thrust.Rotation;
 }
Example #9
0
        public void CloneTest()
        {
            var state1 = _state1.Clone();

            Assert.AreEqual(state1.Transition.Get(1).Count, 1);
            Assert.AreNotEqual(state1.GetNextOne(1).GetNextOne(2), null);
            Assert.AreEqual(state1.Count(), 3);

            var state2 = _state2.Clone();

            Assert.AreNotEqual(state2.GetNextOne(1).GetNextOne(1).GetNextOne(1).GetNextOne(1).GetNextOne(1), null);
            Assert.AreNotEqual(state2.GetNextOne(2).GetNextOne(3).GetNextOne(4), null);
            Assert.AreEqual(state2.GetNextOne(2).GetNextOne(3).GetNextOne(4).GetNextOne(5), null);
            Assert.AreEqual(state2.Count(), 4);
        }
Example #10
0
        // Runs a Monte Carlo Tree Search from the given root node
        // Limited by number of iterations
        public Node IterationLimited(State rootState, int iterations)
        {
            Node rootNode = new Node(null, null, rootState);

            for (int i = 0; i < iterations; i++)
            {
                Node node = rootNode;
                State state = rootState.Clone();

                // 1: Select
                while (node.UntriedMoves.Count == 0 && node.Children.Count != 0)
                {
                    if (state.Player == GameEngine.COMPUTER)
                    {
                        Move move = state.GetRandomMove();
                        state = state.ApplyMove(move);
                        Node parent = node;
                        node = new Node(move, parent, state);
                    }
                    else
                    {
                        node = node.SelectChild();
                        state = state.ApplyMove(node.GeneratingMove);
                    }
                }

                // 2: Expand
                if (node.UntriedMoves.Count != 0)
                {
                    Move randomMove = node.UntriedMoves[random.Next(0, node.UntriedMoves.Count)];
                    state = state.ApplyMove(randomMove);
                    node = node.AddChild(randomMove, state);
                }

                // 3: Simulation
                state = SimulateGame(state, EXPECTIMAX_POLICY);

                // 4: Backpropagation
                while (node != null)
                {
                    node.Update(state.GetResult());
                    node = node.Parent;
                }
            }
            return rootNode;
        }
Example #11
0
        public override List<KeyValuePair<int, int>> Solve()
        {
            List<KeyValuePair<int, int>> result = new List<KeyValuePair<int, int>>();
            GenColumnValues();
            GenRowValues();

            RemoveEmptyRows();
            _columnIndexes = _columnIndexes.AsParallel()
                .OrderBy(i => GetColumnValue(i))
                .ToList();

            states = new List<State>();
            State state = new State();
            states.Add(state);
            Random rnd = new Random(15);
            while (!Empty())
            {
                State state2 = state.Clone();

                int column;
                int row = GetBestRow(out column);

                state.AddRow(row, GetRowValue(row));
                states.Add(state);

                row = GetBest2Row(out column);

                state2.AddRow(row, GetRowValue(row));
                states.Add(state2);

                state = states.OrderByDescending(x => x.Value *(float)(0.75 + 0.25 * rnd.NextDouble())).First();
                states.Remove(state);
                LoadState(state);
            }

            result = state.Rows.Select(x => new KeyValuePair<int, int>(x, 0)).ToList();
            //while (!Empty())
            //{
            //    int column;
            //    int row = GetSyndromRow(out column);

            //    KeyValuePair<int, int> syndromElement = new KeyValuePair<int, int>(row, column);
            //    result.Add(syndromElement);
            //}
            return result;
        }
Example #12
0
        /// <summary>
        /// Create a board with given dimensions and FDP
        /// </summary>
        /// <param name="FPD">Food Poison Distribution</param>
        /// <param name="dimensions">Board dimensinos</param>
        public Board(float[] FPD, int[] dimensions)
        {
            this.FPD        = FPD;
            this.dimensions = dimensions;
            board           = new State[dimensions[0], dimensions[1]];

            for (int i = 0; i < board.GetLength(0); i++)
            {
                for (int j = 0; j < board.GetLength(1); j++)
                {
                    board[i, j] = State.Free;
                }
            }


            InitializeBoard(FPD);

            PlaceRandomPlayer();
            initialBoard = (State[, ])board.Clone();
        }
Example #13
0
File: 1.cs Project: qifanyyy/CLCDSA
        private long waysfromhere(State state)
        {
            long val;

            if (mem.TryGetValue(state, out val))
            {
                return(val);
            }

            for (int r = 0; r < R; r++)
            {
                for (int c = 0; c < C; c++)
                {
                    if (!state.chosen[r, c])
                    {
                        long ret = 0;
                        //state.chosen[r, c] = true;
                        for (int dir = 0; dir < 2; dir++)
                        {
                            int nextr = (r + cDirI[map[r, c]][dir] + R) % R;
                            int nextc = (c + cDirJ[map[r, c]][dir] + C) % C;
                            if (!state.inPointer[nextr, nextc])
                            {
                                State newState = state.Clone();
                                newState.chosen[r, c]            = true;
                                newState.inPointer[nextr, nextc] = true;
                                if (Effects(nextr, nextc, newState))
                                {
                                    ret += waysfromhere(newState);
                                    ret %= MOD;
                                }
                            }
                        }
                        mem.Add(state, ret);
                        return(ret);
                    }
                }
            }
            mem.Add(state, 1);
            return(1);
        }
Example #14
0
        public void StateTests()
        {
            var s = new State();
            Assert.That(s.Start, Is.False);
            Assert.That(s.Final, Is.False);

            s.Start = true;
            Assert.That(s.Start, Is.True);
            Assert.That(s.Final, Is.False);

            s.Final = true;
            Assert.That(s.Start, Is.True);
            Assert.That(s.Final, Is.True);

            s.Start = false;
            Assert.That(s.Start, Is.False);
            Assert.That(s.Final, Is.True);

            var s2 = s.Clone();
            Assert.That(s2, Is.EqualTo(s));
        }
Example #15
0
        public override bool IsLegal(Position move, Color col)
        {
            if (this[move] != Color.Empty)
            {
                return(false);
            }
            Go test = new Go((GoShape)shape)
            {
                board = (Color[])State.Clone()
            };

            test.Play(move, col);
            foreach (Color[] past in History)
            {
                if (past.SequenceEqual(test.board))
                {
                    return(false);
                }
            }
            return(true);
        }
 public void Run()
 {
     updater = Task.Factory.StartNew(() =>
     {
         while (!cts.Token.IsCancellationRequested)
         {
             // wait until we have a new state from some source
             Thread.Sleep(1000);
             var newState = new State()
             {
                 Current = DateTime.Now, X = DateTime.Now.Millisecond, Str = DateTime.Now.ToString()
             };
             // critical part
             lock (syncObj) {
                 state = newState;
             }
         }
     }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
     for (int i = 0; i < 10; i++)
     {
         readers.Add(Task.Factory.StartNew(() =>
         {
             while (!cts.Token.IsCancellationRequested)
             {
                 State readState = null;
                 // critical part
                 lock (syncObj) {
                     readState = state.Clone();
                 }
                 // use it
                 if (readState != null)
                 {
                     Console.WriteLine(readState.Current);
                     Console.WriteLine(readState.Str);
                     Console.WriteLine(readState.X);
                 }
             }
         }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default));
     }
 }
Example #17
0
    /// <summary>
    /// Generates a grid of trees with both height and width equal to the chosen amount.
    /// </summary>
    /// <param name="numberOfTrees">Number of trees in a row/column</param>
    private void Generate(int numberOfTrees)
    {
        treeSets.Clear();
        // Instantiates numberOfTrees^2 Lod game objects and adds them to the tree set
        for (int i = 0; i < numberOfTrees; i++)
        {
            for (int j = 0; j < numberOfTrees; j++)
            {
                var vector3 = new Vector3(r.Next(i * 5, (i + 1) * 5), 0, r.Next(j * 5, (j + 1) * 5));
                var treeSet = Instantiate(LodPrefab, vector3, Quaternion.identity);
                treeSets.Add(treeSet);
            }
        }
        // Executes the rewriting process starting from the axiom, replacing every symbol according to the rules
        sentence = Axiom;
        for (var i = 0; i < Iterations; i++)
        {
            sentence = Replace(sentence);
        }

        // Draws all the trees
        foreach (var treeSet in treeSets)
        {
            // Resets current and the next state
            currentState = new State()
            {
                Heading    = Vector3.up,
                Up         = Vector3.back,
                Left       = Vector3.left,
                Width      = 0,
                Position   = treeSet.transform.position,
                ChangedDir = false
            };
            nextState = currentState.Clone();
            Draw(sentence, treeSet);
        }
    }
Example #18
0
        public override async Task OnInitializing()
        {
            await base.OnInitializing();

            var steps = CalculateInitialStates(Height.CurrentValue);

            visibleItemsCount = steps.Count;
            viewItemsCount    = visibleItemsCount + ReserveCount;

            foreach (var step in steps)
            {
                nextState = step;

                await Load(1, true, ScrollDirection.Forward);

                currentState = nextState.Clone();
            }

            for (var i = 0; i < ReserveCount; i++)
            {
                var recyclerViewItem = adapter.CreateViewItem();
                recyclerViewItem.Height(itemHeight);
                recyclerViewItem.Y((visibleItemsCount + i) * itemHeight);
                await viewItemsContainer.Add(recyclerViewItem);
            }

            currentState.ForwardReserveCount += ReserveCount;
            currentState.LastViewItemIndex   += ReserveCount;
            viewItemsContainer.Height(viewItemsCount * itemHeight);

            nextState = currentState.Clone();

            await Add(viewItemsContainer);

            UserScrolledVertically.Handle(OnUserScrolledVertically);
        }
Example #19
0
        /// <summary>
        /// Creates the childrens of the Node with alpha–beta pruning
        /// </summary>
        /// <param name="curHeight">current subtree height</param>
        /// <param name="height">height Subtree height</param>
        /// <param name="color">Color of next actions</param>
        /// <param name="root">Subtree root</param>
        /// <param name="rootState">Game state at root</param>
        /// <param name="alpha"></param>
        /// <param name="beta"></param>
        /// <returns>The </returns>
        public int Create(int curHeight, int height, sbyte color, GameNode root, State rootState, int alpha, int beta)
        {
            if (curHeight == height || rootState.Finished())
            {
                return(rootState.Score());
            }
            var v = (color == IController.WHITE) ? int.MinValue : int.MaxValue;

            if (rootState.PlacingPhase(color))
            {
                foreach (byte position in State.TRANSPOSED)
                {
                    if (!rootState.IsValidPlace(position, color))
                    {
                        continue;
                    }
                    var nextAction = new Placing(color, position);
                    var newState   = rootState.Clone();
                    nextAction.Update(newState);
                    var childNode = Create(nextAction, root);
                    if (newState.InMill(position, color))
                    {
                        if (newState.TakingIsPossible(State.OppositeColor(color)))
                        {
                            foreach (byte takingPosition in State.TRANSPOSED)
                            {
                                if (newState.IsValidTake(takingPosition, State.OppositeColor(color)))
                                {
                                    var takeState    = rootState.Clone();
                                    var takingAction = new Taking(nextAction, takingPosition);
                                    takingAction.Update(takeState);
                                    var takingNode = Create(takingAction, root);

                                    //Minimizer
                                    if (color == IController.WHITE)
                                    {
                                        v = Math.Max(v,
                                                     Create(curHeight + 1, height, State.OppositeColor(color), takingNode,
                                                            takeState, alpha, beta));

                                        alpha = Math.Max(alpha, v);
                                    }
                                    else //Maximizer
                                    {
                                        v = Math.Min(v, Create(curHeight + 1, height, State.OppositeColor(color), takingNode,
                                                               takeState, alpha, beta));
                                        beta = Math.Min(beta, v);
                                    }

                                    UpdateScore(takingNode, v);

                                    root.m_children.Enqueue(takingNode);
                                    if (beta <= alpha)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        //Minimizer
                        if (color == IController.WHITE)
                        {
                            v = Math.Max(v,
                                         Create(curHeight + 1, height, State.OppositeColor(color), childNode,
                                                newState, alpha, beta));

                            alpha = Math.Max(alpha, v);
                        }
                        else //Maximizer
                        {
                            v = Math.Min(v, Create(curHeight + 1, height, State.OppositeColor(color), childNode,
                                                   newState, alpha, beta));
                            beta = Math.Min(beta, v);
                        }

                        UpdateScore(childNode, v);
                        root.m_children.Enqueue(childNode);
                        if (beta <= alpha)
                        {
                            break;
                        }
                    }
                }
            }
            else if (rootState.MovingPhase(color) || rootState.JumpingPhase(color))
            {
                for (byte i = 0; i < rootState.Board.Length; i++)
                {
                    var moves = (rootState.JumpingPhase(color)) ? State.TRANSPOSED : State.MOVES[i];
                    foreach (byte to in moves)
                    {
                        if (!rootState.IsValidMove(i, to, color))
                        {
                            continue;
                        }
                        var nextAction = new Moving(color, i, to);
                        var childNode  = Create(nextAction, root);
                        var newState   = rootState.Clone();
                        childNode.Data().Update(newState);
                        if (newState.InMill(to, color))
                        {
                            if (newState.TakingIsPossible(State.OppositeColor(color)))
                            {
                                foreach (byte takingPosition in State.TRANSPOSED)
                                {
                                    if (!newState.IsValidTake(takingPosition, State.OppositeColor(color)))
                                    {
                                        continue;
                                    }
                                    var takingNode = Create(new Taking(nextAction, takingPosition), root);
                                    var takeState  = rootState.Clone();
                                    takingNode.Data().Update(takeState);

                                    //Minimizer
                                    if (color == IController.WHITE)
                                    {
                                        v = Math.Max(v,
                                                     Create(curHeight + 1, height, State.OppositeColor(color), takingNode,
                                                            takeState, alpha, beta));

                                        alpha = Math.Max(alpha, v);
                                    }
                                    else //Maximizer
                                    {
                                        v = Math.Min(v, Create(curHeight + 1, height, State.OppositeColor(color), takingNode,
                                                               takeState, alpha, beta));
                                        beta = Math.Min(beta, v);
                                    }

                                    UpdateScore(takingNode, v);
                                    root.m_children.Enqueue(takingNode);
                                    if (beta <= alpha)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Minimizer
                            if (color == IController.WHITE)
                            {
                                v = Math.Max(v,
                                             Create(curHeight + 1, height, State.OppositeColor(color), childNode,
                                                    newState, alpha, beta));

                                alpha = Math.Max(alpha, v);
                            }
                            else //Maximizer
                            {
                                v = Math.Min(v, Create(curHeight + 1, height, State.OppositeColor(color), childNode,
                                                       newState, alpha, beta));
                                beta = Math.Min(beta, v);
                            }

                            UpdateScore(childNode, v);
                            root.m_children.Enqueue(childNode);
                            if (beta <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return(v);
        }
Example #20
0
        /// <summary>
        /// This method is called from element constructors to notify the page of an element
        /// on the page. These constructors will typically construct other elements which will
        /// also call this method, hence these calls are made in a nested heirachy
        /// </summary>
        public IDataContextBuilder BeginAddElement(IElement element, IDataScopeRules dataScopeRules)
        {
            // Data scope rules define the Type+Scope combinations that should be resolved at this
            // level and also the suppliers/supplies that were configured by that application to
            // be injected into the data context.
            dataScopeRules = dataScopeRules ?? element as IDataScopeRules;

            Log("Adding element '" + element + "' to page" +
                (dataScopeRules == null ? ""  : " using data scope rules from '" + dataScopeRules + "'"));

            // Figure out how the assets will be deployed for this element. Elements can inherit from
            // their parent element, follow the module that are in or have an explicit value set.
            var assetDeployment = element.AssetDeployment;

            if (element.Module != null)
            {
                assetDeployment = element.Module.AssetDeployment;
            }

            var module = element.Module ?? _currentState.Module;

            if (assetDeployment == AssetDeployment.Inherit)
            {
                assetDeployment = _currentState.AssetDeployment;
            }

            if (assetDeployment == AssetDeployment.PerModule && module == null)
            {
                assetDeployment = AssetDeployment.PerWebsite;
            }

            Log(element + " asset deployment resolved to '" + assetDeployment +
                (assetDeployment == AssetDeployment.PerModule ? "' in module '" + module + "'" : "'"));

            // The page keeps a list of the elements on the page so that it can extract the static
            // assets later and build css and js files for each module etc
            Elements.Add(new ElementRegistration
            {
                Element         = element,
                AssetDeployment = assetDeployment,
                Module          = module
            });

            // If this element depends on a library component then this component needs to be
            // added to the page.
            var libraryConsumer = element as ILibraryConsumer;

            if (!ReferenceEquals(libraryConsumer, null))
            {
                var dependentComponents = libraryConsumer.GetDependentComponents();
                if (!ReferenceEquals(dependentComponents, null))
                {
                    foreach (var component in dependentComponents)
                    {
                        Log(element + " element needs " + component);
                        _page.AddComponent(component);
                    }
                }
            }

            // Elements are in a tree structure and inherit from thier parents, so we need
            // to keep a state stack and push/pop as we traverse the tree to keep track of
            // the proper state for each stage of the processing
            Log("Pushing new state onto stack");
            _stateStack.Push(_currentState);
            _currentState = _currentState.Clone();

            // If this element introdices a new scope (basically regions do this) then
            // we need to create a new scope for resolving data needs and update the
            // current state
            if (dataScopeRules != null)
            {
                Log("Adding data context builder based on " + dataScopeRules);
                _currentState.DataContextBuilder = _currentState.DataContextBuilder.AddChild(dataScopeRules);
            }

            // If this element needs specifc data then add it to the data context builder.
            var dataConsumer = element as IDataConsumer;

            if (dataConsumer != null)
            {
                Log(element + " element is a data consumer, adding its needs");
                _currentState.DataContextBuilder.AddConsumer(dataConsumer);
            }

            return(_currentState.DataContextBuilder);
        }
Example #21
0
 public override void Reset()
 {
     base.Reset();
     history = new List <Color[]>();
     history.Add((Color[])State.Clone());
 }
Example #22
0
 public override Tensor Reset()
 {
     LastActionAsInt = -1;
     StateAsInt      = CategoricalSample(InitialStateDistribution);
     return(State.Clone());
 }
Example #23
0
        public object Clone()
        {
            var copiedState = (byte[])State.Clone();

            return(new NodeState(Dimensions, copiedState));
        }
Example #24
0
        // Runs a Monte Carlo Tree Search limited by a given time limit
        public Node TimeLimited(State rootState, int timeLimit, Stopwatch timer)
        {
            Node rootNode = new Node(null, null, rootState);
            while (true)
            {
                if (timer.ElapsedMilliseconds > timeLimit)
                {
                    if (FindBestChild(rootNode.Children) == null && !rootNode.state.IsGameOver())
                    {
                        timeLimit += 10;
                        timer.Restart();
                    }
                    else
                    {
                        return rootNode;
                    }
                }
                Node node = rootNode;
                State state = rootState.Clone();

                // 1: Select
                while (node.UntriedMoves.Count == 0 && node.Children.Count != 0)
                {
                    node = node.SelectChild();
                    state = state.ApplyMove(node.GeneratingMove);
                }

                // 2: Expand
                if (node.UntriedMoves.Count != 0)
                {
                    Move randomMove = node.UntriedMoves[random.Next(0, node.UntriedMoves.Count)];
                    state = state.ApplyMove(randomMove);
                    node = node.AddChild(randomMove, state);
                }

                // 3: Simulation
                state = SimulateGame(state, EXPECTIMAX_POLICY);

                // 4: Backpropagation
                while (node != null)
                {
                    node.Update(state.GetResult());
                    node = node.Parent;
                }
            }
        }
Example #25
0
        /// <summary>
        /// FSNSequence 해석. 분기마다 builderState를 복제해야 하므로 새로 호출된다.
        /// </summary>
        /// <param name="builderState"></param>
        /// <param name="snapshotSeq">이번 콜에서 생성할 시퀀스 이전의 스냅샷 인덱스</param>
        /// <param name="bs"></param>
        /// <param name="linkToLast">이 메서드를 호출하기 바로 이전의 Snapshot에 연결할지 여부. 기본은 true. 선택지 등등에서 false로 해줘야함</param>
        /// <returns>이번 콜에서 생성한 시퀀스들 중 제일 첫번째 것. 다른 시퀀스 흐름과 연결할 때 사용 가능</returns>
        static Segment ProcessSnapshotBuild(State bs, FSNSnapshotSequence snapshotSeq, int prevSnapshotIndex, bool linkToLast = true)
        {
            ModuleCallQueue moduleCalls = new ModuleCallQueue();

            Segment     sseg;                                                                                                                   // 새로 생성할 Segment/Snapshot
            FSNSnapshot sshot;

            NewSnapshot(out sseg, out sshot);

            var firstSeg    = sseg;                                                             // 최초 스냅샷
            var prevCallSeg = snapshotSeq.Get(prevSnapshotIndex);                               // 이번에 생성할 시퀀스의 이전 스냅샷

            var lastSeg = prevCallSeg;                                                          // 바로 이전에 처리한 스냅샷 (최초 루프시에는 실행 이전의 마지막 스냅샷과 동일)

            List <Segments.Control>     jumpSegs  = new List <Segments.Control>();              // 점프(goto, SwipeOption 등) 세그먼트가 등장했을 경우 여기에 보관된다
            List <Segment.CallFuncInfo> funcCalls = new List <Segment.CallFuncInfo>();          // 함수 콜이 있을 경우 여기에 먼저 누적하고 period때 한번에 처리한다

            float snapshotDelay = 0f;                                                           // 스냅샷에 적용할 지연 시간 (/기다리기 커맨드)

            //

            // 처음 시작할 때는 무조건 모든 객체들을 Hard-Clone한다 (분기점에서 Initial/Final 스테이트 독립을 하기 위해)

            moduleCalls.CatchupPreviousLayerState(prevCallSeg.snapshot);                        // 기존의 유효한 Layer들을 활성화 (안그러면 모듈 콜을 누락해버림)
            moduleCalls.AddAllModuleCall(new Segments.HardClone(), bs.settings);


            // 스크립트 Sequence가 끝나거나 특정 명령을 만날 때까지 반복

            bool keepProcess = true;

            while (keepProcess)
            {
                var curSeg = bs.sequence[bs.segIndex];                                          // 현재 명령어 (Sequence 세그먼트)
                FSNDebug.currentProcessingScriptLine = curSeg.scriptLineNumber;                 // 디버깅 정보 세팅 (줄 번호)

                switch (curSeg.type)                                                            // 명령어 타입 체크 후 분기
                {
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Setting:                                                                    // ** 세팅
                {
                    var settingSeg = curSeg as Segments.Setting;

                    if (settingSeg.settingMethod == Segments.Setting.SettingMethod.Pop)                         // * 세팅 pop
                    {
                        if (bs.settings.ParentChain != null)
                        {
                            bs.settings = bs.settings.ParentChain;
                        }
                        else
                        {
                            Debug.LogError("Cannot pop settings anymore - there is no settings pushed");
                        }
                    }
                    else
                    {
                        if (settingSeg.settingMethod == Segments.Setting.SettingMethod.Push)                            // * Push일 경우에는 새 Chain을 생성한다
                        {
                            bs.settings = new FSNInGameSetting.Chain(bs.settings);
                        }

                        foreach (var settingPair in settingSeg.RawSettingTable)                         // Setting 설정
                        {
                            bs.settings.SetPropertyByString(settingPair.Key, settingPair.Value);
                        }
                    }

                    bs.SetSettingDirty();                                                                                               // 세팅 변경됨 플래그 올리기
                }
                break;

                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Text:                                                               // ** 텍스트
                {
                    var module = FSNEngine.Instance.GetModule(FSNEngine.ModuleType.Text) as IFSNProcessModule;

                    moduleCalls.AddCall(module, curSeg, bs.FrozenSetting);                              // 해당 명령 저장
                }
                break;

                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Object:                                                             // ** 오브젝트 (이미지 등)
                {
                    var objSeg = curSeg as Segments.Object;
                    var module = FSNEngine.Instance.GetModuleByLayerID(objSeg.layerID) as IFSNProcessModule;

                    moduleCalls.AddCall(module, objSeg, bs.FrozenSetting);
                }
                break;

                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Label:                                                              // ** 레이블
                {
                    //var labelSeg		= curSeg as Segments.Label;
                    // 현재 이 시점에서는 labelSeg로 하는 일이 없다...
                    //Debug.Log("Label : " + labelSeg.labelName);
                }
                break;

                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Control:                                                    // ** 엔진 컨트롤
                {
                    var controlSeg = curSeg as Segments.Control;

                    switch (controlSeg.controlType)                                                                             // 종류에 따라 처리
                    {
                    case Segments.Control.ControlType.Block:
                        keepProcess = false;                                            // 블로킹 - 이 분기에서는 해석 종료
                        break;

                    case Segments.Control.ControlType.SwipeOption:
                        sseg.Type = FlowType.UserChoice;                                                                        // 스냅샷 세그먼트 종류 변경 (유저 선택으로)

                        jumpSegs.Add(controlSeg);                                                                               // 점프 명령어로 보관해두고 나중에 처리한다.

                        break;

                    case Segments.Control.ControlType.Goto:
                    case Segments.Control.ControlType.ReverseGoto:
                    case Segments.Control.ControlType.ConditionJump:
                        jumpSegs.Add(controlSeg);                                                                                       // 점프 명령어로 보관해두고 나중에 처리한다.
                        break;

                    case Segments.Control.ControlType.Clear:                                                            // 모든 모듈에 clear를 보낸다
                        moduleCalls.AddAllModuleCall(controlSeg, bs.FrozenSetting);
                        break;

                    case Segments.Control.ControlType.Oneway:
                        sseg.OneWay = true;
                        break;

                    case Segments.Control.ControlType.ForceBack:
                        sseg.snapshot.ForceBackward = true;
                        break;

                    case Segments.Control.ControlType.Load:
                        sseg.Type      = FlowType.Load;
                        sseg.Parameter = controlSeg.GetLoadScriptData();                                        // 스냅샷 세그먼트의 parameter에 스크립트 파일명 보관
                        break;

                    case Segments.Control.ControlType.UnityCall:                                                // 함수콜
                    {
                        var callinfo = new Segment.CallFuncInfo();
                        controlSeg.GetUnityCallData(out callinfo.funcname, out callinfo.param);
                        funcCalls.Add(callinfo);
                    }
                    break;

                    case Segments.Control.ControlType.Delay:                                                            // 딜레이
                        snapshotDelay = controlSeg.GetDelay();                                                          // 지연 시간을 미리 지정해둔다
                        break;
                    }
                }
                break;

                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Period:                                                             // ** Period : 현재까지 누적한 call을 실행하는 개념으로 사용중
                {
                    var periodSeg = curSeg as Segments.Period;

                    // 다음 snapshot을 위해 현재 진행 방향의 반대방향으로 FlowDirection 정해놓기
                    bs.settings.BackwardFlowDirection = FSNInGameSetting.GetOppositeFlowDirection(bs.settings.CurrentFlowDirection);
                    bs.SetSettingDirty();

                    sshot.InGameSetting = bs.FrozenSetting;                                                     // 현재까지의 세팅 적용 (굳힌거 사용)

                    moduleCalls.ProcessCall(lastSeg.snapshot, sshot);                                           // 지금까지 모인 모듈 콜 집행하기

                    if (linkToLast)                                                                             // 이전 스냅샷에 붙여야하는경우
                    {
                        LinkSnapshots(lastSeg, sseg);

                        if (bs.prevPeriodWasChain)                                                                                      // 이전 period가 chaining이었다면, 역방향 chaining 걸기
                        {
                            sseg.snapshot.NonstopToBackward = true;
                            bs.prevPeriodWasChain           = false;                                                            // (플래그 해제)
                        }

                        if (periodSeg.isChaining)                                                                                       // Chaining 옵션이 켜져있을 경우
                        {
                            sseg.snapshot.NonstopToForward = true;
                            bs.prevPeriodWasChain          = true;                                                              // (chaining 상태 기록)
                        }
                    }
                    else
                    {
                        linkToLast = true;                              // FIX : linkToLast는 맨 첫번째 스냅샷에만 해당하는 파라미터임. 두번째는 꺼준다
                    }

                    sseg.FunctionCalls = funcCalls.ToArray();                                                           // 쌓인 함수콜 리스트를 배열로 변환하여 세팅
                    funcCalls.Clear();

                    snapshotSeq.Add(sseg);                                                                                              // 현재 스냅샷을 시퀀스에 추가
                    //

                    sseg.snapshot.AfterSwipeDelay = snapshotDelay;                                              // 현재 지정된 딜레이를 적용.
                    snapshotDelay = 0f;
                    //


                    // Condition 링크 임시 보관소 - 나중에 한번에 특정 방향으로 몰아넣는다
                    FSNInGameSetting.FlowDirection        conditionLinkDir      = FSNInGameSetting.FlowDirection.None;
                    FSNInGameSetting.FlowDirection        conditionLinkBackDir  = FSNInGameSetting.FlowDirection.None;
                    List <Segment.FlowInfo.ConditionLink> conditionLinks        = null;
                    Dictionary <string, Segment>          conditionLinkSegCache = new Dictionary <string, Segment>();           // 조건부 점프시, 중복되는 점프는 이전 것을 사용하게

                    foreach (var jumpSeg in jumpSegs)                                                                           // * 점프 세그먼트가 있을 경우 처리
                    {
                        // NOTE : 현재 Label은 Soft만 구현한다.

                        if (jumpSeg.controlType == Segments.Control.ControlType.SwipeOption)                                    // *** 선택지
                        {
                            bool isNonTextOption = jumpSeg.IsNonTextOption();
                            for (int i = 0; i < 4; i++)                                                                                                                         // 모든 방향마다 처리
                            {
                                var    dir   = (FSNInGameSetting.FlowDirection)i;
                                string label = jumpSeg.GetLabelFromSwipeOptionData(dir);
                                if (!string.IsNullOrEmpty(label))                                                                                                       // 라벨이 지정된 경우만 처리(= 해당 방향으로 분기가 있을 때만)
                                {
                                    // FIX : 만약 해당 선택지 방향이 원래의 역방향에 해당하는 것이었다면, 역방향을 None으로 재설정한다. (역방향 오버라이드 지원)
                                    if (dir == sseg.BackDirection)
                                    {
                                        sseg.BackDirection            = FSNInGameSetting.FlowDirection.None;
                                        sseg.snapshot.DisableBackward = true;                                           // 역방향 비활성화
                                    }

                                    int labelIndex = bs.sequence.GetIndexOfLabel(label);
                                    var labelSeg   = bs.sequence.GetSegment(labelIndex) as Segments.Label;

                                    if (labelSeg.labelType == Segments.Label.LabelType.Soft)                                                    // * SOFT 라벨로 점프
                                    {
                                        if (labelIndex < bs.segIndex)                                                                           // SOFT 라벨은 거슬러올라갈 수 없다.
                                        {
                                            Debug.LogError("Cannot jump to previous soft label");
                                        }

                                        var clonnedState = bs.Clone();                                                                                  // 상태 복제
                                        clonnedState.segIndex = labelIndex;                                                                             // 라벨 인덱스 세팅
                                        clonnedState.settings.CurrentFlowDirection  = dir;                                                              // 진행 방향 세팅 - 선택지 방향으로 진행 방향을 강제 세팅한다
                                        clonnedState.settings.BackwardFlowDirection = FSNInGameSetting.GetOppositeFlowDirection(dir);

                                        var newSeg = ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false);                        // 새 분기 해석하기. 이전 스냅샷에 바로 붙이지 않는다.
                                        LinkSnapshotAsOption(sseg, newSeg, dir, isNonTextOption);                                               // 선택지로 연결하기
                                    }
                                    else
                                    {                                                                                                                                                                   // * HARD 라벨로 점프
                                        Debug.LogError("Not implemented");
                                    }
                                }
                            }
                        }
                        else if (jumpSeg.controlType == Segments.Control.ControlType.Goto)                                              // *** GOTO
                        {
                            string label      = jumpSeg.GetGotoLabel();
                            int    labelIndex = bs.sequence.GetIndexOfLabel(label);
                            var    labelSeg   = bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if (labelSeg.labelType == Segments.Label.LabelType.Soft)                                                            // * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)                                                                                   // SOFT 라벨은 거슬러올라갈 수 없다.
                                {
                                    Debug.LogError("Cannot jump to previous soft label");
                                }

                                var clonnedState = bs.Clone();                                                                          // 상태 복제
                                clonnedState.segIndex = labelIndex;                                                                     // 라벨 인덱스 세팅

                                ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index);                                            // 새 분기 해석하기

                                // SOFT 라벨로 점프하는 경우엔 사실상 이 분기점으로 다시 되돌아올 일이 생기지 않는다.
                                // 추가 스크립트 해석을 중단한다.
                                keepProcess = false;
                            }
                            else
                            {                                                                                                                                                                           // * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else if (jumpSeg.controlType == Segments.Control.ControlType.ReverseGoto)                               // ** ReverseGoto
                        {
                            string label      = jumpSeg.GetReverseGotoLabel();
                            int    labelIndex = bs.sequence.GetIndexOfLabel(label);
                            var    labelSeg   = bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if (labelSeg.labelType == Segments.Label.LabelType.Soft)                                                            // * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)                                                                                   // SOFT 라벨은 거슬러올라갈 수 없다.
                                {
                                    Debug.LogError("Cannot jump to previous soft label");
                                }

                                var clonnedState = bs.Clone();                                                                                                  // 상태 복제
                                clonnedState.segIndex = labelIndex;                                                                                             // 라벨 인덱스 세팅

                                // 진행 방향을 역방향으로 세팅
                                clonnedState.settings.CurrentFlowDirection  = FSNInGameSetting.GetOppositeFlowDirection(clonnedState.settings.CurrentFlowDirection);
                                clonnedState.settings.BackwardFlowDirection = FSNInGameSetting.GetOppositeFlowDirection(clonnedState.settings.BackwardFlowDirection);

                                // 가장 마지막 세그먼트를 잠시동안만 UserChoice로 변경해서 새 스냅샷시퀀스를 정방향에 붙이지 못하게 막는다.
                                // 생성한 스냅샷을 역방향에 직접 붙여줘야하기 때문.
                                // 좀 Hacky한 방법이라서 변경이 필요할지도.

                                var newSeg = ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false); // 새 분기 해석한 후 레퍼런스 받기. 링크는 하지 않음

                                LinkSnapshotsReverseOverride(sseg, newSeg);                                      //붙이기

                                sseg.snapshot.DisableBackward = true;                                            // 역방향 비활성화
                            }
                            else
                            {                                                                                                                                                                           // * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else if (jumpSeg.controlType == Segments.Control.ControlType.ConditionJump)                             // ** 조건부 점프
                        {
                            string    funcname;
                            string [] param;
                            string    label      = jumpSeg.GetConditionJumpLabel();
                            int       labelIndex = bs.sequence.GetIndexOfLabel(label);
                            var       labelSeg   = bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if (labelSeg.labelType == Segments.Label.LabelType.Soft)                                                            // * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)                                                                                   // SOFT 라벨은 거슬러올라갈 수 없다.
                                {
                                    Debug.LogError("Cannot jump to previous soft label");
                                }

                                Segment newSeg;
                                if (!conditionLinkSegCache.TryGetValue(label, out newSeg))                                                      // 이전에 캐싱된 것이 없을 때만 새로 해석한다.
                                {
                                    var clonnedState = bs.Clone();                                                                              // 상태 복제
                                    clonnedState.segIndex = labelIndex;                                                                         // 라벨 인덱스 세팅

                                    // 가장 마지막 세그먼트를 잠시동안만 UserChoice로 변경해서 새 스냅샷시퀀스를 정방향에 붙이지 못하게 막는다.
                                    // 생성한 스냅샷을 역방향에 직접 붙여줘야하기 때문.
                                    // 좀 Hacky한 방법이라서 변경이 필요할지도.

                                    newSeg = ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false);                                                // 새 분기 해석한 후 레퍼런스 받기. 링크는 하지 않음

                                    conditionLinkSegCache[label] = newSeg;                                                                                      // 캐싱해두기
                                }

                                // Note : 현재 스크립트 스펙 상, 한 스냅샷 안에서 Condition Link은 한쪽 방향으로밖에 나올 수 없다.
                                // 따라서 방향 구분 없이 리스트 하나에 모두 모아둔 후, 기록해둔 방향에 모두 집어넣는다.

                                conditionLinkDir     = newSeg.snapshot.InGameSetting.CurrentFlowDirection;
                                conditionLinkBackDir = newSeg.snapshot.InGameSetting.BackwardFlowDirection;

                                // 만약 일반 링크가 등장하지 않아 방향이 설정되지 않을 때를 대비해서 세팅
                                if (sseg.FlowDirection == FSNInGameSetting.FlowDirection.None)
                                {
                                    sseg.FlowDirection = conditionLinkDir;
                                }
                                if (newSeg.BackDirection == FSNInGameSetting.FlowDirection.None)
                                {
                                    newSeg.BackDirection = conditionLinkBackDir;
                                }

                                List <Segment.CallFuncInfo> callfuncs = new List <Segment.CallFuncInfo>();
                                while (jumpSeg.DequeueConditionJumpData(out funcname, out param))                                                       // AND 조건으로 묶인 모든 condition 읽기
                                {
                                    callfuncs.Add(new Segment.CallFuncInfo()
                                        {
                                            funcname = funcname, param = param
                                        });
                                }
                                if (conditionLinks == null)
                                {
                                    conditionLinks = new List <Segment.FlowInfo.ConditionLink>();
                                }
                                conditionLinks.Add(new Segment.FlowInfo.ConditionLink()
                                    {
                                        funcinfo = callfuncs.ToArray(), Linked = newSeg
                                    });

                                if (!newSeg.OneWay)
                                {
                                    newSeg.SetDirectFlow(conditionLinkBackDir, sseg);                                                                                   // 역방향 설정
                                }
                            }
                            else
                            {                                                                                                                                                                           // * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else
                        {
                            Debug.LogError("Unknown or not-yet-implemented jump statement!");
                        }
                    }
                    jumpSegs.Clear();

                    if (conditionLinks != null)                                                                                         // 모아뒀던 조건부 점프 한번에 세팅
                    {
                        sseg.SetConditionFlow(conditionLinkDir, conditionLinks.ToArray());
                    }

                    lastSeg = sseg;
                    NewSnapshot(out sseg, out sshot);                                                                           // 새 스냅샷 인스턴스 준비
                }
                break;

                /////////////////////////////////////////////////////////////
                default:
                    Debug.LogError("?????????");
                    break;
                }


                //
                bs.segIndex++;                                                                                          // 다음 명령어 인덱스

                if (bs.segIndex >= bs.sequence.Length)                                                                  // * Sequence 가 끝났다면 루프 종료
                {
                    keepProcess = false;
                }
            }

            return(firstSeg);
        }
Example #26
0
 protected override bool CloneEntity(Diagram diagram)
 {
     return(diagram.InsertState(State.Clone()));
 }
Example #27
0
 public State GetState()
 {
     return(_state.Clone());
 }
        /// <summary>
        /// FSNSequence 해석. 분기마다 builderState를 복제해야 하므로 새로 호출된다.
        /// </summary>
        /// <param name="builderState"></param>
        /// <param name="snapshotSeq">이번 콜에서 생성할 시퀀스 이전의 스냅샷 인덱스</param>
        /// <param name="bs"></param>
        /// <param name="linkToLast">이 메서드를 호출하기 바로 이전의 Snapshot에 연결할지 여부. 기본은 true. 선택지 등등에서 false로 해줘야함</param>
        /// <returns>이번 콜에서 생성한 시퀀스들 중 제일 첫번째 것. 다른 시퀀스 흐름과 연결할 때 사용 가능</returns>
        static Segment ProcessSnapshotBuild(State bs, FSNSnapshotSequence snapshotSeq, int prevSnapshotIndex, bool linkToLast = true)
        {
            ModuleCallQueue moduleCalls	= new ModuleCallQueue();

            Segment	sseg;														// 새로 생성할 Segment/Snapshot
            FSNSnapshot sshot;
            NewSnapshot(out sseg, out sshot);

            var firstSeg		= sseg;											// 최초 스냅샷
            var prevCallSeg		= snapshotSeq.Get(prevSnapshotIndex);			// 이번에 생성할 시퀀스의 이전 스냅샷

            var lastSeg			= prevCallSeg;									// 바로 이전에 처리한 스냅샷 (최초 루프시에는 실행 이전의 마지막 스냅샷과 동일)

            List<Segments.Control>	jumpSegs	= new List<Segments.Control>();	// 점프(goto, SwipeOption 등) 세그먼트가 등장했을 경우 여기에 보관된다
            List<Segment.CallFuncInfo> funcCalls= new List<Segment.CallFuncInfo>();	// 함수 콜이 있을 경우 여기에 먼저 누적하고 period때 한번에 처리한다

            float snapshotDelay	= 0f;											// 스냅샷에 적용할 지연 시간 (/기다리기 커맨드)
            //

            // 처음 시작할 때는 무조건 모든 객체들을 Hard-Clone한다 (분기점에서 Initial/Final 스테이트 독립을 하기 위해)

            moduleCalls.CatchupPreviousLayerState(prevCallSeg.snapshot);		// 기존의 유효한 Layer들을 활성화 (안그러면 모듈 콜을 누락해버림)
            moduleCalls.AddAllModuleCall(new Segments.HardClone(), bs.settings);

            // 스크립트 Sequence가 끝나거나 특정 명령을 만날 때까지 반복

            bool keepProcess	= true;
            while(keepProcess)
            {
                var curSeg	= bs.sequence[bs.segIndex];							// 현재 명령어 (Sequence 세그먼트)
                FSNDebug.currentProcessingScriptLine = curSeg.scriptLineNumber;	// 디버깅 정보 세팅 (줄 번호)

                switch(curSeg.type)												// 명령어 타입 체크 후 분기
                {
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Setting:							// ** 세팅
                {
                    var settingSeg		= curSeg as Segments.Setting;

                    if(settingSeg.settingMethod == Segments.Setting.SettingMethod.Pop)	// * 세팅 pop
                    {
                        if(bs.settings.ParentChain != null)
                        {
                            bs.settings	= bs.settings.ParentChain;
                        }
                        else
                        {
                            Debug.LogError("Cannot pop settings anymore - there is no settings pushed");
                        }
                    }
                    else
                    {
                        if(settingSeg.settingMethod == Segments.Setting.SettingMethod.Push)	// * Push일 경우에는 새 Chain을 생성한다
                        {
                            bs.settings	= new FSNInGameSetting.Chain(bs.settings);
                        }

                        foreach(var settingPair in settingSeg.RawSettingTable)	// Setting 설정
                        {
                            bs.settings.SetPropertyByString(settingPair.Key, settingPair.Value);
                        }
                    }

                    bs.SetSettingDirty();										// 세팅 변경됨 플래그 올리기
                }
                break;
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Text:						// ** 텍스트
                {
                    var module			= FSNEngine.Instance.GetModule(FSNEngine.ModuleType.Text) as IFSNProcessModule;

                    moduleCalls.AddCall(module, curSeg, bs.FrozenSetting);		// 해당 명령 저장
                }
                break;
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Object:						// ** 오브젝트 (이미지 등)
                {
                    var objSeg	= curSeg as Segments.Object;
                    var module	= FSNEngine.Instance.GetModuleByLayerID(objSeg.layerID) as IFSNProcessModule;

                    moduleCalls.AddCall(module, objSeg, bs.FrozenSetting);
                }
                break;
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Label:						// ** 레이블
                {
                    //var labelSeg		= curSeg as Segments.Label;
                    // 현재 이 시점에서는 labelSeg로 하는 일이 없다...
                    //Debug.Log("Label : " + labelSeg.labelName);
                }
                break;
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Control:					// ** 엔진 컨트롤
                {
                    var controlSeg		= curSeg as Segments.Control;

                    switch(controlSeg.controlType)								// 종류에 따라 처리
                    {
                        case Segments.Control.ControlType.Block:
                            keepProcess	= false;	// 블로킹 - 이 분기에서는 해석 종료
                            break;

                        case Segments.Control.ControlType.SwipeOption:
                            sseg.Type	= FlowType.UserChoice;					// 스냅샷 세그먼트 종류 변경 (유저 선택으로)

                            jumpSegs.Add(controlSeg);							// 점프 명령어로 보관해두고 나중에 처리한다.

                            break;

                        case Segments.Control.ControlType.Goto:
                        case Segments.Control.ControlType.ReverseGoto:
                        case Segments.Control.ControlType.ConditionJump:
                            jumpSegs.Add(controlSeg);							// 점프 명령어로 보관해두고 나중에 처리한다.
                            break;

                        case Segments.Control.ControlType.Clear:				// 모든 모듈에 clear를 보낸다
                            moduleCalls.AddAllModuleCall(controlSeg, bs.FrozenSetting);
                            break;

                        case Segments.Control.ControlType.Oneway:
                            sseg.OneWay	= true;
                            break;

                        case Segments.Control.ControlType.ForceBack:
                            sseg.snapshot.ForceBackward = true;
                            break;

                        case Segments.Control.ControlType.Load:
                            sseg.Type		= FlowType.Load;
                            sseg.Parameter	= controlSeg.GetLoadScriptData();	// 스냅샷 세그먼트의 parameter에 스크립트 파일명 보관
                            break;

                        case Segments.Control.ControlType.UnityCall:			// 함수콜
                            {
                                var callinfo	= new Segment.CallFuncInfo();
                                controlSeg.GetUnityCallData(out callinfo.funcname, out callinfo.param);
                                funcCalls.Add(callinfo);
                            }
                            break;

                        case Segments.Control.ControlType.Delay:				// 딜레이
                            snapshotDelay	= controlSeg.GetDelay();			// 지연 시간을 미리 지정해둔다
                            break;
                    }
                }
                break;
                //////////////////////////////////////////////////////////////
                case FSNScriptSequence.Segment.Type.Period:						// ** Period : 현재까지 누적한 call을 실행하는 개념으로 사용중
                {
                    var periodSeg		= curSeg as Segments.Period;

                    // 다음 snapshot을 위해 현재 진행 방향의 반대방향으로 FlowDirection 정해놓기
                    bs.settings.BackwardFlowDirection	= FSNInGameSetting.GetOppositeFlowDirection(bs.settings.CurrentFlowDirection);
                    bs.SetSettingDirty();

                    sshot.InGameSetting	= bs.FrozenSetting;						// 현재까지의 세팅 적용 (굳힌거 사용)

                    moduleCalls.ProcessCall(lastSeg.snapshot, sshot);			// 지금까지 모인 모듈 콜 집행하기

                    if(linkToLast)												// 이전 스냅샷에 붙여야하는경우
                    {
                        LinkSnapshots(lastSeg, sseg);

                        if(bs.prevPeriodWasChain)								// 이전 period가 chaining이었다면, 역방향 chaining 걸기
                        {
                            sseg.snapshot.NonstopToBackward	= true;
                            bs.prevPeriodWasChain			= false;			// (플래그 해제)
                        }

                        if(periodSeg.isChaining)								// Chaining 옵션이 켜져있을 경우
                        {
                            sseg.snapshot.NonstopToForward	= true;
                            bs.prevPeriodWasChain			= true;				// (chaining 상태 기록)
                        }
                    }
                    else
                    {
                        linkToLast = true;	// FIX : linkToLast는 맨 첫번째 스냅샷에만 해당하는 파라미터임. 두번째는 꺼준다
                    }

                    sseg.FunctionCalls	= funcCalls.ToArray();					// 쌓인 함수콜 리스트를 배열로 변환하여 세팅
                    funcCalls.Clear();

                    snapshotSeq.Add(sseg);										// 현재 스냅샷을 시퀀스에 추가
                    //

                    sseg.snapshot.AfterSwipeDelay	= snapshotDelay;			// 현재 지정된 딜레이를 적용.
                    snapshotDelay					= 0f;
                    //

                    // Condition 링크 임시 보관소 - 나중에 한번에 특정 방향으로 몰아넣는다
                    FSNInGameSetting.FlowDirection			conditionLinkDir		= FSNInGameSetting.FlowDirection.None;
                    FSNInGameSetting.FlowDirection			conditionLinkBackDir	= FSNInGameSetting.FlowDirection.None;
                    List<Segment.FlowInfo.ConditionLink>	conditionLinks			= null;
                    Dictionary<string, Segment>				conditionLinkSegCache	= new Dictionary<string, Segment>();	// 조건부 점프시, 중복되는 점프는 이전 것을 사용하게

                    foreach(var jumpSeg in jumpSegs)							// * 점프 세그먼트가 있을 경우 처리
                    {
                        // NOTE : 현재 Label은 Soft만 구현한다.

                        if (jumpSeg.controlType == Segments.Control.ControlType.SwipeOption)		// *** 선택지
                        {
                            bool isNonTextOption	= jumpSeg.IsNonTextOption();
                            for (int i = 0; i < 4; i++)												// 모든 방향마다 처리
                            {
                                var dir			= (FSNInGameSetting.FlowDirection)i;
                                string label	= jumpSeg.GetLabelFromSwipeOptionData(dir);
                                if (!string.IsNullOrEmpty(label))									// 라벨이 지정된 경우만 처리(= 해당 방향으로 분기가 있을 때만)
                                {
                                    // FIX : 만약 해당 선택지 방향이 원래의 역방향에 해당하는 것이었다면, 역방향을 None으로 재설정한다. (역방향 오버라이드 지원)
                                    if (dir == sseg.BackDirection)
                                    {
                                        sseg.BackDirection	= FSNInGameSetting.FlowDirection.None;
                                        sseg.snapshot.DisableBackward = true;	// 역방향 비활성화
                                    }

                                    int labelIndex	= bs.sequence.GetIndexOfLabel(label);
                                    var labelSeg	= bs.sequence.GetSegment(labelIndex) as Segments.Label;

                                    if (labelSeg.labelType == Segments.Label.LabelType.Soft)		// * SOFT 라벨로 점프
                                    {
                                        if (labelIndex < bs.segIndex)								// SOFT 라벨은 거슬러올라갈 수 없다.
                                            Debug.LogError("Cannot jump to previous soft label");

                                        var clonnedState		= bs.Clone();						// 상태 복제
                                        clonnedState.segIndex	= labelIndex;						// 라벨 인덱스 세팅
                                        clonnedState.settings.CurrentFlowDirection	= dir;			// 진행 방향 세팅 - 선택지 방향으로 진행 방향을 강제 세팅한다
                                        clonnedState.settings.BackwardFlowDirection	= FSNInGameSetting.GetOppositeFlowDirection(dir);

                                        var newSeg	= ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false);	// 새 분기 해석하기. 이전 스냅샷에 바로 붙이지 않는다.
                                        LinkSnapshotAsOption(sseg, newSeg, dir, isNonTextOption);	// 선택지로 연결하기
                                    }
                                    else
                                    {																// * HARD 라벨로 점프
                                        Debug.LogError("Not implemented");
                                    }
                                }
                            }
                        }
                        else if(jumpSeg.controlType == Segments.Control.ControlType.Goto)			// *** GOTO
                        {
                            string label	= jumpSeg.GetGotoLabel();
                            int labelIndex	= bs.sequence.GetIndexOfLabel(label);
                            var labelSeg	= bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if(labelSeg.labelType == Segments.Label.LabelType.Soft)					// * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)										// SOFT 라벨은 거슬러올라갈 수 없다.
                                    Debug.LogError("Cannot jump to previous soft label");

                                var clonnedState		= bs.Clone();								// 상태 복제
                                clonnedState.segIndex	= labelIndex;								// 라벨 인덱스 세팅

                                ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index);		// 새 분기 해석하기

                                // SOFT 라벨로 점프하는 경우엔 사실상 이 분기점으로 다시 되돌아올 일이 생기지 않는다.
                                // 추가 스크립트 해석을 중단한다.
                                keepProcess	= false;
                            }
                            else
                            {																		// * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else if(jumpSeg.controlType == Segments.Control.ControlType.ReverseGoto)	// ** ReverseGoto
                        {
                            string label	= jumpSeg.GetReverseGotoLabel();
                            int labelIndex	= bs.sequence.GetIndexOfLabel(label);
                            var labelSeg	= bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if (labelSeg.labelType == Segments.Label.LabelType.Soft)				// * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)										// SOFT 라벨은 거슬러올라갈 수 없다.
                                    Debug.LogError("Cannot jump to previous soft label");

                                var clonnedState		= bs.Clone();								// 상태 복제
                                clonnedState.segIndex	= labelIndex;								// 라벨 인덱스 세팅

                                // 진행 방향을 역방향으로 세팅
                                clonnedState.settings.CurrentFlowDirection	= FSNInGameSetting.GetOppositeFlowDirection(clonnedState.settings.CurrentFlowDirection);
                                clonnedState.settings.BackwardFlowDirection	= FSNInGameSetting.GetOppositeFlowDirection(clonnedState.settings.BackwardFlowDirection);

                                // 가장 마지막 세그먼트를 잠시동안만 UserChoice로 변경해서 새 스냅샷시퀀스를 정방향에 붙이지 못하게 막는다.
                                // 생성한 스냅샷을 역방향에 직접 붙여줘야하기 때문.
                                // 좀 Hacky한 방법이라서 변경이 필요할지도.

                                var newSeg	= ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false);	// 새 분기 해석한 후 레퍼런스 받기. 링크는 하지 않음

                                LinkSnapshotsReverseOverride(sseg, newSeg);	//붙이기

                                sseg.snapshot.DisableBackward = true;		// 역방향 비활성화
                            }
                            else
                            {																		// * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else if (jumpSeg.controlType == Segments.Control.ControlType.ConditionJump)	// ** 조건부 점프
                        {
                            string funcname;
                            string [] param;
                            string label	= jumpSeg.GetConditionJumpLabel();
                            int labelIndex	= bs.sequence.GetIndexOfLabel(label);
                            var labelSeg	= bs.sequence.GetSegment(labelIndex) as Segments.Label;

                            if(labelSeg.labelType == Segments.Label.LabelType.Soft)					// * SOFT 라벨로 점프
                            {
                                if (labelIndex < bs.segIndex)										// SOFT 라벨은 거슬러올라갈 수 없다.
                                    Debug.LogError("Cannot jump to previous soft label");

                                Segment newSeg;
                                if(!conditionLinkSegCache.TryGetValue(label, out newSeg))			// 이전에 캐싱된 것이 없을 때만 새로 해석한다.
                                {
                                    var clonnedState		= bs.Clone();							// 상태 복제
                                    clonnedState.segIndex	= labelIndex;							// 라벨 인덱스 세팅

                                    // 가장 마지막 세그먼트를 잠시동안만 UserChoice로 변경해서 새 스냅샷시퀀스를 정방향에 붙이지 못하게 막는다.
                                    // 생성한 스냅샷을 역방향에 직접 붙여줘야하기 때문.
                                    // 좀 Hacky한 방법이라서 변경이 필요할지도.

                                    newSeg		= ProcessSnapshotBuild(clonnedState, snapshotSeq, sseg.Index, false);	// 새 분기 해석한 후 레퍼런스 받기. 링크는 하지 않음

                                    conditionLinkSegCache[label]	= newSeg;									// 캐싱해두기
                                }

                                // Note : 현재 스크립트 스펙 상, 한 스냅샷 안에서 Condition Link은 한쪽 방향으로밖에 나올 수 없다.
                                // 따라서 방향 구분 없이 리스트 하나에 모두 모아둔 후, 기록해둔 방향에 모두 집어넣는다.

                                conditionLinkDir	= newSeg.snapshot.InGameSetting.CurrentFlowDirection;
                                conditionLinkBackDir= newSeg.snapshot.InGameSetting.BackwardFlowDirection;

                                // 만약 일반 링크가 등장하지 않아 방향이 설정되지 않을 때를 대비해서 세팅
                                if (sseg.FlowDirection == FSNInGameSetting.FlowDirection.None)
                                    sseg.FlowDirection = conditionLinkDir;
                                if (newSeg.BackDirection == FSNInGameSetting.FlowDirection.None)
                                    newSeg.BackDirection = conditionLinkBackDir;

                                List<Segment.CallFuncInfo> callfuncs	= new List<Segment.CallFuncInfo>();
                                while (jumpSeg.DequeueConditionJumpData(out funcname, out param))			// AND 조건으로 묶인 모든 condition 읽기
                                {
                                    callfuncs.Add(new Segment.CallFuncInfo() { funcname = funcname, param = param });
                                }
                                if (conditionLinks == null)
                                    conditionLinks	= new List<Segment.FlowInfo.ConditionLink>();
                                conditionLinks.Add(new Segment.FlowInfo.ConditionLink() { funcinfo = callfuncs.ToArray(), Linked = newSeg });

                                if(!newSeg.OneWay)
                                    newSeg.SetDirectFlow(conditionLinkBackDir, sseg);						// 역방향 설정

                            }
                            else
                            {																		// * HARD 라벨로 점프
                                Debug.LogError("Not implemented");
                            }
                        }
                        else
                        {
                            Debug.LogError("Unknown or not-yet-implemented jump statement!");
                        }
                    }
                    jumpSegs.Clear();

                    if (conditionLinks != null)									// 모아뒀던 조건부 점프 한번에 세팅
                    {
                        sseg.SetConditionFlow(conditionLinkDir, conditionLinks.ToArray());
                    }

                    lastSeg	= sseg;
                    NewSnapshot(out sseg, out sshot);							// 새 스냅샷 인스턴스 준비
                }
                break;
                /////////////////////////////////////////////////////////////
                default:
                Debug.LogError("?????????");
                break;
                }

                //
                bs.segIndex++;													// 다음 명령어 인덱스

                if(bs.segIndex >= bs.sequence.Length)							// * Sequence 가 끝났다면 루프 종료
                {
                    keepProcess	= false;
                }
            }

            return firstSeg;
        }
        public void Generate()
        {
            state = new State()
            {
                x     = 40,
                y     = 40,
                dir   = 0,
                size  = sizeValue,
                angle = angleValue
            };

            foreach (char c in input)
            {
                switch (c)
                {
                case 'F':
                    float newX = state.x + state.size * Mathf.Cos(state.dir * Mathf.PI / 180);
                    float newY = state.y + state.size * Mathf.Sin(state.dir * Mathf.PI / 180);

                    nodes[Mathf.RoundToInt(state.x), Mathf.RoundToInt(state.y)].isStreet = true;
                    nodes[Mathf.RoundToInt(newX), Mathf.RoundToInt(newY)].isStreet       = true;

                    state.x = newX;
                    state.y = newY;
                    break;

                case '+':
                    state.dir += state.angle;
                    break;

                case '-':
                    state.dir -= state.angle;
                    break;

                case '>':
                    state.size *= (1 - sizeGrowth);
                    break;

                case '<':
                    state.size *= (1 + sizeGrowth);
                    break;

                case ')':
                    state.angle *= (1 + angleGrowth);
                    break;

                case '(':
                    state.angle *= (1 - angleGrowth);
                    break;

                case '[':
                    states.Push(state.Clone());
                    break;

                case ']':
                    state = states.Pop();
                    break;

                case '!':
                    state.angle *= -1;
                    break;

                case '|':
                    state.dir += 180;
                    break;
                }
            }
        }
Example #30
0
 public State CloneState()
 {
     return(state.Clone());
 }
Example #31
0
        /**
         * Play human player action
         * @param a Action
         * @return status flag
         */
        private Status Human(ActionPM a)
        {
            State s = m_gameTree.CurrentState();

            // play human action
            if (s == null)
            {
                if (a is Placing)
                {
                    if (m_humanColor != IController.WHITE)
                    {
                        throw new Exception("wrong human player color");
                    }
                    m_gameTree.Create(TREEDEPTH, (Placing)a);
                    s = m_gameTree.CurrentState();
                    if (VERBOSE)
                    {
                        Debug.WriteLine("Human has played\n\ttree size: " + m_gameTree.Size());
                    }
                }
                else
                {
                    m_view.UpdateBoard(m_gameTree.CurrentState(), a, false);
                    return(Status.INVALIDACTION);
                }
            }
            else
            {
                // check if a is a valid human player action
                if (a.IsValid(s))
                {
                    var sCopy = s.Clone();

                    // update temporary state with user action
                    a.Update(sCopy);

                    // check if a mill has been closed
                    if (sCopy.InMill(a.EndPosition, a.Color()))
                    {
                        // action is not yet played, because it is part of a taking action
                        if (VERBOSE)
                        {
                            Debug.WriteLine("Human closed mill\n\ttree size: " + m_gameTree.Size());
                        }
                        // redraw game board
                        m_view.UpdateBoard(sCopy, a, false);
                        return(Status.CLOSEDMILL);
                    }
                    else
                    {
                        // play human player action a
                        m_gameTree.HumanPlayer(a);
                        if (VERBOSE)
                        {
                            Debug.WriteLine("Human has played\n\ttree size: " + m_gameTree.Size());
                        }
                    }
                }
                else
                {
                    if (VERBOSE)
                    {
                        Debug.WriteLine("Human played an invalid action");
                    }
                    m_view.UpdateBoard(m_gameTree.CurrentState(), a, false);
                    return(Status.INVALIDACTION);
                }
            }

            if (s.Finished())
            {
                if (VERBOSE)
                {
                    Debug.WriteLine("Human has won");
                }
                m_view.UpdateBoard(m_gameTree.CurrentState(), a, false);
                return(Status.FINISHED);
            }
            else
            {
                m_view.UpdateBoard(m_gameTree.CurrentState(), a, false);
                return(Status.OK);
            }
        }
Example #32
0
        public Project(State state)
        {
            Guard.ThrowIfNull(state, nameof(state));

            _state = state.Clone();
        }
Example #33
0
        /// <summary>
        /// The actual recursive function that return the max reward of a state
        /// </summary>
        /// <param name="IsMaxing">Is the current player the player that is maximizing</param>
        /// <param name="player">The current player</param>
        /// <param name="alpha">The best option for maximizing player</param>
        /// <param name="beta">The best option for minimizing player</param>
        private double GetMaxRewardRec(GameControlBase control, State s, bool IsMaxing, Players player, double alpha, double beta, int level, int maxLevel)
        {
            // If reached the max depth
            if (level > maxLevel)
            {
                return(0);
            }

            // This is needed in order to register the next action as the opponent's
            Players opponent;

            if (player == Players.Player1)
            {
                opponent = Players.Player2;
            }
            else
            {
                opponent = Players.Player1;
            }

            double BestVal;
            double Reward = 0;

            State currState = (State)s.Clone();

            if (IsMaxing)
            {
                BestVal = int.MinValue;
                for (int i = 0; i < control.ActionNum; i++)
                {
                    if (control.IsLegalAction(new Actione(i), currState))
                    {
                        s.Copy(currState);
                        control.RegisterAction(currState, new Actione(i), player);
                        if (control.IsTerminalState(currState)) // If its terminal, reward is the reward that the control returns
                        {
                            Reward = control.GetReward(player, currState);
                        }
                        else // If not terminal, return the minimax recursive function return
                        {
                            Reward = 0.9 * GetMaxRewardRec(control, currState, !IsMaxing, opponent, alpha, beta, level + 1, maxLevel);
                        }
                        BestVal = Math.Max(Reward, BestVal);
                        // Alpha beta pruning
                        alpha = Math.Max(alpha, BestVal);
                        if (beta <= alpha)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                BestVal = int.MaxValue;
                for (int i = 0; i < control.ActionNum; i++)
                {
                    if (control.IsLegalAction(new Actione(i), currState))
                    {
                        s.Copy(currState);
                        control.RegisterAction(currState, new Actione(i), player);
                        if (control.IsTerminalState(currState)) // If its terminal, reward is the reward that the control returns
                        {
                            Reward = control.GetReward(opponent, currState);
                        }
                        else // If not terminal, return the minimax recursive function return
                        {
                            Reward = 0.9 * GetMaxRewardRec(control, currState, !IsMaxing, opponent, alpha, beta, level + 1, maxLevel);
                        }
                        BestVal = Math.Min(Reward, BestVal);
                        // Alpha beta pruning
                        beta = Math.Min(beta, BestVal);
                        if (beta <= alpha)
                        {
                            break;
                        }
                    }
                }
            }
            return(BestVal);
        }
Example #34
0
 public State Migrate(State s)
 {
     var newState = s.Clone() as State;
     Execute(newState);
     return newState;
 }
Example #35
0
        /// <summary>
        /// A wrapper function to the recursive function, that returns the best action
        /// </summary>
        /// <param name="control">Control that the state is in</param>
        /// <param name="s">The current control state</param>
        /// <param name="alpha">Has to be int.MinValue</param>
        /// <param name="beta">Has to be int.MaxVakue</param>
        /// <param name="player">The player that is maximizing</param>
        private Actione BestMove(GameControlBase control, State s, double alpha, double beta, Players player)
        {
            // This is needed in order to register the next action as the opponent's
            Players opponent;

            if (player == Players.Player1)
            {
                opponent = Players.Player2;
            }
            else
            {
                opponent = Players.Player1;
            }

            int    maxID     = 0;
            double maxReward = -1000000;
            double Reward    = 0;

            bool    allSame = true; // Are all the rewards the same?
            Actione botAction;

            State currState = (State)s.Clone(); // Clone the state because it is a reference, so save the original state

            for (int i = 0; i < control.ActionNum; i++)
            {
                if (control.IsLegalAction(new Actione(i), currState))
                {
                    // Make the action as the player
                    s.Copy(currState);
                    control.RegisterAction(currState, new Actione(i), player);
                    if (control.IsTerminalState(currState)) // If its terminal, reward is the reward that the control returns
                    {
                        Reward = control.GetReward(player, currState);
                    }
                    else // If not terminal, return the minimax recursive function return
                    {
                        Reward = 0.9 * GetMaxRewardRec(control, currState, false, opponent, alpha, beta, 1, MaxDepth);
                    }
                    if (Reward != maxReward && i != 0) // If the reward changed along the call
                    {
                        allSame = false;
                    }
                    if (Reward > maxReward)
                    {
                        maxID     = i;
                        maxReward = Reward;
                    }
                    // Alpha beta pruning
                    alpha = Math.Max(alpha, maxReward);
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
            }
            if (!allSame)
            {
                return(new Actione(maxID));
            }
            else // If all rewards were the same, do a random action
            {
                botAction = new Actione(rand.Next(control.ActionNum));
                while (!control.IsLegalAction(botAction))
                {
                    botAction = new Actione(rand.Next(control.ActionNum));
                }
                return(botAction);
            }
        }
Example #36
0
        public virtual State CaptureState()
        {
            State state = this.GetCurrentState();

            return((state == null) ? null : (State)state.Clone());
        }
Example #37
0
    private void GeneratePlantFromString()
    {
        states.Push(currentState);

        statesOfBranch.Add(currentState.Clone());

        int trisCount = 0;

        for (int i = 0; i < output.Length; i++)
        {
            char c = output[i];
            switch (c)
            {
            case 'F':
                MoveForward();
                trisCount += 2;

                statesOfBranch.Add(currentState.Clone());

                break;

            case '[':

                states.Push(currentState.Clone());
                break;

            case ']':
                currentState = states.Pop();
                ///////
                DrawLines(statesOfBranch.ToArray());
                statesOfBranch.Clear();
                statesOfBranch.Add(currentState.Clone());
                ///////

                break;

            case '+':
                currentState.rotation *= Rotate(3, mainAngle);
                break;

            case '-':
                currentState.rotation *= Rotate(3, -mainAngle);
                break;

            case '^':
                currentState.rotation *= Rotate(1, mainAngle);
                break;

            case '&':
                currentState.rotation *= Rotate(1, -mainAngle);
                break;

            case '/':
                currentState.rotation *= Rotate(2, mainAngle);
                break;

            case '\\':
                currentState.rotation *= Rotate(2, -mainAngle);
                break;

            case 'W':
                currentState.rotation *= Rotate(Random.Range(1, 4), wobbleStrength);
                break;

            default:
                break;
            }
        }
        DrawLines(statesOfBranch.ToArray());
        statesOfBranch.Clear();


        print("triscount : " + trisCount);

        int branches = 0;

        foreach (GameObject go in FindObjectsOfType(typeof(GameObject)) as GameObject[])
        {
            if (go.name == "branch")
            {
                branches++;
            }
        }
        print("branches : " + branches);
    }