public Need(string name, Func <ProcessState> task, Utility u, float min, float max, float scale = 1) { state = new StateMachine <State, Trigger>(State.Fufilled); InternalNeedMethod = task; state.Configure(State.Fufilled) .Permit(Trigger.OnMinValueReached, State.Unfufilled); state.Configure(State.Unfufilled) .OnEntry(t => ActionPriorityList.Add(InternalNeedMethod)) .Permit(Trigger.OnMaxValueReached, State.Fufilled); _minValue = min; _maxValue = max; _scale = scale; utility = u; Value = max; Name = name; Priority = 0; fuzzyengine = new FuzzyEngine(); LinguisticVariable priority = new LinguisticVariable("Priority"); priority.MembershipFunctionCollection.Add(new MembershipFunction("High", 0, 25, 25, 50)); priority.MembershipFunctionCollection.Add(new MembershipFunction("Low", 50, 75, 75, 100)); fuzzyengine.LinguisticVariableCollection.Add(priority); fuzzyengine.Consequent = "Priority"; }
//Basic update function will be fixed called rate at 60 per second but will decay the needs and fire registered //Need methods in the ActionPriorityList public void Update(bool fuzzy) { foreach (KeyValuePair <string, Need> need in AINeedsList) { need.Value.Update(1f); } Sort(); if (fuzzy) { //fire the action bound to the first need in our fuzzy sorted list ActionPriorityList.Fire(AINeedsList.First().Value); } else { ActionPriorityList.Fire(); } }
// Update is called once per frame void Update() { if (entity == null || hunger == null || stamina == null || thirst == null || hygiene == null) { entity = FindObjectOfType <Entity>(); hunger = FindObjectOfType <Canvas>().transform.FindChild("Hunger").GetComponent <Text>(); stamina = FindObjectOfType <Canvas>().transform.FindChild("Stamina").GetComponent <Text>(); thirst = FindObjectOfType <Canvas>().transform.FindChild("Thirst").GetComponent <Text>(); hygiene = FindObjectOfType <Canvas>().transform.FindChild("Hygiene").GetComponent <Text>(); score = FindObjectOfType <Canvas>().transform.FindChild("Score").GetComponent <Text>(); mode = FindObjectOfType <Canvas>().transform.FindChild("Mode").GetComponent <Text>(); } hunger.text = "Hunger: " + entity.hunger.Value; thirst.text = "Thirst: " + entity.thirst.Value; stamina.text = "Stamina: " + entity.stamina.Value; hygiene.text = "Hygiene: " + entity.hygine.Value; score.text = "Score: " + entity.score; if (entity.fuzzy) { mode.text = "Mode: Fuzzy"; } else { mode.text = "Mode: Finite State Machine"; } if (Input.GetKeyDown(KeyCode.Space)) { ActionPriorityList.Clear(); SceneManager.LoadScene("Main"); } if (Input.GetKeyDown(KeyCode.F)) { entity.fuzzy = !entity.fuzzy; } }
void Start() { score = 0; ai = new AI(); nodes = FindObjectsOfType <Node>().OrderBy(node => node.order).ToList <Node>(); fhunger = new LinguisticVariable("Hunger"); fstamina = new LinguisticVariable("Stamina"); fthirst = new LinguisticVariable("Thirst"); fhygine = new LinguisticVariable("Hygine"); bath = GameObject.Find("Bath").GetComponent <Utility>(); refrigerator = GameObject.Find("Refrigerator").GetComponent <Utility>(); bed = GameObject.Find("Bed").GetComponent <Utility>(); task = GameObject.Find("Task").GetComponent <Utility>(); hunger = new Need("Hunger", eat, refrigerator, 0f, 100f, 0.1f); stamina = new Need("Stamina", rest, bed, 0f, 100f, .2f); thirst = new Need("Thirst", drink, refrigerator, 0f, 100f, 0.02f); hygine = new Need("Hygine", shower, bath, 0f, 100f, 0.05f); //FuzzyLogicEngine setup goes here fhunger.MembershipFunctionCollection.Add(new MembershipFunction("Hungry", 0, 0, 20, 40)); fhunger.MembershipFunctionCollection.Add(new MembershipFunction("Neutral", 30, 50, 50, 70)); fhunger.MembershipFunctionCollection.Add(new MembershipFunction("Full", 50, 80, 100, 100)); fstamina.MembershipFunctionCollection.Add(new MembershipFunction("Tired", 0, 0, 20, 40)); fstamina.MembershipFunctionCollection.Add(new MembershipFunction("Neutral", 30, 50, 50, 70)); fstamina.MembershipFunctionCollection.Add(new MembershipFunction("Rested", 50, 80, 100, 100)); fthirst.MembershipFunctionCollection.Add(new MembershipFunction("Thirsty", 0, 0, 20, 40)); fthirst.MembershipFunctionCollection.Add(new MembershipFunction("Neutral", 30, 50, 50, 70)); fthirst.MembershipFunctionCollection.Add(new MembershipFunction("Full", 50, 80, 100, 100)); fhygine.MembershipFunctionCollection.Add(new MembershipFunction("Dirty", 0, 0, 20, 40)); fhygine.MembershipFunctionCollection.Add(new MembershipFunction("Neutral", 30, 50, 50, 70)); fhygine.MembershipFunctionCollection.Add(new MembershipFunction("Clean", 50, 80, 100, 100)); hunger.fuzzyengine.LinguisticVariableCollection.Add(fhunger); stamina.fuzzyengine.LinguisticVariableCollection.Add(fstamina); thirst.fuzzyengine.LinguisticVariableCollection.Add(fthirst); hygine.fuzzyengine.LinguisticVariableCollection.Add(fhygine); hunger.newRule(new FuzzyRule("IF (Hunger IS Hungry) OR (Hunger IS Neutral) THEN Priority IS High")); hunger.newRule(new FuzzyRule("IF (Hunger IS Full) THEN Priorty IS Low")); stamina.newRule(new FuzzyRule("IF (Stamina IS Tired) OR (Stamina IS Neutral) THEN Priority IS High")); stamina.newRule(new FuzzyRule("IF (Stamina IS Rested) THEN Priorty IS Low")); thirst.newRule(new FuzzyRule("IF (Thirst IS Thirsty) OR (Thirst IS Neutral) THEN Priority IS High")); thirst.newRule(new FuzzyRule("IF (Thirst IS Full) THEN Priorty IS Low")); hygine.newRule(new FuzzyRule("IF (Hygine IS Dirty) OR (Hygine IS Neutral) THEN Priority IS High")); hygine.newRule(new FuzzyRule("IF (Hygine IS Clean) THEN Priorty IS Low")); //register the Needs with our AI for need sorting and for need searching ai.registerNeed(hunger); ai.registerNeed(stamina); ai.registerNeed(thirst); ai.registerNeed(hygine); //register the default task for the entity with the ActionPriorityList ActionPriorityList.registerDefaultAction(Task); }