예제 #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]);
        }
예제 #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);
                }
            }
        }
예제 #3
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);
         }
     }
 }
예제 #4
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);
         }
     }
 }
예제 #5
0
        public void Process_Get1MineAfterDrinkingTwice_4Mines15Turns42Profit()
        {
            var map   = MapTest.Map10Mines8;
            var state = State.Create(1,
                                     new Hero(99, 8, 9, 0, 2),
                                     new Hero(01, 1, 0, 0, 0),
                                     new Hero(50, 3, 2, 0, 0),
                                     new Hero(99, 8, 8, 0, 0),
                                     MineOwnership.Parse(".22......"));

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

            collection.Procces();
            foreach (var item in collection)
            {
                Console.WriteLine(item.DebuggerDisplay);
            }

            var act = collection.BestPath;
            var exp = new SafePath(3, 7, 13, MoveDirection.E);

            Assert.AreEqual(exp, act);
        }
예제 #6
0
        public void Process_Get4Mines_4Mines15Turns42Profit()
        {
            var map   = MapTest.Map10Mines8;
            var state = State.Create(0,
                                     new Hero(100, 3, 4, 0, 0),
                                     new Hero(100, 8, 0, 0, 0, true),
                                     new Hero(100, 8, 9, 0, 0, true),
                                     new Hero(100, 1, 9, 0, 0, true),
                                     MineOwnership.Create(map));

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

            collection.Procces();
            foreach (var item in collection)
            {
                Console.WriteLine(item.DebuggerDisplay);
            }

            var act = collection.BestPath;
            var exp = new SafePath(4, 15, 42, MoveDirection.E);

            Assert.AreEqual(exp, act);
        }
예제 #7
0
        public void Process_Get1Mine1Mine4Turns4Profit()
        {
            var map   = MapTest.Map10;
            var state = State.Create(0,
                                     new Hero(23, 0, 0, 0, 0),
                                     new Hero(99, 9, 0, 0, 0),
                                     new Hero(99, 9, 9, 0, 0),
                                     new Hero(99, 0, 9, 0, 0),
                                     MineOwnership.Create(map));

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

            collection.Procces();
            foreach (var item in collection)
            {
                Console.WriteLine(item.DebuggerDisplay);
            }

            var act = collection.BestPath;
            var exp = new SafePath(1, 4, 4, MoveDirection.S);

            Assert.AreEqual(exp, act);
        }
예제 #8
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);
        }
예제 #9
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);
            }
        }
예제 #10
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));
                }
            }
        }
예제 #11
0
 public abstract void Process(PotentialPath potentialPath, SafePathCollection collection);