private void UpdateAI() { // exceptions if (_actualAction == AIAction.Attack && _life < 0.5f || _actualAction == AIAction.Attack && _isShootAt) { SetFree(); } if (_isOccupied && _actualAction != AIAction.Wander) { return; } List <double> inputs = new List <double>(); // target distance and elevation difference factors if (_target == null) { inputs.Add(0.0); } else { inputs.Add(AIUtils.Clamp(1 - _targetDistance / _sightRange + Position.Y / _target.Position.Y / 200)); } // cover inputs.Add(_inCover ? 1.0 : AIUtils.Clamp(1 - (GetNearestAvailableStatic(AIStaticType.Cover).Position - Position).Length() / _sightRange)); // bonus inputs.Add(AIUtils.Clamp(1 - (GetNearestAvailableStatic(AIStaticType.Bonus).Position - Position).Length() / _sightRange)); // med inputs.Add(AIUtils.Clamp(1 - (GetNearestAvailableStatic(AIStaticType.FirstAidKit).Position - Position).Length() / _sightRange)); // life inputs.Add((1 - _life)); // experience inputs.Add(_experience / 100); // speed //inputs.Add(MovementSpeed / Settings.OBJECTS_MOVEMENT_SPEED); // is shoot at inputs.Add(_isShootAt ? 1.0 : 0.0); List <double> output = _aiNeuralBrain.Update(inputs); if (output.Count < AIParams.NumOutputs) { throw new Exception("Brain mulfunction for " + this.Identifier + "!"); } switch (RangeIndex(output[0], 5)) { case 0: if (_target != null) { Attack(_target); _actionCounter[AIAction.Attack]++; Status = AIMovementStatus.Run; } else { PickUpBonus(); _actionCounter[AIAction.PUBonus]++; Status = AIMovementStatus.Run; } break; case 1: PickUpBonus(); _actionCounter[AIAction.PUBonus]++; Status = AIMovementStatus.Run; break; case 2: Wander(); _actionCounter[AIAction.Wander]++; Status = AIMovementStatus.Walk; break; case 3: TakeCover(); _actionCounter[AIAction.TakeCover]++; Status = AIMovementStatus.Run; break; case 4: PickUpMedKit(); _actionCounter[AIAction.PUMed]++; Status = AIMovementStatus.Run; break; default: throw new Exception("Not valid number of ANN outputs!"); } #region Old calculations with 5 outputs ////assign the outputs to the aiobject physics //double max = double.MinValue; //int max_index = 0; //for (int i = 0; i < output.Count; i++) //{ // if (output[i] > max) // { // max = output[i]; // max_index = i; // } //} //switch (max_index) //{ // case 0: // if (_target != null) // { // Attack(_target); // _actionCounter[AIAction.Attack]++; // Status = AIMovementStatus.Run; // } // else // { // PickUpBonus(); // _actionCounter[AIAction.PickUpBonus]++; // Status = AIMovementStatus.Run; // } // break; // case 1: // TakeCover(); // _actionCounter[AIAction.TakeCover]++; // Status = AIMovementStatus.Run; // break; // case 2: // PickUpMedKit(); // _actionCounter[AIAction.PickUpMed]++; // Status = AIMovementStatus.Run; // break; // case 3: // Wander(); // _actionCounter[AIAction.Wander]++; // Status = AIMovementStatus.Walk; // break; // default: // throw new Exception("Wrong number of outputs from ANN!"); // //Wander(); // //_actionCounter[AIAction.Wander]++; // //Status = AIMovementStatus.Walk; // //SetFree(); // break; //} #endregion }