Exemple #1
0
    /// <summary>
    /// determines which nodes exist on the right hand side of the grammar but not on the left hand and ads them to the translation table
    /// </summary>
    /// <param name="rule"></param>
    /// <param name="nodeGraph"></param>
    /// <param name="translationTable"></param>
    private static void AddMissingNodes(NodeGrammar rule, ref NodeGraph nodeGraph, ref OrderedDictionary <int, int> translationTable)
    {
        if (rule.RightHand.NodeDict.Count == 0)
        {
            return;
        }
        // we use the first node as a reference point to offset the positions
        var rightHandPosition = rule.RightHand.NodeDict.First().Value.Pos;
        var graphPosition     = nodeGraph.NodeDict[translationTable.First().Value].Pos;

        // add all new nodes created by the rule and give them the proper index
        foreach (var rhNode in rule.RightHand.NodeDict)
        {
            // if the node exists on the right hand but no the left hand it's a missing node and we add it
            if (!rule.LeftHand.NodeDict.ContainsKey(rhNode.Key))
            {
                var newNode = new Node()
                {
                    Node_text = rhNode.Value.Node_text,
                    Value     = rhNode.Value.Value,
                    Pos       = graphPosition + rhNode.Value.Pos - rightHandPosition
                };

                var newIndex = nodeGraph.AddNode(newNode);
                translationTable.Add(rhNode.Key, newIndex);
            }
        }
    }
    private void SaveGrammar(int grammarIndex)
    {
        if (_grammars.Count < grammarIndex)
        {
            return;
        }

        _grammars[grammarIndex] = new NodeGrammar
        {
            Name      = _grammars[grammarIndex].Name,
            LeftHand  = _nodeEditorWindows[(int)HandSide.LEFT].Nodegraph,
            RightHand = _nodeEditorWindows[(int)HandSide.RIGHT].Nodegraph
        };
    }
Exemple #3
0
    /// <summary>
    /// returns true if the grammar rule <paramref name="rule"/> has a left hand side that is a subgraph of <paramref name="nodeGraph"/>,
    /// </summary>
    /// <param name="rule">the rule containing the subgraph to match against</param>
    /// <param name="nodeGraph">the supergraph</param>
    /// <param name="translationTable">the IDs of the subgraph as they corrolate to IDs on the supergraph</param>
    /// <returns></returns>
    private static bool IsGrammarApplicable(NodeGrammar rule, ref NodeGraph nodeGraph, out OrderedDictionary <int, int> translationTable, int seed)
    {
        translationTable = null;
        var subgraphDict    = rule.LeftHand.NodeDict;
        var firstSubgraphID = subgraphDict.Keys.Min();

        // we brute force check all the nodes in the super graph to see if we can start inserting the subgraph there

        foreach (var superGraphNode in ShuffleDictionary(nodeGraph.NodeDict, seed))
        {
            if (IsPlacementValid(new OrderedDictionary <int, int>(), firstSubgraphID, superGraphNode.Key, ref subgraphDict, nodeGraph.NodeDict, out OrderedDictionary <int, int> translation))
            {
                translationTable = translation;
                return(true);
            }
        }
        return(false);
    }
Exemple #4
0
    /// <summary>
    /// applies a single node graph translation where a matching precept from the left hand side, found in the graph <paramref name="nodeGraph"/> is applied according to the <paramref name="nodeGraph"/> e.g.  the tranlsation table has an entry [1,5] thus the node with ID 5 in <paramref name="nodeGraph"/> matches ID 1 in <paramref name="rule"/>.LeftHand and will thus be replace by the node linked to by ID 5 of <paramref name="rule"/>.RightHand
    /// </summary>
    /// <param name="rule"></param>
    /// <param name="nodeGraph"></param>
    /// <param name="translationTable"></param>
    private static void ApplyNodeRule(NodeGrammar rule, ref NodeGraph nodeGraph, ref OrderedDictionary <int, int> translationTable)
    {
        // nodes existing in the replacement but not in the translation table are added
        AddMissingNodes(rule, ref nodeGraph, ref translationTable);

        foreach (var translation in translationTable)
        {
            // the node that is to be transformed
            var node = nodeGraph.NodeDict[translation.Value];
            // the Key indicates the LeftHand node that matched with this one, we thus want the matching righthand to replace it
            if (rule.RightHand.NodeDict.TryGetValue(translation.Key, out Node replacementNode))
            {
                // * nodes won't have their values changed, only their connections are modified
                if (replacementNode.Node_text != "*")
                {
                    node.Node_text = replacementNode.Node_text;
                    node.Value     = replacementNode.Value;
                }
                List <int> newConnections = new List <int>();
                // maintain the connections this node had and translate them to the new IDs
                foreach (var connection in node.ConnectedNodes)
                {
                    if (!translationTable.Values.Contains(connection))
                    {
                        newConnections.Add(connection);
                    }
                }
                // add new connections as described in the grammar
                foreach (var connection in replacementNode.ConnectedNodes)
                {
                    if (translationTable.TryGetValue(connection, out int index))
                    {
                        newConnections.Add(index);
                    }
                }
                node.ConnectedNodes = newConnections;
            }
            else
            {
                // this node doesn't exist in the right hand thus is indicates a deletion
                nodeGraph.Delete(node);
            }
        }
    }
Exemple #5
0
    public void LoadMechanicGraph(int inputSeed = -1)
    {
        List <NodeGrammar> grammars = new List <NodeGrammar>();

        foreach (var grammar in _nodeGrammars)
        {
            grammars.AddRange(NodeGrammar.ImportGrammars(Application.streamingAssetsPath + "/Grammar/Node/" + grammar + ".json"));
        }

        // generate a simple left hand side for now
        var inputGraph = new NodeGraph();

        inputGraph.AddNode(new Node()
        {
            Node_text = "S"
        });

        var seed = _randomString ? UnityEngine.Random.Range(0, 1000) : _seed;

        if (inputSeed != -1)
        {
            seed = inputSeed;
        }

        var stringgrams = GrammarUtils.ImportGrammars(Application.streamingAssetsPath + "/Grammar/String/" + _stringGrammar + ".json");
        var inputString = GrammarUtils.ApplyGrammars(ref stringgrams, _inputString, seed);

        Debug.Log("mechanic generated with input string " + inputString);
        Debug.Log("Seed: " + seed);
        FindObjectOfType <SeedDisplay>()?.DisplaySeed(seed);
        _mechanicGraph = GrammarUtils.ApplyNodeGrammars(inputString, ref grammars, inputGraph, seed);
        AnalyseMechanicNodes();


        AdjustBalance();
        AnalyseMechanicNodes();
        ApplySignifiers();

        NodeBehaviour.Callbacks      = new Stack <NodeActivationCallBack>();
        NodeBehaviour.PlayerAttacks  = GetComponent <PlayerAttackControl>();
        NodeBehaviour.PlayerMovement = GetComponent <PlayerMovement>();
    }
 private void GrammarSaveAndLoad()
 {
     _exportName = EditorGUILayout.TextField("File Name : ", _exportName);
     EditorGUILayout.BeginHorizontal();
     if (GUILayout.Button("import"))
     {
         _grammars = NodeGrammar.ImportGrammars(_directory + _exportName + ".json");
         if (_grammars == default)
         {
             Reset();
         }
         LoadGrammar(_grammarSelectedIndex);
     }
     if (GUILayout.Button("export"))
     {
         SaveGrammar(_grammarSelectedIndex);
         StreamWriter writer     = new StreamWriter(_directory + _exportName + ".json");
         var          jsonString = SerializableNodeGrammars_Converter.ToJson(_grammars);
         writer.Write(jsonString);
         writer.Close();
         writer.Dispose();
     }
     EditorGUILayout.EndHorizontal();
 }