From 35982c092af0018bb348723fb909de9f192900da Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sun, 20 Oct 2013 17:14:49 +0200 Subject: Refactored project to have separate AIAgents for each tank --- Entelect.BattleCity.Challenge/AiAgent.cs | 35 ++---- .../Entelect.BattleCity.Challenge.csproj | 1 - Entelect.BattleCity.Challenge/GameInProgress.cs | 131 ++++++++++++++++----- Entelect.BattleCity.Challenge/Move.cs | 5 + Entelect.BattleCity.Challenge/Program.cs | 6 +- 5 files changed, 124 insertions(+), 54 deletions(-) (limited to 'Entelect.BattleCity.Challenge') diff --git a/Entelect.BattleCity.Challenge/AiAgent.cs b/Entelect.BattleCity.Challenge/AiAgent.cs index e577bcb..df9afb4 100644 --- a/Entelect.BattleCity.Challenge/AiAgent.cs +++ b/Entelect.BattleCity.Challenge/AiAgent.cs @@ -7,46 +7,35 @@ namespace Entelect.BattleCity.Challenge { private int _tankId; - public AiAgent() - { - - } - public AiAgent(int tankId) { _tankId = tankId; } - public Move GetBestMove(ChallengeService.state?[][] state, ChallengeService.game game, int tankIndex) + public Move GetBestMove(ChallengeService.game game, ChallengeService.state?[][] board, ChallengeService.player me, ChallengeService.player enemy) { - ChallengeService.player me = null; - ChallengeService.player enemy = null; ChallengeService.unit tank = null; bool bulletInAir = false; - string playerName = game.playerName; - foreach (ChallengeService.player player in game.players) + foreach (var unit in me.units) { - if (player.name.Equals(playerName)) + if (unit.id == _tankId) { - me = player; - } - else - { - enemy = player; + tank = unit; } } - if (me.units.Length <= tankIndex) + + if (tank == null) { + Console.WriteLine("Tank {0} does not exist", _tankId); return null; } - tank = me.units[tankIndex]; if (me.bullets != null) { foreach (var bullet in me.bullets) { - if (Math.Abs(bullet.x - tank.x) < state.Length / 4) + if (Math.Abs(bullet.x - tank.x) < board.Length / 4) { bulletInAir = true; } @@ -56,18 +45,20 @@ namespace Entelect.BattleCity.Challenge var enemyBase = enemy.@base; ChallengeService.direction chosenDirection = - tank.y != enemyBase.y ? + tank.y+2 != enemyBase.y ? ( - tank.y > enemyBase.y ? + tank.y+2 > enemyBase.y ? ChallengeService.direction.UP : ChallengeService.direction.DOWN ) : ( - tank.x > enemyBase.x ? + tank.x+2 > enemyBase.x ? ChallengeService.direction.LEFT : ChallengeService.direction.RIGHT ); + Console.WriteLine("Chosen direction for tank {0} is {1} and bulletInAir is {2}", _tankId, chosenDirection, bulletInAir); + if (chosenDirection != tank.direction || bulletInAir) { return MoveInDirection(tank.id, chosenDirection); diff --git a/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj b/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj index 83bc159..74f95c6 100644 --- a/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj +++ b/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj @@ -56,7 +56,6 @@ - Reference.svcmap diff --git a/Entelect.BattleCity.Challenge/GameInProgress.cs b/Entelect.BattleCity.Challenge/GameInProgress.cs index 61fa436..6581eb7 100644 --- a/Entelect.BattleCity.Challenge/GameInProgress.cs +++ b/Entelect.BattleCity.Challenge/GameInProgress.cs @@ -5,59 +5,132 @@ using System.Threading; namespace Entelect.BattleCity.Challenge { - class GameInProgress + public class GameInProgress { - public static void run(ChallengeService.ChallengeClient service, ChallengeService.state?[][] state) + private ChallengeService.ChallengeClient _service; + private ChallengeService.game _currentState; + private ChallengeService.player _me; + private ChallengeService.player _enemy; + + private ChallengeService.state?[][] _board; + + private AiAgent _tank1Ai; + private AiAgent _tank2Ai; + + public GameInProgress(ChallengeService.ChallengeClient service, ChallengeService.state?[][] board) { - AiAgent agent = new AiAgent(); + _service = service; + _board = board; + + updateGameStatus(); + + _tank1Ai = new AiAgent(_me.units[0].id); + _tank2Ai = new AiAgent(_me.units[1].id); + } + + + public void run() + { while (true) { - var game = service.getStatus(); long currentTick = DateTime.Now.Ticks; - long nextTick = game.nextTickTime.Ticks; + long nextTick = _currentState.nextTickTime.Ticks; if (currentTick > nextTick) { + Console.Error.WriteLine("Current game state is out of date"); + updateGameStatus(); continue; } + makeNextMove(); + waitForNextTick(); + + updateGameStatus(); + } + } - // AI logic here - Move tank1Move = agent.GetBestMove(state, game, 0); - Move tank2Move = agent.GetBestMove(state, game, 1); + private void makeNextMove() + { + Move tank1Move = _tank1Ai.GetBestMove(_currentState, _board, _me, _enemy); + Move tank2Move = _tank2Ai.GetBestMove(_currentState, _board, _me, _enemy); + + sendMovesToService(tank1Move, tank2Move); + } + + private void sendMovesToService(Move tank1Move, Move tank2Move) + { + if (tank1Move != null && tank2Move != null) + { + Console.WriteLine("Actions chosen for two tanks"); + Console.WriteLine(tank1Move.ToString()); + Console.WriteLine(tank2Move.ToString()); + _service.setActions(tank1Move.Action, tank2Move.Action); + } + else if (tank1Move != null) + { + Console.WriteLine("Actions chosen for first tank only"); + Console.WriteLine(tank1Move.ToString()); + _service.setAction(tank1Move.Tank, tank1Move.Action); + } + else if (tank2Move != null) + { + Console.WriteLine("Actions chosen for second tank only"); + Console.WriteLine(tank2Move.ToString()); + _service.setAction(tank2Move.Tank, tank2Move.Action); + } + } - if (tank1Move != null) + private void waitForNextTick() + { + var nextTick = _currentState.nextTickTime.Ticks; + var currentTick = DateTime.Now.Ticks; + + long sleepTime = nextTick - currentTick; + if (sleepTime < 0L) + { + Console.Error.WriteLine("ERROR: Gone passed the next tick time"); + } + else + { + Console.WriteLine("Sleeping until {1} for {0}ms", sleepTime, _currentState.nextTickTime.ToString()); + try { - service.setActionAsync(tank1Move.Tank, tank1Move.Action); + Thread.Sleep(TimeSpan.FromTicks(sleepTime)); } - if (tank2Move != null) + catch (Exception ex) { - service.setActionAsync(tank2Move.Tank, tank2Move.Action); + Console.Error.WriteLine("Exception thrown while waiting for next tick"); + Console.Error.WriteLine("Exception message: "+ ex.Message); } + } + } - currentTick = DateTime.Now.Ticks; + private void updateGameStatus() + { + _currentState = _service.getStatus(); + + bool meFound = false; + bool enemyFound = false; - long sleepTime = nextTick - currentTick; - if (sleepTime < 0L) + foreach (ChallengeService.player player in _currentState.players) + { + if (player.name.Equals(_currentState.playerName)) { - Console.Error.WriteLine("ERROR: Gone passed the next tick time"); + _me = player; } else { - Console.WriteLine("Sleeping until {1} for {0}ms", sleepTime, game.nextTickTime.ToString()); + _enemy = player; } + } - try - { - Thread.Sleep(TimeSpan.FromTicks(sleepTime)); - } - catch (Exception) - { - continue; - } - //while (startTick < nextTick) - //{ - // startTick += (DateTime.Now.Ticks - startTick); - //} + if (!meFound) + { + Console.Error.WriteLine("Logged in player was not found"); + } + if (!enemyFound) + { + Console.Error.WriteLine("Logged in opponent was not found"); } } } diff --git a/Entelect.BattleCity.Challenge/Move.cs b/Entelect.BattleCity.Challenge/Move.cs index 1813c59..7fba664 100644 --- a/Entelect.BattleCity.Challenge/Move.cs +++ b/Entelect.BattleCity.Challenge/Move.cs @@ -15,5 +15,10 @@ namespace Entelect.BattleCity.Challenge Tank = tank; Action = action; } + + public override string ToString() + { + return string.Format("Tank {0}: {1}", Tank, Action.ToString()); + } } } diff --git a/Entelect.BattleCity.Challenge/Program.cs b/Entelect.BattleCity.Challenge/Program.cs index 5764426..29d8e8e 100644 --- a/Entelect.BattleCity.Challenge/Program.cs +++ b/Entelect.BattleCity.Challenge/Program.cs @@ -9,8 +9,10 @@ namespace Entelect.BattleCity.Challenge var endpointConfigurationName = "ChallengePort"; var address = new EndpointAddress(args[0]); var service = new ChallengeService.ChallengeClient(endpointConfigurationName, address); - var state = service.login(); - GameInProgress.run(service, state); + var board = service.login(); + + var game = new GameInProgress(service, board); + game.run(); } } } -- cgit v1.2.3