Exemple #1
0
        private DialogPoint ReadGame(IEnumerator <char> charEnumer)
        {
            ReadGameStates state = ReadGameStates.ReadNothing;

            Dictionary <int, DialogPoint> dialogPointDictionary = new Dictionary <int, DialogPoint>();

            DialogPoint currDialogPoint = new DialogPoint();

            List <DialogLink> linkList = new List <DialogLink>();

            DialogLink currLink = new DialogLink();

            using (var baseTokenEnumer = GetBaseTokens(charEnumer))
            {
                while (baseTokenEnumer.MoveNext())
                {
                    var token = baseTokenEnumer.Current;

                    switch (state)
                    {
                    // reading transition equals to reading nothing
                    case ReadGameStates.ReadLinkTransition:
                    case ReadGameStates.ReadNothing:
                    {
                        // if we have read link transition and met minus, it means - now we're reading new transition
                        if (state == ReadGameStates.ReadLinkTransition && token.Type == BaseTokenType.minus)
                        {
                            currLink = new DialogLink()
                            {
                                Number = linkList.Count,
                            };
                            linkList.Add(currLink);
                            state = ReadGameStates.ReadLinkStart;
                        }
                        // it means - now we're reading point number
                        else if (token.Type == BaseTokenType.rndBrktContent)
                        {
                            // saving previous dialog-point's transitions
                            if (state == ReadGameStates.ReadLinkTransition)
                            {
                                currDialogPoint.Links = linkList.ToArray();
                            }

                            bool parseResult = int.TryParse(token.Content, out int result);

                            if (!parseResult)
                            {
                                throw new SyntaxError($"Next point number reading error, found: '{token.Content}'");
                            }

                            bool getResult = dialogPointDictionary.TryGetValue(result, out currDialogPoint);

                            if (!getResult)
                            {
                                currDialogPoint = new DialogPoint()
                                {
                                    ID = result
                                };
                                dialogPointDictionary.Add(currDialogPoint.ID, currDialogPoint);
                            }

                            state = ReadGameStates.ReadPointNumber;
                        }
                        else
                        {
                            throw new SyntaxError($"Point number reading error: found '{token.Content}'");
                        }
                        break;
                    }

                    case ReadGameStates.ReadPointNumber:
                    {
                        if (token.Type == BaseTokenType.text)
                        {
                            currDialogPoint.Text = token.Content;

                            state = ReadGameStates.ReadPointText;
                        }
                        else
                        {
                            throw new SyntaxError($"Expected text after point number, found: '{token.Content}'");
                        }
                        break;
                    }

                    case ReadGameStates.ReadPointActions:
                    case ReadGameStates.ReadPointText:
                    {
                        if (token.Type == BaseTokenType.sqrBrktContent)
                        {
                            bool parseResult = int.TryParse(token.Content, out int result);

                            if (!parseResult)
                            {
                                throw new SyntaxError($"Point number reading error: found '{token.Content}'");
                            }

                            bool getResult = dialogPointDictionary.TryGetValue(result, out DialogPoint nextPoint);

                            if (!getResult)
                            {
                                nextPoint = new DialogPoint()
                                {
                                    ID = result
                                };
                                dialogPointDictionary.Add(nextPoint.ID, nextPoint);
                            }

                            DialogLink link = new DialogLink()
                            {
                                Text      = "next...",
                                NextPoint = nextPoint,
                                Number    = 0,
                            };

                            currDialogPoint.Links = new DialogLink[1] {
                                link
                            };

                            state = ReadGameStates.ReadNothing;
                        }
                        else if (token.Type == BaseTokenType.rndBrktContent && state == ReadGameStates.ReadPointText)
                        {
                            GameAction[] actions = ParseActions(token.Content);

                            currDialogPoint.Actions = actions;

                            state = ReadGameStates.ReadPointActions;
                        }
                        else if (token.Type == BaseTokenType.minus)
                        {
                            linkList.Clear();

                            currLink = new DialogLink()
                            {
                                Number = linkList.Count,
                            };
                            linkList.Add(currLink);
                            state = ReadGameStates.ReadLinkStart;
                        }
                        else
                        {
                            throw new SyntaxError($"Excpected actions, transitions or link start '-', found: '{token.Content}'");         // expected actions or transition or link start
                        }
                        break;
                    }

                    case ReadGameStates.ReadCondition:
                    case ReadGameStates.ReadLinkStart:
                    {
                        if (token.Type == BaseTokenType.rndBrktContent && state == ReadGameStates.ReadLinkStart)
                        {
                            LinkCondition[] conditions = ParseCondition(token.Content);

                            currLink.Conditions = conditions;

                            state = ReadGameStates.ReadCondition;
                        }
                        else if (token.Type == BaseTokenType.text)
                        {
                            currLink.Text = token.Content;

                            state = ReadGameStates.ReadLinkText;
                        }
                        break;
                    }

                    case ReadGameStates.ReadLinkAction:
                    case ReadGameStates.ReadLinkText:
                    {
                        if (token.Type == BaseTokenType.rndBrktContent && state == ReadGameStates.ReadLinkText)
                        {
                            GameAction[] actions = ParseActions(token.Content);

                            currLink.Actions = actions;

                            state = ReadGameStates.ReadLinkAction;
                        }
                        else if (token.Type == BaseTokenType.sqrBrktContent)
                        {
                            bool parseResult = int.TryParse(token.Content, out int result);

                            if (!parseResult)
                            {
                                // expected number
                            }

                            bool getResult = dialogPointDictionary.TryGetValue(result, out DialogPoint nextPoint);

                            if (!getResult)
                            {
                                nextPoint = new DialogPoint()
                                {
                                    ID = result
                                };
                                dialogPointDictionary.Add(nextPoint.ID, nextPoint);
                            }

                            currLink.NextPoint = nextPoint;

                            state = ReadGameStates.ReadLinkTransition;
                        }
                        else
                        {
                            throw new SyntaxError($"Expected next point number, found: '{token.Content}'");
                        }

                        break;
                    }
                    }
                }

                if (state != ReadGameStates.ReadNothing && state != ReadGameStates.ReadLinkTransition)
                {
                    throw new UnexpectedEndOfInputError($"Incorrect input, the state, when stop: '{state.ToString()}'");
                }

                if (state == ReadGameStates.ReadLinkTransition)
                {
                    currDialogPoint.Links = linkList.ToArray();
                }
            }

            AnalizeGameGraph(dialogPointDictionary);

            dialogPointDictionary.TryGetValue(0, out DialogPoint root);

            return(root);
        }
Exemple #2
0
        private void AnalizeGameGraph(Dictionary <int, DialogPoint> pointDict)
        {
            // it should contain start-state (with number 0)
            // (throws exception)
            DialogPoint start = null;

            {
                bool containsStart = pointDict.TryGetValue(0, out start);

                if (!containsStart || (start.Links == null || start.Links.Length == 0))
                {
                    throw new ApplicationException("Game doesn't contain the start-state (state with number 0)");
                }
            }

            // looking for defined dialog points, which don't exist
            // (adds warnings)
            using (var dictEnumer = pointDict.GetEnumerator())
            {
                while (dictEnumer.MoveNext())
                {
                    var currPoint = dictEnumer.Current.Value;

                    if (currPoint.Links == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < currPoint.Links.Length; ++i)
                    {
                        var nextPoint = currPoint.Links[i].NextPoint;

                        if (nextPoint.Links == null || nextPoint.Links.Length == 0)
                        {
                            var notDefinedNextPointWarning = $"in point({currPoint.ID}) in {i} position - " +
                                                             $"transition to point({nextPoint.ID}), which hadn't been read (incorrect transition)";

                            nextPoint = currPoint;

                            nextPoint.Text += "(INVALID TRANSITION)";

                            warnings.Add(notDefinedNextPointWarning);
                        }
                    }
                }
            }

            // find not-linked components
            var notConnectedPoints = new Dictionary <int, DialogPoint>();

            using (var dictEnumer = pointDict.GetEnumerator())
            {
                while (dictEnumer.MoveNext())
                {
                    notConnectedPoints.Add(dictEnumer.Current.Key, dictEnumer.Current.Value);
                }
            }

            using (var dictEnumer = notConnectedPoints.GetEnumerator())
            {
                var pointQueue = new Queue <DialogPoint>();

                var connectedPoints = new Dictionary <int, DialogPoint>();

                pointQueue.Enqueue(start);

                while (pointQueue.Count > 0)
                {
                    var currPoint = pointQueue.Dequeue();

                    for (int i = 0; i < currPoint.Links.Length; ++i)
                    {
                    }
                }
            }
        }