Experimental new method of going straight to center and then shooting forwards
authorJustin Worthe <justin.worthe@entelect.co.za>
Sun, 10 Nov 2013 18:35:42 +0000 (20:35 +0200)
committerJustin Worthe <justin.worthe@entelect.co.za>
Sun, 10 Nov 2013 18:35:42 +0000 (20:35 +0200)
Does not really work on the map it was intended for :(
Still, might be useful.

Entelect.BattleCity.Challenge/AiAgent.cs
Entelect.BattleCity.Challenge/BoardCell.cs [new file with mode: 0644]
Entelect.BattleCity.Challenge/Entelect.BattleCity.Challenge.csproj
Entelect.BattleCity.Challenge/GameInProgress.cs
Entelect.BattleCity.Challenge/Program.cs

index 06e6fcc..8b362ef 100644 (file)
@@ -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 (file)
index 0000000..bd7063e
--- /dev/null
@@ -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
+    }
+}
index 74f95c6..0a8cb97 100644 (file)
@@ -44,6 +44,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AiAgent.cs" />
+    <Compile Include="BoardCell.cs" />
     <Compile Include="GameInProgress.cs" />
     <Compile Include="Move.cs" />
     <Compile Include="Program.cs" />
index 549df5f..3f48019 100644 (file)
@@ -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;
+        }
     }
 }
index 29d8e8e..ec8af76 100644 (file)
@@ -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());
+            }
         }
     }
 }