private Tuple <int, int> Turn(GameTurnInfos infosTurn, SimulationResult simResult, SimulationInfos simInfos) { var move = new Tuple <int, int>(-1, -1); foreach (Zombie zombie in infosTurn.Zombies) { FindZombieTarget(zombie, infosTurn); MoveZombie(zombie, infosTurn.Nash); } move = GetPlayerDestination(infosTurn.Nash); MovePlayer(infosTurn.Nash); Evaluate(infosTurn, simResult); ZombiesEat(infosTurn); if ((infosTurn.Humans.Count) > 0 && (infosTurn.Zombies.Count > 0)) { if (infosTurn.Nash.Arrived || infosTurn.NashTargetDiedThisTurn) { ComputePlayerTarget(infosTurn, simInfos); infosTurn.NashTargetDiedThisTurn = false; } } else { simInfos.SimFailure = (infosTurn.Humans.Count <= 0); simInfos.SimZombieAllDead = (infosTurn.Zombies.Count <= 0); } return(move); }
private void Evaluate(GameTurnInfos infosTurn, SimulationResult sr) { int tmpPoints; int humanNum = infosTurn.Humans.Count; int humanPoints = 10 * humanNum * humanNum; var killableZombies = new List <Zombie>(); var killableZombiesLen = ZombiesInRangeOfPlayer(killableZombies, infosTurn); var tmpId = (infosTurn.Nash.Target != null) ? infosTurn.Nash.Target.Id : GameInfos.EMPTY_ZOMBIE; for (var i = 0; i < killableZombiesLen; i++) { tmpPoints = humanPoints; if (killableZombiesLen > 1) { tmpPoints *= Tools.Fibonacci(i + 1); } sr.Points += tmpPoints; } if (killableZombies.Any(x => x.Id == tmpId)) { infosTurn.Nash.Target = null; infosTurn.NashTargetDiedThisTurn = true; } var zombiesToRemove = new HashSet <Zombie>(killableZombies); infosTurn.Zombies.RemoveAll(x => zombiesToRemove.Contains(x)); }
public SimulationResult Simulation(GameInfosForDebug gameInfosDebug) { var simResult = new SimulationResult(); var agent = new SimulationAgent(); while (agent.TotalMs < GameInfos.TIMEOUT_FOR_A_TURN_IN_MS && agent.SimRun <= GameInfos.MAX_SIMULATIONS_RUN) { var t0 = DateTime.UtcNow; var infosTurn = new GameTurnInfos( nash: TurnInfos.Nash, humans: TurnInfos.Humans, zombies: TurnInfos.Zombies ); var tmpResult = SimulateGame(infosTurn, gameInfosDebug); if (tmpResult.Points >= simResult.Points) { simResult = new SimulationResult(tmpResult); } var t1 = DateTime.UtcNow; agent.TotalMs += Tools.TimeDifferenceInMillisecond(t0, t1); agent.SimRun++; } DebugInfos.WriteDebugMessage( functionName: "Simulation end", strings: new string[] { $"total sim run {agent.SimRun} in {agent.TotalMs} ms\n" }, debugLevel: DebugInfos.INFOS ); return(simResult); }
public void InitTurnInfos(GameTurnInfos turnInfos) { TurnInfos = new GameTurnInfos( nash: turnInfos.Nash, humans: turnInfos.Humans, zombies: turnInfos.Zombies ); }
private void ZombiesEat(GameTurnInfos infosTurn) { var zombieTargetIdTmp = new List <int>(); foreach (Zombie zombie in infosTurn.Zombies.Where(x => x.Target != null)) { if (ZombieArrivedAtTarget(zombie)) { if (infosTurn.Humans.Any(x => x.Id == zombie.Target.Id)) { infosTurn.Humans.RemoveAll(x => x.Id == zombie.Target.Id); } } } }
private int ZombiesInRangeOfPlayer(List <Zombie> zombiesInRange, GameTurnInfos infosTurn) { var len = 0; foreach (Zombie zombie in infosTurn.Zombies) { if (Tools.GetDistance(infosTurn.Nash.Position, zombie.Position) <= PlayerNash.RANGE) { zombiesInRange.Add(zombie); len++; } } return(len); }
private SimulationResult SimulateGame(GameTurnInfos infosTurn, GameInfosForDebug gameInfosDebug) { var rand = new Random(); var sr = new SimulationResult(); var simInfos = new SimulationInfos(); var moves = new List <Tuple <int, int> >(); var gameDebug = new GameInfosForDebug(); var turnInfosDebug = new DebugInfosForEachTurn(); simInfos.SimStartingRandomMovesNum = rand.Next(GameInfos.MAX_SIMULATION_RANDOM_STARTING_MOVES + 1); ComputePlayerTarget(infosTurn, simInfos); while (!simInfos.SimZombieAllDead && !simInfos.SimFailure && simInfos.SimMovesCount < GameInfos.MAX_MOVES) { // Simulate a turn of the game. simInfos.Moves.Add(Turn(infosTurn, sr, simInfos)); #if DEBUG_MODE turnInfosDebug.Nash = infosTurn.Nash; turnInfosDebug.SetHumansOrZombies(infosTurn.Humans); turnInfosDebug.SetHumansOrZombies(infosTurn.Zombies); turnInfosDebug.Points = sr.Points; turnInfosDebug.Move = simInfos.Moves.Last(); turnInfosDebug.NumTurn = simInfos.SimMovesCount; gameDebug.DebugInfosForTurn.Add(new DebugInfosForEachTurn(turnInfosDebug)); #endif simInfos.SimMovesCount++; } if (simInfos.SimZombieAllDead && !simInfos.SimFailure && ((sr.Points + ActualScore) > BestSimulation.SimPoints || (sr.Points + ActualScore) == BestSimulation.SimPoints && (simInfos.SimMovesCount < (BestSimulation.SimMovesCount - NumTurn)))) { simInfos.SimPoints = sr.Points + ActualScore; BestSimulation = simInfos; NewBest = true; #if DEBUG_MODE gameInfosDebug.SetDebugInfosForTurn(gameDebug.DebugInfosForTurn); #endif } return(sr); }
private void FindZombieTarget(Zombie zombie, GameTurnInfos infosTurn) { float minDist = float.PositiveInfinity; float tmpDist; foreach (Human human in infosTurn.Humans) { tmpDist = Tools.GetDistance(zombie.Position, human.Position); if (tmpDist < minDist) { zombie.Target = human; minDist = tmpDist; } } tmpDist = Tools.GetDistance(zombie.Position, infosTurn.Nash.Position); if (tmpDist < minDist) { zombie.Target = null; minDist = tmpDist; } }
private void ComputePlayerTarget(GameTurnInfos infosTurn, SimulationInfos simInfos) { var rand = new Random(); var zombiesThatDoNotTargetPlayer = new List <Zombie>(); // If there is some random moves, we made Nash do the moves; otherwise we set a target for Nash. if (simInfos.SimStartingRandomMovesNum > 0) { infosTurn.Nash.NextPosition = new Tuple <int, int>(rand.Next(GameInfos.MAX_X), rand.Next(GameInfos.MAX_Y)); infosTurn.Nash.Target = null; simInfos.SimStartingRandomMovesNum--; } else { zombiesThatDoNotTargetPlayer.AddRange(infosTurn.Zombies.Where(x => x.Target != null)); // Define a zombie target for Nash : target is a zombie targetting a human, if there is at least one; any zombie in the map, otherwise. infosTurn.Nash.Target = (zombiesThatDoNotTargetPlayer.Count > 0) ? zombiesThatDoNotTargetPlayer[rand.Next(zombiesThatDoNotTargetPlayer.Count)] : infosTurn.Zombies[rand.Next(infosTurn.Zombies.Count)]; infosTurn.Nash.Arrived = false; } }
static void Main(string[] args) { string[] inputs; var previousHumansCount = 0; var previousZombiesCount = 0; var simulation = new SimulationGame(); var gameInfosDebug = new GameInfosForDebug(); // game loop while (true) { inputs = Console.ReadLine().Split(' '); var nashPosition = new Tuple <int, int>(int.Parse(inputs[0]), int.Parse(inputs[1])); var nash = new PlayerNash(nashPosition); int humanCount = int.Parse(Console.ReadLine()); var humans = new List <Human>(); for (var i = 0; i < humanCount; i++) { inputs = Console.ReadLine().Split(' '); var human = new Human( id: int.Parse(inputs[0]), pos: new Tuple <int, int>(int.Parse(inputs[1]), int.Parse(inputs[2])) ); humans.Add(human); } int zombieCount = int.Parse(Console.ReadLine()); var zombies = new List <Zombie>(); for (var i = 0; i < zombieCount; i++) { inputs = Console.ReadLine().Split(' '); var zombie = new Zombie( id: int.Parse(inputs[0]), pos: new Tuple <int, int>(int.Parse(inputs[1]), int.Parse(inputs[2])), nextPos: new Tuple <int, int>(int.Parse(inputs[3]), int.Parse(inputs[4])) ); zombies.Add(zombie); } if (zombieCount < previousZombiesCount) { int zombiesDead = previousZombiesCount - zombieCount; int humanPoints = 10 * previousHumansCount * previousHumansCount; for (var i = 0; i < zombiesDead; i++) { var tmpPoints = humanPoints; if (zombiesDead > 1) { tmpPoints *= Tools.Fibonacci(i + 1); } simulation.ActualScore += tmpPoints; } } var turnInfos = new GameTurnInfos(nash, humans, zombies); // For each turn, we want to simulate the maximum of game played to find the best next move possible. simulation.InitTurnInfos(turnInfos); var simResult = simulation.Simulation(gameInfosDebug); if (simulation.NewBest) { simulation.NumTurn = 0; simulation.NewBest = false; } #if DEBUG_MODE DebugInfos.WriteSimulTurnInfos(gameInfosDebug.DebugInfosForTurn[simulation.NumTurn], DebugInfos.DEBUG); #endif Tools.PrintMove(simulation.BestSimulation.Moves[simulation.NumTurn]); previousHumansCount = humanCount; previousZombiesCount = zombieCount; simulation.NumTurn++; } }