public void AddAnt(int col, int row, int team) { if (team == 0) { var ant = new MyAnt { X = col, Y = row }; var index = MyAnts.BinarySearch(ant); if (index < 0) { MyAnts.Insert(~index, ant); NewAnt(ant); ant.Live = true; ant.Home = Hills.Where(x => x.DirectDistanceTo(ant) == Hills.Min(h => h.DirectDistanceTo(ant))).First(); } else { ApplyAntVision(ant); MyAnts[index].Live = true; } } else { var ant = new Ant { X = col, Y = row, Team = team }; EnemyAnts.Add(ant); } Map[col, row] = Tile.Ant; }
List <MoveData> MoveToExploreNV(MyAnt ant, GameState state) { var result = new List <MoveData>(); int maxExplore = 0; for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (ant.Exploration[i].VisibleCellCount > maxExplore && !state.NextTurnPreview[newLoc.X, newLoc.Y]) { maxExplore = ant.Exploration[i].VisibleCellCount; } } } if (maxExplore > 0) { for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (ant.Exploration[i].VisibleCellCount == maxExplore && !state.NextTurnPreview[newLoc.X, newLoc.Y]) { result.Add(new MoveData(newLoc, (Direction)i)); } } } } return(result); }
void ApplyAntVision(MyAnt ant) { FillVisionMap(ant); foreach (var loc in MoveVision) { var point = loc + ant; var tile = GetTile(point); if (tile == Tile.Unseen) { SetTile(point, Tile.Land); } } }
void NewAnt(MyAnt ant) { FillVisionMap(ant); foreach (var loc in FullVision) { var point = loc + ant; var tile = GetTile(point); if (tile == Tile.Unseen) { SetTile(point, Tile.Land); } } }
List <MoveData> MoveToFood(MyAnt ant, GameState state) { var result = new List <MoveData>(); for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (ant.Food.DistanceMap[newLoc.X, newLoc.Y] == ant.FoodDistance - 1 && !state.NextTurnPreview[newLoc.X, newLoc.Y]) { result.Add(new MoveData(newLoc, (Direction)i)); } } } return(result); }
List <MoveData> MoveFromHill(MyAnt ant, GameState state) { var result = new List <MoveData>(); if (ant.Home == null) { return(result); } if (ant.PointFromHill != null) { return(result); } var fromHillDirections = new int[4]; var stochastics = new int[4]; var locs = new Location[4]; var count = 0; for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (state.NextTurnPreview[newLoc.X, newLoc.Y]) { continue; } if (ant.Home.DistanceMap[ant.X, ant.Y] < ant.Home.DistanceMap[newLoc.X, newLoc.Y] && ant.Home.DistanceMap[ant.X, ant.Y] != -1) { if (ant.Home.StochasticMap[newLoc.X, newLoc.Y] == 0) { ant.Home.StochasticMap[newLoc.X, newLoc.Y] = PathFinding.GetTotalLeafCount(newLoc, ant.Home); } fromHillDirections[count] = i; stochastics[count] = ant.Home.StochasticMap[newLoc.X, newLoc.Y]; locs[count] = newLoc; count++; } } } if (count == 0 || stochastics.Sum() < 20) { return(result); } else { int r = rnd.Next(stochastics.Sum()); int sum = 0; for (int i = 0; i < count; i++) { if (r >= sum && r < sum + stochastics[i]) { return new List <MoveData> { new MoveData(locs[i], (Direction)fromHillDirections[i]) } } ; sum += stochastics[i]; } return(result); } } List <MoveData> MoveFromHillFast(MyAnt ant, GameState state) { var result = new List <MoveData>(); if (ant.PointFromHill != null) { return(result); } var fromHillDirections = new bool[4]; for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (state.NextTurnPreview[newLoc.X, newLoc.Y]) { continue; } if (ant.Home.DistanceMap[ant.X, ant.Y] <= ant.Home.DistanceMap[newLoc.X, newLoc.Y] && ant.Home.DistanceMap[ant.X, ant.Y] != -1) { result.Add(new MoveData(newLoc, (Direction)i)); } } } return(result); } List <MoveData> SpecificMoveFromHill(MyAnt ant, GameState state) { if (ant.Home == null) { return(new List <MoveData>()); } if (ant.PointFromHill != null) { var result = new List <MoveData>(); for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (!state.NextTurnPreview[newLoc.X, newLoc.Y]) { if (ant.SpecificPath[newLoc.X, newLoc.Y] != -1 && ant.SpecificPath[newLoc.X, newLoc.Y] < ant.SpecificPath[ant.X, ant.Y]) { result.Add(new MoveData(newLoc, (Direction)i)); } } } } return(result); } int radius = Math.Min(30, Math.Min(state.Width - 1, state.Height - 1)); do { var d = new Location(); for (int dCoo = 0; dCoo < radius; dCoo++) { for (int k = 0; k < 4; k++) { d.X = dCoo * (k / 2 == 0 ? -1 : 1); d.Y = (radius - dCoo) * (k % 2 == 0 ? -1 : 1); var loc = ant + d; if (!state.NextTurnPreview[loc.X, loc.Y]) { if (ant.Home.DistanceMap[loc.X, loc.Y] > ant.Home.DistanceMap[ant.X, ant.Y]) { if (ant.Home.StochasticMap[loc.X, loc.Y] == 0) { ant.Home.StochasticMap[loc.X, loc.Y] = PathFinding.GetTotalLeafCount(loc, ant.Home); } if (ant.Home.StochasticMap[loc.X, loc.Y] < 20) { continue; } ant.PointFromHill = loc; if (ant.SpecificPath == null) { ant.SpecificPath = new int[state.Width, state.Height]; } PathFinding.FillArray(loc, ant.SpecificPath, ant); var result = new List <MoveData>(); for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (!state.NextTurnPreview[newLoc.X, newLoc.Y]) { if (ant.SpecificPath[newLoc.X, newLoc.Y] != -1 && ant.SpecificPath[newLoc.X, newLoc.Y] < ant.SpecificPath[ant.X, ant.Y]) { result.Add(new MoveData(newLoc, (Direction)i)); } } } } return(result); } } } } radius++; }while (radius < state.Width && radius < state.Height); return(new List <MoveData>()); } List <MoveData> MoveRandom(MyAnt ant, GameState state) { var result = new List <MoveData>(); for (int i = 0; i < 4; i++) { if (ant.RightDirections[i]) { var newLoc = ant + PathFinding.Directions[i]; if (!state.NextTurnPreview[newLoc.X, newLoc.Y]) { result.Add(new MoveData(newLoc, (Direction)i)); } } } return(result); }
List <MoveData> TryMove(MyAnt ant, GameState state) { List <MoveData> result; if (ant.Defend != null) { result = DefendHill(ant, state); for (int i = 0; i < result.Count; i++) { result[i].Critical = true; } if (result.Count == 0) { return(MoveRandom(ant, state)); } else { return(result); } } if (ant.EnemyHill != null && ant.EnemyHillDistance < 10) { result = MoveToEnemyHill(ant, state); if (result.Count > 0) { return(result); } } if (state.Hills.Count > 0) { if (ant.Food != null) { result = MoveToFood(ant, state); if (ant.FoodDistance < 10) { for (int i = 0; i < result.Count; i++) { result[i].DeathForFood = true; } } if (result.Count > 0) { return(result); } } } if (!iSeeEnemy) { if (state.RemainMs > 150) { result = MoveFromHill(ant, state); } else { result = MoveFromHillFast(ant, state); } if (result.Count > 0) { return(result); } } result = MoveToExploreNew(ant, state); if (result.Count > 0) { return(result); } if (!ant.GoToEnemyHill) { if (state.RemainMs > 150) { result = MoveFromHill(ant, state); } else { result = MoveFromHillFast(ant, state); } if (result.Count > 0) { return(result); } } if (ant.EnemyHill != null) { result = MoveToEnemyHill(ant, state); if (result.Count > 0) { return(result); } } result = SpecificMoveFromHill(ant, state); if (result.Count > 0) { return(result); } result = MoveToExploreNV(ant, state); if (result.Count > 0) { return(result); } result = MoveRandom(ant, state); return(result); }
bool ProcessAnt(MyAnt ant, GameState state, int depth, List <MyAnt> usedAnts, List <Location> usedLocs) { if (!ant.RightDirections[0] && !ant.RightDirections[1] && !ant.RightDirections[2] && !ant.RightDirections[3]) { int minAttack = int.MaxValue; int goodDir = -1; for (int dir = 0; dir < 4; dir++) { var newLoc = ant + PathFinding.Directions[dir]; if (state.Map[newLoc.X, newLoc.Y] != Tile.Food && state.Map[newLoc.X, newLoc.Y] != Tile.Water) { int index = state.MyAnts.BinarySearch(new MyAnt(newLoc)); if (index >= 0 && state.MyAnts[index].Processed) { continue; } if (!state.NextTurnPreview[newLoc.X, newLoc.Y]) { int att = state.GetAttackLoc(newLoc); if (att < minAttack) { goodDir = dir; minAttack = att; } } } } if (minAttack != int.MaxValue) { ant.Move = true; ant.Direction = (Direction)goodDir; ant.Processed = true; var newLoc = ant + PathFinding.Directions[goodDir]; state.NextTurnPreview[newLoc.X, newLoc.Y] = true; return(true); } ant.Move = false; ant.Processed = true; state.NextTurnPreview[ant.X, ant.Y] = true; return(false); } var possibleMoves = TryMove(ant, state); if (possibleMoves.Count == 0) { return(false); } foreach (var md in possibleMoves) { md.Order = rnd.Next(0, 1000); } foreach (var md in possibleMoves.OrderBy(m => m.Order)) { List <MyAnt> rUsedAnts = null; List <Location> rUsedLocs = null; bool result = true; ant.Processed = true; state.NextTurnPreview[md.X, md.Y] = true; var index = state.MyAnts.BinarySearch(new MyAnt(md)); if (index >= 0) { if (!state.MyAnts[index].Processed) { rUsedAnts = new List <MyAnt>(); rUsedLocs = new List <Location>(); result = ProcessAnt(state.MyAnts[index], state, depth + 1, rUsedAnts, rUsedLocs); } } if (result) { if (!md.Critical || ant.FightDirections[(int)md.Direction] > 1) { if (!md.DeathForFood || (ant.FightDirections[(int)md.Direction] > 1 && state.Players == 2)) { if (ant.FightDirections[(int)md.Direction] > 0) { result = CheckForFight(md, state, null, null); if (!result && rUsedAnts != null && rUsedLocs != null) { for (int i = 0; i < rUsedAnts.Count; i++) { rUsedAnts[i].Processed = false; } for (int i = 0; i < rUsedLocs.Count; i++) { state.NextTurnPreview[rUsedLocs[i].X, rUsedLocs[i].Y] = false; } } } } } } if (!result) { if (depth == 0) { ant.RightDirections[(int)md.Direction] = false; } ant.Processed = false; ant.Move = false; state.NextTurnPreview[md.X, md.Y] = false; } if (result) { ant.Processed = true; ant.Direction = md.Direction; ant.Move = true; ant.AttackEnemyHill = md.AttackEnemyHill; if (usedAnts != null && usedLocs != null) { usedAnts.Add(ant); usedLocs.Add(md); if (rUsedAnts != null && rUsedLocs != null) { usedAnts.AddRange(rUsedAnts); usedLocs.AddRange(rUsedLocs); } } return(true); } } if (depth == 0) { return(ProcessAnt(ant, state, depth, null, null)); } else { return(false); } }