private void checkTransitions()
        {
            PossibleTransitions.Clear();
            _alwaysVisibleTransitions.Clear();

            // ID локации
            var locationId = CurrentLocation.id;
            // Получаем все переходы с локации
            var transitions = Quest.Transitions.Where(v => v.from == locationId).ToList();

            transitions.ForEach(v => CheckTransition(v));

            //ReduceTransition(CurrentLocation);

            //transitions = transitions.Where(t => CheckTransition(t)).ToList();
        }
        public bool CheckTransition(Transition transition)
        {
            var condition = _parameterIndexToUse
                            .Where(v => v.Value)
                            .Select(v => v.Key)
                            .All(index => CheckModification(_parameterIndexToValue[index], transition.modifiers[index]));

            var passed = (transition.passCount == 0) ||
                         !(_transitionCounts.ContainsKey(transition.id) && (_transitionCounts[transition.id] >= transition.passCount));

            if (passed && condition && (transition.globalCondition.Length == 0 ||
                                        (int)Token.eval(transition.globalCondition, _parameterIndexToValue) != 0))
            {
                PossibleTransitions.Add(transition);
            }

            if (transition.alwaysVisible)
            {
                _alwaysVisibleTransitions.Add(transition);
            }

            return(false);
        }
        private void ReduceTransition(Location currentLocation)
        {
            var rnd = new Random();

            var allTransactions          = new Dictionary <string, IList <Transition> >();
            var alwaysVisibleTransitions = new List <Transition>();

            // Группируем транзакции по имени перехода
            foreach (var possibleTransition in PossibleTransitions)
            {
                IList <Transition> transactionList;
                var titleText = string.IsNullOrEmpty(possibleTransition.title.Text)
                    ?""
                    :possibleTransition.title.Text;
                if (!allTransactions.TryGetValue(titleText, out transactionList))
                {
                    transactionList = new List <Transition>();
                    allTransactions.Add(titleText, transactionList);
                }
                transactionList.Add(possibleTransition);
            }

            // Добавляем всегда видимыет транзакции
            foreach (var alwaysVisibleTransition in _alwaysVisibleTransitions)
            {
                var titleText = string.IsNullOrEmpty(alwaysVisibleTransition.title.Text)
                    ? ""
                    : alwaysVisibleTransition.title.Text;
                if (!allTransactions.ContainsKey(alwaysVisibleTransition.title.Text))
                {
                    alwaysVisibleTransitions.Add(alwaysVisibleTransition);
                }
            }

            //var allTransactions = _possibleTransitions.Concat(_alwaysVisibleTransitions).ToList();

            PossibleTransitions.Clear();
            _alwaysVisibleTransitions.Clear();

            alwaysVisibleTransitions.ForEach(v => _alwaysVisibleTransitions.Add(v));

            foreach (var allTransaction in allTransactions)
            {
                if (allTransaction.Value.Count == 1)
                {
                    var transition = allTransaction.Value.Single();
                    var priority   = transition.priority;
                    if (priority < 1f)
                    {
                        if (rnd.Next(1000) < (int)(priority * 1000))
                        {
                            PossibleTransitions.Add(transition);
                        }
                    }
                    else
                    {
                        PossibleTransitions.Add(transition);
                    }
                    continue;
                }
                var        allRange          = allTransaction.Value.Sum(v => v.priority);
                var        randValue         = rnd.Next((int)(allRange * 1000));
                var        countPriority     = 0;
                Transition selectTransaction = null;
                foreach (var transition in allTransaction.Value)
                {
                    selectTransaction = transition;
                    countPriority     = (int)(transition.priority * 1000);
                    if (countPriority >= randValue)
                    {
                        break;
                    }
                }
                PossibleTransitions.Add(selectTransaction);
            }
        }
        private void SetLocation(Location location)
        {
            CurrentLocation = location;
            var oldParametersValue = _parameterIndexToValue.ToDictionary(key => key.Key, value => value.Value);

            location.modifiers.ForEach((modifier, index) => ApplyModifier(index, modifier, oldParametersValue));


            checkTransitions();
            ReduceTransition(CurrentLocation);

            if (CurrentLocation.LocationType != LocationType.LOCATION_EMPTY ||
                CurrentLocation.descriptions.Count != 0)
            {
                if (CurrentLocation.descriptionExpression && CurrentLocation.expression.Length != 0)
                {
                    var t = (int)Token.eval(CurrentLocation.expression, _parameterIndexToValue);
                    //FIXME: Bug or feature?
                    if (t == 0)
                    {
                        t = 1;
                    }
                    if ((t < 1) || (t > 10) || (CurrentLocation.descriptions[t - 1].Length == 0))
                    {
                        Console.WriteLine(
                            $"Invalid location description selection ({t}) in location {CurrentLocation.id}");
                        LocationText = "";
                    }
                    else
                    {
                        LocationText = substituteValues(CurrentLocation.descriptions[t - 1]);
                    }
                }
                else
                {
                    var value            = 0;
                    int descriptionIndex = 0;
                    var allDescriptions  = CurrentLocation.descriptions.Where(v => v.Length > 0).ToList();
                    if (!_locationDescriptionsCount.TryGetValue(CurrentLocation.id, out descriptionIndex))
                    {
                        _locationDescriptionsCount.Add(CurrentLocation.id, 0);
                        descriptionIndex = 0;
                    }
                    else
                    {
                        descriptionIndex = (++descriptionIndex) % allDescriptions.Count;
                        _locationDescriptionsCount[CurrentLocation.id] = descriptionIndex;
                    }
                    LocationText = substituteValues(allDescriptions[descriptionIndex]);
                }
            }

            Console.WriteLine($"QuestPlayer: {CurrentLocation.id}");

            var currentLocationTransactions = Quest.Transitions.Where(v => v.from == CurrentLocation.id);

            if (PossibleTransitions.Count == 1 &&
                PossibleTransitions.Single().title.Length == 0 &&
                CurrentTransition.description.Length == 0)
            {
                StartTransition(PossibleTransitions.Single());
            }
            else if (CurrentLocation.LocationType == LocationType.LOCATION_SUCCESS)
            {
                throw new Exception($"Complite: {LocationText}");
            }
            else if (CurrentLocation.LocationType == LocationType.LOCATION_FAIL)
            {
                throw new Exception($"Fail: {LocationText}");
            }
            else if (CurrentLocation.LocationType == LocationType.LOCATION_DEATH)
            {
                throw new Exception($"Death: {LocationText}");
            }
            else if (!CheckCriticalParameters())
            {
                throw new Exception($"Param: {LocationText}");
            }
        }
 public void AddTransition(string command, BaseFolder folder)
 {
     PossibleTransitions.Add(command, folder);
 }