public float GetProperRotation(Ant criticalAnt, List <FormationInfo> allFormationInfos, out double deviation) { FormationInfo criticalFormationInfo = allFormationInfos.Find(x => x.ant == criticalAnt); double[,] currentDistributionWeight = new double[11, 11]; cuw = new double[11, 11]; foreach (FormationInfo info in allFormationInfos) { currentDistributionWeight[5 + info.blockX, 5 + info.blockY] += 1.0 / allFormationInfos.Count; cuw[5 + info.blockX, 5 + info.blockY] += 1.0 / allFormationInfos.Count; } deviation = Math.Sqrt(Variance(distributionWeight, currentDistributionWeight)); dev = deviation; List <BlockInfo> blockInfos = new List <BlockInfo>(); for (int x = -5; x <= 5; x++) { for (int y = -5; y <= 5; y++) { int newBlockX = Math.Min(Math.Max(criticalFormationInfo.blockX + x, -5), 5); int newBlockY = Math.Min(Math.Max(criticalFormationInfo.blockY + y, -5), 5); currentDistributionWeight[5 + newBlockX, 5 + newBlockY] -= 1.0 / allFormationInfos.Count; blockInfos.Add(new BlockInfo { x = newBlockX, y = newBlockY, weight = Variance(currentDistributionWeight, distributionWeight) }); currentDistributionWeight[5 + newBlockX, 5 + newBlockY] += 1.0 / allFormationInfos.Count; } } float minWeight = blockInfos.Min().weight; var blocks = blockInfos.FindAll(x => x.weight == minWeight); BlockInfo bestBlock = blocks.OrderBy(x => Guid.NewGuid().GetHashCode()).FirstOrDefault(); if (bestBlock.x == 0 && bestBlock.y == 0) { return(-1f); } else { Random r = new Random(Guid.NewGuid().GetHashCode()); return((MathTool.Direction2DToRotation2D(bestBlock.x + r.NextDouble() / 2 - 0.25, bestBlock.y + r.NextDouble() / 2 - 0.25) + 360f) % 360f); } }
public bool TakeFood(Ant ant) { if (!ant.IsTakingFood && storedFoodList.Count > 0) { Food food = storedFoodList[0]; if (ant.TakeFood(food)) { storedFoodList.RemoveAt(0); OnRemainedFoodCountChange?.Invoke(RemainedFoodCount); return(true); } else { return(false); } } else { return(false); } }
public virtual void Hit(Ant ant) { ant.Hurt(Damage); }
public float GetProperRotation(Ant ant) { Random annelingFactorGenerator = new Random(Guid.NewGuid().GetHashCode()); double annelingFactor = annelingFactorGenerator.NextDouble() * ant.HP / ant.MaxHP * 0.6; if (ant.IsTakingFood) { annelingFactor *= 0.2; } int sensorDistance = 1 + GrowthProperties.sensitivity; int antBlockX = Convert.ToInt32(ant.PositionX / 20) + 24; int antBlockY = Convert.ToInt32(ant.PositionY / 20) + 15; int formationX, formationY; GetFormationIndex(ant, out formationX, out formationY); List <BlockInfo> blockInfos = new List <BlockInfo>(); for (int x = -sensorDistance; x <= sensorDistance; x++) { if (antBlockX + x < 0 || x == 0 || antBlockX + x >= 48) { continue; } for (int y = -sensorDistance; y <= sensorDistance; y++) { if (antBlockY + y < 0 || y == 0 || antBlockY + y >= 30) { continue; } float extraWeight = 0; if (ant.IsTakingFood) { if (Math.Sqrt(Math.Pow(ant.PositionX + x - game.NestPositionX, 2) + Math.Pow(ant.PositionY + y - game.NestPositionY, 2)) < Math.Sqrt(Math.Pow(ant.PositionX - game.NestPositionX, 2) + Math.Pow(ant.PositionY - game.NestPositionY, 2))) { extraWeight = 0.1f; } } else if (game.FoodFactory.RemainedFoodCount > 0) { if (Math.Sqrt(Math.Pow(ant.PositionX + x - game.FoodPlatePositionX, 2) + Math.Pow(ant.PositionY + y - game.FoodPlatePositionY, 2)) < Math.Sqrt(Math.Pow(ant.PositionX - game.FoodPlatePositionX, 2) + Math.Pow(ant.PositionY - game.FoodPlatePositionY, 2))) { extraWeight = 0.1f; } } float formationWeight = 0; if (ant.IsTakingFood) { formationWeight = distributionMap.GetDirectionWeight(ant, game.AntFactory.GetFormationInfo(ant), x, y) / 2; } else { formationWeight = distributionMap.GetDirectionWeight(ant, game.AntFactory.GetFormationInfo(ant), x, y); } searchHelper = new HashSet <PositionInfo>(); blockInfos.Add(new BlockInfo { x = x, y = y, weight = GetLocalSurvive(antBlockX + x, antBlockY + y, 1 + GrowthProperties.sensitivity) / (1 + (float)Math.Sqrt(x * x + y * y) / 10) + extraWeight + formationWeight }); } } blockInfos.Sort(); int selectIndex = blockInfos.Count - 1 - annelingFactorGenerator.Next(Convert.ToInt32((blockInfos.Count - 1) * annelingFactor)); BlockInfo bestBlock = blockInfos[selectIndex]; if (bestBlock.x == 0 && bestBlock.y == 0) { return(-1); } else { return((Convert.ToSingle(Math.Atan2(bestBlock.y, bestBlock.x) * 180 / Math.PI + 45 * annelingFactor) + 360f) % 360f); } }
public float DistanceBetween(Ant ant) { return((float)Math.Sqrt(Math.Pow(PositionX - ant.PositionX, 2) + Math.Pow(PositionY - ant.PositionY, 2))); }