Пример #1
0
        public static (int fullyFinishedRounds, int totalHitpoints, bool anyElfDied) ProcessGame(string pathToInputFile, int elvesAttackPower = 3)
        {
            var      lines = File.ReadAllLines(pathToInputFile);
            Day15Map game  = new Day15Map(lines[0].Length, lines.Length);

            for (int y = 0; y < lines.Length; y++)
            {
                var line = lines[y];
                for (int x = 0; x < line.Length; x++)
                {
                    switch (line[x])
                    {
                    case '#':
                        game.Set(x, y);
                        break;

                    case 'G':
                        game.AddUnit(new Day15Unit(Day15UnitType.Goblin, new Point(x, y), 3));
                        break;

                    case 'E':
                        game.AddUnit(new Day15Unit(Day15UnitType.Elf, new Point(x, y), elvesAttackPower));
                        break;
                    }
                }
            }

            int elvesonTheBattleField = game.AllUnits.Where(x => x.Type == Day15UnitType.Elf).Count();

            int roundCounter = 0;

            PrintAndWait();
            while (!game.MakeARound())
            {
                roundCounter++;
                PrintAndWait();
            }

            PrintAndWait();

            void PrintAndWait()
            {
                //game.Print();
                //Console.WriteLine(roundCounter);
                //Console.ReadLine();
            }

            return(roundCounter, game.AllUnits.Sum(x => x.hitPoints), elvesonTheBattleField != game.AllUnits.Where(x => x.Type == Day15UnitType.Elf).Count());
        }
Пример #2
0
            public bool TakeATurn(Day15Map map)
            {
                var allEnemyUnits = map.AllUnits.Where(x => x.IsTarget(Type)).ToList();

                if (!allEnemyUnits.Any())
                {
                    return(false);
                }

                var costs = map.GetCosts(Position);

                (Point point, int cost)? GetCost(Day15Unit unit)
                {
                    List <(Point point, int cost)> reachablePoints = new List <(Point point, int cost)>();

                    foreach (var offset in offsets)
                    {
                        var copy = unit.Position;
                        copy.Offset(offset);
                        if (costs.ContainsKey(copy))
                        {
                            var value = costs[copy];
                            if (value > 0)
                            {
                                reachablePoints.Add((copy, value));
                            }
                        }
                    }

                    if (reachablePoints.Any())
                    {
                        return(reachablePoints.OrderBy(x => x.cost).ThenBy(x => x.point.Y).ThenBy(x => x.point.X).First());
                    }
                    return(null);
                }

                List <Day15Unit> possibleAttackUnits = new List <Day15Unit>();

                foreach (var offset in offsets)
                {
                    var copy = Position;
                    copy.Offset(offset);
                    var enemy = allEnemyUnits.FirstOrDefault(x => x.Position.Equals(copy));
                    if (enemy != null && !enemy.IsDead)
                    {
                        possibleAttackUnits.Add(enemy);
                    }
                }
                var unitToAttack = possibleAttackUnits.OrderBy(x => x.hitPoints).ThenBy(x => x.Position.Y).ThenBy(x => x.Position.X).FirstOrDefault();

                if (unitToAttack == null)
                {
                    var pointToReach = allEnemyUnits.Select(GetCost).Where(x => x != null).OrderBy(x => x.Value.cost).ThenBy(x => x.Value.point.Y).ThenBy(x => x.Value.point.X).FirstOrDefault();
                    if (pointToReach != null)
                    {
                        var newPoint = map.GetPath(Position, pointToReach.Value.point);
                        if (newPoint == null)
                        {
                            throw new Exception();
                        }
                        if (newPoint.Value.cost != pointToReach.Value.cost)
                        {
                            throw new Exception();
                        }

                        Position = newPoint.Value.firstStep;
                    }
                    else
                    {
                    }
                }


                //var possibleTargets = map.GetAllTargets().ToList();
                //if (possibleTargets.Where(x => x.unit.IsTarget(Type)).Count() == 0)
                //    return false;

                //var possible = possibleTargets.Select(x => (x, map.GetPaths(Position, x.unit.Position))).Where(x => x.Item2 != null).OrderBy(x => x.Item2.Value.lenght).ThenBy(x => x.Item2.Value.firstStep.Y).ThenBy(x => x.Item2.Value.firstStep.X);
                //if (!possible.Where(x => x.Item1.unit.IsTarget(Type)).Any())
                //    return true;

                //var f = possible.Where(x => x.Item1.unit.IsTarget(Type) && x.Item2.Value.lenght < 1000);
                //if (f.Any() && f.Min(x => x.Item2.Value.lenght) > 1)
                //{
                //    var actual = f.Where(x => !possibleTargets.Select(y => y.unit.Position).Contains(x.Item2.Value.firstStep)).SkipWhile(x => !x.Item1.canBeTargeted).FirstOrDefault();
                //    if (actual.Item2 != null)
                //        Position = actual.Item2.Value.firstStep;
                //}

                //attack


                //List<Day15Unit> possibleAttackUnits = new List<Day15Unit>();
                foreach (var offset in offsets)
                {
                    var copy = Position;
                    copy.Offset(offset);
                    var enemy = allEnemyUnits.FirstOrDefault(x => x.Position.Equals(copy));
                    if (enemy != null && !enemy.IsDead)
                    {
                        possibleAttackUnits.Add(enemy);
                    }
                }
                unitToAttack = possibleAttackUnits.OrderBy(x => x.hitPoints).ThenBy(x => x.Position.Y).ThenBy(x => x.Position.X).FirstOrDefault();
                if (unitToAttack != null)
                {
                    unitToAttack.hitPoints -= attackPower;
                }

                return(true);
            }