Jan. 20th marked the end and the beginning of an era, in more ways than one. On the world stage, Mr. Trump has entered office as the 45th POTUS, ending 8 years of Mr. Obama. Whatever you think of either man's politics, Mr. Obama presided with dignity and respect, and delivered his speeches with gravitas and eloquence. Nobody knows exactly what Mr. Trump will do, but we all know it will be done in an outrageous and probably offensive manner.
On my own small personal stage, Jan. 20th marked my last full time day as an English teacher. Starting Monday, I will be devoting my mornings to programming, research on game design and development, and job hunting for positions in the game industry.
...
public float SimulateMoodChange(NeedType nt, float potency) { float curmood = CurrentMood; float deltamood = 0; //float curmood = CurrentMood- nee.MoodResponse((int)nt)[potency]; float nttwo = 0; switch (nt) { case NeedType.Food: nttwo = nee.Hunger; break; case NeedType.Hydration: nttwo = nee.Thirst; break; case NeedType.Rest: nttwo = nee.Tiredness; break; case NeedType.Sex: nttwo = nee.Lust; break; case NeedType.Comfort: nttwo = nee.Comfort; break; case NeedType.Cleanliness: nttwo = nee.Cleanliness; break; case NeedType.Shelter: nttwo = nee.Shelter; break; case NeedType.Intimacy: nttwo = nee.Intimacy; break; case NeedType.Fun: nttwo = nee.Fun; break; case NeedType.Safety: nttwo = nee.Safety; break; case NeedType.Respect: nttwo = nee.Respect; break; case NeedType.MAX: break; default: break; } Debug.Log("Simulate mood change" + " need is " + nt); //Debug.Log("potency ") for (int i = 0; i < nee.NumberOfNeeds; i++) { ResponseCurveFloat mr = nee.MoodResponse(i); switch ((NeedType)i) { case NeedType.Food: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Hunger], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Hydration: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Thirst], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Rest: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Tiredness], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Sex: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Lust], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Comfort: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Comfort], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Cleanliness: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Cleanliness], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Shelter: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Shelter], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Intimacy: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Intimacy], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Fun: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Fun], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Safety: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Safety], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.Respect: if ((NeedType)i != nt) { deltamood = Mathf.Clamp(deltamood + mr[nee.Respect], -100, 100); } else { deltamood = Mathf.Clamp(deltamood + nee.MoodResponse((int)nt)[nttwo - (100f - potency)], -100, 100); } break; case NeedType.MAX: break; default: break; } } //float delta = nee.MoodResponse((int)nt)[nttwo - (100f-potency)]; float delta = deltamood - CurrentMood; //curmood = Mathf.Clamp(curmood + nee.MoodResponse((int)nt)[nttwo - (potency*nttwo)], -100, 100); return delta; }
Following the lecture notes to Richard Evans's GDC talk about The Sims 3, I am converting the delta value into a probability. Since his equation is a little bit mystical to me still,
void EvaluateMood() { float runningTotal = 0f; float needlevel = 0; List < NeedProb > needProbabilities = new List < NeedProb > (); foreach (GameObject go in adObjects) { switch (go.GetComponent < advertisingobject > ().MyNeedType) { case NeedType.Food: needlevel = myNeeds.Hunger; break; case NeedType.Hydration: needlevel = myNeeds.Thirst; break; case NeedType.Rest: needlevel = myNeeds.Tiredness; break; case NeedType.Sex: needlevel = myNeeds.Lust; break; case NeedType.Comfort: needlevel = myNeeds.Comfort; break; case NeedType.Cleanliness: needlevel = myNeeds.Cleanliness; break; case NeedType.Shelter: needlevel = myNeeds.Shelter; break; case NeedType.Intimacy: needlevel = myNeeds.Intimacy; break; case NeedType.Fun: needlevel = myNeeds.Fun; break; case NeedType.Safety: needlevel = myNeeds.Safety; break; case NeedType.Respect: needlevel = myNeeds.Respect; break; case NeedType.MAX: break; default: break; } needProbabilities.Add(new NeedProb(go.GetComponent < advertisingobject > ().MyNeedType, myMood.SimulateMoodChange(go.GetComponent < advertisingobject >().MyNeedType, go.GetComponent < advertisingobject > ().MyMeetNeed.potency))); runningTotal += myMood.SimulateMoodChange(go.GetComponent < advertisingobject > ().MyNeedType, go.GetComponent < advertisingobject > ().MyMeetNeed.potency); } for (int i = 0; i < needProbabilities.Count; i++) { Debug.Log(needProbabilities[i].nt + " probability is " + needProbabilities[i].probabilty); } for (int i = 0; i < needProbabilities.Count; i++) { if (runningTotal > 0) { needProbabilities[i].probabilty = needProbabilities[i].probabilty / runningTotal; } } for (int i = 0; i < needProbabilities.Count; i++) { Debug.Log(needProbabilities[i].nt + " normalized probability is " + needProbabilities[i].probabilty); } }
I've also set up another function that just evaluates the needs, and ran into the following problem. If I want to implement one of the common methods of picking an option, I create a simple array of length 100, and assign a NeedType to each, I need a way of rounding the floating probabilities to integers such that they will add up to 100. For example, if Food is 45.65934% probable, Hydration is 23.763%, etc. I need a way to round those fractional values in such a way that they get assigned to appropriate needs.
Luckily for me, one of America's Founding Fathers, Alexander Hamilton, had already figured out a way to deal with this problem. Basically, you take the integer part of each percentage and sum them. You find the difference between the sum and the target number, then you take integers that had the largest remainders and add 1 to them until there no places available.
How great is it that this method was developed by a man who was the first Secretary of Treasury of the US, and, given his desire for a strong executive branch and military, and support for industrialization, would most likely have had the support of our current POTUS.
int integalPart = 0; List < NeedProb > remainder = new List < NeedProb > (); int extra = 0; for (int i = 0; i < needProbabilities.Count; i++) { integalPart += (int)(needProbabilities[i].probabilty * 100); remainder.Add(new NeedProb(needProbabilities[i].nt,(needProbabilities[i].probabilty * 100)- (int)(needProbabilities[i].probabilty * 100))); } //for (int i = 0; i < needProbabilities.Count; i++) //{ // Debug.Log(needProbabilities[i].nt + " " + needProbabilities[i].probabilty); //} for (int i = 0; i < needProbabilities.Count; i++) { needProbabilities[i].probabilty = (int)(needProbabilities[i].probabilty * 100); } //needProbabilities.Sort(); //for (int i = 0; i < needProbabilities.Count; i++) //{ // Debug.Log(needProbabilities[i].nt + " at time " + Time.time + " is " + needProbabilities[i].probabilty); //} extra = 100 - integalPart; remainder.Sort(); remainder.Reverse(); for (int i = 0; i < extra; i++) { needProbabilities[(int)remainder[i].nt].probabilty++; } int cur = 0; int cur2 = 0; for (int i = 0; i < needProbabilities.Count; i++) { cur = cur2; for (int j = cur; j < cur + (int)(needProbabilities[i].probabilty); j++) { prob[j] = needProbabilities[i].nt; cur2++; } }
So anyway, using these probabilities, I can generate a random number from between 0 - 99, and access my probability array, prob, to pick a need to satisfy. The next step is to start moving towards it using my Steering Behaviors.
Cheers,
No comments:
Post a Comment