Added strategy tweaks for awareness calculation and friend death noticing.

Implemented game global awareness.

Signed-off-by: RosimInc <rosim_inc@hotmail.com>
This commit is contained in:
RosimInc 2015-08-16 14:48:35 -04:00
parent 8cc63306a0
commit b0dfa36552
9 changed files with 298 additions and 45 deletions

View File

@ -1338,6 +1338,126 @@ Prefab:
propertyPath: DetailsPanel propertyPath: DetailsPanel
value: value:
objectReference: {fileID: 1197925315} 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_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2} m_ParentPrefab: {fileID: 100100000, guid: 136ea38d5deb4c9418beb879167d9b03, type: 2}
m_IsPrefabParent: 0 m_IsPrefabParent: 0

View File

@ -40,6 +40,9 @@ namespace DeathBook.Model
//This function is only called when friend is dead //This function is only called when friend is dead
//awareness = Mathf.Min(awareness + deltaTime * CalculateWeight(), 1); //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); link.Awareness = Mathf.Min(link.Awareness + deltaTime * 0.1f, 1f);
if (link.Awareness >= 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) public int CompareTo(Friendship other)
{ {
int value = 0; int value = 0;
@ -74,10 +66,5 @@ namespace DeathBook.Model
return value; return value;
} }
/*internal enum Knowledge
{
Alive, Doubt, Dead
}*/
} }
} }

View File

@ -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];
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9885183170e38dc418850b2e911f4cfe
timeCreated: 1439717430
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -27,10 +27,41 @@ namespace DeathBook.Model
private float globalAwareness; //on a scale from 0 to 1 private float globalAwareness; //on a scale from 0 to 1
public float GlobalAwareness { get { return globalAwareness; } } public float GlobalAwareness { get { return globalAwareness; } }
public Level(List<Person> people, List<FriendshipLink> 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<Person> people, List<FriendshipLink> friendships, GameStrategy strategy)
{ {
this.people = people; this.people = people;
this.friendships = friendships; 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) public void Update(float deltaTime)
@ -42,8 +73,6 @@ namespace DeathBook.Model
lastHour = hour; lastHour = hour;
NotifyObservers(); NotifyObservers();
} }
//TODO Global awareness - start trends
} }
} }
} }

View File

@ -13,7 +13,7 @@ namespace DeathBook.Model
private const float minConnTime = 3; private const float minConnTime = 3;
private const float maxConnTime = 20; 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.numPeople = numPeople;
this.avgConnections = avgFriends; this.avgConnections = avgFriends;
@ -23,7 +23,7 @@ namespace DeathBook.Model
List<Person> people = CreatePeople(); List<Person> people = CreatePeople();
List<FriendshipLink> friendships = CreateFriendships(people); List<FriendshipLink> friendships = CreateFriendships(people);
return new Level(people, friendships); return new Level(people, friendships, strategy);
} }
private List<Person> CreatePeople() private List<Person> CreatePeople()

View File

@ -15,9 +15,9 @@ namespace DeathBook.Model
private LevelManager() {} 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);
} }
} }
} }

View File

@ -37,7 +37,14 @@ namespace DeathBook.Model
public int DisconnectionTime { get { return disconnectionTime; } } public int DisconnectionTime { get { return disconnectionTime; } }
private float awarenessLevel = 0; //on a scale from 0 to 1 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; private int lastFriendDeath = 0;
public int LastFriendDeath { get { return lastFriendDeath; } } public int LastFriendDeath { get { return lastFriendDeath; } }
@ -54,6 +61,17 @@ namespace DeathBook.Model
private Action onSelected; private Action onSelected;
public Action OnSelected {get {return onSelected;} set { onSelected = value; } } 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) public Person(int id, string fName, string lName, Vector3 pos, int conn, int disconn, float freq, Sprite pic)
{ {
this.id = id; this.id = id;
@ -62,7 +80,7 @@ namespace DeathBook.Model
this.initialPosition = pos; this.initialPosition = pos;
this.connectionTime = conn; this.connectionTime = conn;
this.disconnectionTime = disconn; 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.postFrequency = freq;
this.picture = pic; this.picture = pic;
@ -78,7 +96,7 @@ namespace DeathBook.Model
public void NotifyFriendWasKilled(Friendship f) 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--; numAliveFriends--;
numDeadFriends++; numDeadFriends++;
deadFriendsList.Add(f); deadFriendsList.Add(f);
@ -89,33 +107,30 @@ namespace DeathBook.Model
if (Online) if (Online)
return false; return false;
Debug.Log("Person " + id + " died!"); //Debug.Log("Person " + id + " died!");
alive = false; alive = false;
foreach (Friendship f in friendsList) foreach (Friendship f in friendsList)
f.Other.NotifyFriendWasKilled(); f.Other.NotifyFriendWasKilled();
NotifyObservers(); NotifyObservers();
LevelManager.Instance.GameLevel.RegisterKill(this);
return true; return true;
} }
public void NoticeDeath(Friendship f) public void NoticeDeath(Friendship f)
{ {
int deathTime = LevelManager.Instance.GameLevel.GameTime; int deathTime = LevelManager.Instance.GameLevel.GameTime;
float lastFriendDeathMalus = 0; int sinceLastDeath = numDeadFriends == 0 ? int.MaxValue/2 : deathTime - lastFriendDeath;
//Last friend death
if (numDeadFriends > 0)
{
//TODO malus
//Mathf.Clamp float strategyOutput = Strategy.GetAwarenessChange(numDeadFriends, numAliveFriends, sinceLastDeath);
//lastFriendDeathMalus = deathTime - lastFriendDeath
} AwarenessLevel = Mathf.Min(AwarenessLevel + strategyOutput, 1f);
lastFriendDeath = deathTime;
//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(); NotifyObservers();
//Debug.Log("I am " + id + " and I know my friend " + f.Friend.Id + " was killed.. " + strategyOutput);
} }
//Time in hours //Time in hours
@ -128,6 +143,9 @@ namespace DeathBook.Model
public void Update(float deltaTime) public void Update(float deltaTime)
{ {
if (!Alive)
return;
int time = LevelManager.Instance.GameLevel.DayTime; int time = LevelManager.Instance.GameLevel.DayTime;
bool isOnline = IsOnline(time); bool isOnline = IsOnline(time);
@ -151,4 +169,4 @@ namespace DeathBook.Model
} }
} }
} }
} }

View File

@ -6,7 +6,8 @@ using DeathBook.Model;
public class NetworkingSphere : MonoBehaviour public class NetworkingSphere : MonoBehaviour
{ {
public GameObjectsOptions gameObjects = new GameObjectsOptions(); public GameObjectsOptions gameObjects = new GameObjectsOptions();
public LevelOptions levelOptions = new LevelOptions(); public LevelOptions levelOptions = new LevelOptions();
public GameStrategy strategy = new GameStrategy();
private NetworkDisconnection sphere; private NetworkDisconnection sphere;
[System.Serializable] [System.Serializable]
@ -47,8 +48,7 @@ public class NetworkingSphere : MonoBehaviour
void Awake() void Awake()
{ {
manager = LevelManager.Instance; manager = LevelManager.Instance;
manager.NewLevel(levelOptions.NumPeople, levelOptions.AvgNumFriends, levelOptions.FriendshipLikeliness, levelOptions.SphereRadius); Level lvl = manager.NewLevel(levelOptions.NumPeople, levelOptions.AvgNumFriends, levelOptions.FriendshipLikeliness, levelOptions.SphereRadius, strategy);
Level lvl = manager.GameLevel;
InstantiateNodes(lvl); InstantiateNodes(lvl);
AssignLinks(lvl); AssignLinks(lvl);
@ -57,8 +57,9 @@ public class NetworkingSphere : MonoBehaviour
void OnGUI() void OnGUI()
{ {
int time = manager.GameLevel.DayTime; int time = manager.GameLevel.DayTime;
GUI.Button(new Rect(50, 50, 100, 40), Utils.GetTimeString(time)); GUI.Button(new Rect(50, 50, 100, 40), Utils.GetTimeString(time));
GUI.Button(new Rect(160, 50, 100, 40), manager.GameLevel.Awareness + "");
} }
void Update() void Update()