// 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); }