From df85dc86b12ba3073338afc695c64a1127df3764 Mon Sep 17 00:00:00 2001 From: Jakob Schaal Date: Thu, 27 Oct 2016 13:18:12 +0200 Subject: [PATCH] Creature Stats Rendering --- EvoNet/AI/Neuron.cs | 5 +- EvoNet/AI/NeuronalNetwork.cs | 82 ++++++++++++++++++++++++++++--- EvoNet/AI/WorkingNeuron.cs | 11 +++++ EvoNet/EvoGame.cs | 2 +- EvoNet/Mathf.cs | 10 ++++ EvoNet/Objects/Creature.cs | 28 +++++++++-- EvoNet/Objects/CreatureManager.cs | 15 ++++-- EvoNet/Rendering/RenderHelper.cs | 14 ++---- 8 files changed, 137 insertions(+), 30 deletions(-) diff --git a/EvoNet/AI/Neuron.cs b/EvoNet/AI/Neuron.cs index e23ff16..9da6908 100644 --- a/EvoNet/AI/Neuron.cs +++ b/EvoNet/AI/Neuron.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Xna.Framework; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -21,7 +22,7 @@ public virtual void Deserialize(BinaryReader reader) name = reader.ReadString(); } - + public Vector2 DrawPosition { get; set; } public string GetName() { diff --git a/EvoNet/AI/NeuronalNetwork.cs b/EvoNet/AI/NeuronalNetwork.cs index cc3f2dd..5819f62 100644 --- a/EvoNet/AI/NeuronalNetwork.cs +++ b/EvoNet/AI/NeuronalNetwork.cs @@ -3,6 +3,7 @@ using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -280,27 +281,51 @@ public void Deserialize(BinaryReader reader) public void Draw(SpriteBatch spriteBatch, Rectangle rect) { + CalculateNeuronsRenderPosition(rect); float yMin = rect.Y + NEURONSIZE / 2; float yMax = rect.Y + rect.Height - NEURONSIZE / 2; - DrawLayer(spriteBatch, rect.X + NEURONSIZE / 2, yMin, yMax, inputNeurons, new Vector2(-10, -10), true); - DrawLayer(spriteBatch, rect.X + rect.Width / 2, yMin, yMax, hiddenNeurons); - DrawLayer(spriteBatch, rect.X + rect.Width - NEURONSIZE / 2, yMin, yMax, outputNeurons, new Vector2(10, -10)); + float strongestConnection = GetStrongestConnection(); + DrawLayer(spriteBatch, outputNeurons, strongestConnection, new Vector2(10, -10)); + DrawLayer(spriteBatch, hiddenNeurons, strongestConnection); + DrawLayer(spriteBatch, inputNeurons, strongestConnection, new Vector2(-10, -10), true); } - private void DrawLayer(SpriteBatch spriteBatch, float x, float yMin, float yMax, List layer, Vector2? nameOffset = null, bool writeRight = false) { + private void CalculateNeuronsRenderPosition(Rectangle rect) + { + float yMin = rect.Y + NEURONSIZE / 2; + float yMax = rect.Y + rect.Height - NEURONSIZE / 2; + CalculateNeuronsRederPositionLayer(outputNeurons, rect.X + rect.Width - NEURONSIZE / 2, yMin, yMax); + CalculateNeuronsRederPositionLayer(hiddenNeurons, rect.X + rect.Width / 2, yMin, yMax); + CalculateNeuronsRederPositionLayer(inputNeurons, rect.X + NEURONSIZE / 2, yMin, yMax); + } + + private void CalculateNeuronsRederPositionLayer(List layer, float x, float yMin, float yMax) + { float yDiff = yMax - yMin; float distanceBetweenNeurons = yDiff / (layer.Count - 1); float currentY = yMin; + for (int i = 0; i < layer.Count; i++) + { + layer[i].DrawPosition = new Vector2(x, currentY); + currentY += distanceBetweenNeurons; + } + } + private void DrawLayer(SpriteBatch spriteBatch, List layer, float strongestConnection, Vector2? nameOffset = null, bool writeRight = false) { for(int i = 0; i 0) + { + color = new Color(0f, 1f, 0f, alpha); + }else + { + + color = new Color(1f, 0f, 0f, alpha); + } + RenderHelper.DrawLine(spriteBatch, n.DrawPosition.X, n.DrawPosition.Y, c.entryNeuron.DrawPosition.X, c.entryNeuron.DrawPosition.Y, color, 1); + } + } + + public float GetStrongestConnection() + { + return Mathf.Max(GetStrongestLayerConnection(hiddenNeurons), GetStrongestLayerConnection(outputNeurons)); + } + + private float GetStrongestLayerConnection(List layer) + { + float strongestConnection = 0; + foreach (Neuron n in layer) + { + WorkingNeuron wn = (WorkingNeuron)n; + float strongestNeuronConnection = Math.Abs(wn.GetStrongestConnection()); + if (strongestNeuronConnection > strongestConnection) + { + strongestConnection = strongestNeuronConnection; + } + } + return strongestConnection; + } } } diff --git a/EvoNet/AI/WorkingNeuron.cs b/EvoNet/AI/WorkingNeuron.cs index 519c1d9..496f7ed 100644 --- a/EvoNet/AI/WorkingNeuron.cs +++ b/EvoNet/AI/WorkingNeuron.cs @@ -71,5 +71,16 @@ public override Neuron NameCopy() clone.SetName(GetName()); return clone; } + + public float GetStrongestConnection() + { + float strongest = 0; + foreach(Connection c in connections) + { + float val = Mathf.Abs(c.weight); + if (val > strongest) strongest = val; + } + return strongest; + } } } diff --git a/EvoNet/EvoGame.cs b/EvoNet/EvoGame.cs index eb1c279..6ba0672 100644 --- a/EvoNet/EvoGame.cs +++ b/EvoNet/EvoGame.cs @@ -95,7 +95,7 @@ protected override void LoadContent() Creature.Initialize(); - RenderHelper.Ini(spriteBatch, WhiteTexture, WhiteCircleTexture); + RenderHelper.Ini(WhiteTexture, WhiteCircleTexture); tileMap = TileMap.DeserializeFromFile("tilemap.dat", this); if (tileMap == null) { diff --git a/EvoNet/Mathf.cs b/EvoNet/Mathf.cs index db07d00..309710f 100644 --- a/EvoNet/Mathf.cs +++ b/EvoNet/Mathf.cs @@ -93,5 +93,15 @@ public static float Min(List list) } return min; } + + public static float Max(float a, float b) + { + return a > b ? a : b; + } + + public static float Min(float a, float b) + { + return a > b ? b : a; + } } } diff --git a/EvoNet/Objects/Creature.cs b/EvoNet/Objects/Creature.cs index a2e5595..2de1acc 100644 --- a/EvoNet/Objects/Creature.cs +++ b/EvoNet/Objects/Creature.cs @@ -62,6 +62,13 @@ public static Creature oldestCreatureEver private long id; private Vector2 pos; + public Vector2 Pos + { + get + { + return pos; + } + } private float viewAngle; private float feelerAngle; @@ -140,6 +147,13 @@ public NeuronalNetwork Brain private List children = new List(); + public List Children + { + get + { + return children; + } + } // Temps for deserialization private long motherId; @@ -448,13 +462,19 @@ public void CalculateFeelerPos() public void Draw() { spriteBatch.Begin(transformMatrix: Camera.instanceGameWorld.Matrix); - RenderHelper.DrawLine(pos.X, pos.Y, feelerPos.X, feelerPos.Y, Color.White); - spriteBatch.Draw(bodyTex, new Rectangle((int)pos.X - 27, (int)pos.Y - 27, 54, 54), color_inv); - spriteBatch.Draw(bodyTex, new Rectangle((int)pos.X - 25, (int)pos.Y - 25, 50, 50), color); - spriteBatch.Draw(feelerTex, new Rectangle((int)feelerPos.X - 5, (int)feelerPos.Y - 5, 10, 10), Color.Blue); + DrawCreature(spriteBatch, Vector2.Zero); + spriteBatch.End(); } + public void DrawCreature(SpriteBatch spriteBatch, Vector2 offset) + { + RenderHelper.DrawLine(spriteBatch, pos.X + offset.X, pos.Y + offset.Y, feelerPos.X + offset.X, feelerPos.Y + offset.Y, Color.White); + spriteBatch.Draw(bodyTex, new Rectangle((int)(pos.X + offset.X - 27), (int)(pos.Y + offset.Y - 27), 54, 54), color_inv); + spriteBatch.Draw(bodyTex, new Rectangle((int)(pos.X + offset.X - 25), (int)(pos.Y + offset.Y - 25), 50, 50), color); + spriteBatch.Draw(feelerTex, new Rectangle((int)(feelerPos.X + offset.X - 5), (int)(feelerPos.Y + offset.Y - 5), 10, 10), Color.Blue); + } + public void Serialize(BinaryWriter writer) { writer.Write("CreatureBegin"); diff --git a/EvoNet/Objects/CreatureManager.cs b/EvoNet/Objects/CreatureManager.cs index 64265b1..3e66bed 100644 --- a/EvoNet/Objects/CreatureManager.cs +++ b/EvoNet/Objects/CreatureManager.cs @@ -98,8 +98,6 @@ public override void Update(GameTime deltaTime) } } - Debug.WriteLine(OldestCreatureAlive.Age + " " + OldestCreatureAlive.Energy); - AliveCreaturesRecord.Add(Creatures.Count); SelectedCreature = OldestCreatureAlive; @@ -140,8 +138,6 @@ private void DrawGeneralStats() else { spriteBatch.DrawString(Fonts.FontArial, "Creatures Alive Graph ", new Vector2(20, 180), Color.Red); - GraphRenderer.RenderGraph(spriteBatch, new Rectangle(20, 200, 260, 100), Color.Blue, AliveCreaturesRecord, Fonts.FontArial, true); - spriteBatch.DrawString(Fonts.FontArial, "Creatures Alive Graph ", new Vector2(20, 180), Color.Red); GraphRenderer.RenderGraph(spriteBatch, new Rectangle(20, 200, 260, 100), Color.Blue, AliveCreaturesRecord, Fonts.FontArial, true); spriteBatch.DrawString(Fonts.FontArial, "Average Age on Death Graph ", new Vector2(20, 320), Color.Red); if (AverageAgeOfLastCreaturesAccurate) @@ -154,7 +150,16 @@ private void DrawGeneralStats() if(SelectedCreature != null) { - SelectedCreature.Brain.Draw(spriteBatch, new Rectangle(950, 0, 200, 200)); + Primitives2D.FillRectangle(spriteBatch, new Rectangle(800, 0, 500, 400), AdditionalColors.TRANSPARENTBLACK); + + spriteBatch.DrawString(Fonts.FontArial, "Selected Creature: ", new Vector2(820, 50), Color.Red); + spriteBatch.DrawString(Fonts.FontArial, "A: " + SelectedCreature.Age, new Vector2(820, 70), Color.Red); + spriteBatch.DrawString(Fonts.FontArial, "E: " + SelectedCreature.Energy, new Vector2(820, 90), Color.Red); + spriteBatch.DrawString(Fonts.FontArial, "C: " + SelectedCreature.Children.Count, new Vector2(820, 110), Color.Red); + spriteBatch.DrawString(Fonts.FontArial, "G: " + SelectedCreature.Generation, new Vector2(820, 130), Color.Red); + spriteBatch.DrawString(Fonts.FontArial, "S: " + (SelectedCreature.Energy > 100 ? "Alive" : "Dead"), new Vector2(820, 150), Color.Red); + SelectedCreature.DrawCreature(spriteBatch, SelectedCreature.Pos * -1 + new Vector2(1050, 70)); + SelectedCreature.Brain.Draw(spriteBatch, new Rectangle(950, 160, 200, 200)); } spriteBatch.End(); diff --git a/EvoNet/Rendering/RenderHelper.cs b/EvoNet/Rendering/RenderHelper.cs index 53436bb..9f1e2f4 100644 --- a/EvoNet/Rendering/RenderHelper.cs +++ b/EvoNet/Rendering/RenderHelper.cs @@ -14,25 +14,18 @@ namespace EvoNet.Rendering { class RenderHelper { - private static SpriteBatch spriteBatch = null; private static Texture2D whiteTexture = null; private static Texture2D whiteCircleTexture = null; - public static void Ini(SpriteBatch spriteBatch, Texture2D whiteTexture, Texture2D whiteCircleTexture) + public static void Ini(Texture2D whiteTexture, Texture2D whiteCircleTexture) { - RenderHelper.spriteBatch = spriteBatch; RenderHelper.whiteTexture = whiteTexture; RenderHelper.whiteCircleTexture = whiteCircleTexture; } - public static void DrawLine(float x0, float y0, float x1, float y1, Color c) + public static void DrawLine(SpriteBatch spriteBatch, float x0, float y0, float x1, float y1, Color c, int lineWidth = 1) { - float xDiff = x0 - x1; - float yDiff = y0 - y1; - float angle = (float)Math.Atan2(yDiff, xDiff); - float dist = (float)Math.Sqrt(xDiff * xDiff + yDiff * yDiff); - - spriteBatch.Draw(whiteTexture, new Rectangle((int)x1, (int)y1, (int)dist, 1), null, c, angle, Vector2.Zero, SpriteEffects.None, 0); + Primitives2D.DrawLine(spriteBatch, x0, y0, x1, y1, c); } public static void DrawCircle(SpriteBatch spriteBatch, float x, float y, float radius, Color c) @@ -42,5 +35,6 @@ public static void DrawCircle(SpriteBatch spriteBatch, float x, float y, float r int radiusD = (int)Math.Round(radius * 2); spriteBatch.Draw(whiteCircleTexture, new Rectangle(xD, yD, radiusD, radiusD), c); } + } }