From a0c4a6c45fc425e5957b3f838155e4a93c73c269 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sun, 10 Nov 2013 20:35:42 +0200 Subject: Experimental new method of going straight to center and then shooting forwards Does not really work on the map it was intended for :( Still, might be useful. --- Entelect.BattleCity.Challenge/AiAgent.cs | 129 ++++++++++++++++----- Entelect.BattleCity.Challenge/BoardCell.cs | 16 +++ .../Entelect.BattleCity.Challenge.csproj | 1 + Entelect.BattleCity.Challenge/GameInProgress.cs | 77 +++++++++++- Entelect.BattleCity.Challenge/Program.cs | 23 ++-- 5 files changed, 205 insertions(+), 41 deletions(-) create mode 100644 Entelect.BattleCity.Challenge/BoardCell.cs (limited to 'Entelect.BattleCity.Challenge') diff --git a/Entelect.BattleCity.Challenge/AiAgent.cs b/Entelect.BattleCity.Challenge/AiAgent.cs index 06e6fcc..8b362ef 100644 --- a/Entelect.BattleCity.Challenge/AiAgent.cs +++ b/Entelect.BattleCity.Challenge/AiAgent.cs @@ -14,29 +14,22 @@ namespace Entelect.BattleCity.Challenge private int? _targetX; - public AiAgent(int tankId) + private bool _checkForOpenPathToMiddle; + private bool _headingToMiddle; + + public AiAgent(int tankId, bool checkForOpenPathToMiddle) { _tankId = tankId; + _checkForOpenPathToMiddle = checkForOpenPathToMiddle; _lastAction = ChallengeService.action.NONE; _hasShotFromLastPosition = false; + _headingToMiddle = false; } - public Move GetBestMove(ChallengeService.game game, ChallengeService.state?[][] board, ChallengeService.player me, ChallengeService.player enemy) + public Move GetBestMove(ChallengeService.game game, BoardCell[][] board, ChallengeService.player me, ChallengeService.player enemy) { Move move = null; - ChallengeService.unit tank = null; - - if (me != null && me.units != null) - { - foreach (var unit in me.units) - { - if (unit.id == _tankId) - { - Console.WriteLine("Tank found in list of tanks"); - tank = unit; - } - } - } + ChallengeService.unit tank = findTankInPlayer(_tankId, me); if (tank == null) { @@ -49,6 +42,8 @@ namespace Entelect.BattleCity.Challenge _hasShotFromLastPosition = false; } + Console.WriteLine("Tank {0} position: {1}, {2}", _tankId, tank.x, tank.y); + var bulletInAir = checkIsBulletInAir(board, me, tank); var stuckLastTurn = checkStuckLastTurn(tank); @@ -61,30 +56,58 @@ namespace Entelect.BattleCity.Challenge _targetX = tank.x + (pastMidpoint!=(tank.x > enemyBase.x) ? +1 : -1); } + if (_checkForOpenPathToMiddle && !_headingToMiddle && tank.x != enemyBase.x) + { + var pathToMiddleIsOpen = testPathToMiddleIsOpen(board, tank, enemyBase, true); + //TODO Disable driving over own base + if (pathToMiddleIsOpen) + { + Console.WriteLine("Path to middle is open, heading there now"); + _headingToMiddle = true; + } + else + { + Console.WriteLine("Checked for path to middle, but path is not clear"); + } + } + if (_checkForOpenPathToMiddle && _headingToMiddle && tank.x == enemyBase.x) + { + _headingToMiddle = false; + } + + ChallengeService.direction chosenDirection = - tank.y != enemyBase.y ? + _headingToMiddle ? + ( + tank.x > enemyBase.x ? + ChallengeService.direction.LEFT : + ChallengeService.direction.RIGHT + ) : ( - _targetX.HasValue && _targetX != tank.x ? + tank.y != enemyBase.y ? ( - tank.x > _targetX ? - ChallengeService.direction.LEFT : - ChallengeService.direction.RIGHT + _targetX.HasValue && _targetX != tank.x ? + ( + tank.x > _targetX ? + ChallengeService.direction.LEFT : + ChallengeService.direction.RIGHT + ) : + ( + tank.y > enemyBase.y ? + ChallengeService.direction.UP : + ChallengeService.direction.DOWN + ) ) : ( - tank.y > enemyBase.y ? - ChallengeService.direction.UP : - ChallengeService.direction.DOWN + tank.x > enemyBase.x ? + ChallengeService.direction.LEFT : + ChallengeService.direction.RIGHT ) - ) : - ( - tank.x > 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) + if (chosenDirection != tank.direction || bulletInAir || _headingToMiddle) { move = MoveInDirection(tank.id, chosenDirection); } @@ -101,6 +124,52 @@ namespace Entelect.BattleCity.Challenge return move; } + private bool testPathToMiddleIsOpen(BoardCell[][] board, ChallengeService.unit tank, ChallengeService.@base enemyBase, bool allowGoThroughBase) + { + var minY = tank.y - 2; + var maxY = tank.y + 2; + var minX = Math.Min(tank.x, enemyBase.x)-2; + var maxX = Math.Max(tank.x, enemyBase.x)+2; + + bool insideRange = board.Length > maxX && board[maxX].Length > maxY && 0 <= minX && 0 <= minY; + if (!insideRange) + { + Console.Error.WriteLine("Somehow, range to check for emptiness ended outside of bounds of board"); + return false; + } + + for (int x = minX; x <= maxX; ++x) + { + for (int y = minY; y <= maxY; ++y) + { + if (board[x][y] != BoardCell.EMPTY) + { + Console.WriteLine("Obstacle found at {0}, {1}, type {2}", x, y, board[x][y]); + return false; + } + + } + } + + return true; + } + + private ChallengeService.unit findTankInPlayer(int tankId, ChallengeService.player me) + { + if (me != null && me.units != null) + { + foreach (var unit in me.units) + { + if (unit.id == _tankId) + { + Console.WriteLine("Tank found in list of tanks"); + return unit; + } + } + } + return null; + } + public Move MoveInDirection(int tankId, ChallengeService.direction direction) { switch (direction) @@ -118,7 +187,7 @@ namespace Entelect.BattleCity.Challenge } } - private bool checkIsBulletInAir(ChallengeService.state?[][] board, ChallengeService.player me, ChallengeService.unit tank) + private bool checkIsBulletInAir(BoardCell[][] board, ChallengeService.player me, ChallengeService.unit tank) { var bulletInAir = false; if (me.bullets != null) diff --git a/Entelect.BattleCity.Challenge/BoardCell.cs b/Entelect.BattleCity.Challenge/BoardCell.cs new file mode 100644 index 0000000..bd7063e --- /dev/null +++ b/Entelect.BattleCity.Challenge/BoardCell.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Entelect.BattleCity.Challenge +{ + public enum BoardCell + { + EMPTY, + WALL, + BASE, + OUT_OF_BOUNDS + } +} diff --git a/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj b/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj index 74f95c6..0a8cb97 100644 --- a/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj +++ b/Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj @@ -44,6 +44,7 @@ + diff --git a/Entelect.BattleCity.Challenge/GameInProgress.cs b/Entelect.BattleCity.Challenge/GameInProgress.cs index 549df5f..3f48019 100644 --- a/Entelect.BattleCity.Challenge/GameInProgress.cs +++ b/Entelect.BattleCity.Challenge/GameInProgress.cs @@ -3,6 +3,7 @@ using System.Windows; using System.Collections.Generic; using System.Threading; using System.Diagnostics; +using System.Text; namespace Entelect.BattleCity.Challenge { @@ -15,7 +16,7 @@ namespace Entelect.BattleCity.Challenge private ChallengeService.player _me; private ChallengeService.player _enemy; - private ChallengeService.state?[][] _board; + private BoardCell[][] _board; private AiAgent _tank1Ai; private AiAgent _tank2Ai; @@ -25,14 +26,19 @@ namespace Entelect.BattleCity.Challenge public GameInProgress(ChallengeService.ChallengeClient service, ChallengeService.state?[][] board) { _service = service; - _board = board; + _board = getBoardCellArrayFromServiceStates(board); updateGameStatus(true); + _board[_me.@base.x][_me.@base.y] = BoardCell.BASE; + _board[_enemy.@base.x][_enemy.@base.y] = BoardCell.BASE; - _tank1Ai = new AiAgent(_me.units[0].id); - _tank2Ai = new AiAgent(_me.units[1].id); + _tank1Ai = new AiAgent(_me.units[0].id, false); + _tank2Ai = new AiAgent(_me.units[1].id, true); + drawBoard(); } + + public void run() { while (true) @@ -157,5 +163,68 @@ namespace Entelect.BattleCity.Challenge Console.Error.WriteLine("Logged in opponent was not found"); } } + + private void drawBoard() + { + for (int x = 0; x < _board.Length; ++x) + { + var stringBoard = new StringBuilder(); + for (int y = 0; y < _board[x].Length; ++y) + { + switch (_board[x][y]) + { + case BoardCell.EMPTY: + stringBoard.Append(' '); + break; + case BoardCell.WALL: + stringBoard.Append('#'); + break; + case BoardCell.OUT_OF_BOUNDS: + stringBoard.Append('O'); + break; + case BoardCell.BASE: + stringBoard.Append('@'); + break; + default: + stringBoard.Append('!'); + break; + } + + } + Console.WriteLine(stringBoard.ToString()); + } + } + + private BoardCell[][] getBoardCellArrayFromServiceStates(ChallengeService.state?[][] stateBoard) + { + BoardCell[][] newBoard = new BoardCell[stateBoard.Length][]; + for (int x = 0; x < stateBoard.Length; ++x) + { + newBoard[x] = new BoardCell[stateBoard[x].Length]; + for (int y = 0; y < stateBoard[x].Length; ++y) + { + switch (stateBoard[x][y]) + { + case null: + case ChallengeService.state.NONE: + case ChallengeService.state.EMPTY: + newBoard[x][y] = BoardCell.EMPTY; + break; + case ChallengeService.state.FULL: + newBoard[x][y] = BoardCell.WALL; + break; + case ChallengeService.state.OUT_OF_BOUNDS: + newBoard[x][y] = BoardCell.OUT_OF_BOUNDS; + break; + default: + newBoard[x][y] = BoardCell.OUT_OF_BOUNDS; + break; + } + + } + } + + return newBoard; + } } } diff --git a/Entelect.BattleCity.Challenge/Program.cs b/Entelect.BattleCity.Challenge/Program.cs index 29d8e8e..ec8af76 100644 --- a/Entelect.BattleCity.Challenge/Program.cs +++ b/Entelect.BattleCity.Challenge/Program.cs @@ -1,4 +1,5 @@ -using System.ServiceModel; +using System; +using System.ServiceModel; namespace Entelect.BattleCity.Challenge { @@ -6,13 +7,21 @@ namespace Entelect.BattleCity.Challenge { static void Main(string[] args) { - var endpointConfigurationName = "ChallengePort"; - var address = new EndpointAddress(args[0]); - var service = new ChallengeService.ChallengeClient(endpointConfigurationName, address); - var board = service.login(); + try + { + var endpointConfigurationName = "ChallengePort"; + var address = new EndpointAddress(args[0]); + var service = new ChallengeService.ChallengeClient(endpointConfigurationName, address); + var board = service.login(); - var game = new GameInProgress(service, board); - game.run(); + var game = new GameInProgress(service, board); + game.run(); + } + catch (Exception ex) + { + Console.Error.WriteLine("Exception thrown. Exiting"); + Console.Error.WriteLine(ex.StackTrace.ToString()); + } } } } -- cgit v1.2.3