//turn locations into antData objects for compatibility with reused methods from previous practical public virtual void DoAction(GameState state, int hashcode) { //actions are serialised at the end, make sure to start fresh by clearing all the ant related data orders.Clear(); allAnts.Clear(); antLocations.Clear(); CreatAntData(state); }
protected void CreatAntData(GameState state) { foreach (Location loc in state.MyAnts) { if (!antLocations.ContainsKey(loc)) { AntData newAnt = new AntData(loc); antLocations.Add(loc, newAnt); allAnts.Add(newAnt); } } }
/// <summary> /// Ants took a page out of Google's book, "I'm feeling lucky". /// </summary> /// <param name="state"></param> public override void DoAction(GameState state, int hashcode) { base.DoAction(state, hashcode); //to guarantee the same actions regardless of the particular run Random random = new Random(hashcode); foreach (AntData ant in allAnts) { Location goal = SelectRandomNeighbor(ant.CurrentLocation, random); ant.AntRoute = new Route(ant.CurrentLocation, goal, new Location[] { ant.CurrentLocation, goal }); ant.AdvancePath(this); } }
public QState(GameState state) { MyAnts = CopyList(state.MyAnts); Food = CopyList(state.FoodTiles); EnemyAnts = CopyList(state.EnemyAnts); foreach (Location l in state.map) { if (state.GetIsVisible(l)) visibleTiles++; if (l.Visited) visitedTiles++; } CalculateReward(state); }
/// <summary> /// Ants will move and cluster towards enemies, dead ants add a fraction to the enemy influence. /// </summary> /// <param name="state"></param> public override void DoAction(GameState state, int hashcode) { base.DoAction(state, hashcode); // Make all ants attack, or at least close in on the enemy presence. foreach (AntData ant in allAnts) { // Select unoccupied/passable tile with maximum influence. Location next = ant.CurrentLocation.Neighbors[0]; float max = Globals.enemyInfluence[next.Row, next.Col]; foreach (Location l in ant.CurrentLocation.Neighbors) { if (Globals.enemyInfluence[l.Row, l.Col] > max && Globals.state.GetIsUnoccupied(l) && Globals.state.GetIsPassable(l)) { max = Globals.enemyInfluence[l.Row, l.Col]; next = l; } } //Perform move. ant.AntRoute = new Route(ant.CurrentLocation, next, new Location[] { ant.CurrentLocation, next }); ant.AdvancePath(this); } }
/// <summary> /// Move ants towards the nearest food source. /// </summary> /// <param name="state"></param> public override void DoAction(GameState state, int hashcode) { base.DoAction(state, hashcode); // We moved to influence based food gathering after some issues with the path planner. // Move all ants towards their closest food piece. foreach (AntData ant in allAnts) { // Select the unoccupied/passable tile in the direction of the closest food piece. Location next = ant.CurrentLocation.Neighbors[0]; float max = Globals.foodInfluence[next.Row, next.Col]; foreach (Location l in ant.CurrentLocation.Neighbors) if (Globals.foodInfluence[l.Row, l.Col] > max && Globals.state.GetIsUnoccupied(l) && Globals.state.GetIsPassable(l)) { max = Globals.foodInfluence[l.Row, l.Col]; next = l; } // Perform move. ant.AntRoute = new Route(ant.CurrentLocation, next, new Location[] { ant.CurrentLocation, next }); ant.AdvancePath(this); } }
public override void DoTurn(GameState state) { foreach (Location enm in state.EnemyAnts) Globals.enemyInfluence.AddInfluence(enm, 10.0f); foreach (Location enm in state.EnemyHills) { Globals.enemyInfluence.AddInfluence(enm, 1.0f); Globals.hillInfluence.AddInfluence(enm, 15.0f); } foreach (Location fnd in state.MyAnts) Globals.friendlyInfluence.AddInfluence(fnd, 10.0f); foreach (Location fnd in state.MyHills) Globals.friendlyInfluence.AddInfluence(fnd, 1.0f); foreach (Location ded in state.DeadTiles) Globals.enemyInfluence.AddInfluence(ded, 10.0f); foreach (Location loc in state.FoodTiles) Globals.foodInfluence.AddInfluence(loc, 10.0f); Globals.enemyInfluence.UpdateInfluence(); Globals.friendlyInfluence.UpdateInfluence(); Globals.hillInfluence.UpdateInfluence(); Globals.foodInfluence.UpdateInfluence(); #if DEBUG Learner.LearnPolicy(state, false); #endif #if RELEASE Learner.ExecutePolicy(state,false); #endif }
// DoTurn is run once per turn public override void DoTurn(GameState state) { state.expectedLocation.Clear(); //attack until our number of ants falls below 250 from 300 if (!attackMode && state.MyAnts.Count > 300) attackMode = true; if (attackMode && state.MyAnts.Count < 250) attackMode = false; this.diffuseOne(state); this.diffuseTwo(state); // loop through all my ants and try to give them orders foreach (Ant ant in state.MyAnts) { Location up = state.GetDestination(ant, Direction.North); Location right = state.GetDestination(ant, Direction.East); Location left = state.GetDestination(ant, Direction.West); Location down = state.GetDestination(ant, Direction.South); List<Tup4> adjacentTiles = new List<Tup4>(); //use diffusion layer 1 this layer prefers to harvest food and grow the ant colony if (!attackMode) { Tup4 n1 = new Tup4(state.diffusionOne[up.Row, up.Col], Direction.North, up.Row, up.Col); Tup4 e1 = new Tup4(state.diffusionOne[right.Row, right.Col], Direction.East, right.Row, right.Col); Tup4 w1 = new Tup4(state.diffusionOne[left.Row, left.Col], Direction.West, left.Row, left.Col); Tup4 s1 = new Tup4(state.diffusionOne[down.Row, down.Col], Direction.South, down.Row, down.Col); adjacentTiles.Add(n1); adjacentTiles.Add(e1); adjacentTiles.Add(s1); adjacentTiles.Add(w1); } else { Tup4 n2 = new Tup4(state.diffusionTwo[up.Row, up.Col], Direction.North, up.Row, up.Col); Tup4 e2 = new Tup4(state.diffusionTwo[right.Row, right.Col], Direction.East, right.Row, right.Col); Tup4 w2 = new Tup4(state.diffusionTwo[left.Row, left.Col], Direction.West, left.Row, left.Col); Tup4 s2 = new Tup4(state.diffusionTwo[down.Row, down.Col], Direction.South, down.Row, down.Col); //use diffusion layer 2, this layer prefers to be aggressive adjacentTiles.Add(n2); adjacentTiles.Add(s2); adjacentTiles.Add(e2); adjacentTiles.Add(w2); } double maxDiffusion = 0; //assume the ant can't move Direction direction = Direction.East; int ct = 0; int row = 0; int col = 0; //check the four adjacent tiles to move while (ct < 4) { //check if this tile has a higher diffusion score and that it is not occupied already by a friendly ant if (adjacentTiles[ct].Item1 > maxDiffusion && state.diffusionOne[adjacentTiles[ct].Item3, adjacentTiles[ct].Item4] > 0 && state.GetIsUnoccupied(new Location(adjacentTiles[ct].Item3, adjacentTiles[ct].Item4))) { maxDiffusion = adjacentTiles[ct].Item1; direction = adjacentTiles[ct].Item2; row = adjacentTiles[ct].Item3; col = adjacentTiles[ct].Item4; } ct += 1; } //ants will only move onto tiles with a diffusion score > 0 if (maxDiffusion > 0) { IssueOrder(ant, direction); state.diffusionOne[row, col] = 0; state.expectedLocation[state.GetDestination(ant, direction)] = ant; } else { //ant could not move expected location is the same state.expectedLocation[new Location(ant.Row, ant.Col)] = ant; } // check if we have time left to calculate more orders if (state.TimeRemaining < 10) { //exit the loop immediately to prevent the bot from timing out break; } } }
/// <summary> /// Calculate the current diffusion scores for layer 2. /// </summary> /// <param name="state">The state.</param> public void diffuseTwo(GameState state) { for (int row = 0; row < state.Height; row++) { for (int col = 0; col < state.Width; col++) { if (state.map[row, col] == Tile.Water) state.diffusionTwo[row, col] = WATER_SCORE; else if (state.map[row, col] == Tile.Ant && state.ants.ContainsKey(new Location(row, col)) && state.ants[new Location(row, col)].Team != 0) { state.diffusionTwo[row, col] = ENEMY_ANT_SCORE_D2; } else if (state.map[row, col] == Tile.Unseen) { state.diffusionTwo[row, col] = UNSEEN_SCORE_D2; } else if (state.isEnemyHill(row, col)) { state.diffusionTwo[row, col] = ENEMYHILL_SCORE_D2; } else if (state.isMyHill(row, col)) { state.diffusionTwo[row, col] = MYHILL_SCORE; } else { double u = state.diffusionTwo[row, col]; Location location = new Location(row, col); Location up = state.GetDestination(location, Direction.North); Location right = state.GetDestination(location, Direction.East); Location left = state.GetDestination(location, Direction.West); Location down = state.GetDestination(location, Direction.South); state.diffusionTwo[row, col] = u + D2_COEFFICIENT * (1 + state.diffusionTwo[up.Row, up.Col] + state.diffusionTwo[down.Row, down.Col] + state.diffusionTwo[left.Row, left.Col] + state.diffusionTwo[right.Row, right.Col] - u * 4); } } } }
private Goal GatherFood(AntLoc ant, GameState state) { if (!state.FoodTiles.Any()) return Scout(ant, state); Log("foodtiles: " + state.FoodTiles.Count); // look for some food var searchingspots = state.FoodTiles.Where(f => Goals.Count(g => g.EndPoint.Equals(f))==0); Log("searchingspots: " + searchingspots.Count()); //searchingspots = searchingspots.Where(f => f.GetDistance(ant) < GetSearchRadius(state)).OrderBy(f => f.GetDistance(ant)).Take(2); var foodpoints = searchingspots.Select(f => new { Tile = f, Point = f.ToPoint(), Distance = state.GetDistance(ant,f)//astar.Search(ant.ToPoint(), f.ToPoint(), new Object()) ?? Enumerable.Empty<Tile>() }); var closest = foodpoints.OrderBy(f => f.Distance).FirstOrDefault(); if (closest != null) { Log("closest food:" + closest.Tile); return new Goal(closest.Tile, GetPath(ant,closest.Tile,state), (g => !g.HasFood(closest.Tile)), Strategy.GatherFood); } return SpreadOut(ant, state); }
public abstract void Initialise(GameState state);
// doTurn is run once per turn public override void doTurn(GameState state) { #if DEBUG sw.WriteLine ("!Turn " + number++); #endif destinations.Clear (); currentTurn.Clear (); #region Setup Discovery Aims List<Location > Discovery = new List<Location> (); for (int row = 0; row < state.Height / (state.ViewRadius2 / 2); row++) { for (int col = 0; col < state.Width / (state.ViewRadius2 / 2); col++) { Discovery.Add (new Location (row, col)); } } foreach (var ant in state.MyAnts) { Location tmp = new Location (ant.row / (state.ViewRadius2 / 2), ant.col / (state.ViewRadius2 / 2)); if (Discovery.Contains (tmp)) Discovery.Remove (tmp); } #endregion Location[] hod = new Location[] {new Location (0, -state.ViewRadius2 - 1), new Location (0, state.ViewRadius2 + 1), new Location (-state.ViewRadius2 - 1, 0), new Location (state.ViewRadius2 + 1, 0) , new Location (-state.ViewRadius2 / 2 - 1, -state.ViewRadius2 / 2 + 1), new Location (state.ViewRadius2 / 2 + 1, state.ViewRadius2 / 2 + 1), new Location (state.ViewRadius2 / 2 + 1, -state.ViewRadius2 / 2 - 1), new Location (-state.ViewRadius2 / 2 - 1, state.ViewRadius2 / 2 + 1)}; Location[] smeshnie = new Location[] {new Location (0, -state.ViewRadius2 - rng.Next (state.ViewRadius2)), new Location (0, state.ViewRadius2 + rng.Next (state.ViewRadius2)), new Location (-state.ViewRadius2 - rng.Next (state.ViewRadius2), 0), new Location (state.ViewRadius2 + rng.Next (state.ViewRadius2), 0)}; #region Find Guard for my Hills IDictionary<AntLoc, Location > Guard = new Dictionary<AntLoc, Location> (); foreach (var hill in state.MyHills) { foreach (var dest in Ants.Aim.Keys) { Location loc = state.destination (hill, dest); if (state.passable (loc)) { Guard.Add (hill, loc); break; } } } #endregion #region aim ants to food + Enemy hills //Add Enemy Hill to AIM food :) foreach (var hill in state.EnemyHills) { state.FoodTiles.Add (new Location (hill.row, hill.col)); } foreach (var food in state.FoodTiles) { int dist = int.MaxValue; AntLoc antFood = null; foreach (var ant in state.MyAnts) { if (!currentTurn.ContainsKey (ant)) if (state.distance (ant, food) < dist) { dist = state.distance (ant, food); antFood = ant; } } if (antFood != null) { currentTurn.Add (antFood, food); #if DEBUG sw.WriteLine (" ant " + antFood + " food " + food); #endif } else break; } #endregion #region Enemy aim foreach (var ant in state.MyAnts) { int distEnemy = state.ViewRadius2 * 3; Location aimEnemy = null; int dist; int attakEnemy = 0; foreach (var enemy in state.EnemyAnts) { dist = state.distance (ant, enemy); if (dist < distEnemy) { distEnemy = dist; aimEnemy = enemy; } if (dist < state.AttackRadius2 + 1) attakEnemy++; } if (aimEnemy != null) { //find frinds in state.AttackRadius2 int attakFrinds = 0; int saveDist = state.AttackRadius2 + 1; foreach (var friends in state.MyAnts) { dist = state.distance (aimEnemy, friends); if (dist < saveDist) { attakFrinds++; } } #if DEBUG sw.WriteLine (" ant " + ant + " friends " + attakFrinds + " they " + attakEnemy + " aim " + aimEnemy); #endif //I am alone if ((attakFrinds <= attakEnemy) && (distEnemy < state.AttackRadius2 + 3)) { int runDist = distEnemy; Location runLoc = null; foreach (Location loc in hod) { Location newLoc = state.destination (ant, loc); if (state.unoccupied (newLoc)) { if (runDist < state.distance (newLoc, aimEnemy)) { runDist = state.distance (newLoc, aimEnemy); runLoc = newLoc; } } } if (runLoc != null) { aimEnemy = runLoc; distEnemy = runDist; } #if DEBUG sw.WriteLine (" ant " + ant + " run from enemy to " + aimEnemy); #endif } /**/ if (currentTurn.ContainsKey (ant)) { int tmp = state.distance (ant, currentTurn [ant]); if (tmp > distEnemy) { Location food = currentTurn [ant]; currentTurn [ant] = aimEnemy; aimEnemy = null; tmp = int.MaxValue; foreach (var ants in state.MyAnts) { if (!currentTurn.ContainsKey (ants) && (state.distance (ant, food) < tmp)) { tmp = state.distance (ant, food); aimEnemy = ants; } } if (aimEnemy != null) currentTurn.Add (new AntLoc (aimEnemy, 0), food); } } else currentTurn.Add (ant, aimEnemy); } } #endregion #region Move other ants foreach (var ant in state.MyAnts) { if (!currentTurn.ContainsKey (ant)) { Location aim = smeshnie [rng.Next (4)]; if (Discovery.Count > 0) { int dist = int.MaxValue; foreach (var loc in Discovery) { Location aimTmp = new Location (loc.row * (state.ViewRadius2 / 2), loc.col * (state.ViewRadius2 / 2)); int tmp = state.distance (aimTmp, ant); if (tmp < dist) { dist = tmp; aim = aimTmp; } } } if (oldTurn.ContainsKey (ant)) { if (state.distance (ant, oldTurn [ant]) > (state.ViewRadius2 / 2)) { aim = oldTurn [ant]; } } currentTurn.Add (ant, aim); #if DEBUG sw.WriteLine (" ant " + ant + " move " + aim); #endif } } #endregion #region Setup guard if (state.MyAnts.Count > 5 * state.MyHills.Count) { foreach (var hill in Guard.Keys) { AntLoc tmp = new AntLoc (Guard [hill], 0); if (currentTurn.ContainsKey (tmp)) { currentTurn [tmp] = Guard [hill]; } else { int dist = int.MaxValue; AntLoc antGuard = null; foreach (var ant in state.MyAnts) { if (state.distance (hill, ant) < dist) { dist = state.distance (hill, ant); antGuard = ant; } } if (antGuard != null) if (currentTurn.ContainsKey (antGuard)) currentTurn [antGuard] = Guard [hill]; else currentTurn.Add (antGuard, Guard [hill]); } } } #endregion /**/ #if DEBUG sw.WriteLine("runs ANTS"); #endif #region runs Ants oldTurn = new Dictionary<AntLoc, Location> (); foreach (AntLoc ant in currentTurn.Keys) { List<char > directions = state.direction_algor_A (ant, currentTurn [ant]); if (directions.Count == 0) { //добавление препядствия state.addAnt (ant.row, ant.col, 0); #if DEBUG sw.WriteLine (" ant " + ant + " stop "); #endif } else { AntLoc NewAnt = new AntLoc (state.destination (ant, directions [0]), 0); //странно пытаемся переститься на своего муровья if (!oldTurn.ContainsKey (NewAnt)) { issueOrder (ant, directions [0]); //добавление препядствия state.addAnt (NewAnt.row, NewAnt.col, 0); oldTurn.Add (NewAnt, currentTurn [ant]); #if DEBUG sw.WriteLine (" ant " + ant + " move " + NewAnt); #endif } else { state.addAnt (ant.row, ant.col, 0); } }/**/ if (state.TimeRemaining < 50) { return; } } #endregion } #endregion Methods } }
public override bool Apllicable(GameState state) { return state.FoodTiles.Count > 0; }
private void SetTurnStrategy(GameState state) { foreach (var a in state.MyAnts) { Log("ant loc: " + a); } Location mycenter = new Location(state,(int)Math.Round(state.MyAnts.Average(a => a.Row)), (int)Math.Round(state.MyAnts.Average(a => a.Col))); Log("ants center:" + mycenter); int totalfriends = state.MyAnts.Count; int closefriends = state.MyAnts.Count(a => state.GetDistance(a, mycenter) <= state.AttackRadius2 * CLOSE_FACTOR); Log("friends:" + totalfriends + "," + closefriends); int totalenemies = state.EnemyAnts.Count; int closeenemies = state.EnemyAnts.Count(a => state.GetDistance(a, mycenter) <= state.AttackRadius2 * CLOSE_FACTOR); Log("enemies:" + totalenemies + "," + closeenemies); int totalfood = state.FoodTiles.Count; int closefood = state.FoodTiles.Count(f => state.GetDistance(f, mycenter) <= state.AttackRadius2 * CLOSE_FACTOR); Log("food:" + totalfood + "," + closefood); if (closefood > 0 || totalfood > 0) AlterStrategy(Strategy.GatherFood, Preference.MildlyEncourage); else { AlterStrategy(Strategy.Scout, Preference.StronglyEncourage); AlterStrategy(Strategy.Scout, Preference.StronglyEncourage); AlterStrategy(Strategy.Scatter, Preference.StronglyEncourage); AlterStrategy(Strategy.SpreadOut, Preference.StronglyEncourage); AlterStrategy(Strategy.SpreadOut, Preference.StronglyEncourage); } if (closeenemies > closefriends) { AlterStrategy(Strategy.Fight, Preference.StronglyDiscourage); AlterStrategy(Strategy.Condense, Preference.MildlyEncourage); AlterStrategy(Strategy.Scatter, Preference.MildlyDiscourage); AlterStrategy(Strategy.Retreat, Preference.StronglyEncourage); } else if (closeenemies == closefriends && closeenemies > 0) { AlterStrategy(Strategy.Condense, Preference.StronglyEncourage); AlterStrategy(Strategy.Scatter, Preference.StronglyDiscourage); AlterStrategy(Strategy.Fight, Preference.MildlyEncourage); } else //if (closeenemies < closefriends) { if (closeenemies > 0) { AlterStrategy(Strategy.Fight, Preference.StronglyEncourage); AlterStrategy(Strategy.Retreat, Preference.StronglyDiscourage); AlterStrategy(Strategy.Condense, Preference.MildlyEncourage); AlterStrategy(Strategy.Scatter, Preference.StronglyDiscourage); } else { AlterStrategy(Strategy.Scout, Preference.MildlyEncourage); AlterStrategy(Strategy.Condense, Preference.MildlyDiscourage); AlterStrategy(Strategy.Scatter, Preference.MildlyEncourage); } } if (totalfriends < totalenemies && totalenemies > 0) { if (closefood > closeenemies) { AlterStrategy(Strategy.GatherFood, Preference.StronglyEncourage); AlterStrategy(Strategy.Fight, Preference.MildlyDiscourage); AlterStrategy(Strategy.Retreat, Preference.MildlyDiscourage); AlterStrategy(Strategy.Scatter, Preference.MildlyEncourage); } else { AlterStrategy(Strategy.Scout, Preference.StronglyEncourage); AlterStrategy(Strategy.Fight, Preference.MildlyDiscourage); AlterStrategy(Strategy.Scatter, Preference.MildlyEncourage); } } else //if (totalfriends > totalenemies) { if (totalenemies > 0) { AlterStrategy(Strategy.Fight, Preference.StronglyEncourage); } AlterStrategy(Strategy.Scout, Preference.MildlyEncourage); AlterStrategy(Strategy.Scatter, Preference.MildlyEncourage); } }
private Goal Scout(AntLoc ant, GameState state) { return SpreadOut(ant, state); }
private Goal Scatter(AntLoc ant, GameState state) { // wander aimlessly foreach (var d in Ants.Ants.Aim.Values.OrderBy(c => rng.Next())) { var loc = ant.GetDestination(d); if (loc.IsPassable()) { return new Goal(ant, GetPath(ant, loc, state), (s => state.FoodTiles.Any()), Strategy.Scatter); } } return null; }
private Goal Retreat(AntLoc ant, GameState state) { return Condense(ant, state); }
private double GetSearchRadius(GameState state) { return Math.Sqrt(state.Width * state.Height) / 15; }
private LinkedList<Tile> GetPath(Location loc1, Location loc2, GameState state) { if (Math.Abs(loc1.Col - loc2.Col) > state.ViewRadius2 || Math.Abs(loc1.Row - loc2.Row) > state.ViewRadius2) { Log("closest is a map wrap - use basic path function"); return state.GetPath(loc1, loc2); } else { Log("use astar path function"); return astar.Search(loc1.ToPoint(), loc2.ToPoint(), new Object()); } }
// parse initial input and setup starting game state private void ParseSetup(List<string> input) { int width = 0, height = 0; int turntime = 0, loadtime = 0; int playerSeed = 0; int viewradius2 = 0, attackradius2 = 0, spawnradius2 = 0; foreach (string line in input) { if (string.IsNullOrEmpty (line)) continue; string[] tokens = line.Split(); string key = tokens[0]; switch (key) { case "cols": width = int.Parse(tokens[1]); break; case "rows": height = int.Parse(tokens[1]); break; case "player_seed": playerSeed = int.Parse(tokens[1]); break; case "turntime": turntime = int.Parse(tokens[1]); break; case "loadtime": loadtime = int.Parse(tokens[1]); break; case "viewradius2": viewradius2 = int.Parse(tokens[1]); break; case "attackradius2": attackradius2 = int.Parse(tokens[1]); break; case "spawnradius2": spawnradius2 = int.Parse(tokens[1]); break; } } this.state = new GameState(width, height, turntime, loadtime, viewradius2, attackradius2, spawnradius2, playerSeed); }
public override bool Apllicable(GameState state) { return true; }
private Goal SpreadOut(AntLoc ant, GameState state) { if (state.TimeRemaining < 10) return Scatter(ant, state); // try and figure out how close to the edge of vision I am var x = ant.Col; var y = ant.Row; var minX = state.MyAnts.Min(a => a.Col); var maxX = state.MyAnts.Max(a => a.Col); var minY = state.MyAnts.Min(a => a.Row); var maxY = state.MyAnts.Max(a => a.Row); var widthModifier = state.Width / 30; if (widthModifier <= 1) widthModifier = 2; var heightModifier = state.Height / 30; if (heightModifier <= 1) heightModifier = 2; Func<GameState, bool> terminationFunc = (s => false); Log("spread out: minx:" + minX + " miny:" + minY + " maxx:" + maxX + " maxy:" + maxY + " widthmod:" + widthModifier + " heightmod:" + heightModifier); // near the left (ish) if (x < ( minX + widthModifier)) { var loc = new Location(state,y,x-widthModifier); //move left Log("left, path :" + ant + " " + loc); var path = GetPath(ant, loc, state); if (path != null) { return new Goal(ant, path, terminationFunc, Strategy.SpreadOut); } } else if (x > ( maxX - widthModifier )) { var loc = new Location(state, y,x + widthModifier); //move right Log("right, path :" + ant + " " + loc); var path = GetPath(ant, loc, state); if (path != null) { return new Goal(ant, path, terminationFunc, Strategy.SpreadOut); } } else if (y < ( maxY + heightModifier )) { var loc = new Location(state, y - heightModifier,x); //move up Log("top, path :" + ant + " " + loc); var path = GetPath(ant, loc, state); if (path != null) { return new Goal(ant, path, terminationFunc, Strategy.SpreadOut); } } else if (y > ( maxY - heightModifier )) { var loc = new Location(state, y + heightModifier,x); // move down Log("bottom, path :" + ant + " " + loc); var path = GetPath(ant, loc, state); if (path != null) { return new Goal(ant, path, terminationFunc, Strategy.SpreadOut); } } return Scatter(ant,state); }
// parse initial input and setup starting game state private void ParseSetup(List<string> input) { int width = 0, height = 0; int turntime = 0, loadtime = 0; int viewradius2 = 0, attackradius2 = 0, spawnradius2 = 0; foreach (string line in input) { if (line.Length <= 0) continue; string[] tokens = line.Split(); string key = tokens[0]; if (key.Equals(@"cols")) { width = int.Parse(tokens[1]); } else if (key.Equals(@"rows")) { height = int.Parse(tokens[1]); } else if (key.Equals(@"seed")) { ; } else if (key.Equals(@"turntime")) { turntime = int.Parse(tokens[1]); } else if (key.Equals(@"loadtime")) { loadtime = int.Parse(tokens[1]); } else if (key.Equals(@"viewradius2")) { viewradius2 = int.Parse(tokens[1]); } else if (key.Equals(@"attackradius2")) { attackradius2 = int.Parse(tokens[1]); } else if (key.Equals(@"spawnradius2")) { spawnradius2 = int.Parse(tokens[1]); } } this.state = new GameState(width, height, turntime, loadtime, viewradius2, attackradius2, spawnradius2); }
public override void doTurn(GameState state) { try { if (state.TimeRemaining < 5) return; if (turn == 0) { Log("my team: player " + (state.MyAnts.First().Team + 1)); Log("map " + state.Width+"x"+state.Height); Log("turn time " + state.TurnTime); } Log(""); Log("Turn " + (turn++)); Log("My Ants: " + state.MyAnts.Count); SetTurnStrategy(state); string stratstring = ""; foreach (var v in Enum.GetValues(typeof(Strategy))) { stratstring += Enum.GetName(typeof(Strategy), v) + ":" + strategies[(int)v] + ";"; } Log("Strategy: " + stratstring); this.Destinations.Clear(); astar = new SpatialAStar<Tile, object>(state.Map); foreach (var goal in Goals) goal.AntExists = false; //need to check these each turn and clean up if ant gone foreach (AntLoc ant in state.MyAnts) { Log("ant: " + ant); Goal goal = this.Goals.FirstOrDefault(g => g.CurrentPoint.Equals(ant)); if (goal != null && (goal.CurrentPath.Count==0 || goal.IsTerminated(state))) { if (goal.CurrentPath.Count == 0) Log("ant goal complete"); else Log("ant goal terminated"); Goals.Remove(goal); goal = null; } if (goal != null) { goal.AntExists = true; Log("ant existing goal: " + String.Join(";", goal.CurrentPath.Select(p => p.Location.ToString()).ToArray()) + " " + Enum.GetName(typeof(Strategy), goal.CurrentStrategy)); } else { if (state.TimeRemaining < 50) // choose a fast strategy { Log("short on time ("+state.TimeRemaining+") - choose scatter"); goal = Scatter(ant, state); } else { goal = ChooseStrategy(ant, state); if (!goal.CurrentPath.Any()) { Log("bad goal/path - scatter instead"); goal = Scatter(ant, state); } } Goals.Add(goal); Log("new ant goal: " + String.Join(";", goal.CurrentPath.Select(p => p.Location.ToString()).ToArray()) + " " + Enum.GetName(typeof(Strategy), goal.CurrentStrategy)); } if (goal != null) { var loc = goal.CurrentPath.Dequeue(); var directions = ant.GetDirections(loc.Location); foreach (var d in directions) { var newLoc = ant.GetDestination(d); if (state.IsUnoccupied(newLoc) && state.IsPassable(newLoc) && !Destinations.Contains(newLoc)) { ant.Move(d); goal.CurrentPoint = newLoc; goal.CurrentStep++; Destinations.Add(newLoc); break; } } } } int removed = Goals.RemoveAll(g => !g.AntExists);//clean up goals for missing ants Log("ant goals(" + Goals.Count + ", "+removed+" removed): " + String.Join(";", Goals.Select(g => "["+Enum.GetName(typeof(Strategy),g.CurrentStrategy)+"]"+g.CurrentPoint.ToString()+"->"+g.EndPoint.ToString()).ToArray())); if (removed > 0) // losing fights - condense { AlterStrategy(Strategy.Condense, Preference.StronglyEncourage); AlterStrategy(Strategy.Condense, Preference.StronglyEncourage); AlterStrategy(Strategy.Condense, Preference.StronglyEncourage); } } catch (Exception exc) { Log(exc.Message); Log(exc.StackTrace); } }
private Goal ChooseStrategy(AntLoc ant, GameState state) { Strategy? strat = null; float rnd = rng.Next(0, (int)(strategies.Sum()*100)) * .01f; for (int i = 1; i < STRAT_COUNT; i++) { if (rnd < strategies.Take(i).Sum()) { strat = (Strategy)(i - 1); break; } } if(strat==null) strat = (Strategy)(STRAT_COUNT - 1); Goal goal = null; if (strat == Strategy.GatherFood) goal = GatherFood(ant, state); else if (strat == Strategy.Fight) goal = Fight(ant, state); else if (strat == Strategy.SpreadOut) goal = SpreadOut(ant, state); else if (strat == Strategy.Scatter) goal = Scatter(ant, state); else if (strat == Strategy.Scout) goal = Scout(ant, state); else if (strat == Strategy.Condense) goal = Condense(ant, state); else if (strat == Strategy.Retreat) goal = Retreat(ant, state); if (goal == null) { goal = GatherFood(ant, state); } if (goal == null) { goal = Scout(ant, state); } if (goal == null) { goal = Fight(ant, state); } if (goal == null) { goal = SpreadOut(ant, state); } if (goal == null) { goal = Scatter(ant, state); } if (goal == null) { goal = Condense(ant, state); } if (goal == null) { goal = Retreat(ant, state); } return goal; }
private void CalculateReward(GameState state) { int result = 0; result += MyAnts.Count * 100; result += visibleTiles + visitedTiles; float foodClaimed = 0f; float longestDistanceToFood = 0f; foreach (Location food in Food)//calculates how many food bits we can gather, and how far the furthest one is { if (foodClaimed >= MyAnts.Count) break; int leastDistance = int.MaxValue; Location closestAnt = null; foreach (Location ant in MyAnts) { int distance = Globals.pathFinder.FindRoute(ant, food).GetDistance; if (distance < leastDistance) { leastDistance = distance; closestAnt = ant; } } foodClaimed++; if (longestDistanceToFood < leastDistance) longestDistanceToFood = leastDistance; } int expectedAntGain = (int)Math.Ceiling(foodClaimed / longestDistanceToFood); result += expectedAntGain * 10; Reward = result; }
public abstract void DoTurn(GameState state);
/// <summary> /// Calculate the current diffusion scores for layer 1. /// </summary> /// <param name="state">The state.</param> public void diffuseOne(GameState state) { for (int row = 0; row < state.Height; row++) { for (int col = 0; col < state.Width; col++) { if (state.map[row, col] == Tile.Water) { state.diffusionOne[row, col] = WATER_SCORE; } else if (state.map[row, col] == Tile.Ant) { state.diffusionOne[row, col] = MY_ANT_SCORE_D1; Location location = new Location(row, col); if (state.ants.ContainsKey(location)) { Ant ant = state.ants[location]; if (ant.Team != 0) { List<AntHill> myHills = state.MyHills; foreach (AntHill myHill in myHills) { if (state.GetDistance(myHill, ant) <= 12) { state.diffusionOne[row, col] = HILL_IN_DANGER; break; } } } } } else if (state.map[row, col] == Tile.Food) { state.diffusionOne[row, col] = FOOD_SCORE_D1; } else if (state.map[row, col] == Tile.Unseen) { state.diffusionOne[row, col] = UNSEEN_SCORE_D1; } else if (state.isEnemyHill(row, col)) { state.diffusionOne[row, col] = ENEMYHILL_SCORE_D1; } else if (state.isMyHill(row, col)) { state.diffusionOne[row, col] = MYHILL_SCORE; } else { double u = state.diffusionOne[row, col]; Location L = new Location(row, col); Location up = state.GetDestination(L, Direction.North); Location right = state.GetDestination(L, Direction.East); Location left = state.GetDestination(L, Direction.West); Location down = state.GetDestination(L, Direction.South); state.diffusionOne[row, col] = u + D1_COEFFICIENT * (1 + state.diffusionOne[up.Row, up.Col] + state.diffusionOne[down.Row, down.Col] + state.diffusionOne[left.Row, left.Col] + state.diffusionOne[right.Row, right.Col] - u * 4); } } } }
public abstract void LastTurn(GameState state, bool won);
private Goal Fight(AntLoc ant, GameState state) { if (!state.EnemyAnts.Any()) return Scout(ant, state); // look for some food var searchingspots = state.EnemyAnts.Where(f => Goals.Count(g => g.EndPoint.Equals(f)) <= 1); //searchingspots = searchingspots.Where(f => f.GetDistance(ant) < GetSearchRadius(state)).OrderBy(f => f.GetDistance(ant)).Take(2); var antpoint = ant.ToPoint(); var enemypoints = searchingspots.Select(f => new { Tile = f, Point = f.ToPoint(), Distance = state.GetDistance(ant,f)//astar.Search(ant.ToPoint(), f.ToPoint(), new Object()) ?? Enumerable.Empty<Tile>() }); var closest = enemypoints.OrderBy(f => f.Distance).FirstOrDefault(); if (closest != null) { var goal = new Goal(closest.Tile, GetPath(ant, closest.Tile, state), (g => g.IsUnoccupied(closest.Tile)), Strategy.Fight); return goal; } return SpreadOut(ant, state); }