diff --git a/Assets/Scenes/Gameplay.unity b/Assets/Scenes/Gameplay.unity index 5f20a6f..974218e 100644 --- a/Assets/Scenes/Gameplay.unity +++ b/Assets/Scenes/Gameplay.unity @@ -1338,6 +1338,126 @@ Prefab: propertyPath: DetailsPanel value: objectReference: {fileID: 1197925315} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.friendRatio.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.friendRatio.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.friendRatio.z + value: .200000003 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.lastDeath.x + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.popularity.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.importance.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.numFriends.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.awareness.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.popularity.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.importance.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.frequency.x + value: .100000001 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.lastDeath.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.popularity.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.importance.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.numFriends.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.awareness.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.popularity.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.importance.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.frequency.y + value: .899999976 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.awarenessChange.lastDeath.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.popularity.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.importance.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.numFriends.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.deathNoticing.awareness.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.popularity.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.importance.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: strategy.chanceToPost.frequency.z + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: levelOptions.NumPeople + value: 10 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: levelOptions.AvgNumFriends + value: 5 + objectReference: {fileID: 0} + - target: {fileID: 11432906, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} + propertyPath: levelOptions.FriendshipLikeliness + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} m_IsPrefabParent: 0 diff --git a/Assets/Scripts/Models/Friendship.cs b/Assets/Scripts/Models/Friendship.cs index e25cc5c..277d38c 100644 --- a/Assets/Scripts/Models/Friendship.cs +++ b/Assets/Scripts/Models/Friendship.cs @@ -40,6 +40,9 @@ namespace DeathBook.Model //This function is only called when friend is dead //awareness = Mathf.Min(awareness + deltaTime * CalculateWeight(), 1); + + link.Awareness += Self.Strategy.GetDeathNoticing(1f /*Friend.Popularity*/, Link.Importance, Self.FriendCount, Self.AwarenessLevel); + link.Awareness = Mathf.Min(link.Awareness + deltaTime * 0.1f, 1f); if (link.Awareness >= 1f) { @@ -48,17 +51,6 @@ namespace DeathBook.Model } } - //returns a number between 0 and 1 - private float CalculateWeight() - { - float weight = 0; - - weight += link.Importance; - //weight += friend.TimeBetweenPosts; - - return weight * 0.1f; - } - public int CompareTo(Friendship other) { int value = 0; @@ -74,10 +66,5 @@ namespace DeathBook.Model return value; } - - /*internal enum Knowledge - { - Alive, Doubt, Dead - }*/ } } diff --git a/Assets/Scripts/Models/GameStrategy.cs b/Assets/Scripts/Models/GameStrategy.cs new file mode 100644 index 0000000..ae89cf2 --- /dev/null +++ b/Assets/Scripts/Models/GameStrategy.cs @@ -0,0 +1,86 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System; + +namespace DeathBook.Model +{ + [System.Serializable] + public class GameStrategy + { + [System.Serializable] + public class AwarenessChangeOptions + { + public Vector3 friendRatio = new Vector3(); + public Vector3 lastDeath = new Vector3(); + public float maxDeathDuration = 24 * 60 * 7; + } + + [System.Serializable] + public class DeathNoticingOptions + { + public Vector3 popularity = new Vector3(); + public Vector3 importance = new Vector3(); + public Vector3 numFriends = new Vector3(); + public Vector3 awareness = new Vector3(); + } + + [System.Serializable] + public class ChanceToPostOptions + { + public Vector3 popularity = new Vector3(); + public Vector3 importance = new Vector3(); + public Vector3 frequency = new Vector3(); + } + + + public AwarenessChangeOptions awarenessChange = new AwarenessChangeOptions(); + public DeathNoticingOptions deathNoticing = new DeathNoticingOptions(); + public ChanceToPostOptions chanceToPost = new ChanceToPostOptions(); + + public float GetAwarenessChange(int numDeadFriends, int numAliveFriends, int sinceLastDeath) + { + float friendsRatioInd = numAliveFriends == 0 ? 1 : GetValue(Mathf.Min(numDeadFriends / numAliveFriends, 1), awarenessChange.friendRatio); + + float max = awarenessChange.maxDeathDuration; + float lastDeathInd = GetValue(1 - Mathf.Min(sinceLastDeath, max) / max, awarenessChange.lastDeath); + + //Debug.Log(lastDeathInd + " " + friendsRatioInd); + + return Mathf.Clamp(friendsRatioInd * lastDeathInd, 0, 1); + } + + public float GetDeathNoticing(float friendPopularity, float friendshipImportance, int numAliveFriends, float awareness) + { + float popularityInd = GetValue(friendPopularity, deathNoticing.popularity); + + float importanceInd = GetValue(friendshipImportance, deathNoticing.importance); + + //TODO Should be inverse and there should be an expected number of friends + float aliveFriendsInd = GetValue(numAliveFriends, deathNoticing.numFriends); + + float awarenessInd = GetValue(awareness, deathNoticing.awareness); + + return Mathf.Clamp(popularityInd * importanceInd * aliveFriendsInd * awarenessInd, 0, 1); + } + + public float GetChanceToPost(float friendPopularity, float friendshipImportance) + { + float popularityInd = GetValue(1 - friendPopularity, deathNoticing.popularity); + + float importanceInd = GetValue(1 - friendshipImportance, deathNoticing.importance); + + return Mathf.Clamp(popularityInd * importanceInd, 0, 1); + } + + public float GetChanceToRead() + { + return 0; + } + + private float GetValue(float data, Vector3 modifier) + { + return Mathf.Clamp(modifier[0] + modifier[1] * data, 0, 1) * modifier[2]; + } + } +} diff --git a/Assets/Scripts/Models/GameStrategy.cs.meta b/Assets/Scripts/Models/GameStrategy.cs.meta new file mode 100644 index 0000000..9bb0326 --- /dev/null +++ b/Assets/Scripts/Models/GameStrategy.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9885183170e38dc418850b2e911f4cfe +timeCreated: 1439717430 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Models/Level.cs b/Assets/Scripts/Models/Level.cs index fe663d6..71bc23b 100644 --- a/Assets/Scripts/Models/Level.cs +++ b/Assets/Scripts/Models/Level.cs @@ -27,10 +27,41 @@ namespace DeathBook.Model private float globalAwareness; //on a scale from 0 to 1 public float GlobalAwareness { get { return globalAwareness; } } - public Level(List people, List friendships) + private GameStrategy strategy = null; + public GameStrategy Strategy { get { return strategy; } } + + private int numAlive; + public int NumAlive { get { return numAlive; } set { numAlive = value; NotifyObservers(); } } + + private int numDead; + public int NumDead { get { return numDead; } set { numDead = value; NotifyObservers(); } } + + private float awareness; + public float Awareness { get { return awareness; } set { awareness = value; NotifyObservers(); } } + + + public Level(List people, List friendships, GameStrategy strategy) { this.people = people; this.friendships = friendships; + this.strategy = strategy; + this.numAlive = people.Count; + this.numDead = 0; + this.awareness = 0; + } + + public void RegisterKill(Person p) + { + numDead++; + numAlive--; + Awareness = (Awareness * (NumAlive + 1) - p.AwarenessLevel) / NumAlive; + Debug.Log("Killed - " + p.AwarenessLevel + " nK = " + numAlive); + } + + public void AddAwareness(float addition) + { + Awareness += addition / NumAlive; + Debug.Log("Added - " + addition + " nK = " + numAlive); } public void Update(float deltaTime) @@ -42,8 +73,6 @@ namespace DeathBook.Model lastHour = hour; NotifyObservers(); } - - //TODO Global awareness - start trends } } } diff --git a/Assets/Scripts/Models/LevelGenerator.cs b/Assets/Scripts/Models/LevelGenerator.cs index a87f12f..5252e55 100644 --- a/Assets/Scripts/Models/LevelGenerator.cs +++ b/Assets/Scripts/Models/LevelGenerator.cs @@ -13,7 +13,7 @@ namespace DeathBook.Model private const float minConnTime = 3; private const float maxConnTime = 20; - public Level GenerateLevel(int numPeople, int avgFriends, float probability, float radius) + public Level GenerateLevel(int numPeople, int avgFriends, float probability, float radius, GameStrategy strategy) { this.numPeople = numPeople; this.avgConnections = avgFriends; @@ -23,7 +23,7 @@ namespace DeathBook.Model List people = CreatePeople(); List friendships = CreateFriendships(people); - return new Level(people, friendships); + return new Level(people, friendships, strategy); } private List CreatePeople() diff --git a/Assets/Scripts/Models/LevelManager.cs b/Assets/Scripts/Models/LevelManager.cs index 393cd01..53075d2 100644 --- a/Assets/Scripts/Models/LevelManager.cs +++ b/Assets/Scripts/Models/LevelManager.cs @@ -15,9 +15,9 @@ namespace DeathBook.Model private LevelManager() {} - public void NewLevel(int numPeople, int avgFriends, float probability, float radius) + public Level NewLevel(int numPeople, int avgFriends, float probability, float radius, GameStrategy strategy) { - level = gen.GenerateLevel(numPeople, avgFriends, probability, radius); + return level = gen.GenerateLevel(numPeople, avgFriends, probability, radius, strategy); } } } diff --git a/Assets/Scripts/Models/Person.cs b/Assets/Scripts/Models/Person.cs index 77b7a91..9c54c27 100644 --- a/Assets/Scripts/Models/Person.cs +++ b/Assets/Scripts/Models/Person.cs @@ -37,7 +37,14 @@ namespace DeathBook.Model public int DisconnectionTime { get { return disconnectionTime; } } private float awarenessLevel = 0; //on a scale from 0 to 1 - public float AwarenessLevel { get { return awarenessLevel; } } + public float AwarenessLevel { get { return awarenessLevel; } + set + { + float change = value - awarenessLevel; + awarenessLevel = value; + LevelManager.Instance.GameLevel.AddAwareness(change); + } + } private int lastFriendDeath = 0; public int LastFriendDeath { get { return lastFriendDeath; } } @@ -54,6 +61,17 @@ namespace DeathBook.Model private Action onSelected; public Action OnSelected {get {return onSelected;} set { onSelected = value; } } + private GameStrategy strategy; + public GameStrategy Strategy + { + get + { + if (strategy == null) + strategy = LevelManager.Instance.GameLevel.Strategy; + return strategy; + } + } + public Person(int id, string fName, string lName, Vector3 pos, int conn, int disconn, float freq, Sprite pic) { this.id = id; @@ -62,7 +80,7 @@ namespace DeathBook.Model this.initialPosition = pos; this.connectionTime = conn; this.disconnectionTime = disconn; - Debug.Log("I am " + id + " and I connect at " + Utils.GetTimeString(connectionTime) + " until " + Utils.GetTimeString(disconnectionTime)); + //Debug.Log("I am " + id + " and I connect at " + Utils.GetTimeString(connectionTime) + " until " + Utils.GetTimeString(disconnectionTime)); this.postFrequency = freq; this.picture = pic; @@ -78,7 +96,7 @@ namespace DeathBook.Model public void NotifyFriendWasKilled(Friendship f) { - Debug.Log("I am " + id + " and my friend " + f.Friend.Id + " was killed"); + //Debug.Log("I am " + id + " and my friend " + f.Friend.Id + " was killed"); numAliveFriends--; numDeadFriends++; deadFriendsList.Add(f); @@ -89,33 +107,30 @@ namespace DeathBook.Model if (Online) return false; - Debug.Log("Person " + id + " died!"); + //Debug.Log("Person " + id + " died!"); alive = false; foreach (Friendship f in friendsList) f.Other.NotifyFriendWasKilled(); NotifyObservers(); + LevelManager.Instance.GameLevel.RegisterKill(this); + return true; } public void NoticeDeath(Friendship f) { int deathTime = LevelManager.Instance.GameLevel.GameTime; - float lastFriendDeathMalus = 0; - //Last friend death - if (numDeadFriends > 0) - { - //TODO malus + int sinceLastDeath = numDeadFriends == 0 ? int.MaxValue/2 : deathTime - lastFriendDeath; - //Mathf.Clamp - //lastFriendDeathMalus = deathTime - lastFriendDeath - } - lastFriendDeath = deathTime; + float strategyOutput = Strategy.GetAwarenessChange(numDeadFriends, numAliveFriends, sinceLastDeath); + + AwarenessLevel = Mathf.Min(AwarenessLevel + strategyOutput, 1f); - //TODO apply more rules here - awarenessLevel = Mathf.Min(AwarenessLevel + 0.2f, 1f); - Debug.Log("I am " + id + " and I know my friend " + f.Friend.Id + " was killed.. " + AwarenessLevel); NotifyObservers(); + + + //Debug.Log("I am " + id + " and I know my friend " + f.Friend.Id + " was killed.. " + strategyOutput); } //Time in hours @@ -128,6 +143,9 @@ namespace DeathBook.Model public void Update(float deltaTime) { + if (!Alive) + return; + int time = LevelManager.Instance.GameLevel.DayTime; bool isOnline = IsOnline(time); @@ -151,4 +169,4 @@ namespace DeathBook.Model } } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/NetworkingSphere.cs b/Assets/Scripts/NetworkingSphere.cs index 72e93b4..1d1acca 100644 --- a/Assets/Scripts/NetworkingSphere.cs +++ b/Assets/Scripts/NetworkingSphere.cs @@ -6,7 +6,8 @@ using DeathBook.Model; public class NetworkingSphere : MonoBehaviour { public GameObjectsOptions gameObjects = new GameObjectsOptions(); - public LevelOptions levelOptions = new LevelOptions(); + public LevelOptions levelOptions = new LevelOptions(); + public GameStrategy strategy = new GameStrategy(); private NetworkDisconnection sphere; [System.Serializable] @@ -47,8 +48,7 @@ public class NetworkingSphere : MonoBehaviour void Awake() { manager = LevelManager.Instance; - manager.NewLevel(levelOptions.NumPeople, levelOptions.AvgNumFriends, levelOptions.FriendshipLikeliness, levelOptions.SphereRadius); - Level lvl = manager.GameLevel; + Level lvl = manager.NewLevel(levelOptions.NumPeople, levelOptions.AvgNumFriends, levelOptions.FriendshipLikeliness, levelOptions.SphereRadius, strategy); InstantiateNodes(lvl); AssignLinks(lvl); @@ -57,8 +57,9 @@ public class NetworkingSphere : MonoBehaviour void OnGUI() { - int time = manager.GameLevel.DayTime; - GUI.Button(new Rect(50, 50, 100, 40), Utils.GetTimeString(time)); + int time = manager.GameLevel.DayTime; + GUI.Button(new Rect(50, 50, 100, 40), Utils.GetTimeString(time)); + GUI.Button(new Rect(160, 50, 100, 40), manager.GameLevel.Awareness + ""); } void Update()