Advertisement
Guest User

NightmareZ's CodeTroopers

a guest
Dec 9th, 2013
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 46.01 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using Com.CodeGame.CodeTroopers2013.DevKit.CSharpCgdk.Model;
  5.  
  6. namespace Com.CodeGame.CodeTroopers2013.DevKit.CSharpCgdk
  7. {
  8.     public sealed class MyStrategy : IStrategy
  9.     {
  10.         private Trooper _self;
  11.         private static World _world;
  12.         private static Game _game;
  13.         private Move _move;
  14.         private const int RegionSize = 6;
  15.         private static readonly Random Rnd = new Random();
  16.         private Region _oldRegion = Region.Unknown,
  17.                        _targetRegion = Region.Center;
  18.         private static int _stepsWithoutEnemies;
  19.         private static int _dispositionRequested;
  20.         private const int MaxLeaderDistance = 3;
  21.         private int[,,] _dangerField;
  22.  
  23.         private enum Region
  24.         {
  25.             Unknown, NW, NE, SW, SE, Center
  26.         }
  27.  
  28.         private static readonly List<Region> RandomRegions = new List<Region>
  29.         {
  30.             Region.NE,
  31.             Region.NW,
  32.             Region.SE,
  33.             Region.SW,
  34.             Region.Center
  35.         };
  36.  
  37.         private Region GetRandomRegion()
  38.         {
  39.             if (RandomRegions.Count == 0)
  40.             {
  41.                 return Rnd.Next(2) > 0
  42.                     ? (Rnd.Next(2) > 0 ? Region.NW : Region.NE)
  43.                     : (Rnd.Next(2) > 0 ? Region.SE : Region.SW);
  44.             }
  45.  
  46.             int idx = Rnd.Next(RandomRegions.Count);
  47.             Region region = RandomRegions[idx];
  48.             RandomRegions.RemoveAt(idx);
  49.             return region;
  50.         }
  51.  
  52.         private IEnumerable<Point> FindEmptyPointsForRegion(Region region)
  53.         {
  54.             if (region == Region.Unknown)
  55.                 yield break;
  56.  
  57.             Trooper leader = Leader;
  58.  
  59.             switch (region)
  60.             {
  61.                 case Region.NW:
  62.                     for (int j = 0; j < RegionSize; ++j)
  63.                         for (int i = 0; i < RegionSize; ++i)
  64.                             if (_world.Cells[i][j] == CellType.Free && !_world.Troopers.Any(t => t.X == i && t.Y == j))
  65.                                 if (FindPathDistance(new Point(leader.X, leader.Y), new Point(i, j), false, false) > 2)
  66.                                     yield return new Point(i, j);
  67.  
  68.                     break;
  69.  
  70.                 case Region.NE:
  71.                     for (int j = 0; j < RegionSize; ++j)
  72.                         for (int i = _world.Width - 1; i >= _world.Width - RegionSize; --i)
  73.                             if (_world.Cells[i][j] == CellType.Free && !_world.Troopers.Any(t => t.X == i && t.Y == j))
  74.                                 if (FindPathDistance(new Point(leader.X, leader.Y), new Point(i, j), false, false) > 2)
  75.                                     yield return new Point(i, j);
  76.  
  77.                     break;
  78.  
  79.                 case Region.SW:
  80.                     for (int j = _world.Height - 1; j >= _world.Height - RegionSize; --j)
  81.                         for (int i = 0; i < RegionSize; ++i)
  82.                             if (_world.Cells[i][j] == CellType.Free && !_world.Troopers.Any(t => t.X == i && t.Y == j))
  83.                                 if (FindPathDistance(new Point(leader.X, leader.Y), new Point(i, j), false, false) > 2)
  84.                                     yield return new Point(i, j);
  85.  
  86.                     break;
  87.  
  88.                 case Region.SE:
  89.                     for (int j = _world.Height - 1; j >= _world.Height - RegionSize; --j)
  90.                         for (int i = _world.Width - 1; i >= _world.Width - RegionSize; --i)
  91.                             if (_world.Cells[i][j] == CellType.Free && !_world.Troopers.Any(t => t.X == i && t.Y == j))
  92.                                 if (FindPathDistance(new Point(leader.X, leader.Y), new Point(i, j), false, false) > 2)
  93.                                     yield return new Point(i, j);
  94.  
  95.                     break;
  96.  
  97.                 case Region.Center:
  98.                     for (int j = _world.Height / 2 - RegionSize / 2; j < _world.Height / 2 + RegionSize / 2; ++j)
  99.                         for (int i = _world.Width / 2 - RegionSize / 2; i < _world.Width / 2 + RegionSize / 2; ++i)
  100.                             if (_world.Cells[i][j] == CellType.Free && !_world.Troopers.Any(t => t.X == i && t.Y == j))
  101.                                 if (FindPathDistance(new Point(leader.X, leader.Y), new Point(i, j), false, false) > 2)
  102.                                     yield return new Point(i, j);
  103.  
  104.                     break;
  105.             }
  106.         }
  107.  
  108.         private Region GetRegion(Point pt)
  109.         {
  110.             if (pt.Y < RegionSize && pt.X < RegionSize) return Region.NW;
  111.             if (pt.Y < RegionSize && pt.X >= _world.Width - RegionSize) return Region.NE;
  112.             if (pt.Y >= _world.Height - RegionSize && pt.X < RegionSize) return Region.SW;
  113.             if (pt.Y >= _world.Height - RegionSize && pt.X >= _world.Width - RegionSize) return Region.SE;
  114.             if (pt.Y >= _world.Height / 2 - RegionSize / 2 && pt.Y < _world.Height / 2 + RegionSize / 2 &&
  115.                 pt.X >= _world.Width / 2 - RegionSize / 2 && pt.X < _world.Width / 2 + RegionSize / 2) return Region.Center;
  116.             return Region.Unknown;
  117.         }
  118.  
  119.         private Region GetCurrentRegion()
  120.         {
  121.             return GetRegion(new Point(_self.X, _self.Y));
  122.         }
  123.  
  124.         private struct Point
  125.         {
  126.             public Point(int x, int y)
  127.             {
  128.                 X = x;
  129.                 Y = y;
  130.             }
  131.  
  132.             public readonly int X, Y;
  133.  
  134.             public bool InWorld
  135.             {
  136.                 get { return X >= 0 && Y >= 0 && X < _world.Width && Y < _world.Height; }
  137.             }
  138.  
  139.             public static bool operator ==(Point pt0, Point pt1)
  140.             {
  141.                 return pt0.X == pt1.X && pt0.Y == pt1.Y;
  142.             }
  143.  
  144.             public static bool operator !=(Point pt0, Point pt1)
  145.             {
  146.                 return !(pt0 == pt1);
  147.             }
  148.  
  149.             public override bool Equals(object o)
  150.             {
  151.                 return o is Point && ((Point)o) == this;
  152.             }
  153.  
  154.             public override int GetHashCode()
  155.             {
  156.                 return X.GetHashCode() ^ Y.GetHashCode();
  157.             }
  158.         }
  159.  
  160.         public Trooper Leader
  161.         {
  162.             get
  163.             {
  164.                 List<TrooperType> LeadershipRating = null;
  165.  
  166.                 switch (_self.Type)
  167.                 {
  168.                     case TrooperType.Sniper:
  169.                         LeadershipRating = new List<TrooperType>
  170.                             {
  171.                                 TrooperType.Sniper,
  172.                                 TrooperType.Soldier,
  173.                                 TrooperType.Commander,
  174.                                 TrooperType.Scout,
  175.                                 TrooperType.FieldMedic
  176.                             };
  177.                         break;
  178.  
  179.                     case TrooperType.Soldier:
  180.                         LeadershipRating = new List<TrooperType>
  181.                             {
  182.                                 TrooperType.Soldier,
  183.                                 TrooperType.Sniper,
  184.                                 TrooperType.Commander,
  185.                                 TrooperType.Scout,
  186.                                 TrooperType.FieldMedic
  187.                             };
  188.                         break;
  189.  
  190.                     case TrooperType.Commander:
  191.                         LeadershipRating = new List<TrooperType>
  192.                             {
  193.                                 TrooperType.Soldier,
  194.                                 TrooperType.Sniper,
  195.                                 TrooperType.Commander,
  196.                                 TrooperType.Scout,
  197.                                 TrooperType.FieldMedic
  198.                             };
  199.                         break;
  200.  
  201.                     case TrooperType.Scout:
  202.                         LeadershipRating = new List<TrooperType>
  203.                             {
  204.                                 TrooperType.Soldier,
  205.                                 TrooperType.Sniper,
  206.                                 TrooperType.Commander,
  207.                                 TrooperType.Scout,
  208.                                 TrooperType.FieldMedic
  209.                             };
  210.                         break;
  211.  
  212.                     case TrooperType.FieldMedic:
  213.                         LeadershipRating = new List<TrooperType>
  214.                             {
  215.                                 TrooperType.Sniper,
  216.                                 TrooperType.Soldier,
  217.                                 TrooperType.Commander,
  218.                                 TrooperType.Scout,
  219.                                 TrooperType.FieldMedic
  220.                             };
  221.                         break;
  222.                 }
  223.  
  224.                 return Teammates.First(trooper => trooper.Type == Teammates.Aggregate(
  225.                     TrooperType.FieldMedic,
  226.                     (acc, curr) => LeadershipRating.IndexOf(curr.Type) < LeadershipRating.IndexOf(acc) ? curr.Type : acc));
  227.             }
  228.         }
  229.  
  230.         private Trooper Medic
  231.         {
  232.             get { return Teammates.FirstOrDefault(trooper => trooper.Type == TrooperType.FieldMedic); }
  233.         }
  234.  
  235.         private IEnumerable<Trooper> Wounded
  236.         {
  237.             get
  238.             {
  239.                 return Teammates
  240.                     .Where(trooper => trooper.Hitpoints < trooper.MaximalHitpoints)
  241.                     .OrderBy(trooper => trooper.Hitpoints);
  242.             }
  243.         }
  244.  
  245.         private IEnumerable<Trooper> Teammates
  246.         {
  247.             get { return _world.Troopers.Where(trooper => trooper.IsTeammate); }
  248.         }
  249.  
  250.         private IEnumerable<Trooper> Enemies
  251.         {
  252.             get
  253.             {
  254.                 return _world
  255.                     .Troopers
  256.                     .Where(trooper => !trooper.IsTeammate)
  257.                     .OrderBy(trooper => trooper.Type == TrooperType.Sniper ? 0 : 1)
  258.                     .ThenBy(trooper => trooper.Type == TrooperType.FieldMedic ? 0 : 1);
  259.             }
  260.         }
  261.  
  262.         private IEnumerable<Trooper> GetShootableEnemies(TrooperStance? selfStance)
  263.         {
  264.             return Enemies
  265.                 .Where(enemy => _world.IsVisible(
  266.                     Math.Min(_self.ShootingRange, _self.VisionRange),
  267.                     _self.X, _self.Y, selfStance ?? _self.Stance,
  268.                     enemy.X, enemy.Y, enemy.Stance))
  269.                 .OrderBy(enemy => enemy.Hitpoints);
  270.         }
  271.  
  272.         private IEnumerable<Trooper> GetKillableEnemies(TrooperStance? selfStance)
  273.         {
  274.             return GetShootableEnemies(selfStance)
  275.                 .Where(enemy => enemy.Hitpoints <= _self.ActionPoints / _self.ShootCost * Damage);
  276.         }
  277.  
  278.         private bool CanShoot
  279.         {
  280.             get { return _self.ActionPoints >= _self.ShootCost; }
  281.         }
  282.  
  283.         private int MoveCost
  284.         {
  285.             get
  286.             {
  287.                 switch (_self.Stance)
  288.                 {
  289.                     case TrooperStance.Standing:
  290.                         return _game.StandingMoveCost;
  291.  
  292.                     case TrooperStance.Kneeling:
  293.                         return _game.KneelingMoveCost;
  294.  
  295.                     case TrooperStance.Prone:
  296.                         return _game.ProneMoveCost;
  297.                 }
  298.  
  299.                 return int.MaxValue;
  300.             }
  301.         }
  302.  
  303.         private int Damage
  304.         {
  305.             get
  306.             {
  307.                 switch (_self.Stance)
  308.                 {
  309.                     case TrooperStance.Standing:
  310.                         return _self.StandingDamage;
  311.  
  312.                     case TrooperStance.Kneeling:
  313.                         return _self.KneelingDamage;
  314.  
  315.                     case TrooperStance.Prone:
  316.                         return _self.ProneDamage;
  317.                 }
  318.  
  319.                 return int.MaxValue;
  320.             }
  321.         }
  322.  
  323.         private bool CanMove
  324.         {
  325.             get { return _self.ActionPoints >= MoveCost; }
  326.         }
  327.  
  328.         private static Direction PointsToDirection(int fromX, int fromY, int targetX, int targetY)
  329.         {
  330.             if (targetY == fromY - 1) return Direction.North;
  331.             if (targetY == fromY + 1) return Direction.South;
  332.             if (targetX == fromX - 1) return Direction.West;
  333.             if (targetX == fromX + 1) return Direction.East;
  334.             return Direction.CurrentPoint;
  335.         }
  336.  
  337.         private IEnumerable<Tuple<Bonus, int, Direction>> GetBonuses(int maxDistance)
  338.         {
  339.             return _world.Bonuses
  340.                 .Select(bonus => new {bonus, dist = FindPathTo(new Point(bonus.X, bonus.Y), false).ToArray() })
  341.                 .Where(bonus => bonus.dist != null && bonus.dist.Length <= maxDistance && bonus.dist.Length > 1)
  342.                 .OrderBy(bonus => bonus.dist.Length)
  343.                 .Select(bonus => new Tuple<Bonus, int, Direction>(
  344.                     bonus.bonus,
  345.                     bonus.dist.Length,
  346.                     PointsToDirection(_self.X, _self.Y, bonus.dist[1].X, bonus.dist[1].Y)));
  347.         }
  348.  
  349.         private int FindPathDistance(Point from, Point to, bool transparentTeammates, bool transparentWorld)
  350.         {
  351.             if (!from.InWorld || !to.InWorld)
  352.                 return int.MaxValue;
  353.  
  354.             var arr = new int[_world.Width, _world.Height];
  355.  
  356.             if (!transparentWorld)
  357.                 for (int i = 0; i < _world.Width; ++i)
  358.                     for (int j = 0; j < _world.Height; ++j)
  359.                         if (_world.Cells[i][j] != CellType.Free)
  360.                             arr[i, j] = -1;
  361.  
  362.             if (transparentTeammates)
  363.             {
  364.                 foreach (Trooper trooper in Enemies)
  365.                     if (trooper.X != to.X || trooper.Y != to.Y)
  366.                         arr[trooper.X, trooper.Y] = -1;
  367.             }
  368.             else
  369.             {
  370.                 foreach (Trooper trooper in _world.Troopers)
  371.                     if (trooper.X != to.X || trooper.Y != to.Y)
  372.                         arr[trooper.X, trooper.Y] = -1;
  373.             }
  374.  
  375.             int currStep = 1;
  376.             int worldSize = _world.Width * _world.Height;
  377.             var list = new List<Point>(worldSize);
  378.  
  379.             arr[from.X, from.Y] = currStep;
  380.             list.Add(from);
  381.             if (arr[from.X, from.Y] == -1 || arr[to.X, to.Y] == -1)
  382.                 return int.MaxValue;
  383.  
  384.             while (list.Count > 0)
  385.             {
  386.                 var tmp = new List<Point>(worldSize);
  387.                 int nextStep = currStep + 1;
  388.  
  389.                 foreach (Point pt in list)
  390.                 {
  391.                     if (pt == to)
  392.                         return currStep;
  393.  
  394.                     if (pt.X > 0 && arr[pt.X - 1, pt.Y] == 0)
  395.                     {
  396.                         arr[pt.X - 1, pt.Y] = nextStep;
  397.                         tmp.Add(new Point(pt.X - 1, pt.Y));
  398.                     }
  399.  
  400.                     if (pt.Y > 0 && arr[pt.X, pt.Y - 1] == 0)
  401.                     {
  402.                         arr[pt.X, pt.Y - 1] = nextStep;
  403.                         tmp.Add(new Point(pt.X, pt.Y - 1));
  404.                     }
  405.  
  406.                     if (pt.X < _world.Width - 1 && arr[pt.X + 1, pt.Y] == 0)
  407.                     {
  408.                         arr[pt.X + 1, pt.Y] = nextStep;
  409.                         tmp.Add(new Point(pt.X + 1, pt.Y));
  410.                     }
  411.  
  412.                     if (pt.Y < _world.Height - 1 && arr[pt.X, pt.Y + 1] == 0)
  413.                     {
  414.                         arr[pt.X, pt.Y + 1] = nextStep;
  415.                         tmp.Add(new Point(pt.X, pt.Y + 1));
  416.                     }
  417.                 }
  418.  
  419.                 currStep = nextStep;
  420.                 list = tmp;
  421.             }
  422.  
  423.             return int.MaxValue;
  424.         }
  425.  
  426.         private IEnumerable<Point> FindPath(Point from, Point to, bool transparentTeammates)
  427.         {
  428.             if (!from.InWorld || !to.InWorld)
  429.                 yield break;
  430.  
  431.             var arr = new int[_world.Width, _world.Height];
  432.  
  433.             for (int i = 0; i < _world.Width; ++i)
  434.                 for (int j = 0; j < _world.Height; ++j)
  435.                     if (_world.Cells[i][j] != CellType.Free)
  436.                         arr[i, j] = -1;
  437.  
  438.             if (transparentTeammates)
  439.             {
  440.                 foreach (Trooper trooper in Enemies)
  441.                     if (trooper.X != to.X || trooper.Y != to.Y)
  442.                         arr[trooper.X, trooper.Y] = -1;
  443.             }
  444.             else
  445.             {
  446.                 foreach (Trooper trooper in _world.Troopers)
  447.                     if (trooper.X != to.X || trooper.Y != to.Y)
  448.                         arr[trooper.X, trooper.Y] = -1;
  449.             }
  450.  
  451.             int currStep = 1, nextStep = 2;
  452.             int worldSize = _world.Width * _world.Height;
  453.             var list = new List<Point>(worldSize);
  454.  
  455.             arr[from.X, from.Y] = currStep;
  456.             list.Add(from);
  457.             if (arr[from.X, from.Y] == -1 || arr[to.X, to.Y] == -1)
  458.                 yield break;
  459.  
  460.             while (list.Count > 0)
  461.             {
  462.                 var tmp = new List<Point>(worldSize);
  463.                 nextStep = currStep + 1;
  464.  
  465.                 foreach (Point pt in list)
  466.                 {
  467.                     if (pt == to)
  468.                     {
  469.                         tmp.Clear();
  470.                         --nextStep;
  471.                         break;
  472.                     }
  473.  
  474.                     foreach (Point point in GetCross(pt, false))
  475.                     {
  476.                         if (point.InWorld && arr[point.X, point.Y] == 0)
  477.                         {
  478.                             arr[point.X, point.Y] = nextStep;
  479.                             tmp.Add(point);
  480.                         }
  481.                     }
  482.                 }
  483.  
  484.                 currStep = nextStep;
  485.                 list = tmp;
  486.             }
  487.  
  488.             var path = new List<Point>(nextStep);
  489.             int x = to.X;
  490.             int y = to.Y;
  491.             path.Add(to);
  492.  
  493.             while (currStep != 1)
  494.             {
  495.                 int prevStep = currStep - 1;
  496.  
  497.                 if (!GetCross(new Point(x, y), false).Any(pt =>
  498.                     {
  499.                         if (pt.InWorld && arr[pt.X, pt.Y] == prevStep)
  500.                         {
  501.                             path.Add(pt);
  502.                             x = pt.X;
  503.                             y = pt.Y;
  504.                             --currStep;
  505.                             return true;
  506.                         }
  507.  
  508.                         return false;
  509.                     })) break;
  510.             }
  511.  
  512.             if (currStep != 1)
  513.                 yield break;
  514.  
  515.             for (int i = path.Count - 1; i >= 0; --i)
  516.                 yield return path[i];
  517.         }
  518.  
  519.         private IEnumerable<Point> FindPathTo(Point pt, bool transparentTeammates)
  520.         {
  521.             return FindPath(new Point(_self.X, _self.Y), pt, transparentTeammates);
  522.         }
  523.  
  524.         private IEnumerable<IEnumerable<Point>> PathToEnemies
  525.         {
  526.             get { return Enemies.Select(enemy => FindPathTo(new Point(enemy.X, enemy.Y), false)); }
  527.         }
  528.  
  529.         private int CellDangerous(Point pt, TrooperStance trooperStance)
  530.         {
  531.             if (!pt.InWorld)
  532.                 return 0;
  533.  
  534.             if (_dangerField != null)
  535.                 return _dangerField[pt.X, pt.Y, (int)trooperStance];
  536.  
  537.             int dangerous = 0;
  538.  
  539.             foreach (Trooper enemy in Enemies)
  540.             {
  541.                 if (_world.IsVisible(
  542.                     Math.Min(enemy.ShootingRange, enemy.VisionRange),
  543.                     enemy.X, enemy.Y, enemy.Stance,
  544.                     pt.X, pt.Y, trooperStance))
  545.                 {
  546.                     dangerous += enemy.GetDamage(enemy.Stance);
  547.  
  548.                     if (enemy.IsHoldingGrenade && enemy.GetDistanceTo(_self) <= _game.GrenadeThrowRange)
  549.                         dangerous += _game.GrenadeDirectDamage;
  550.                 }
  551.             }
  552.  
  553.             return dangerous;
  554.         }
  555.  
  556.         private IEnumerable<Point> GetCross(Point pt, bool withCentral)
  557.         {
  558.             List<Point> list;
  559.  
  560.             if (withCentral)
  561.                 list = new List<Point>
  562.                 {
  563.                     new Point(pt.X, pt.Y),
  564.                     new Point(pt.X - 1, pt.Y),
  565.                     new Point(pt.X + 1, pt.Y),
  566.                     new Point(pt.X, pt.Y - 1),
  567.                     new Point(pt.X, pt.Y + 1)
  568.                 };
  569.             else
  570.                 list = new List<Point>
  571.                 {
  572.                     new Point(pt.X - 1, pt.Y),
  573.                     new Point(pt.X + 1, pt.Y),
  574.                     new Point(pt.X, pt.Y - 1),
  575.                     new Point(pt.X, pt.Y + 1)
  576.                 };
  577.  
  578.             var arr = new Point[list.Count];
  579.             for (int i = 0; i < arr.Length; ++i)
  580.             {
  581.                 int idx = Rnd.Next(list.Count);
  582.                 arr[i] = list[idx];
  583.                 list.RemoveAt(idx);
  584.             }
  585.             return arr;
  586.         }
  587.  
  588.         private IEnumerable<Point> GetValidCross(Point pt, bool withCentral)
  589.         {
  590.             return GetCross(pt, withCentral).Where(point => point.InWorld).ToArray();
  591.         }
  592.  
  593.         private bool IsUnitNear(Trooper trooper)
  594.         {
  595.             return trooper != null &&
  596.                    GetValidCross(new Point(_self.X, _self.Y), true).Any(pt => pt.X == trooper.X && pt.Y == trooper.Y);
  597.         }
  598.  
  599.         private bool IsBlockedCross(Point point, IEnumerable<Point> additionalPoints)
  600.         {
  601.             return GetCross(point, false)
  602.                 .All(pt => !pt.InWorld ||
  603.                            _world.Troopers.Any(trooper => trooper.X == pt.X && trooper.Y == pt.Y) ||
  604.                            _world.Cells[pt.X][pt.Y] != CellType.Free ||
  605.                            additionalPoints.Any(additionalPoint => additionalPoint == pt));
  606.         }
  607.  
  608.         private bool TryGetBonusIfItNear()
  609.         {
  610.             int bonusDist = _self.ActionPoints / MoveCost + 1;
  611.             Trooper leader = Leader;
  612.  
  613.             foreach (Direction moveToBonus in GetBonuses(bonusDist)
  614.                 .Where(bonus => CellDangerous(new Point(bonus.Item1.X, bonus.Item1.Y), _self.Stance) == 0)
  615.                 .Where(bonus => FindPathDistance(
  616.                     new Point(leader.X, leader.Y),
  617.                     new Point(bonus.Item1.X, bonus.Item1.Y),
  618.                     true, false) <= _self.InitialActionPoints / MoveCost)
  619.                 .Where(bonus => bonus.Item1.Type == BonusType.FieldRation && !_self.IsHoldingFieldRation ||
  620.                                 bonus.Item1.Type == BonusType.Grenade && !_self.IsHoldingGrenade ||
  621.                                 bonus.Item1.Type == BonusType.Medikit && !_self.IsHoldingMedikit)
  622.                 .Select(bonus => bonus.Item3))
  623.             {
  624.                 _move.Direction = moveToBonus;
  625.                 _move.Action = ActionType.Move;
  626.                 return true;
  627.             }
  628.  
  629.             return false;
  630.         }
  631.  
  632.         private bool TryKillWithGranade()
  633.         {
  634.             if (_self.IsHoldingGrenade && _self.ActionPoints >= _game.GrenadeThrowCost)
  635.             {
  636.                 foreach (Trooper enemy in Enemies.Where(enemy => _self.GetDistanceTo(enemy) <= _game.GrenadeThrowRange &&
  637.                                                                  enemy.Hitpoints <= _game.GrenadeDirectDamage))
  638.                 {
  639.                     _move.X = enemy.X;
  640.                     _move.Y = enemy.Y;
  641.                     _move.Action = ActionType.ThrowGrenade;
  642.                     return true;
  643.                 }
  644.             }
  645.  
  646.             return false;
  647.         }
  648.  
  649.         private bool TryKillEnemy()
  650.         {
  651.             if (CanShoot)
  652.             {
  653.                 foreach (Trooper enemy in GetKillableEnemies(null))
  654.                 {
  655.                     _move.X = enemy.X;
  656.                     _move.Y = enemy.Y;
  657.                     _move.Action = ActionType.Shoot;
  658.                     return true;
  659.                 }
  660.             }
  661.  
  662.             return false;
  663.         }
  664.  
  665.         private bool TryShootToEnemy()
  666.         {
  667.             if (CanShoot)
  668.             {
  669.                 foreach (Trooper enemy in GetShootableEnemies(null))
  670.                 {
  671.                     _move.X = enemy.X;
  672.                     _move.Y = enemy.Y;
  673.                     _move.Action = ActionType.Shoot;
  674.                     return true;
  675.                 }
  676.             }
  677.  
  678.             return false;
  679.         }
  680.  
  681.         private bool TryHealHimself()
  682.         {
  683.             if (_self.Type == TrooperType.FieldMedic &&
  684.                 _self.Hitpoints < _self.MaximalHitpoints &&
  685.                 _self.ActionPoints >= _game.FieldMedicHealCost)
  686.             {
  687.                 _move.X = _self.X;
  688.                 _move.Y = _self.Y;
  689.                 _move.Action = ActionType.Heal;
  690.                 return true;
  691.             }
  692.  
  693.             return false;
  694.         }
  695.  
  696.         private bool TryHealTeammate()
  697.         {
  698.             if (_self.Type == TrooperType.FieldMedic)
  699.             {
  700.                 foreach (Trooper wounded in Wounded)
  701.                 {
  702.                     Point[] pathTo = FindPathTo(new Point(wounded.X, wounded.Y), false).ToArray();
  703.                     if (pathTo.Length == 2)
  704.                     {
  705.                         _move.Direction = PointsToDirection(_self.X, _self.Y, pathTo[1].X, pathTo[1].Y);
  706.                         _move.Action = ActionType.Heal;
  707.                         return true;
  708.                     }
  709.                 }
  710.  
  711.                 if (CanMove)
  712.                 {
  713.                     foreach (Trooper wounded in Wounded)
  714.                     {
  715.                         Point[] pathTo = FindPathTo(new Point(wounded.X, wounded.Y), false).ToArray();
  716.                         if (pathTo.Length == 2)
  717.                         {
  718.                             _move.Direction = PointsToDirection(_self.X, _self.Y, pathTo[1].X, pathTo[1].Y);
  719.                             _move.Action = ActionType.Move;
  720.                             return true;
  721.                         }
  722.                     }
  723.                 }
  724.             }
  725.  
  726.             return false;
  727.         }
  728.  
  729.         private IEnumerable<Tuple<int, int, int>> WhereICanGo(int maxSteps)
  730.         {
  731.             for (int i = _self.X - maxSteps; i <= _self.X + maxSteps; ++i)
  732.                 for (int j = _self.Y - maxSteps; j <= _self.Y + maxSteps; ++j)
  733.                     if (i >= 0 && j >= 0 && i < _world.Width && j < _world.Height)
  734.                         if (_world.Cells[i][j] == CellType.Free && _world.Troopers.Any(t => t.X != i || t.Y != j))
  735.                         {
  736.                             Point[] path = FindPathTo(new Point(i, j), false).ToArray();
  737.                             if (path.Length > 1 && path.Length - 1 <= maxSteps)
  738.                             {
  739.                                 Point coords = path[path.Length - 1];
  740.                                 yield return new Tuple<int, int, int>(coords.X, coords.Y, path.Length);
  741.                             }
  742.                         }
  743.         }
  744.  
  745.         private bool TryMoveToThrowGranade()
  746.         {
  747.             if (_self.IsHoldingGrenade && _self.ActionPoints >= _game.GrenadeThrowCost)
  748.             {
  749.                 int steps = (_self.ActionPoints - _game.GrenadeThrowCost) / MoveCost;
  750.  
  751.                 foreach (Tuple<int, int, int> go in WhereICanGo(steps)
  752.                     .OrderBy(target => target.Item3)
  753.                     .Where(target => Enemies.Any(enemy => enemy.GetDistanceTo(target.Item1, target.Item2) <= _game.GrenadeThrowRange)))
  754.                 {
  755.                     Point[] path = FindPathTo(new Point(go.Item1, go.Item2), false).ToArray();
  756.                     if (path.Length > 1)
  757.                     {
  758.                         _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  759.                         _move.Action = ActionType.Move;
  760.                         return true;
  761.                     }
  762.                 }
  763.             }
  764.  
  765.             return false;
  766.         }
  767.  
  768.         private bool TryMoveToKillWithGranade()
  769.         {
  770.             if (CanMove && _self.IsHoldingGrenade && _self.ActionPoints >= _game.GrenadeThrowCost)
  771.             {
  772.                 int steps = (_self.ActionPoints - _game.GrenadeThrowCost) / MoveCost;
  773.  
  774.                 foreach (Tuple<int, int, int> go in WhereICanGo(steps)
  775.                     .Where(target => Enemies.Any(enemy =>
  776.                         enemy.GetDistanceTo(target.Item1, target.Item2) <= _game.GrenadeThrowRange &&
  777.                         enemy.Hitpoints <= _game.GrenadeDirectDamage))
  778.                     .OrderBy(target => CellDangerous(new Point(target.Item1, target.Item2), _self.Stance)))
  779.                 {
  780.                     Point[] path = FindPathTo(new Point(go.Item1, go.Item2), false).ToArray();
  781.                     if (path.Length > 1)
  782.                     {
  783.                         _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  784.                         _move.Action = ActionType.Move;
  785.                         return true;
  786.                     }
  787.                 }
  788.             }
  789.  
  790.             return false;
  791.         }
  792.  
  793.         private bool TryMoveToKillEnemy()
  794.         {
  795.             if (CanMove)
  796.             {
  797.                 int steps = _self.ActionPoints / MoveCost;
  798.  
  799.                 foreach (Tuple<int, int, int> go in WhereICanGo(steps)
  800.                     .OrderBy(target => target.Item3)
  801.                     .Where(target => Enemies.OrderByDescending(enemy => enemy.Hitpoints).Any(enemy =>
  802.                         _world.IsVisible(
  803.                             Math.Min(_self.ShootingRange, _self.VisionRange),
  804.                             target.Item1, target.Item2, _self.Stance,
  805.                             enemy.X, enemy.Y, enemy.Stance) &&
  806.                         enemy.Hitpoints <= Damage * (steps - (target.Item3 - 1)))))
  807.                 {
  808.                     Point[] path = FindPathTo(new Point(go.Item1, go.Item2), false).ToArray();
  809.                     if (path.Length > 1)
  810.                     {
  811.                         _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  812.                         _move.Action = ActionType.Move;
  813.                         return true;
  814.                     }
  815.                 }
  816.             }
  817.  
  818.             return false;
  819.         }
  820.  
  821.         private bool TryThrowGranade()
  822.         {
  823.             if (_self.IsHoldingGrenade && _self.ActionPoints >= _game.GrenadeThrowCost)
  824.             {
  825.                 foreach (Trooper enemy in Enemies.Where(e => _self.GetDistanceTo(e) <= _game.GrenadeThrowRange))
  826.                 {
  827.                     _move.X = enemy.X;
  828.                     _move.Y = enemy.Y;
  829.                     _move.Action = ActionType.ThrowGrenade;
  830.                     return true;
  831.                 }
  832.             }
  833.  
  834.             return false;
  835.         }
  836.  
  837.         private bool TryUseMedikitOnOther()
  838.         {
  839.             if (_self.IsHoldingMedikit && _self.ActionPoints >= _game.MedikitUseCost)
  840.             {
  841.                 Trooper[] wounded = Wounded.ToArray();
  842.  
  843.                 if (wounded.Length > 0)
  844.                 {
  845.                     foreach (Trooper woundedTrooper in wounded)
  846.                     {
  847.                         Point[] pathTo = FindPathTo(new Point(woundedTrooper.X, woundedTrooper.Y), false).ToArray();
  848.                         if (pathTo.Length > 2)
  849.                         {
  850.                             if (CanMove)
  851.                             {
  852.                                 _move.Direction = PointsToDirection(_self.X, _self.Y, pathTo[1].X, pathTo[1].Y);
  853.                                 _move.Action = ActionType.Move;
  854.                                 return true;
  855.                             }
  856.                         }
  857.                         else if (pathTo.Length == 2)
  858.                         {
  859.                             _move.Direction = PointsToDirection(_self.X, _self.Y, pathTo[1].X, pathTo[1].Y);
  860.                             _move.Action = ActionType.UseMedikit;
  861.                             return true;
  862.                         }
  863.                     }
  864.                 }
  865.             }
  866.  
  867.             return false;
  868.         }
  869.  
  870.         private bool TryUseMedikitOnHimself()
  871.         {
  872.             if (_self.IsHoldingMedikit &&
  873.                 _self.Hitpoints <= _self.MaximalHitpoints - _game.MedikitHealSelfBonusHitpoints &&
  874.                 _self.ActionPoints >= _game.MedikitUseCost)
  875.             {
  876.                 _move.X = _self.X;
  877.                 _move.Y = _self.Y;
  878.                 _move.Action = ActionType.UseMedikit;
  879.                 return true;
  880.             }
  881.  
  882.             return false;
  883.         }
  884.  
  885.         private bool TryEatFieldRation()
  886.         {
  887.             if (_self.IsHoldingFieldRation &&
  888.                 _self.ActionPoints <= _self.InitialActionPoints - _game.FieldRationBonusActionPoints &&
  889.                 _self.ActionPoints >= _game.FieldRationEatCost)
  890.             {
  891.                 _move.Action = ActionType.EatFieldRation;
  892.                 return true;
  893.             }
  894.  
  895.             return false;
  896.         }
  897.  
  898.         private bool TryMovingToEnemy()
  899.         {
  900.             return CanMove && PathToEnemies.Select(p => p.ToArray()).Where(p => p.Length > 2).OrderBy(p => p.Length).Any(path =>
  901.                 {
  902.                     _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  903.                     _move.Action = ActionType.Move;
  904.                     return true;
  905.                 });
  906.         }
  907.  
  908.         private bool TryMovingToMedicIfLowLife()
  909.         {
  910.             if (CanMove && _self.Hitpoints <= _self.MaximalHitpoints / 2)
  911.             {
  912.                 Trooper medic = Medic;
  913.                 if (medic != null && !IsUnitNear(medic))
  914.                 {
  915.                     return FindPathTo(new Point(medic.X, medic.Y), false).Skip(1).Any(pt =>
  916.                         {
  917.                             _move.Direction = PointsToDirection(_self.X, _self.Y, pt.X, pt.Y);
  918.                             _move.Action = ActionType.Move;
  919.                             return true;
  920.                         });
  921.                 }
  922.             }
  923.  
  924.             return false;
  925.         }
  926.  
  927.         private bool TryMovingToLeader()
  928.         {
  929.             Trooper leader = Leader;
  930.  
  931.             if (leader == null)
  932.                 return false;
  933.  
  934.             if (leader.Type == _self.Type)
  935.                 return false;
  936.  
  937.             if (CanMove && !IsUnitNear(leader))
  938.             {
  939.                 Point[] pts = FindPathTo(new Point(leader.X, leader.Y), false).ToArray();
  940.                 if (pts.Length > 1 && !IsBlockedCross(new Point(leader.X, leader.Y), new[] { pts[1] }) /* && pts.Length < 10 */ /* ? */)
  941.                 {
  942.                     _move.Direction = PointsToDirection(_self.X, _self.Y, pts[1].X, pts[1].Y);
  943.                     _move.Action = ActionType.Move;
  944.                     return true;
  945.                 }
  946.  
  947.                 pts = FindPathTo(new Point(leader.X, leader.Y), true).ToArray();
  948.                 if (pts.Length > 1 && !_world.Troopers.Any(t => t.X == pts[1].X && t.Y == pts[1].Y) && !IsBlockedCross(new Point(leader.X, leader.Y), new[] { pts[1] }))
  949.                 {
  950.                     _move.Direction = PointsToDirection(_self.X, _self.Y, pts[1].X, pts[1].Y);
  951.                     _move.Action = ActionType.Move;
  952.                     return true;
  953.                 }
  954.             }  
  955.  
  956.             return false;
  957.         }
  958.  
  959.         private void UpdateRegion()
  960.         {
  961.             Region currentRegion = GetCurrentRegion();
  962.  
  963.             if (_oldRegion == Region.Unknown)
  964.                 _oldRegion = currentRegion;
  965.  
  966.             if (_oldRegion == Region.Unknown)
  967.                 _oldRegion = Region.Center;
  968.  
  969.             if (currentRegion != Region.Unknown && _targetRegion == currentRegion)
  970.             {
  971.                 Region tmp = _targetRegion;
  972.  
  973.                 do
  974.                 {
  975.                     _targetRegion = GetRandomRegion();
  976.                 } while (_targetRegion == _oldRegion);
  977.  
  978.                 _oldRegion = tmp;
  979.             }
  980.  
  981.             if (_targetRegion == Region.Unknown)
  982.             {
  983.                 do
  984.                 {
  985.                     _targetRegion = GetRandomRegion();
  986.                 } while (_targetRegion == _oldRegion);
  987.             }
  988.         }
  989.  
  990.         private bool TryMove()
  991.         {
  992.             if (_self.Type == TrooperType.Commander)
  993.             {
  994.                 if (!Enemies.Any())
  995.                     ++_stepsWithoutEnemies;
  996.                 else
  997.                     _stepsWithoutEnemies = 0;
  998.             }
  999.  
  1000.             if (CanMove)
  1001.             {
  1002.                 UpdateRegion();
  1003.  
  1004.                 IEnumerable<Point> emptyPoints = FindEmptyPointsForRegion(_targetRegion);
  1005.                 foreach (Point pt in emptyPoints)
  1006.                 {
  1007.                     Point[] path = FindPathTo(pt, false).ToArray();
  1008.  
  1009.                     if (path.Length > 1)
  1010.                     {
  1011.                         int targetCellDangerous = CellDangerous(new Point(path[1].X, path[1].Y), _self.Stance);
  1012.  
  1013.                         if (targetCellDangerous > CellDangerous(new Point(_self.X, _self.Y), _self.Stance) ||
  1014.                             targetCellDangerous >= _self.Hitpoints)
  1015.                         {
  1016.                             return false;
  1017.                         }
  1018.  
  1019.                         _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  1020.                         _move.Action = ActionType.Move;
  1021.                         return true;
  1022.                     }
  1023.                 }
  1024.             }
  1025.  
  1026.             return false;
  1027.         }
  1028.  
  1029.         private bool TryLeaderMove()
  1030.         {
  1031.             if (Leader.Type == _self.Type)
  1032.             {
  1033.                 if (_self.Type == TrooperType.Commander)
  1034.                 {
  1035.                     if (!Enemies.Any())
  1036.                         ++_stepsWithoutEnemies;
  1037.                     else
  1038.                         _stepsWithoutEnemies = 0;
  1039.                 }
  1040.  
  1041.                 if (CanMove)
  1042.                 {
  1043.                     if (Teammates.Any(trooper => trooper.Type != _self.Type && FindPathDistance(new Point(_self.X, _self.Y), new Point(trooper.X, trooper.Y), false, true) > MaxLeaderDistance))
  1044.                         return false;
  1045.  
  1046.                     UpdateRegion();
  1047.  
  1048.                     IEnumerable<Point> emptyPoints = FindEmptyPointsForRegion(_targetRegion);
  1049.                     foreach (Point pt in emptyPoints)
  1050.                     {
  1051.                         Point[] path = FindPathTo(pt, false).ToArray();
  1052.  
  1053.                         if (path.Length > 1)
  1054.                         {
  1055.                             int targetCellDangerous = CellDangerous(new Point(path[1].X, path[1].Y), _self.Stance);
  1056.  
  1057.                             if (targetCellDangerous > CellDangerous(new Point(_self.X, _self.Y), _self.Stance) ||
  1058.                                 targetCellDangerous >= _self.Hitpoints)
  1059.                             {
  1060.                                 return false;
  1061.                             }
  1062.  
  1063.                             _move.Direction = PointsToDirection(_self.X, _self.Y, path[1].X, path[1].Y);
  1064.                             _move.Action = ActionType.Move;
  1065.                             return true;
  1066.                         }
  1067.                     }
  1068.                 }
  1069.             }
  1070.  
  1071.             return false;
  1072.         }
  1073.  
  1074.         private bool TryChangeStance()
  1075.         {
  1076.             if (_self.Type == TrooperType.FieldMedic)
  1077.                 return false;
  1078.  
  1079.             if (_self.ActionPoints < _game.StanceChangeCost)
  1080.                 return false;
  1081.  
  1082.             switch (_self.Stance)
  1083.             {
  1084.                 case TrooperStance.Prone:
  1085.                     if (!GetShootableEnemies(null).Any() && !GetShootableEnemies(TrooperStance.Kneeling).Any())
  1086.                     {
  1087.                         _move.Action = ActionType.RaiseStance;
  1088.                         _move.X = _self.X;
  1089.                         _move.Y = _self.Y;
  1090.                         return true;
  1091.                     }
  1092.                     break;
  1093.  
  1094.                 case TrooperStance.Kneeling:
  1095.                     if (GetShootableEnemies(null).Any())
  1096.                     {
  1097.                         if (GetShootableEnemies(TrooperStance.Prone).Any())
  1098.                         {
  1099.                             _move.Action = ActionType.LowerStance;
  1100.                             _move.X = _self.X;
  1101.                             _move.Y = _self.Y;
  1102.                             return true;
  1103.                         }
  1104.                     }
  1105.                     else
  1106.                     {
  1107.                         if (!GetShootableEnemies(TrooperStance.Standing).Any())
  1108.                         {
  1109.                             _move.Action = ActionType.RaiseStance;
  1110.                             _move.X = _self.X;
  1111.                             _move.Y = _self.Y;
  1112.                             return true;
  1113.                         }
  1114.                     }
  1115.                    
  1116.                     break;
  1117.  
  1118.                 case TrooperStance.Standing:
  1119.                     if (GetShootableEnemies(null).Any() && GetShootableEnemies(TrooperStance.Kneeling).Any())
  1120.                     {
  1121.                         _move.Action = ActionType.LowerStance;
  1122.                         _move.X = _self.X;
  1123.                         _move.Y = _self.Y;
  1124.                         return true;
  1125.                     }
  1126.                     break;
  1127.             }
  1128.  
  1129.             return false;
  1130.         }
  1131.  
  1132.         private bool TryMedicRunAway()
  1133.         {
  1134.             if (_self.Type != TrooperType.FieldMedic)
  1135.                 return false;
  1136.  
  1137.             if (CellDangerous(new Point(_self.X, _self.Y), TrooperStance.Prone) == 0)
  1138.                 return false;
  1139.  
  1140.             Trooper leader = Leader;
  1141.  
  1142.             return WhereICanGo(_self.Hitpoints/_game.StandingMoveCost - 2)
  1143.                 .Where(go => CellDangerous(new Point(go.Item1, go.Item2), TrooperStance.Standing) == 0)
  1144.                 .Select(go => new Tuple<int, int, int, int>(
  1145.                     go.Item1,
  1146.                     go.Item2,
  1147.                     go.Item3,
  1148.                     FindPathDistance(new Point(go.Item1, go.Item2), new Point(leader.X, leader.Y), false, false)))
  1149.                 .OrderBy(go => go.Item4)
  1150.                 .Select(go => new Point(go.Item1, go.Item2))
  1151.                 .Any(pt =>
  1152.                 {
  1153.                     Point[] pts = FindPathTo(pt, false).ToArray();
  1154.  
  1155.                     if (pts.Length > 1)
  1156.                     {
  1157.                         _move.Direction = PointsToDirection(_self.X, _self.Y, pts[1].X, pts[1].Y);
  1158.                         _move.Action = ActionType.Move;
  1159.                         return true;
  1160.                     }
  1161.  
  1162.                     return false;
  1163.                 });
  1164.         }
  1165.  
  1166.         private bool TryRequestEnemyDisposition()
  1167.         {
  1168.             if (_self.Type != TrooperType.Commander || _self.ActionPoints < _game.CommanderRequestEnemyDispositionCost)
  1169.                 return false;
  1170.  
  1171.             if (_stepsWithoutEnemies > 24 && _dispositionRequested == 0)
  1172.             {
  1173.                 _move.Action = ActionType.RequestEnemyDisposition;
  1174.                 ++_dispositionRequested;
  1175.                 return true;
  1176.             }
  1177.  
  1178.             if (_dispositionRequested == 1)
  1179.             {
  1180.                 foreach (Player player in _world.Players)
  1181.                 {
  1182.                     if (player.ApproximateX >= 0 && player.ApproximateY >= 0)
  1183.                     {
  1184.                         int x = player.ApproximateX;
  1185.                         int y = player.ApproximateY;
  1186.  
  1187.                         if (y > _world.Height / 3 && y < _world.Height / 3 * 2 &&
  1188.                             x > _world.Width / 3 && x < _world.Width / 3 * 2)
  1189.                         {
  1190.                             _targetRegion = Region.Center;
  1191.                         }
  1192.                         else if (y < _world.Height / 2)
  1193.                         {
  1194.                             _targetRegion = x < _world.Width / 2 ? Region.NW : Region.NE;
  1195.                         }
  1196.                         else
  1197.                         {
  1198.                             _targetRegion = x < _world.Width / 2 ? Region.SW : Region.SE;
  1199.                         }
  1200.  
  1201.                        
  1202.                         return true;
  1203.                     }
  1204.                 }
  1205.                 ++_dispositionRequested;
  1206.                 return false;
  1207.             }
  1208.  
  1209.             return false;
  1210.         }
  1211.  
  1212.         private void FillDangerField()
  1213.         {
  1214.             _dangerField = new int[_world.Width, _world.Height, 3];
  1215.             for (int k = 0; k < 3; ++k)
  1216.             {
  1217.                 var stance = (TrooperStance)k;
  1218.  
  1219.                 for (int j = 0; j < _world.Height; ++j)
  1220.                     for (int i = 0; i < _world.Width; ++i)
  1221.                         _dangerField[i, j, k] = CellDangerous(new Point(i, j), stance);
  1222.             }
  1223.         }
  1224.  
  1225.         public void Move(Trooper self, World world, Game game, Move move)
  1226.         {
  1227.             _self = self;
  1228.             _world = world;
  1229.             _game = game;
  1230.             _move = move;
  1231.  
  1232.             FillDangerField();
  1233.  
  1234.             var strategies = new List<Func<bool>>
  1235.                 {
  1236.                     TryEatFieldRation,
  1237.  
  1238.                     TryKillWithGranade,
  1239.                     TryKillEnemy,
  1240.                     TryMoveToKillEnemy,
  1241.                     TryMoveToKillWithGranade,
  1242.  
  1243.                     TryMovingToMedicIfLowLife,
  1244.                     TryUseMedikitOnHimself,
  1245.                     TryUseMedikitOnOther,
  1246.                     TryHealTeammate,
  1247.                     TryHealHimself,
  1248.                     TryMedicRunAway,
  1249.  
  1250.                     TryThrowGranade,
  1251.                     TryMoveToThrowGranade,
  1252.  
  1253.                     TryChangeStance,
  1254.                     TryShootToEnemy,
  1255.                     TryGetBonusIfItNear,
  1256.                     //TryMovingToLeader,
  1257.                     TryMovingToEnemy,
  1258.                     TryRequestEnemyDisposition,
  1259.                     //TryLeaderMove,
  1260.                     TryMove
  1261.                 };
  1262.  
  1263.             if (strategies.Any(strategy => strategy()))
  1264.                 return;
  1265.  
  1266.             move.Action = ActionType.EndTurn;
  1267.         }
  1268.     }
  1269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement