private static TrainingData GetData(Player player) { DataLock.EnterUpgradeableReadLock(); try { TrainingData data = null; if (!Data.TryGetValue(player.Id, out data)) { DataLock.EnterWriteLock(); try { data = new TrainingData(); Data.Add(player.Id, data); } finally { DataLock.ExitWriteLock(); } } return(data); } finally { DataLock.ExitUpgradeableReadLock(); } }
public override ActionEnum Action(List <Element> elements, float angleToCenter, bool inZone, ref float xdelta, ref float ydelta, ref float angle) { // check if last action failed if (LastActionFailed > 0) { LastActionFailed--; xdelta = Xdelta; ydelta = Ydelta; return(ActionEnum.Move); } // construct a view of the current world var data = new TrainingData() { // core data CenterAngle = angleToCenter, InZone = inZone, Health = Health, Shield = Shield, Z = Z, Primary = Primary != null?Primary.GetType().Name : "", PrimaryAmmo = Primary != null ? Primary.Ammo : 0, PrimaryClip = Primary != null ? Primary.Clip : 0, Secondary = Secondary != null?Secondary.GetType().Name : "", SecondaryAmmo = Secondary != null ? Secondary.Ammo : 0, SecondaryClip = Secondary != null ? Secondary.Clip : 0 }; data.Proximity = AITraining.ComputeProximity(this, elements).Values.ToList(); // use the model to predict its actions var modeldataset = data.AsModelDataSet(); int iAction = 0; { iAction = (int)Math.Round(ActionModel.Predict(modeldataset)); angle = AngleModel.Predict(modeldataset); XYModel.Predict(modeldataset, out xdelta, out ydelta); } // do some sanity checking... if (iAction < 0 || iAction >= (int)ActionEnum.COUNT) { iAction = (int)ActionEnum.Move; } if (Math.Abs(xdelta) + Math.Abs(ydelta) > 1.00001) { throw new Exception("xdelta and ydelta are invalid"); } if (angle < 0) { angle += 360; } if (angle > 360) { angle -= 360; } if (angle < 0 || angle > 360) { throw new Exception("Invalid angle: " + angle); } return((ActionEnum)iAction); }
public static ModelDataSet AsModelDataSet(this TrainingData data) { // transform to ModelDataSet and Normalize (0...1) var result = new ModelDataSet() { // core data CenterAngle = Normalize(data.CenterAngle, 360f), InZone = data.InZone ? 1f : 0, Health = Normalize(data.Health, (float)Constants.MaxHealth), Shield = Normalize(data.Shield, (float)Constants.MaxShield), Primary = Normalize(data.Primary), PrimaryAmmo = data.PrimaryAmmo >= Constants.MaxAmmo ? 1 : Normalize((float)data.PrimaryAmmo, (float)Constants.MaxAmmo), PrimaryClip = Normalize(data.Primary, data.PrimaryClip), Secondary = Normalize(data.Secondary), SecondaryAmmo = data.SecondaryAmmo >= Constants.MaxAmmo ? 1 : Normalize((float)data.SecondaryAmmo, (float)Constants.MaxAmmo), SecondaryClip = Normalize(data.Secondary, data.SecondaryClip), }; // outcome (not normalize) result.Action = (float)data.Action; result.FaceAngle = data.Angle; result.MoveAngle = Collision.CalculateAngleFromPoint(0, 0, data.Xdelta, data.Ydelta); // proximity foreach (var elem in data.Proximity) { switch (elem.Name) { case "Ammo": result.Angle_1 = Normalize(elem.Angle, 360f); result.Distance_1 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Bandage": result.Angle_2 = Normalize(elem.Angle, 360f); result.Distance_2 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Helmet": result.Angle_3 = Normalize(elem.Angle, 360f); result.Distance_3 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "AK47": result.Angle_4 = Normalize(elem.Angle, 360f); result.Distance_4 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Shotgun": result.Angle_5 = Normalize(elem.Angle, 360f); result.Distance_5 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Pistol": result.Angle_6 = Normalize(elem.Angle, 360f); result.Distance_6 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Obstacle": result.Angle_7 = Normalize(elem.Angle, 360f); result.Distance_7 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; case "Player": result.Angle_8 = Normalize(elem.Angle, 360f); result.Distance_8 = Normalize(elem.Distance, (float)Constants.ProximityViewWidth); break; default: throw new Exception("Unknown proximity element type : " + elem.Name); } } return(result); }
public override ActionEnum Action(List <Element> elements, float angleToCenter, bool inZone, ref float xdelta, ref float ydelta, ref float zdelta, ref float angle) { // check if last action failed if (LastActionFailed > 0) { LastActionFailed--; xdelta = Xdelta; ydelta = Ydelta; return(ActionEnum.Move); } // construct a view of the current world var pname = ""; var pammo = 0; var pclip = 0; var sname = ""; var sammo = 0; var sclip = 0; if (Primary != null && Primary is RangeWeapon) { pname = Primary.GetType().Name; pammo = (Primary as RangeWeapon).Ammo; pclip = (Primary as RangeWeapon).Clip; } if (Secondary != null && Secondary.Length == 1 && Secondary[0] != null && Secondary[0] is RangeWeapon) { sname = Secondary.GetType().Name; sammo = (Secondary[0] as RangeWeapon).Ammo; sclip = (Secondary[0] as RangeWeapon).Clip; } var data = new TrainingData() { // core data CenterAngle = angleToCenter, InZone = inZone, Health = Health, Shield = Shield, Z = Z, Primary = pname, PrimaryAmmo = pammo, PrimaryClip = pclip, Secondary = sname, SecondaryAmmo = sammo, SecondaryClip = sclip }; data.Proximity = AITraining.ComputeProximity(this, elements).Values.ToList(); // use the model to predict its actions var modeldataset = data.AsModelDataSet(); int iAction = 0; { iAction = (int)Math.Round(ActionModel.Predict(modeldataset)); angle = AngleModel.Predict(modeldataset); XYModel.Predict(modeldataset, out xdelta, out ydelta); } // do some sanity checking... if (iAction < 0 || iAction >= (int)ActionEnum.COUNT) { iAction = (int)ActionEnum.Move; } if (Math.Abs(xdelta) + Math.Abs(ydelta) > 1.00001) { throw new Exception("xdelta and ydelta are invalid"); } while (angle < 0) { angle += 360; } while (angle >= 360) { angle -= 360; } if (angle < 0 || angle >= 360) { throw new Exception("Invalid angle: " + angle); } return((ActionEnum)iAction); }