private void ReceivedGameState(dynamic content) { try { if (!inGame || muted) { return; } map.BeginRound(); foreach (var obj in content.gameobjects) { string type = obj[0].ToLower(); int row = obj[1]; int col = obj[2]; if (type.Equals("a") || type.Equals("b")) { // Living ant int owner = obj[3]; if (owner == 0) { map.CheckAnt(col, row); } else { map.AddEnemy(col, row); } } else if (type.Equals("d")) { // Dead ant int owner = obj[3]; if (owner == 0) { map.RemoveDeadAnt(col, row); } } else if (type.Equals("w")) { // Wall / water map.RegisterWall(col, row); } else if (type.Equals("f")) { // Food map.AddFood(col, row); } } map.RemoveUnconfirmedAnts(); // Uncomment to display the map in the console every turn //Console.Write("\n"+map); GameActionsMessage msg = new GameActionsMessage(); map.ComputeMoves(msg); SendMessage(msg); } catch (RuntimeBinderException) { Console.WriteLine("Error: malformed server message (gamestate). " + content); } }
public void ComputeMoves(GameActionsMessage msg) { // Next ants positions Dictionary <Coordinates, Ant> updated = new Dictionary <Coordinates, Ant>(); Random rand = new Random(); foreach (KeyValuePair <Coordinates, Ant> pair in MyAnts) { Ant ant = pair.Value; Coordinates pos = pair.Key; AntDirection move; Coordinates next; if (ant.HasFood) { if (ant.History.Count > 0 && !Hills.Contains(pos)) { // Walk back move = ant.History.Pop().Reverse(); next = pos.ApplyDirection(move).Normalize(this); // If the path is blocked, don't move (and put the move back on the history for next round) if (!Enemies.Contains(next) && !updated.ContainsKey(next)) { msg.AddMove(pos.Col, pos.Row, move.ToString()); updated.Add(next, ant); } else { ant.History.Push(move.Reverse()); } continue; } else { ant.HasFood = false; } } move = GetNearbyFood(pos); // If there is accessible food, go there if (move == AntDirection.U) { List <AntDirection> remaining = new List <AntDirection>() { AntDirection.N, AntDirection.S, AntDirection.E, AntDirection.W }; int index; // First move to try : continue the same way or not ? 50% chance if (ant.History.Count > 0 && rand.NextDouble() < 0.5) { move = ant.History.Peek(); remaining.Remove(move); } else { index = rand.Next(4); move = remaining[index]; remaining.RemoveAt(index); } int size = remaining.Count; do { Coordinates result = pos.ApplyDirection(move).Normalize(this); if (!Walls.Contains(result) && !MyAnts.ContainsKey(result) && !updated.ContainsKey(result)) { break; } if (size > 0) { index = rand.Next(size); move = remaining[index]; remaining.RemoveAt(index); } else { move = AntDirection.U; } size--; } while (size >= 0); } else { ant.HasFood = true; } next = pos.ApplyDirection(move).Normalize(this); if (move != AntDirection.U && !updated.ContainsKey(next)) { ant.History.Push(move); msg.AddMove(pos.Col, pos.Row, move.ToString()); updated.Add(next, ant); } } MyAnts = updated; }