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); }
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); }
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); }
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); }
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); }
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)); }
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); }
// 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(); }
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); }
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); }
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); }
public Conversation() { ConversationName = string.Empty; ll = new BrigitGraph(); }
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); }
// 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); }
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); }
// 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); }
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); }
// 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); }
public Conversation(BrigitGraph ll) { ConversationName = "thingy"; this.ll = ll; curr = ll.Head; }