diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..ae3ae41
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,22 @@
+name: .NET
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ dotnet: [ '3.1.200', '3.1.201' ]
+ os: [ubuntu-latest, windows-latest, macOS-latest]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: ${{ matrix.dotnet }}
+ - name: Install dependencies
+ run: dotnet restore source
+ - name: Build
+ run: dotnet build source -c Release --no-restore
diff --git a/.gitignore b/.gitignore
index dae8fd8..f102eac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
-# Created by https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives
-# Edit at https://www.toptal.com/developers/gitignore?templates=windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives
+# Created by https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives,visualstudio
+# Edit at https://www.toptal.com/developers/gitignore?templates=windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives,visualstudio
### Archives ###
# It's better to unpack these files and commit the raw source because
@@ -117,7 +117,361 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
-# End of https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives
+### VisualStudio ###
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*[.json, .xml, .info]
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# End of https://www.toptal.com/developers/gitignore/api/windows,visualstudiocode,microsoftoffice,libreoffice,jupyternotebooks,backup,archives,visualstudio
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
diff --git a/dataset/motives.csv b/dataset/motives.csv
deleted file mode 100644
index b4ab89a..0000000
--- a/dataset/motives.csv
+++ /dev/null
@@ -1,80 +0,0 @@
-Need,Motive,Mood
-1,-1
--56,56
--5,5,
-50,-50
-64,-64
--39,39
--24,24
--12,12
-39,-39
--25,25
--44,44
--61,61
-46,-46
--49,49
-53,-53
--32,32
-38,-38
-52,-52
-83,-83
-27,-27
--54,-54
--23,23
--68,68
-58,-58
-22,-22
--46,46
-1,-1
--26,26
-37,-35
-17,-17
--34,34
--1,1
--16,16
--13,13
--71,71
-55,-55
-59,-59
--52,52
--76,76
--33,33
--37,37
--50,50
--65,65
-74,-74
-76,76
--51,51
--42,42
-80,-80
--59,59
-100,-100
-96,-96
-37,-37
--100,100
--55,55
-4,-4
-65,-65
-63,-63
--48,48
--18,18
--75,75
-43,-43
-51,-51
-30,30
-33,-33
--81,81
--30,30
-29,-29
-28,-28
-79,-79
-61,-61
--40,40
-91,-91
-41,-41
-20,-20
--98,98
--93,93
-68,-68
-35,-35
--82,82
\ No newline at end of file
diff --git a/motives.ipynb b/notebooks/motives.ipynb
similarity index 73%
rename from motives.ipynb
rename to notebooks/motives.ipynb
index 54cdb4d..4be2bad 100644
--- a/motives.ipynb
+++ b/notebooks/motives.ipynb
@@ -6,7 +6,7 @@
"source": [
"# Motive Engine\n",
"\n",
- "\n",
+ "\n",
"\n",
"The Motive Engine is based on opposing weights. An object signals it's presence if the Sim's 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. A Sim's mood is the sum of the current state of their motives. They will only choose the fridge if it increases it's overall mood. The ML portion comes in deciding which has the priority.\n",
"\n",
@@ -28,14 +28,17 @@
"execution_count": 1,
"metadata": {},
"source": [
- "static Random rng = new Random();\n",
- "static int MaxMood = 600;\n",
- "static int MaxMotive = 100;\n",
+ "const int NAX_MOOD = 600;\n",
+ "const int MAX_MOTIVE = 100;\n",
"\n",
- "static int LimitToRange(this int val, int min, int max)\n",
+ "static int MaxLimit(this int val, int max)\n",
"{\n",
- " if (val < min) { return min; }\n",
- " if (val > max) { return max; }\n",
+ " if (max < 0)\n",
+ " throw new ArgumentOutOfRangeException();\n",
+ "\n",
+ " if (val >= max)\n",
+ " return max;\n",
+ "\n",
" return val;\n",
"}"
],
@@ -95,12 +98,12 @@
" var newMood = newMotive + curMood;\n",
"\n",
" // Changed motive is the new motive with the limit\n",
- " var changedMotive = newMotive.LimitToRange(0, MaxMotive);\n",
+ " var changedMotive = newMotive.MaxLimit(MAX_MOTIVE);\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",
+ " if (changedMotive >= curMotive && curMood <= NAX_MOOD \n",
+ " && changedMotive <= MAX_MOTIVE && curMood <= NAX_MOOD)\n",
" return changedMotive;\n",
" \n",
" // Fall back to the current movement\n",
@@ -162,64 +165,34 @@
"execution_count": 1,
"metadata": {},
"source": [
- "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",
- "social: rng.Next(MaxMotive));\n",
+ "// Run this first\n",
+ "var rng = new Random();\n",
+ "var motives = new Motives(hunger: rng.Next(MAX_MOTIVE), \n",
+ "bladder: rng.Next(MAX_MOTIVE), fun: rng.Next(MAX_MOTIVE), \n",
+ "energy: rng.Next(MAX_MOTIVE), environment: rng.Next(MAX_MOTIVE), \n",
+ "social: rng.Next(MAX_MOTIVE));\n",
"\n",
"PrintMotives(motives);"
],
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": "Hunger: 76\r\nFun: 11\r\nBladder: 43\r\nSocial: 54\r\nEnvironment: 19\r\n"
- },
- "execution_count": 1,
- "metadata": {}
- },
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": "Mood: 282\r\n"
- },
- "execution_count": 1,
- "metadata": {}
- }
- ]
+ "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",
+ "// Run this next\n",
+ "var newRng = new Random();\n",
+ "motives.ChangeHunger(newRng.Next(motives.Hunger, MAX_MOTIVE));\n",
+ "motives.ChangeFun(newRng.Next(motives.Fun, MAX_MOTIVE));\n",
+ "motives.ChangeSocial(newRng.Next(motives.Social, MAX_MOTIVE));\n",
+ "motives.ChangeBladder(newRng.Next(motives.Bladder, MAX_MOTIVE));\n",
+ "motives.ChangeEnergy(newRng.Next(motives.Energy, MAX_MOTIVE));\n",
+ "motives.ChangeEnvironment(newRng.Next(motives.Environment, MAX_MOTIVE));\n",
"\n",
"PrintMotives(motives);"
],
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": "Hunger: 100\r\nFun: 42\r\nBladder: 92\r\nSocial: 100\r\nEnvironment: 53\r\n"
- },
- "execution_count": 1,
- "metadata": {}
- },
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": "Mood: 487\r\n"
- },
- "execution_count": 1,
- "metadata": {}
- }
- ]
+ "outputs": []
}
],
"metadata": {
diff --git a/source/.editorconfig b/source/.editorconfig
new file mode 100644
index 0000000..b85d72c
--- /dev/null
+++ b/source/.editorconfig
@@ -0,0 +1,153 @@
+# Default settings:
+# A newline ending every file
+# Use 4 spaces as indentation
+[*]
+charset = utf-8
+end_of_line = crlf
+indent_style = space
+indent_size = 4
+insert_final_newline = false
+trim_trailing_whitespace = true
+
+# VB and C# files
+[*.{vb,cs}]
+# avoid this. unless absolutely necessary
+dotnet_style_qualification_for_field = false : suggestion
+dotnet_style_qualification_for_property = false : suggestion
+dotnet_style_qualification_for_method = false : suggestion
+dotnet_style_qualification_for_event = false : suggestion
+
+# use language keywords instead of BCL types
+dotnet_style_predefined_type_for_locals_parameters_members = true : suggestion
+dotnet_style_predefined_type_for_member_access = true : suggestion
+
+# Use camel_case for or internal constant fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
+
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+
+# Comment this group and uncomment out the next group if you don't want _ prefixed fields.
+
+# protected fields should be kPascalCase
+dotnet_naming_rule.kPascalCase_for_protected_fields.severity = suggestion
+dotnet_naming_rule.kPascalCase_for_protected_fields.symbols = protected_internal_fields
+dotnet_naming_rule.kPascalCase_for_protected_fields.style = sims3_style
+
+dotnet_naming_symbols.protected_internal_fields.applicable_kinds = field
+dotnet_naming_symbols.protected_internal_fields.applicable_accessibilities = protected_internal
+
+dotnet_naming_style.sims3_style.required_prefix = k
+dotnet_naming_style.sims3_style.capitalization = pascal_case
+
+# private static fields should be sPascalCase
+dotnet_naming_rule.sPascalCase_for_static_fields.severity = suggestion
+dotnet_naming_rule.sPascalCase_for_static_fields.symbols = static_internal_fields
+dotnet_naming_rule.sPascalCase_for_static_fields.style = sims3_static
+
+dotnet_naming_symbols.static_internal_fields.required_modifiers = static
+dotnet_naming_symbols.static_internal_fields.applicable_kinds = field
+dotnet_naming_symbols.static_internal_fields.applicable_accessibilities = private
+
+dotnet_naming_style.sims3_static.required_prefix = s
+dotnet_naming_style.sims3_static.capitalization = pascal_case
+
+# all other fields should be _camelCase
+dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
+dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
+dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
+
+dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
+dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
+
+dotnet_naming_style.camel_case_underscore_style.required_prefix = _
+dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
+
+# Public members must be capitalized
+dotnet_naming_rule.public_members_must_be_capitalized.symbols = public_symbols
+dotnet_naming_symbols.public_symbols.applicable_kinds = property,method,field,event,delegate
+dotnet_naming_symbols.public_symbols.applicable_accessibilities = public
+
+dotnet_naming_rule.public_members_must_be_capitalized.style = first_word_upper_case_style
+dotnet_naming_style.first_word_upper_case_style.capitalization = first_word_upper
+
+dotnet_naming_rule.public_members_must_be_capitalized.severity = suggestion
+
+# Code style defaults
+dotnet_sort_system_directives_first = true
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+# Expression-level preferences
+dotnet_style_object_initializer = true : suggestion
+dotnet_style_collection_initializer = true : suggestion
+dotnet_style_explicit_tuple_names = true : suggestion
+dotnet_style_coalesce_expression = true : suggestion
+dotnet_style_null_propagation = true : suggestion
+
+[*.cs]
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = one_less_than_current
+
+# only use var when it's obvious what the variable type is
+csharp_style_var_for_built_in_types = true : none
+csharp_style_var_when_type_is_apparent = true : none
+csharp_style_var_elsewhere = true : suggestion
+
+# Code style defaults
+dotnet_sort_system_directives_first = true
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+# Pattern matching
+csharp_style_pattern_matching_over_is_with_cast_check = true : suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true : suggestion
+csharp_style_inlined_variable_declaration = true : suggestion
+
+# Null checking preferences
+csharp_style_throw_expression = true : warning
+csharp_style_conditional_delegate_call = true : warning
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = do_not_ignore
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# CA1815: Override equals and operator equals on value types
+dotnet_diagnostic.CA1815.severity = silent
diff --git a/source/Servo.MotiveEngine/ExtensionUtils.cs b/source/Servo.MotiveEngine/ExtensionUtils.cs
new file mode 100644
index 0000000..f25f851
--- /dev/null
+++ b/source/Servo.MotiveEngine/ExtensionUtils.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Servo.MotiveEngine
+{
+ public static class ExtensionUtils
+ {
+ public static int MaxLimit(this int val, int max)
+ {
+ if (max < 0)
+ throw new ArgumentOutOfRangeException();
+
+ if (val >= max)
+ return max;
+
+ return val;
+ }
+ }
+}
diff --git a/source/Servo.MotiveEngine/Motives.cs b/source/Servo.MotiveEngine/Motives.cs
new file mode 100644
index 0000000..60efe7f
--- /dev/null
+++ b/source/Servo.MotiveEngine/Motives.cs
@@ -0,0 +1,104 @@
+using System.Linq;
+
+namespace Servo.MotiveEngine
+{
+ public class Motives
+ {
+ const int NAX_MOOD = 600;
+ const int MAX_MOTIVE = 100;
+
+ public Motives(int hunger, int bladder, int fun, int energy,
+ int environment, int social)
+ {
+ Hunger = hunger;
+ Bladder = bladder;
+ Fun = fun;
+ Energy = energy;
+ Environment = environment;
+ Social = social;
+ }
+
+ public int Hunger { get; set; }
+ public int Bladder { get; set; }
+ public int Fun { get; set; }
+ public int Energy { get; set; }
+ public int Environment { get; set; }
+ public int Social { get; set; }
+
+ ///
+ /// The mood is the sum of all the motives.
+ /// It deteremines the best course of action.
+ ///
+ public int Mood
+ {
+ get
+ {
+ var curMood = new[] { Hunger, Bladder, Fun,
+ Social, Environment, Energy };
+
+ return curMood.Sum();
+ }
+ }
+
+ ///
+ /// In the game, this would increament gradually
+ /// until it reaches it's max motive.
+ ///
+ /// Current Motive
+ /// New Motive
+ /// Changed Motive
+ int CalcuateMotiveChange(int motive, int input)
+ {
+ var curMotive = motive;
+ var curMood = Mood;
+
+ // New motive equals the current motive plus the input
+ var newMotive = curMotive + input;
+
+ // New mood equals the new motive plus the current mood
+ var newMood = newMotive + curMood;
+
+ // Changed motive is the new motive with the limit
+ var changedMotive = newMotive.MaxLimit(MAX_MOTIVE);
+
+ // Does the new motive increase my current motive?
+ // Does the new motive increase my overall mood?
+ if (changedMotive >= curMotive && curMood <= newMood
+ && changedMotive <= MAX_MOTIVE && curMood <= NAX_MOOD)
+ return changedMotive;
+
+ // Fall back to the current movement
+ return curMotive;
+ }
+
+ public void ChangeHunger(int input)
+ {
+ Hunger = CalcuateMotiveChange(Hunger, input);
+ }
+
+ public void ChangeFun(int input)
+ {
+ Fun = CalcuateMotiveChange(Fun, input);
+ }
+
+ public void ChangeBladder(int input)
+ {
+ Bladder = CalcuateMotiveChange(Bladder, input);
+ }
+
+ public void ChangeSocial(int input)
+ {
+ Social = CalcuateMotiveChange(Social, input);
+ }
+
+ public void ChangeEnergy(int input)
+ {
+ Energy = CalcuateMotiveChange(Energy, input);
+ }
+
+ public void ChangeEnvironment(int input)
+ {
+ Environment = CalcuateMotiveChange(Environment, input);
+ }
+ }
+}
diff --git a/source/Servo.MotiveEngine/Servo.MotiveEngine.csproj b/source/Servo.MotiveEngine/Servo.MotiveEngine.csproj
new file mode 100644
index 0000000..9f5c4f4
--- /dev/null
+++ b/source/Servo.MotiveEngine/Servo.MotiveEngine.csproj
@@ -0,0 +1,7 @@
+
+
+
+ netstandard2.0
+
+
+
diff --git a/source/Servo.sln b/source/Servo.sln
new file mode 100644
index 0000000..0659d8e
--- /dev/null
+++ b/source/Servo.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30621.155
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Servo.MotiveEngine", "Servo.MotiveEngine\Servo.MotiveEngine.csproj", "{162D701B-5CBA-43A4-A763-F4906B287BE3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3B512BB9-9354-49A4-AE68-97531B21EBD5}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ ..\README.md = ..\README.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|x64.Build.0 = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Debug|x86.Build.0 = Debug|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|x64.ActiveCfg = Release|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|x64.Build.0 = Release|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|x86.ActiveCfg = Release|Any CPU
+ {162D701B-5CBA-43A4-A763-F4906B287BE3}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8D4C7030-BF58-45BB-B093-4DB4FF75E95C}
+ EndGlobalSection
+EndGlobal