Пример #1
0
    // Recursively generate inputs
    static bool GenerateInputs(Term startTerm, Rule parentRule, int depth, Area currentArea, List <Area> accessibleAreas, List <Item> itemsInTheScene)
    {
        List <Item> matchingItems = PuzzleManager.Instance.FindDBItemsFor(startTerm, accessibleAreas, itemsInTheScene);

        //Check if term of this type exists in DB before continuing
        if (matchingItems.Count == 0)
        {
            if (!PuzzleManager.Instance.HasItemOfType(startTerm, accessibleAreas, itemsInTheScene))  // Previously: (!ItemDatabase.HasItemOfType(startTerm, accessibleAreas, itemsInTheScene))
            {
                Debug.Log("GRAMMAR ERROR: Couldn't find accessible item of type: " + startTerm.name);
                return(false);
            }
        }
        else if (startTerm.dbItem == null)
        {
            // Pick a random item to fit the term
            startTerm.dbItem = matchingItems[Random.Range(0, matchingItems.Count)];
            if (itemsInTheScene.Contains(startTerm.dbItem))
            {
                return(true);
            }
        }

        // Find rule with startTerm as output, output could be super-type of startTerm
        List <Rule> possibleRules = new List <Rule>();

        foreach (Rule rule in PuzzleManager.Instance.GetAllRules())
        {       //Previously: foreach (Rule rule in RuleDatabase.GetAllObjects()) {
            //Debug.Log("Main Output: " + rule.outputs[0].name + " vs Start Term: " + startTerm.name + " Main Output? " + rule.MainOutputIs(startTerm));
            if (rule.MainOutputIs(startTerm))
            {
                if (debugMode && startTerm.dbItem != null)
                {
                    Debug.Log("Found matching rule " + rule.outputs[0].name +
                              " with output dbItem: " + startTerm.dbItem.name + " at depth: " + depth);
                    //PuzzleTree.Instance.WriteTree(rule.ToString(), depth, false);
                }
                else if (debugMode)
                {
                    Debug.Log("Found matching rule with output: " + startTerm.name);
                    //PuzzleTree.Instance.WriteTree(rule.ToString(), depth, false);
                }
                possibleRules.Add(rule);
            }
        }

        if (debugMode)
        {
            Debug.Log("number of possible rules: " + possibleRules.Count);
        }

        // Pick a rule
        if (possibleRules.Count > 0 && depth < currentArea.maxDepth)
        {
            string playerPrefKey  = currentArea.name + depth;
            string testPlayerPref = "Player pref original " + PlayerPrefs.GetString(playerPrefKey);
            Rule   chosenRule     = possibleRules[Random.Range(0, possibleRules.Count)];
            if (possibleRules.Count > 1 && PlayerPrefs.HasKey(playerPrefKey))
            {
                while (chosenRule.ruleNumber == PlayerPrefs.GetString(playerPrefKey))
                {
                    chosenRule = possibleRules[Random.Range(0, possibleRules.Count)];
                }
                Debug.Log("Choosing a different rule. ");
            }
            PlayerPrefs.SetString(playerPrefKey, chosenRule.ruleNumber); //Key: area name
            Debug.Log(testPlayerPref + " turns into " + PlayerPrefs.GetString(playerPrefKey));
            _puzzleString += chosenRule.ruleNumber + "_";
            chosenRule.outputs[0].dbItem = startTerm.dbItem;
            chosenRule.parent            = parentRule;
            parentRule.AddChildRule(chosenRule);
            for (int i = 1; i < chosenRule.outputs.Count; i++)
            {
                bool found = false;
                for (int j = 0; j < chosenRule.inputs.Count; j++)
                {
                    if (chosenRule.inputs[j].name == chosenRule.outputs[i].name)
                    {
                        found = true;
                    }
                }
                if (!found)
                {
                    //List<DBItem> sideEffectItem = ItemDatabase.FindDBItemsFor(chosenRule.outputs[i], accessibleAreas, itemsInTheScene);
                    //chosenRule.outputs[i].dbItem = sideEffectItem[Random.Range(0, sideEffectItem.Count)];
                }
            }
            bool result = true;
            for (int i = 0; i < chosenRule.inputs.Count; i++)
            {
                //Check if input is same type as the start term, otherwise make the input as specific as start term
                if (chosenRule.outputs[0].name == chosenRule.inputs[i].name)
                {
                    if (startTerm.dbItem != null)
                    {
                        chosenRule.inputs[i].dbItem = startTerm.dbItem;
                    }
                    else if (startTerm.name != chosenRule.inputs[i].name)
                    {
                        if (startTerm.GetSuperTypes().Contains(chosenRule.inputs[i].name))
                        {
                            chosenRule.inputs[i].name = startTerm.name;
                        }
                    }
                }
                result = GenerateInputs(chosenRule.inputs[i], chosenRule, depth + 1, currentArea, accessibleAreas, itemsInTheScene);
                if (chosenRule.outputs[0].name == chosenRule.inputs[i].name)
                {
                    startTerm.dbItem = chosenRule.inputs[i].dbItem;
                }
            }
            return(result);
        }

        if (debugMode)
        {
            Debug.Log("No suitable rule found for: " + startTerm.name + " at depth " + depth);
        }
        //Find DB item for input & add to spawn list
        if (startTerm.dbItem == null && startTerm.name != "Player")
        {
            Debug.Log("GRAMMAR ERROR: No terminal or non-terminal match for term: " + startTerm.name);
            return(false);
        }
        Spawn(startTerm.dbItem, parentRule, currentArea);
        if (debugMode)
        {
            Debug.Log("DB item added to spawn list: " + startTerm.dbItem.name);
        }
        return(true);
    }