Exemplo n.º 1
0
        public void Process_Health50BesideATavern_1Paths()
        {
            var map   = MapTest.Map10Mines8;
            var state = State.Create(0,
                                     new Hero(50, 1, 0, 0, 0),
                                     new Hero(100, 8, 0, 0, 0),
                                     new Hero(100, 8, 9, 0, 0),
                                     new Hero(100, 1, 9, 0, 0),
                                     MineOwnership.Create(map));

            var source = map[state.Hero1];
            var mines  = state.Mines;

            var collection = SafePathCollection.Create(map, state);
            var processor  = new DrinkBeerProcessor();

            processor.Initialize(map, state);

            var path = PotentialPath.Initial(source, map, state);

            processor.Process(path, collection);

            var act = collection.GetPotentialPaths();

            Assert.AreEqual(1, act.Count);
            PotentialPathAssert.AreEqual(1, source, 99, mines, MoveDirections.E, -2, act[0]);
        }
Exemplo n.º 2
0
        /// <summary>Processes the potential path.</summary>
        public override void Process(PotentialPath potentialPath, SafePathCollection collection)
        {
            var source = potentialPath.Source;

            if (source.Neighbors.Any(n => n.IsTaverne))
            {
                var directions = new MoveDirections(source.Directions.Where(direction => source[direction].IsTaverne));

                var turns  = 0;
                var health = potentialPath.Health;
                var profit = 0;
                var mines  = potentialPath.Mines.Count(this.PlayerToMove);

                while (health < Hero.HealthMax)
                {
                    turns++;
                    health  = Math.Min(health + Hero.HealthTavern, Hero.HealthMax);
                    profit += mines - Hero.CostsTavern;

                    var followUp = potentialPath.CreateFollowUp(
                        source,
                        health - 1,
                        potentialPath.Mines,
                        directions,
                        turns,
                        profit);

                    collection.Enqueue(followUp);
                }
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Creates a new Potential Path which is a copy of an existing Path
 /// </summary>
 /// <param name="p">Potentuak Path</param>
 public PotentialPath(PotentialPath p)
 {
     this._start    = p.Start;
     this._current  = p.Current;
     this._complete = p.IsComplete;
     this._deadend  = p.IsDeadEnd;
     this._partial  = p.IsPartial;
     this._length   = p.Length;
 }
Exemplo n.º 4
0
 /// <summary>
 /// Creates a new Potential Path which is a copy of an existing Path
 /// </summary>
 /// <param name="p">Potentuak Path</param>
 public PotentialPath(PotentialPath p)
 {
     _start    = p.Start;
     _current  = p.Current;
     _complete = p.IsComplete;
     _deadend  = p.IsDeadEnd;
     _partial  = p.IsPartial;
     _length   = p.Length;
 }
Exemplo n.º 5
0
 public override void Process(PotentialPath potentialPath, SafePathCollection collection)
 {
     foreach (var mine in this.Map.Mines.Where(m => potentialPath.Mines[m.MineIndex] != this.PlayerToMove))
     {
         foreach (var target in mine.Neighbors.Where(n => n.IsPassable))
         {
             ProcessToMine(potentialPath, target, mine.MineIndex, collection);
         }
     }
 }
Exemplo n.º 6
0
 public override void Process(PotentialPath potentialPath, SafePathCollection collection)
 {
     foreach (var Tavern in this.Map.Taverns)
     {
         foreach (var target in Tavern.Neighbors.Where(n => n.IsPassable))
         {
             ProcessToTavern(potentialPath, target, collection);
         }
     }
 }
 public static void AddPotential(PotentialPath potential_path, int parent_cell, NavType parent_nav_type, int cost, int underwater_cost, int transition_id, PotentialList potentials, PathGrid path_grid, ref Cell cell_data)
 {
     cell_data.cost           = cost;
     cell_data.underwaterCost = (byte)Math.Min(underwater_cost, 255);
     cell_data.parent         = parent_cell;
     cell_data.navType        = potential_path.navType;
     cell_data.parentNavType  = parent_nav_type;
     cell_data.transitionId   = transition_id;
     potentials.Add(cost, potential_path);
     path_grid.SetCell(potential_path, ref cell_data);
 }
 public static void Run(NavGrid nav_grid, PathFinderAbilities abilities, PotentialPath potential_path, PathFinderQuery query, ref Path path)
 {
     Run(nav_grid, abilities, potential_path, query);
     if (query.GetResultCell() != InvalidCell)
     {
         BuildResultPath(query.GetResultCell(), query.GetResultNavType(), ref path);
     }
     else
     {
         path.Clear();
     }
 }
Exemplo n.º 9
0
 /// <summary>
 /// Checks whether the other object is an equivalent potential path
 /// </summary>
 /// <param name="obj">Object to test</param>
 /// <returns></returns>
 public override bool Equals(object obj)
 {
     if (obj is PotentialPath)
     {
         PotentialPath other = (PotentialPath)obj;
         return(this._start.Equals(other.Start) && this._current.Equals(other.Current));
     }
     else
     {
         return(false);
     }
 }
    public static void Run(NavGrid nav_grid, PathFinderAbilities abilities, PotentialPath potential_path, PathFinderQuery query)
    {
        int     result_cell     = InvalidCell;
        NavType result_nav_type = NavType.NumNavTypes;

        query.ClearResult();
        if (Grid.IsValidCell(potential_path.cell))
        {
            FindPaths(nav_grid, ref abilities, potential_path, query, Temp.Potentials, ref result_cell, ref result_nav_type);
            if (result_cell != InvalidCell)
            {
                bool is_cell_in_range = false;
                Cell cell             = PathGrid.GetCell(result_cell, result_nav_type, out is_cell_in_range);
                query.SetResult(result_cell, cell.cost, result_nav_type);
            }
        }
    }
Exemplo n.º 11
0
 public static void AreEqual(
     int expTurns,
     Tile expSource,
     int expHealth,
     IMineOwnership expMines,
     MoveDirections expDirections,
     int expProfit,
     PotentialPath actual)
 {
     Assert.IsNotNull(actual);
     Assert.AreEqual(expTurns, actual.Turns, "Turns, {0}", actual.DebuggerDisplay);
     Assert.AreEqual(expSource, actual.Source, "Sources, {0}", actual.DebuggerDisplay);
     Assert.AreEqual(expHealth, actual.Health, "Health, {0}", actual.DebuggerDisplay);
     Assert.AreEqual(expMines, actual.Mines, "Mines, {0}", actual.DebuggerDisplay);
     Assert.AreEqual(expDirections, actual.Directions, "Directions, {0}", actual.DebuggerDisplay);
     Assert.AreEqual(expProfit, actual.Profit, "Profit, {0}", actual.DebuggerDisplay);
     //public List<PotentialOpponent> Opponents { get; set; }
 }
    private static void FindPaths(NavGrid nav_grid, ref PathFinderAbilities abilities, PotentialPath potential_path, PathFinderQuery query, PotentialList potentials, ref int result_cell, ref NavType result_nav_type)
    {
        potentials.Clear();
        PathGrid.ResetUpdate();
        PathGrid.BeginUpdate(potential_path.cell, false);
        bool is_cell_in_range;
        Cell cell_data = PathGrid.GetCell(potential_path, out is_cell_in_range);

        AddPotential(potential_path, Grid.InvalidCell, NavType.NumNavTypes, 0, 0, -1, potentials, PathGrid, ref cell_data);
        int num = 2147483647;

        while (potentials.Count > 0)
        {
            KeyValuePair <int, PotentialPath> keyValuePair = potentials.Next();
            cell_data = PathGrid.GetCell(keyValuePair.Value, out is_cell_in_range);
            if (cell_data.cost != keyValuePair.Key)
            {
                continue;
            }
            int num2;
            if (cell_data.navType != NavType.Tube)
            {
                PotentialPath value = keyValuePair.Value;
                if (query.IsMatch(value.cell, cell_data.parent, cell_data.cost))
                {
                    num2 = ((cell_data.cost < num) ? 1 : 0);
                    goto IL_00cc;
                }
            }
            num2 = 0;
            goto IL_00cc;
IL_00cc:
            if (num2 != 0)
            {
                PotentialPath value2 = keyValuePair.Value;
                result_cell     = value2.cell;
                num             = cell_data.cost;
                result_nav_type = cell_data.navType;
                break;
            }
            AddPotentials(nav_grid.potentialScratchPad, keyValuePair.Value, cell_data.cost, cell_data.underwaterCost, ref abilities, query, nav_grid.maxLinksPerCell, nav_grid.Links, potentials, PathGrid, cell_data.parent, cell_data.parentNavType);
        }
        PathGrid.EndUpdate(true);
    }
Exemplo n.º 13
0
        public Path FindPath(Coordinates departure, Coordinates arrival)
        {
            CheckCellIsOnMap(nameof(departure), departure);     
            CheckCellIsOnMap(nameof(arrival), arrival);
            CheckCellIsNotBlock(nameof(departure), departure);
            CheckCellIsNotBlock(nameof(arrival), arrival);

            Dictionary<Coordinates, PotentialPath> potentialPaths = new Dictionary<Coordinates, PotentialPath>();

            foreach(var keyValue in _cells.Where(kv => kv.Value.Type != CellType.Block))
            {
                potentialPaths[keyValue.Key] = keyValue.Key == departure ? 
                    new PotentialPath() {
                        Path = Path.Create(Step.Create(departure)),
                        Explored = false 
                    } : null;
            }

            while (potentialPaths[arrival] == null)
            {
                var nextCellsToExplore = potentialPaths.Where(p => p.Value != null && !p.Value.Explored);
                if (!nextCellsToExplore.Any())
                {
                    break;
                }
                var minPathWeight = nextCellsToExplore.Min(c => c.Value.Path.Weight);
                var nextCellToExplore = nextCellsToExplore.First(c => c.Value.Path.Weight == minPathWeight);
                nextCellToExplore.Value.Explored = true;
                foreach (var neighbor in _cells[nextCellToExplore.Key].Coordinates.Surrounding)
                {
                    if (potentialPaths.ContainsKey(neighbor) && potentialPaths[neighbor] == null)
                    {
                        potentialPaths[neighbor] = new PotentialPath() {
                            Path = nextCellToExplore.Value.Path.AddStep(Step.Create(neighbor, _cells[neighbor].Weight)),
                            Explored = false
                        };
                    }
                }
            }

            return potentialPaths[arrival]?.Path;
        }
Exemplo n.º 14
0
        public void Process_Health99BesideATavern_NoPaths()
        {
            var map   = MapTest.Map10Mines8;
            var state = State.Create(0,
                                     new Hero(100, 1, 0, 0, 0),
                                     new Hero(100, 8, 0, 0, 0),
                                     new Hero(100, 8, 9, 0, 0),
                                     new Hero(100, 1, 9, 0, 0),
                                     MineOwnership.Create(map));

            var collection = SafePathCollection.Create(map, state);
            var processor  = new DrinkBeerProcessor();

            processor.Initialize(map, state);

            var path = PotentialPath.Initial(map[state.Hero1], map, state);

            processor.Process(path, collection);

            var act = collection.GetPotentialPaths();

            Assert.AreEqual(0, act.Count);
        }
 public static bool ValidatePath(NavGrid nav_grid, PathFinderAbilities abilities, ref Path path)
 {
     if (!path.IsValid())
     {
         return(false);
     }
     for (int i = 0; i < path.nodes.Count; i++)
     {
         Path.Node node = path.nodes[i];
         if (i < path.nodes.Count - 1)
         {
             Path.Node    node2 = path.nodes[i + 1];
             int          num   = node.cell * nav_grid.maxLinksPerCell;
             bool         flag  = false;
             NavGrid.Link link  = nav_grid.Links[num];
             while (link.link != InvalidHandle)
             {
                 if (link.link == node2.cell && node2.navType == link.endNavType && node.navType == link.startNavType)
                 {
                     PotentialPath path2 = new PotentialPath(node.cell, node.navType, PotentialPath.Flags.None);
                     flag = abilities.TraversePath(ref path2, node.cell, node.navType, 0, link.transitionId, 0);
                     if (flag)
                     {
                         break;
                     }
                 }
                 num++;
                 link = nav_grid.Links[num];
             }
             if (!flag)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Exemplo n.º 16
0
 public abstract void Process(PotentialPath potentialPath, SafePathCollection collection);
Exemplo n.º 17
0
        public void ProcessToMine(PotentialPath potentialPath, Tile target, int mineIndex, SafePathCollection collection)
        {
            var source = potentialPath.Source;

            var distances         = GetEmptyDistances();
            var distancesToTarget = this.Map.GetDistances(target);

            var startDistance = distancesToTarget.Get(source);
            var distance      = startDistance;
            var health        = potentialPath.Health;
            var turns         = potentialPath.Turns;

            var queue = new Queue <Tile>();

            distances.Set(source, distance);
            queue.Enqueue(source);

            while (distance > Distance.Zero)
            {
                var options = queue.Count;

                // No options available.
                if (options == 0)
                {
                    return;
                }
                distance--;
                health = Math.Max(Hero.HealthMin, health - 1);
                turns++;

                for (int option = 0; option < options; option++)
                {
                    var tile = queue.Dequeue();

                    foreach (var neighbor in tile.Neighbors)
                    {
                        //if (ShouldEnqueue(distances, distancesToTarget, distance, turns, health, neighbor))
                        //{
                        //	queue.Enqueue(neighbor);
                        //}
                    }
                }
            }

            var isSafe = false;

            // It takes another turn to get the mine.
            turns++;

            while (!isSafe && queue.Count > 0)
            {
                var tile = queue.Dequeue();
                isSafe =
                    health > Hero.HealthBattle ||
                    potentialPath.Opponents.All(oppo => !oppo.StrongerAtLocationAndTime(this.Map, tile, health, turns));
            }
            if (isSafe)
            {
                var directions = potentialPath.Directions;
                if (directions.IsEmpty())
                {
                    directions = new MoveDirections(source.Directions.Where(dir => distances.Get(source[dir]) < startDistance));

                    if (directions.Length == 0)
                    {
                        // we are already standing beside a mine.
                        if (startDistance == Distance.Zero)
                        {
                            directions = new MoveDirections(source.Directions.Where(dir => source[dir].MineIndex == mineIndex));
                        }
                        if (directions.Length == 0)
                        {
#if DEBUG
                            throw new Exception("No directions found.");
#else
                            return;
#endif
                        }
                    }
                }
                var mines = potentialPath.Mines.Set(mineIndex, this.PlayerToMove);
                health -= Hero.HealthBattle;

                var profit = potentialPath.Profit;
                profit += (mines.Count(this.PlayerToMove) - 1) * (turns - potentialPath.Turns) + 1;

                var followUp = potentialPath.CreateFollowUp(target, health, mines, directions, turns, profit);
                collection.Enqueue(followUp);
            }
        }
Exemplo n.º 18
0
        public void ProcessToTavern(PotentialPath potentialPath, Tile target, SafePathCollection collection)
        {
            var source            = potentialPath.Source;
            var distances         = GetEmptyDistances();
            var distancesToTarget = this.Map.GetDistances(target);

            var startDistance = distancesToTarget.Get(source);
            var distance      = startDistance;
            var health        = potentialPath.Health;
            var turns         = potentialPath.Turns;

            // We don't consider it a safe path (yet) when we are already beside a Tavern.
            if (potentialPath.Turns == 0 && startDistance == Distance.Zero)
            {
                return;
            }

            var queue = new Queue <Tile>();

            distances.Set(source, distance);
            queue.Enqueue(source);

            while (distance > Distance.Zero)
            {
                var options = queue.Count;

                // No options available.
                if (options == 0)
                {
                    return;
                }
                distance--;
                health = Math.Max(Hero.HealthMin, health - 1);
                turns++;

                for (int option = 0; option < options; option++)
                {
                    var tile = queue.Dequeue();
                    foreach (var neighbor in tile.Neighbors)
                    {
                        //if (ShouldEnqueue(distances, distancesToTarget, distance, potentialPath.Turns, health, neighbor))
                        //{
                        //	queue.Enqueue(neighbor);
                        //}
                    }
                }
            }
            var isSafe = false;

            while (!isSafe && queue.Count > 0)
            {
                var tile = queue.Dequeue();
                isSafe =
                    health > Hero.HealthBattle ||
                    potentialPath.Opponents.All(oppo => !oppo.StrongerAtLocationAndTime(this.Map, tile, health, turns));
            }
            if (isSafe)
            {
                var profit = potentialPath.Profit;
                profit += potentialPath.Mines.Count(this.PlayerToMove) * (int)startDistance;

                if (potentialPath.Directions.IsEmpty())
                {
                    var directions = source.Directions
                                     .Where(dir => distances.Get(source[dir]) < startDistance)
                                     .ToArray();

                    // We just found a direct safe paht to a Tavern.
                    collection.Add(new SafePath(potentialPath.Mines.Count(this.PlayerToMove), turns, profit, directions));
                }
                else
                {
                    collection.Add(potentialPath.ToSafePath(this.PlayerToMove, turns, profit));
                }
            }
        }
 public void Add(int cost, PotentialPath path)
 {
     queue.Enqueue(cost, path);
 }
 public static void UpdatePath(NavGrid nav_grid, PathFinderAbilities abilities, PotentialPath potential_path, PathFinderQuery query, ref Path path)
 {
     Run(nav_grid, abilities, potential_path, query, ref path);
 }
    public static void AddPotentials(PotentialScratchPad potential_scratch_pad, PotentialPath potential, int cost, int underwater_cost, ref PathFinderAbilities abilities, PathFinderQuery query, int max_links_per_cell, NavGrid.Link[] links, PotentialList potentials, PathGrid path_grid, int parent_cell, NavType parent_nav_type)
    {
        int num = 0;

        NavGrid.Link[] linksWithCorrectNavType = potential_scratch_pad.linksWithCorrectNavType;
        int            num2 = potential.cell * max_links_per_cell;

        NavGrid.Link link = links[num2];
        for (int link2 = link.link; link2 != InvalidHandle; link2 = link.link)
        {
            if (link.startNavType == potential.navType && (parent_cell != link2 || parent_nav_type != link.startNavType))
            {
                linksWithCorrectNavType[num++] = link;
            }
            num2++;
            link = links[num2];
        }
        int num4 = 0;

        PotentialScratchPad.PathGridCellData[] linksInCellRange = potential_scratch_pad.linksInCellRange;
        for (int i = 0; i < num; i++)
        {
            NavGrid.Link link3            = linksWithCorrectNavType[i];
            int          link4            = link3.link;
            bool         is_cell_in_range = false;
            Cell         cell             = path_grid.GetCell(link4, link3.endNavType, out is_cell_in_range);
            if (is_cell_in_range)
            {
                int  num5  = cost + link3.cost;
                bool flag  = cell.cost == -1;
                bool flag2 = num5 < cell.cost;
                if (flag || flag2)
                {
                    linksInCellRange[num4++] = new PotentialScratchPad.PathGridCellData
                    {
                        pathGridCell = cell,
                        link         = link3
                    };
                }
            }
        }
        for (int j = 0; j < num4; j++)
        {
            PotentialScratchPad.PathGridCellData pathGridCellData = linksInCellRange[j];
            NavGrid.Link link5 = pathGridCellData.link;
            int          link6 = link5.link;
            pathGridCellData.isSubmerged = IsSubmerged(link6);
            linksInCellRange[j]          = pathGridCellData;
        }
        for (int k = 0; k < num4; k++)
        {
            PotentialScratchPad.PathGridCellData pathGridCellData2 = linksInCellRange[k];
            NavGrid.Link  link7     = pathGridCellData2.link;
            int           link8     = link7.link;
            Cell          cell_data = pathGridCellData2.pathGridCell;
            int           num7      = cost + link7.cost;
            PotentialPath path      = potential;
            path.cell    = link8;
            path.navType = link7.endNavType;
            int underwater_cost2;
            if (pathGridCellData2.isSubmerged)
            {
                underwater_cost2 = underwater_cost + 1;
                int submergedPathCostPenalty = abilities.GetSubmergedPathCostPenalty(path, link7);
                num7 += submergedPathCostPenalty;
            }
            else
            {
                underwater_cost2 = 0;
            }
            PotentialPath.Flags flags = path.flags;
            bool flag3 = abilities.TraversePath(ref path, potential.cell, potential.navType, num7, link7.transitionId, underwater_cost2);
            if (path.flags != flags)
            {
                KProfiler.AddEvent("NavChange");
            }
            if (flag3)
            {
                AddPotential(path, potential.cell, potential.navType, num7, underwater_cost2, link7.transitionId, potentials, path_grid, ref cell_data);
            }
        }
    }