예제 #1
0
        private static GridCell[,] ParseGrid(IEnumerable <string> lines)
        {
            int y            = 0;
            var allLines     = lines.ToList();
            int width        = allLines[0].Length;
            var grid         = new GridCell[allLines.Count, width];
            int nextGoblinId = 0;
            int nextElfId    = 0;

            foreach (string line in lines.Where(s => !string.IsNullOrWhiteSpace(s)))
            {
                if (line.Length != width)
                {
                    throw new ArgumentException("All lines must be same length");
                }

                int x = 0;
                foreach (char c in line)
                {
                    GridCell cell;
                    switch (c)
                    {
                    case '#':
                        cell = GridCell.Wall();
                        break;

                    case '.':
                        cell = GridCell.Empty();
                        break;

                    case 'G':
                        cell = GridCell.Goblin(nextGoblinId++);
                        break;

                    case 'E':
                        cell = GridCell.Elf(nextElfId++);
                        break;

                    default:
                        throw new ArgumentException("Unknown map cell type: " + c);
                    }

                    grid[y, x++] = cell;
                }

                y += 1;
            }

            return(grid);
        }
예제 #2
0
파일: GameState.cs 프로젝트: idg10/AoC2018
        public (GameState state, bool combatEnds) PlayRound()
        {
            bool combatEnds = false;

            var coordinates = new List <(int x, int y)>();
            int height      = Grid.GetLength(0);
            int width       = Grid.GetLength(1);

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    GridCell cell = Grid[y, x];
                    if (cell.IsElf || cell.IsGoblin)
                    {
                        coordinates.Add((x, y));
                    }
                }
            }

            var elfHitPoints    = ElfHitPoints;
            var goblinHitPoints = GoblinHitPoints;

            GridCell[,] grid = Grid;
            for (int i = 0; i < coordinates.Count; ++i)
            {
                var xy = coordinates[i];

                GridCell unitCell = grid[xy.y, xy.x];
                if (!(unitCell.IsElf || unitCell.IsGoblin))
                {
                    // Already taken out in an earlier turn this round.
                    continue;
                }

                if ((unitCell.IsElf && !goblinHitPoints.Any(kv => kv.Value > 0)) ||
                    (unitCell.IsGoblin && !elfHitPoints.Any(kv => kv.Value > 0)))
                {
                    combatEnds = true;
                    break;
                }

                int hitPower = unitCell.IsElf
                    ? elfHitPoints[unitCell.ElfId.Value]
                    : goblinHitPoints[unitCell.GoblinId.Value];

                // Move if appropriate.
                var move = GridOperations.CalculateMove(grid, xy.x, xy.y);
                if (move.HasValue)
                {
                    bool isElf  = unitCell.IsElf;
                    int  unitId = isElf ? unitCell.ElfId.Value : unitCell.GoblinId.Value;

                    RemoveItem(height, width, grid, xy);

                    var newCoordinates = (x : xy.x + move.Value.dx, y : xy.y + move.Value.dy);
                    grid[newCoordinates.y, newCoordinates.x] = isElf
                        ? GridCell.Elf(unitId)
                        : GridCell.Goblin(unitId);
                    GridOperations.CalculateCloseness(_gridPair);
                    coordinates[i] = newCoordinates;
                }

                // Attack if appropriate.
                xy = coordinates[i];
                var match = GridOperations.FindBest(
                    grid,
                    xy.x,
                    xy.y,
                    c =>
                {
                    bool isTarget = unitCell.IsElf ? c.IsGoblin : c.IsElf;
                    return(isTarget
                            ? NullIfDead(unitCell.IsElf ? goblinHitPoints[c.GoblinId.Value] : elfHitPoints[c.ElfId.Value])
                            : default);

                    int?NullIfDead(int v) => v > 0 ? v : default;
                },