diff --git a/Agent.cs b/Agent.cs index cfcb629..0f6e6ea 100644 --- a/Agent.cs +++ b/Agent.cs @@ -1,4 +1,6 @@  +using System.Collections.Generic; + using UnityEngine; public class Agent { @@ -7,9 +9,11 @@ public class Agent { public int id; - public int sugar; - public int vision; - public int metabolism; + public bool isAlive { get; private set; } = true; + + public int sugar { get; private set; } + public readonly int vision; + public readonly int metabolism; public Location location; @@ -23,8 +27,46 @@ public Agent () { InitGameObject(); } + public void Step () { + this.Move(); + this.Harvest(); + this.Eat(); + } + public void Render () { - gameObject.transform.localPosition = new Vector3(Utils.RandomInt(50), 0, Utils.RandomInt(50)); + gameObject.transform.localPosition = new Vector3(this.location.y, 0, this.location.x); + } + + private void Move () { + Location next = this.location; + + foreach ( List locationsInDirection in Utils.Shuffle(this.location.GetAllLocationsInSight(this.vision)) ) { + foreach ( Location potential in locationsInDirection ) { + if ( potential.agent == null && potential.sugar > next.sugar ) { + next = potential; + } + } + } + + this.location.agent = null; + this.location = next; + this.location.agent = this; + } + + private void Harvest () { + this.sugar += this.location.Harvest(); + } + + private void Eat () { + sugar -= metabolism; + if ( sugar < 0 ) { + this.Die(); + } + } + + private void Die () { + Object.Destroy(gameObject); + isAlive = false; } private void InitGameObject () { @@ -39,4 +81,5 @@ private void InitGameObject () { renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; renderer.sharedMaterial = Materials.DEFAULT; } + } diff --git a/Environment.cs b/Environment.cs index 442f2dd..f72b836 100644 --- a/Environment.cs +++ b/Environment.cs @@ -12,6 +12,14 @@ public Environment () { InitGameObject(); } + public void Step () { + for ( int y = 0 ; y < locations.GetLength(0) ; y++ ) { + for ( int x = 0 ; x < locations.GetLength(1) ; x++ ) { + locations[y, x].Step(); + } + } + } + public void Render () { for ( int y = 0 ; y < locations.GetLength(0) ; y++ ) { for ( int x = 0 ; x < locations.GetLength(1) ; x++ ) { @@ -40,6 +48,7 @@ private void InitLocations () { locations[y, x] = new Location(x, y, Utils.SUGAR_CAPACITIES[y, x]); } } + for ( int y = 0 ; y < height ; y++ ) { for ( int x = 0 ; x < width ; x++ ) { int up = y == 0 ? height - 1 : y - 1; diff --git a/Location.cs b/Location.cs index b25e0fc..1d61f67 100644 --- a/Location.cs +++ b/Location.cs @@ -1,4 +1,6 @@  +using System.Collections.Generic; + using UnityEngine; public class Location { @@ -40,10 +42,69 @@ Location west this.west = west; } + public void Step () { + this.sugar = Mathf.Min(this.sugar + Simulation.Parameters.SUGAR_GROWTH_RATE, capacity); + } + public void Render () { gameObject.transform.localScale = Mathf.Sqrt(sugar) * Vector3.one / 25; } + public int Harvest () { + int sugar = this.sugar; + this.sugar = 0; + return sugar; + } + + public List> GetAllLocationsInSight (int distance) { + List> allLocations = new List>(); + allLocations.Add(GetNorthernLocations(distance)); + allLocations.Add(GetSouthernLocations(distance)); + allLocations.Add(GetEasternLocations(distance)); + allLocations.Add(GetWesternLocations(distance)); + return allLocations; + } + + private List GetNorthernLocations (int distance) { + List locations = new List(); + Location that = this; + do { + locations.Add(that.north); + that = that.north; + } while ( --distance > 0 ); + return locations; + } + + private List GetSouthernLocations (int distance) { + List locations = new List(); + Location that = this; + do { + locations.Add(that.south); + that = that.south; + } while ( --distance > 0 ); + return locations; + } + + private List GetEasternLocations (int distance) { + List locations = new List(); + Location that = this; + do { + locations.Add(that.east); + that = that.east; + } while ( --distance > 0 ); + return locations; + } + + private List GetWesternLocations (int distance) { + List locations = new List(); + Location that = this; + do { + locations.Add(that.west); + that = that.west; + } while ( --distance > 0 ); + return locations; + } + private void InitGameObject () { gameObject = GameObject.CreatePrimitive(PrimitiveType.Plane); gameObject.name = "Sugar" + x + "," + y; diff --git a/Main.cs b/Main.cs index bff919a..69f857b 100644 --- a/Main.cs +++ b/Main.cs @@ -3,10 +3,20 @@ public class Main : MonoBehaviour { - void Start() - { + private float elaspedTime = 0; + + void Awake () { Simulation.Init(); Simulation.Render(); } + void Update () { + this.elaspedTime += Time.deltaTime; + float secondsPerStep = 1.0f / Simulation.Parameters.STEPS_PER_SECOND; + for ( int i = (int) ( this.elaspedTime * secondsPerStep ) ; i > 0 ; i-- ) { + Simulation.Step(); + Simulation.Render(); + this.elaspedTime -= secondsPerStep; + } + } } diff --git a/Simulation.cs b/Simulation.cs index 07288b4..0e17ed7 100644 --- a/Simulation.cs +++ b/Simulation.cs @@ -1,10 +1,14 @@  using System.Collections.Generic; +using UnityEngine; + public class Simulation { public static class Parameters { + public static float STEPS_PER_SECOND = 4; public static int NUMBER_OF_AGENTS = 400; + public static int SUGAR_GROWTH_RATE = 1; public static class Endowment { public static int MIN = 20; public static int MAX = 40; @@ -19,6 +23,8 @@ public static class Metabolism { } } + public static int STEPS { get; private set; } = 0; + public static Environment environment = new Environment(); public static List agents = new List(); @@ -32,10 +38,23 @@ public static void Init () { } } + public static void Step () { + foreach ( Agent agent in Utils.Shuffle(agents) ) { + if ( agent.isAlive ) { + agent.Step(); + } + } + environment.Step(); + STEPS++; + } + public static void Render () { environment.Render(); foreach ( Agent agent in agents ) { - agent.Render(); + if ( agent.isAlive ) { + agent.Render(); + } } } + }