servo/motives.ipynb
Anthony Leland 373170f98e More change methods
- Merge LimitToRange() extension method into other static values
- Added social motive to printing of motive values
2020-10-28 21:09:46 -04:00

195 lines
No EOL
6.5 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Motive Engine\n",
"\n",
"![](images/v3_slide0094_image039.gif)\n",
"\n",
"From [Under the Hood of The Sims](https://users.cs.northwestern.edu/~forbus/c95-gd/lectures/The_Sims_Under_the_Hood_files/v3_document.htm)\n",
"\n",
"The Motive Engine is based on opposing weights. An object signals it's presence if the Sims' need is low. The need is the motive and that drives a Sims' decision. All games in the franchise are based on this dynamic at it's core. For example, if hunger is low then the fridge's presence is high and vice versa. The sum of all the Sims' needs is it's mood. A Sim will only choose the fridge if it increases it's overall mood. The sum of all the Sims' needs is it's mood. A Sim will only choose the fridge if it increases it's overall mood. The ML portion comes in deciding which has the priority."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"using System;\n",
"using System.Linq;"
],
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For this experiment, the current motives are randomized with a max of 10. If this were a game, the max would be 100 with a downward increment throughout the day."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"static Random rng = new Random();\n",
"static int MaxMood = 60;\n",
"static int MaxMotive = 10;\n",
"\n",
"static int LimitToRange(this int val, int min, int max)\n",
"{\n",
" if (val < min) { return min; }\n",
" if (val > max) { return max; }\n",
" return val;\n",
"}"
],
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"class Motives\n",
"{\n",
" public Motives(int hunger, int bladder, int fun, int energy, \n",
" int environment, int social)\n",
" {\n",
" Hunger = hunger;\n",
" Bladder = bladder;\n",
" Fun = fun;\n",
" Energy = energy;\n",
" Environment = environment;\n",
" Social = social;\n",
" }\n",
"\n",
" public int Hunger { get; set; }\n",
" public int Bladder { get; set; }\n",
" public int Fun { get; set; }\n",
" public int Energy { get; set; }\n",
" public int Environment { get; set; }\n",
" public int Social { get; set; }\n",
"\n",
" /// <summary>\n",
" /// The mood is the sum of all the motives.\n",
" /// It deteremines the best course of action.\n",
" /// </summary>\n",
" public int Mood\n",
" {\n",
" get\n",
" {\n",
" var curMood = new[] { Hunger, Bladder, Fun,\n",
" Social, Environment, Energy };\n",
"\n",
" return curMood.Sum();\n",
" }\n",
" }\n",
"\n",
" // In the game, this would increament gradually\n",
" // until it reaches it's max motive.\n",
" int CalcuateMotiveChange(int motive, int input)\n",
" {\n",
" var curMotive = motive;\n",
" var curMood = Mood;\n",
"\n",
" // New motive equals the current motive plus the input\n",
" var newMotive = curMotive + input;\n",
"\n",
" // New mood equals the new motive plus the current mood\n",
" var newMood = newMotive + curMood;\n",
"\n",
" // Changed motive is the new motive with the limit\n",
" var changedMotive = newMotive.LimitToRange(0, MaxMotive);\n",
"\n",
" // Does the new motive increase my current motive?\n",
" // Does the new motive increase my overall mood?\n",
" if (changedMotive >= curMotive && curMood <= newMood \n",
" && changedMotive <= MaxMotive && curMood <= MaxMood)\n",
" return changedMotive;\n",
" \n",
" // Fall back to the current movement\n",
" return curMotive;\n",
" }\n",
"\n",
" public void ChangeHunger(int input)\n",
" {\n",
" Hunger = CalcuateMotiveChange(Hunger, input);\n",
" }\n",
"\n",
" public void ChangeFun(int input)\n",
" {\n",
" Fun = CalcuateMotiveChange(Fun, input);\n",
" }\n",
"\n",
" public void ChangeBladder(int input)\n",
" {\n",
" Bladder = CalcuateMotiveChange(Bladder, input);\n",
" }\n",
"\n",
" public void ChangeSocial(int input)\n",
" {\n",
" Social = CalcuateMotiveChange(Social, input);\n",
" }\n",
"}"
],
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"// Max a motive can be is 10. With all motives combined, the\n",
"// the max can be about 60. In-game, this is always going down\n",
"// to whatever degree.\n",
"var motives = new Motives(hunger: rng.Next(MaxMotive), \n",
"bladder: rng.Next(MaxMotive), fun: rng.Next(MaxMotive), \n",
"energy: rng.Next(MaxMotive), environment: MaxMotive, \n",
"social: rng.Next(MaxMotive));\n",
"Console.WriteLine($\"Hunger: {motives.Hunger}{Environment.NewLine}\" +\n",
" $\"Fun: {motives.Fun}{Environment.NewLine}\" +\n",
" $\"Bladder: {motives.Bladder}{Environment.NewLine}\" +\n",
" $\"Social: {motives.Social}{Environment.NewLine}\" +\n",
" $\"Environment: {motives.Environment}\");\n",
"Console.WriteLine($\"Mood: {motives.Mood}\");"
],
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"motives.ChangeHunger(rng.Next(MaxMotive));\n",
"motives.ChangeFun(rng.Next(MaxMotive));\n",
"motives.ChangeSocial(rng.Next(MaxMotive));\n",
"motives.ChangeBladder(rng.Next(MaxMotive));\n",
"Console.WriteLine($\"New Hunger: {motives.Hunger}{Environment.NewLine}\" +\n",
" $\"New Fun: {motives.Fun}{Environment.NewLine}\" +\n",
" $\"New Bladder: {motives.Bladder}{Environment.NewLine}\" +\n",
" $\"New Social: {motives.Social}\");\n",
"Console.WriteLine($\"New Mood: {motives.Mood}\");"
],
"outputs": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}