servo/motives.ipynb

207 lines
6.6 KiB
Text
Raw Normal View History

{
"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": []
},
2020-10-28 20:57:06 -04:00
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
2020-10-28 20:58:13 -04:00
"static Random rng = new Random();\n",
"static int MaxMood = 600;\n",
"static int MaxMotive = 100;\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",
2020-10-28 20:42:47 -04:00
"\n",
" // New motive equals the current motive plus the input\n",
" var newMotive = curMotive + input;\n",
2020-10-28 20:42:47 -04:00
"\n",
" // New mood equals the new motive plus the current mood\n",
" var newMood = newMotive + curMood;\n",
2020-10-28 20:57:06 -04:00
"\n",
" // Changed motive is the new motive with the limit\n",
2020-10-28 20:58:13 -04:00
" 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",
2020-10-28 20:58:13 -04:00
" && 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",
"\n",
" public void ChangeEnergy(int input)\n",
" {\n",
" Energy = CalcuateMotiveChange(Energy, input);\n",
" }\n",
"\n",
" public void ChangeEnvironment(int input)\n",
" {\n",
" Environment = CalcuateMotiveChange(Environment, input);\n",
" }\n",
"}"
],
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"void PrintMotives(Motives motives)\n",
"{\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}\");\n",
"}"
],
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
2020-10-28 20:58:13 -04:00
"var motives = new Motives(hunger: rng.Next(MaxMotive), \n",
"bladder: rng.Next(MaxMotive), fun: rng.Next(MaxMotive), \n",
"energy: rng.Next(MaxMotive), environment: rng.Next(MaxMotive), \n",
2020-10-28 20:58:13 -04:00
"social: rng.Next(MaxMotive));\n",
"\n",
"PrintMotives(motives);"
],
2020-10-28 20:42:47 -04:00
"outputs": []
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"motives.ChangeHunger(rng.Next(motives.Hunger, MaxMotive));\n",
"motives.ChangeFun(rng.Next(motives.Fun, MaxMotive));\n",
"motives.ChangeSocial(rng.Next(motives.Social, MaxMotive));\n",
"motives.ChangeBladder(rng.Next(motives.Bladder, MaxMotive));\n",
"motives.ChangeEnergy(rng.Next(motives.Energy, MaxMotive));\n",
"motives.ChangeEnvironment(rng.Next(motives.Environment, MaxMotive));\n",
"\n",
"PrintMotives(motives);"
],
2020-10-28 20:42:47 -04:00
"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
}