/// <summary> /// A very important function. Compute the neural network within the ant to choose an action. /// /// First go over restrictions for immediate actions to constrain the search of the neuroevolution /// </summary> public void Act() { // Exchange health according to function // Give three quarters of health to the queen (if room) if (colony.queen != null) { Ant queenScript = colony.queen.GetComponent <Ant>(); if (!queenScript.dead && queenScript.position == this.position) { timesTouchedQueen++; if (queenScript.currhealth + (int)(0.75f * this.currhealth) < queenScript.totalHealth) { queenScript.updateHealth((int)(0.75f * this.currhealth)); this.updateHealth((int)(-0.75f * this.currhealth)); // No other choice but to exchange health return; } } } // Consume mulch //if (Terrain.WorldManager.Instance.GetBlock(position.x, position.y - 1, position.z).GetType() == typeof(Terrain.MulchBlock)) //this.consumeBlock(); // The output layer of the nervous system // byte[] {u, r, d, l, consume, null} float[] perception = ns.perceive(); lastPerception = ""; lastPerception += " u: " + perception[0].ToString(); lastPerception += " r: " + perception[1].ToString(); lastPerception += " d: " + perception[2].ToString(); lastPerception += " l: " + perception[3].ToString(); lastPerception += " consume: " + perception[4].ToString(); lastPerception += " nothing: " + perception[5].ToString(); if (perception[0] == 0 && perception[0] == perception[1] && perception[0] == perception[2] && perception[0] == perception[3] && perception[0] == perception[4] && perception[0] == perception[5]) { // All outputs are 0, do nothing timeSinceLastAction++; return; } int todo = ns.indexOfMax(perception); if (todo == 0) { Move(new Vector2Int(0, 1)); transform.eulerAngles = new Vector3(0, 90f, 0); } else if (todo == 1) { Move(new Vector2Int(1, 0)); transform.eulerAngles = new Vector3(0, 180f, 0); } else if (todo == 2) { Move(new Vector2Int(0, -1)); transform.eulerAngles = new Vector3(0, -90f, 0); } else if (todo == 3) { Move(new Vector2Int(-1, 0)); transform.eulerAngles = new Vector3(0, 0, 0); } else if (todo == 4) { consumeBlock(); } else { // Do nothing timeSinceLastAction++; } // Reduce health by frame amount this.updateHealth(-ConfigurationManager.Instance.healthReduction); }