private static string _points = "[2-1](3-1)(1-1)(2-2)[2-2](3-2)(1-2)(2-3)[2-3](3-3)(1-3)(2-4)[2-4](3-4)[3-4](4-4)[4-4](5-4)(3-4)(4-5)(4-3)[4-3](5-3)(3-3)(4-4)(4-2)[4-2](5-2)(3-2)(4-3)(4-1)(2-4)(3-5)(3-3)(1-4)(2-5)[2-5](2-3)(2-2)(2-1)(2-0)"; private List GetNodeConvention(string input) { // Trasforma la stringa in >2-1|3-1|1-1|2-2>|>2-2 var t = input.Replace("-", "."); t = t.Replace(")[", ">)["); t = t.Replace("]", "").Replace(")", "").Replace("[", "|>").Replace("(", "|"); t = t.Substring(1); // per togliere la prima barra return t.Split('|').ToList(); } /// /// Una volta spezzata la string di input in tanti piccoli blocchi il carattere > nel blocco indica: /// 1] se all'inizio che il nodo è un nodo "successivo" (ho fatto un passo nel labirinto) /// 2] se alla fine della stringa (che il nodo successivo sarà preso) /// Abbiamo quindi la sequenza |1-1|2-2>|>2-2 dove il nodo 2-2 che rappresenta il passo successivo viene scritto 2 volte /// Nella lista outputList ci sono tutti i nodi che rappresentano i passi fatti nel labirinto. /// Ogni nodo ha la lista dei tentativi che ha fatto (max 4) /// /// /// protected void cmdProlog_Click(object sender, EventArgs e) { List inputList = GetNodeConvention(txtInput.Text); if (inputList.Count < 2) { return; } List outputList = new List(); foreach(var nextStep in inputList) { if (IsNextNode(nextStep) == true) { outputList.Add(new Node(nextStep)); } else { AddTentativeToNode(outputList, new Node(nextStep)); } } txtOutput.Text = GetDiagram(outputList); } private string GetDiagram(List list) { // Ogni riga del grafico // a1 -> b3; //string prolog = //@"X = dot(""digraph G { // start -> {0} ; // {2} // {1} -> end; // start [shape=Mdiamond]; // end [shape=Msquare]; //}"")."; string arcs = ""; foreach (var node in list) { foreach (var step in node.GetSteps()) { if (step.GetState() == NodeState.step) { arcs += CreateEdge(node.GetName(), step.GetName()) ; } } } var firstNode = list.First().GetName(); var lastNode = list.Last().GetName(); var res = @"X = dot(""digraph G { start -> "+ firstNode + @"; "+ arcs + @" "+ lastNode + @" -> end; start [shape=Mdiamond]; end [shape=Msquare]; }"")."; //var res = string.Format(prolog, firstNode, lastNode, arcs); return res; } private void AddTentativeToNode(List outputList, Node node) { if (outputList.Count > 0) { for (int i = 1; i <= outputList.Count; i++) { var lastNode = outputList[outputList.Count - i]; if (lastNode.CanAddMove() == true) { lastNode.AddMove(node); break; } } } } private static string CreateEdge(string nodeA, string nodeB) { return string.Format("{0} -> {1};\r\n", nodeA, nodeB); } private static bool IsNextNode(string c) { return (c[0] == '>'); } private enum NodeState { tentative, step } private class Node { public string _name; private NodeState _state; private List _moves = new List(); public Node(string name) { if (name[0] == '>') { this._name = name.Substring(1); this._state = NodeState.step; } else if (name[name.Length - 1] == '>') { this._name = name.Substring(0, name.Length - 1); this._state = NodeState.step; } else { this._name = name; this._state = NodeState.tentative; } } public string GetName() { return this._name; } public List GetSteps() { return this._moves; } public NodeState GetState() { return this._state; } public bool AddMove(Node nextNode) { _moves.Add(nextNode); if (_moves.Count < 4) { return true; } return false; } public bool CanAddMove() { if (_moves.Count < 4) { return true; } return false; } }