예제 #1
0
        public void Add_GraphInBetweenNodes_NoException()
        {
            BrigitGraph bg = new BrigitGraph();

            bg.AddNode(new Node()
            {
                Data = 1
            });
            bg.AddNode(new Node()
            {
                Data = 3
            });

            BrigitGraph bg2 = new BrigitGraph();

            bg2.AddNode(new Node()
            {
                Data = 6
            });
            bg2.AddNode(new Node()
            {
                Data = 7
            });

            bg.AddInBetween(bg.Head, bg2);
        }
예제 #2
0
        public void Create_Choice_Object_From_Yaml()
        {
            // arrange
            String testString = @"graph:
                                  - decision:
                                    - choice: This is a choice
                                    - choice: This is another choice";

            var expected = new BrigitGraph();
            var decision = new Decision();

            decision.Choices.Add(new Choice("This is a choice"));
            decision.Choices.Add(new Choice("This is another choice"));
            expected.AddNode(new Node(decision));

            var yaml = new YamlStream();

            yaml.Load(new StringReader(testString));
            var mapping     = (YamlMappingNode)yaml.Documents[0].RootNode;
            var brigitNodes = (YamlSequenceNode)mapping.Children[new YamlScalarNode("graph")];
            var parser      = new BrigitYamlParser();

            // act
            var descision = parser.CreateDecision((YamlMappingNode)brigitNodes.Children[0]);

            // assert
            Assert.AreEqual(expected, descision);
        }
예제 #3
0
        public BrigitGraph CreateDecision(YamlMappingNode yamlNode)
        {
            BrigitGraph graph    = new BrigitGraph();
            Decision    decision = new Decision();
            Node        baseNode = new Node(decision);

            graph.AddNode(baseNode);

            foreach (YamlMappingNode choiceYamlNode in (YamlSequenceNode)yamlNode.Children[new YamlScalarNode("decision")])
            {
                Choice choice = DeserializeChoice(choiceYamlNode);
                choice.NextNode = -1;
                decision.Choices.Add(choice);

                // Node has inline branch
                if (choiceYamlNode.Children.ContainsKey(new YamlScalarNode("graph")))
                {
                    var inlineBranch = CreateGraph((YamlSequenceNode)choiceYamlNode.Children[new YamlScalarNode("graph")]);
                    graph.AddBranch(baseNode, inlineBranch);
                    choice.NextNode = baseNode.Next.Count - 1;
                }
            }

            foreach (Choice choice in decision.Choices.Where(x => x.NextNode == -1))
            {
                choice.NextNode = baseNode.Next.Count;
            }

            return(graph);
        }
예제 #4
0
        public BrigitGraph CreateGraph(YamlSequenceNode rootGraphNode)
        {
            var graph = new BrigitGraph();

            foreach (YamlNode node in rootGraphNode)
            {
                string brigitNodeType = ((YamlMappingNode)node).Children.Keys.First().ToString();

                switch (brigitNodeType)
                {
                case "dialog":
                    var brigitNode = new Node(CreateDialog((YamlMappingNode)node));
                    graph.AddNode(brigitNode);
                    break;

                case "decision":
                    var subGraph = CreateDecision((YamlMappingNode)node);
                    graph.AddGraph(subGraph);
                    break;

                case "fork":
                    var forkGraph = CreateFork((YamlMappingNode)node);
                    graph.AddGraph(forkGraph);
                    break;

                default:
                    throw new Exception(String.Format("Node Type {0} not recognized", brigitNodeType));
                }
            }

            return(graph);
        }
예제 #5
0
        public BrigitGraph CreateFork(YamlMappingNode yamlNode)
        {
            var forkingGraph           = new BrigitGraph();
            var nonInteractiveDecision = new Decision();

            nonInteractiveDecision.Interactive = false;
            var baseNode = new Node(nonInteractiveDecision);

            forkingGraph.AddNode(baseNode);

            foreach (YamlMappingNode node in (YamlSequenceNode)yamlNode.Children[new YamlScalarNode("fork")])
            {
                var choice = new Choice();
                choice.NextNode = -1;
                string expression = GetScalarYamlNodeValue("path", node);
                choice.Attributes.Expression = BrigitExpressionParser.Parse(expression);

                if (node.Children.ContainsKey(new YamlScalarNode("graph")))
                {
                    var subGraph = CreateGraph((YamlSequenceNode)node.Children[new YamlScalarNode("graph")]);
                    forkingGraph.AddBranch(baseNode, subGraph);
                    choice.NextNode = baseNode.Next.Count - 1;
                }

                nonInteractiveDecision.Choices.Add(choice);
            }

            foreach (Choice choice in nonInteractiveDecision.Choices.Where(x => x.NextNode == -1))
            {
                choice.NextNode = baseNode.Next.Count;
            }

            return(forkingGraph);
        }
예제 #6
0
        public BrigitGraph CreateGraphFromYaml()
        {
            var graph = new BrigitGraph();

            // The graphs attributes

            // Getting the graph from the yaml node
            var brigitNodes = (YamlSequenceNode)RootNode.Children[new YamlScalarNode("graph")];

            return(CreateGraph(brigitNodes));
        }
예제 #7
0
        public BrigitGraph ParseBranch(TomeStream stream, ref string name)
        {
            BrigitGraph branchGraph = new BrigitGraph();

            // parse away the > and the name
            AssertChar(stream, '>');
            // getting the name
            name = ParseOnlyTextNoEscape(stream);

            // whitespace can be between the name and the opener
            EatWhitespace(stream);
            AssertChar(stream, '{');

            // parse like an ordinary tome after ward
            branchGraph = ParseBrigitGraph(stream);

            return(branchGraph);
        }
예제 #8
0
        // Tests to make sure that you can add a node just fine
        public void Add_NodeToLinkList_NoException()
        {
            BrigitGraph ll = new BrigitGraph();
            Node        n1 = new Node()
            {
                Data = 1
            };

            ll.AddNode(n1);
            Node n2 = new Node()
            {
                Data = 2
            };

            ll.AddNode(n2);

            string dotFile = ll.ToString();
        }
예제 #9
0
        public void Add_BranchingLinkedListToLinkedList_NoException()
        {
            BrigitGraph ll = new BrigitGraph();
            Node        n1 = new Node()
            {
                Data = 1
            };

            ll.AddNode(n1);

            Node n2 = new Node()
            {
                Data = 2
            };

            ll.AddNode(n2);

            Node n3 = new Node()
            {
                Data = 3
            };

            ll.AddNode(n3);

            Node nn1 = new Node()
            {
                Data = 4
            };
            Node nn2 = new Node()
            {
                Data = 5
            };
            Node nn3 = new Node()
            {
                Data = 6
            };
            BrigitGraph ll2 = new BrigitGraph();

            ll2.AddNode(nn1);
            ll2.AddNode(nn2);
            ll2.AddNode(nn3);

            ll.AddBranch(n2, ll2);
        }
예제 #10
0
        public void Parse_Multi_Character_Exchange()
        {
            var yaml = new YamlStream();

            yaml.Load(GetReader("MultipleCharacterExchange.yml"));
            var mapping    = (YamlMappingNode)yaml.Documents[0].RootNode;
            var yamlParser = new BrigitYamlParser(mapping);
            var conv       = yamlParser.CreateGraphFromYaml();

            var constructed = new BrigitGraph();

            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diego", "Heyo!", "How ya doing?", "You look cute today")
            });
            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diana", "Haha thanks.", "I'm fine, how are you?")
            });

            Assert.AreEqual(constructed, conv);
        }
예제 #11
0
        public void Parse_TomeTest1()
        {
            var yaml = new YamlStream();

            yaml.Load(GetReader("TomeTest_1.yml"));
            var mapping    = (YamlMappingNode)yaml.Documents[0].RootNode;
            var yamlParser = new BrigitYamlParser(mapping);
            var conv       = yamlParser.CreateGraphFromYaml();

            BrigitGraph constructed = new BrigitGraph();

            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diego", "Hello")
            });
            constructed.AddNode(new Node()
            {
                Data = new Decision()
                {
                    Choices = new List <Choice>()
                    {
                        new Choice("F**k you"),
                        new Choice("Hello"),
                        new Choice("Blahblah")
                    }
                }
            });
            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diego", "Ok")
            });

            bool checker = conv.Equals(constructed);

            Assert.AreEqual(true, checker);
        }
예제 #12
0
 public Conversation()
 {
     ConversationName = string.Empty;
     ll = new BrigitGraph();
 }
예제 #13
0
        public void Parse_TomeTest4()
        {
            var yaml = new YamlStream();

            yaml.Load(GetReader("TomeTest_4.yml"));
            var mapping    = (YamlMappingNode)yaml.Documents[0].RootNode;
            var yamlParser = new BrigitYamlParser(mapping);
            var conv       = yamlParser.CreateGraphFromYaml();

            var constructed = new BrigitGraph();

            constructed.AddNode(new Node
            {
                Data = new Dialog("Diego", "Hey what's happening")
            });

            // first choice
            Choice ch1 = new Choice("This sets one to true", 0);

            ch1.Attributes.SetFlags.Add("one", Attributes.Flag.True);
            Choice ch2 = new Choice("This sets two to true", 0);

            ch2.Attributes.SetFlags.Add("two", Attributes.Flag.True);

            // the decsion block
            var choices = new Node()
            {
                Data = new Decision()
                {
                    Choices = new List <Choice>
                    {
                        ch1,
                        ch2
                    }
                }
            };

            constructed.AddNode(choices);

            // Dialog Node
            var dialog  = new Dialog("Person");
            var speech1 = new SpeechText("Hello");

            speech1.Attributes.Expression = new Variable("one");
            var speech2 = new SpeechText("Hey");

            speech2.Attributes.Expression = new Variable("two");
            dialog.Text = new List <SpeechText>()
            {
                speech1,
                speech2,
                new SpeechText("Blah")
            };

            constructed.AddNode(new Node()
            {
                Data = dialog
            });

            // second dialog node
            var dialog2 = new Dialog("Other", "Heyo", "What's going on");

            dialog2.Attributes.Expression = new Variable("one");

            constructed.AddNode(new Node()
            {
                Data = dialog2
            });

            //assertion
            bool checker = conv.Equals(constructed);

            Assert.AreEqual(true, checker);
        }
예제 #14
0
        // The multiple lines to the tail node are being created
        // because of the recurisve nature of the ToString function i wrote
        public void Parse_TomeTest3()
        {
            var yaml = new YamlStream();

            yaml.Load(GetReader("TomeTest_3.yml"));
            var mapping    = (YamlMappingNode)yaml.Documents[0].RootNode;
            var yamlParser = new BrigitYamlParser(mapping);
            var conv       = yamlParser.CreateGraphFromYaml();

            var constructed = new BrigitGraph();

            constructed.AddNode(new Node
            {
                Data = new Dialog("Diana", "I didn't want to be the one to forget")
            });
            constructed.AddNode(new Node
            {
                Data = new Dialog("Diego", "I thought of everything I'd never regret")
            });

            // looks like they're routing to the wrong places
            var choice = new Node()
            {
                Data = new Decision()
                {
                    Choices = new List <Choice>()
                    {
                        new Choice("A little time with you is all that I get", 0),
                        new Choice("That's all we need because that's all we can take", 1),
                        new Choice("I don't believe in him - his lips on the ground", 2),
                        new Choice("I wanna take you back to the place by the rock", 2)
                    }
                }
            };

            constructed.AddNode(choice);

            // chorus creation and then addition
            var chorusSubGraph = new BrigitGraph();

            chorusSubGraph.AddNode(new Node
            {
                Data = new Dialog("Diego", "I gotta be in your arms baby", "But far away I seek for your light",
                                  "I hold on because for you my heart keeps beating")
            });
            constructed.AddBranch(choice, chorusSubGraph);


            var diegoChoiceSubGraph = new BrigitGraph();

            diegoChoiceSubGraph.AddNode(new Node()
            {
                Data = new Dialog("Diego", "One thing I never see the same when you're round")
            });

            // will probably check here to make sure this works
            // the error may happen some where around here
            constructed.AddBranch(choice, diegoChoiceSubGraph);

            // everything seems fine up to this point
            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diana", "But no one gives us time anymore")
            });

            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diego", "Will you be my light?")
            });


            bool checker = conv.Equals(constructed);

            Assert.AreEqual(true, checker);
        }
예제 #15
0
        public void Parse_TomeTest2()
        {
            var yaml = new YamlStream();

            yaml.Load(GetReader("TomeTest_2.yml"));
            var mapping    = (YamlMappingNode)yaml.Documents[0].RootNode;
            var yamlParser = new BrigitYamlParser(mapping);
            var conv       = yamlParser.CreateGraphFromYaml();

            BrigitGraph constructed = new BrigitGraph();

            constructed.AddNode(new Node()
            {
                Data = new Dialog("Yulia", "What the f**k is this", "What are you doing?")
            });

            // the choice sub graph
            BrigitGraph subGraph = new BrigitGraph();
            Decision    root     = new Decision()
            {
                Choices = new List <Choice>()
                {
                    new Choice("Nothing", 0),
                    new Choice("Everything", 2),
                    new Choice("Go away", 1),
                }
            };

            subGraph.AddNode(new Node()
            {
                Data = root
            });

            // the first branch
            BrigitGraph nothingBranch = new BrigitGraph();

            nothingBranch.AddNode(new Node()
            {
                Data = new Dialog("Yulia", "You're lying")
            });
            nothingBranch.AddNode(new Node()
            {
                Data = new Dialog("Diego", "Yeah she is")
            });

            subGraph.AddBranch(subGraph.Head, nothingBranch);

            // the second branch pointed to by the 3rd choice
            BrigitGraph goAwayBranch = new BrigitGraph();

            goAwayBranch.AddNode(new Node()
            {
                Data = new Dialog("Yulia", "NO")
            });
            subGraph.AddBranch(subGraph.Head, goAwayBranch);

            constructed.AddGraph(subGraph);
            constructed.AddNode(new Node()
            {
                Data = new Dialog("Diego", "There's a lot of yelling going on right now")
            });


            bool checker = conv.Equals(constructed);

            Assert.AreEqual(true, checker);
        }
예제 #16
0
        // this will select a branch from a set given to it
        // this looks really similar to chioce with some smaller but important changes
        public BrigitGraph ParseBranchSelector(Dictionary <string, OpenChoice> branchEndings)
        {
            AssertChar(Stream, '{');
            // the loop consists of parsing expression, parsing branch
            // then check for a new expression or the end

            // TODO replace this fix with a more elegant solution
            // hot fix used for resetting the open choices
            List <string> branches = new List <string>();
            Decision      selector = new Decision();

            selector.Interactive = false;
            BrigitGraph graph = new BrigitGraph();
            Node        root  = new Node()
            {
                Data = selector
            };

            graph.AddNode(root);

            while (Stream.PeekChar() != '}')
            {
                // gets chars up to the *
                string      expression = FetchNonStarSubString();
                IExpression exp;
                if (expression == "_")
                {
                    //exp = new Tautalogy();
                    exp = new Variable("TRUE");
                }
                else
                {
                    exp = BrigitExpressionParser.Parse(expression);
                }
                // eat the star that ends the expresssion
                AssertChar(Stream, '*');
                Choice ch = new Choice();
                ch.Attributes.Expression = exp;
                ch.Text     = string.Empty;
                ch.NextNode = -1;

                EatWhitespace(Stream);

                // if there is no arrow then it should be considered a
                // "pass"
                // there can be multiple passes, but there can only be one default which is "_"
                if (Stream.PeekChar() == '-')
                {
                    // parse either a sub graph or parse a branchname
                    ParseArrow(Stream);
                    EatWhitespace(Stream);

                    if (Stream.PeekChar() == '{')
                    {
                        AssertChar(Stream, '{');
                        BrigitGraph subGraph = ParseBrigitGraph(Stream);
                        graph.AddBranch(root, subGraph);
                        ch.NextNode = root.Next.Count - 1;
                    }
                    else if (Char.IsLetterOrDigit(Stream.PeekChar()))
                    {
                        string BranchName = ParseOnlyTextNoEscape(Stream);
                        branches.Add(BranchName);
                        OpenChoice open = new OpenChoice(root, ch);
                        branchEndings.Add(BranchName, open);
                    }
                    else
                    {
                        // throw not recognized
                        string msg = String.Format("Expected beginning of branch name or sub graph but found {0} at {1}", Stream.PeekChar(), Stream.Position);
                        throw new Exception(msg);
                    }
                }
                // a pass
                else
                {
                }
                selector.Choices.Add(ch);
                EatWhitespace(Stream);
            }

            // to end this off
            AssertChar(Stream, '}');

            foreach (Choice ch in selector.Choices)
            {
                if (ch.NextNode == -1)
                {
                    ch.NextNode = root.Next.Count;
                }
            }

            foreach (string s in branches)
            {
                branchEndings[s].TailNode = null;
            }

            return(graph);
        }
예제 #17
0
        public BrigitGraph ParseDescision(TomeStream stream, Dictionary <string, OpenChoice> branchEndings)
        {
            Decision    descision = new Decision();
            BrigitGraph ll        = new BrigitGraph();
            Node        root      = new Node()
            {
                Data = descision
            };

            ll.AddNode(root);

            // first parse away the @player:
            AssertChar(stream, '@');
            AssertAlphaDigitString(stream, "player");
            AssertChar(stream, '{');
            EatWhitespace(stream);

            ParsingState state = ParsingState.ExpectingMore;

            while (state == ParsingState.ExpectingMore)
            {
                // parse the choice (same as parse text with esacape)
                // parse attributes if there are any
                Choice ch = ParseChoice(stream, ref state);
                // -1 is the place holder for now. will be set to an actual number
                // or to the size of list
                ch.NextNode = -1;
                descision.Choices.Add(ch);

                // at this point either the parsing is complete
                // or there is an arrow pointing to a sub branch or a branch name

                // Parseing.Expecting more implies that the arrow maybe still be here
                // Some branches have multiple "nexts" where the next either points to the same node
                // or to two different ones within the same branching pattern.
                //  It's the addition of the nodes that's wrong
                if (ParseArrow(stream))
                {
                    // whitespace
                    EatWhitespace(stream);
                    // either it's a branch
                    if (stream.PeekChar() == '{')
                    {
                        AssertChar(stream, '{');
                        // parse the subbranch if there is one
                        // parse the branch name is there is one, and we didn't parse a sub branch
                        // add the subbranch to the next list if there is none set their "next" to -1
                        BrigitGraph subGraph = ParseBrigitGraph(stream);

                        ll.AddBranch(root, subGraph);
                        ch.NextNode = root.Next.Count - 1;
                    }
                    // or a branch name
                    else
                    {
                        string     BranchName = ParseOnlyTextNoEscape(stream);
                        OpenChoice openCh     = new OpenChoice(root, ch);
                        branchEndings.Add(BranchName, openCh);
                    }

                    // this means it has reach the end
                    if (stream.PeekChar() == '}')
                    {
                        state = ParsingState.Complete;
                        stream.NextChar();
                    }
                }
            }

            // any next nodes in descision that are -1 should be set
            // to the count of the list
            foreach (Choice c in descision.Choices)
            {
                if (c.NextNode == -1)
                {
                    c.NextNode = root.Next.Count;
                }
            }

            return(ll);
        }
예제 #18
0
        // public for testing purpose
        // this chooses what is parsed next, IE a branch, a dialog or descision
        public BrigitGraph ParseBrigitGraph(TomeStream stream)
        {
            BrigitGraph ll = new BrigitGraph();

            while (!(stream.Complete() || stream.PeekChar() == '}'))
            {
                // getting rid of some beginning whitespace
                EatWhitespace(stream);

                // the real parsing starts here
                // can't use switch need to use if elses
                char c = stream.PeekChar();
                if (Char.IsLetterOrDigit(c))
                {
                    // start parsing as a dialog
                    // this one is simple. parse the dialog. then add
                    // it to the list
                    Node n = ParseDialog(stream);

                    // for the new AddInBetween function
                    // this will only work for whatever comes next. This isn't very good
                    // if there's multiple branches to place
                    // TODO make this functionality work better with dummy tail in the subgraphs
                    foreach (KeyValuePair <string, OpenChoice> kvp in BranchesToPlace)
                    {
                        if (kvp.Value.TailNode == null)
                        {
                            kvp.Value.TailNode = n;
                            break;
                        }
                    }

                    ll.AddNode(n);
                }
                else if (c == '@')
                {
                    // naybe use a struct here?
                    Dictionary <string, OpenChoice> branchesToNode = new Dictionary <string, OpenChoice>();
                    // TODO change signature of ParseDescision to (obj stream, Dict brachesToNode)
                    BrigitGraph subGraph = ParseDescision(stream, branchesToNode);

                    foreach (KeyValuePair <string, OpenChoice> kvp in branchesToNode)
                    {
                        BranchesToPlace.Add(kvp.Key, kvp.Value);
                    }

                    // adding the dictionary entries to this
                    ll.AddGraph(subGraph);
                }
                else if (c == '{')
                {
                    // this is a branch selector
                    // we can just pass in the big dictionary
                    BrigitGraph subGraph = ParseBranchSelector(BranchesToPlace);
                    ll.AddGraph(subGraph);
                }
                else if (c == '>')
                {
                    // this is a branch name
                    // TODO change signature of ParseBranch to ParseBranch(stream, ref string branchName)
                    // TODO i'll probably need a wrapper for the Node and Ch entires
                    string      branchName = String.Empty;
                    BrigitGraph subGraph   = ParseBranch(stream, ref branchName);
                    if (BranchesToPlace.ContainsKey(branchName))
                    {
                        OpenChoice openCh = BranchesToPlace[branchName];
                        Node       n      = openCh.EnclosingNode;
                        Choice     ch     = openCh.BranchingChoice;

                        ll.AddInBetween(n, new List <Node>()
                        {
                            openCh.TailNode
                        }, subGraph);
                        ch.NextNode = n.Next.Count - 1;
                    }
                    else
                    {
                        String msg = String.Format("{0} not found in dictionary, could the name be mispelled?",
                                                   branchName);
                        throw new Exception(msg);
                    }
                }
                else
                {
                    // panic here
                    String msg = String.Format("Expected beginning of character name, branch or chioce but found {0} at {1}",
                                               stream.PeekChar(), stream.Position);
                    throw new Exception(msg);
                }

                EatWhitespace(stream);
            }

            if (!stream.Complete())
            {
                AssertChar(stream, '}');
            }

            return(ll);
        }
예제 #19
0
 public Conversation(BrigitGraph ll)
 {
     ConversationName = "thingy";
     this.ll          = ll;
     curr             = ll.Head;
 }