示例#1
0
        public long SolveA(string input)
        {
            /*
             * int[,] myarray = new int[1, 200];
             */
            // 8, 3
            var myList = Parser.TokenizeLines(input);
            var coords = new List <Coords>();

            foreach (var row in myList)
            {
                var myRow = Parser.Tokenize(row);
                coords.Add(new Coords(int.Parse(myRow[0]), int.Parse(myRow[1])));
            }

            var minRow = int.MaxValue;
            var maxRow = int.MinValue;
            var minCol = int.MaxValue;
            var maxCol = int.MinValue;

            foreach (var coord in coords)
            {
                if (coord.Row < minRow)
                {
                    minRow = coord.Row;
                }
                if (coord.Row > maxRow)
                {
                    maxRow = coord.Row;
                }
                if (coord.Col < minCol)
                {
                    minCol = coord.Col;
                }
                if (coord.Col > maxCol)
                {
                    maxCol = coord.Col;
                }
            }

            // Instead of being clever, let's just grow rows and cols by the largest difference.
            var maxDiff = Math.Max(maxRow - minRow, maxCol - minCol);

            // What do we have to add to the actual row / col to get its array index?
            // Or ... just change the points by these offsets.  Then we won't need clever math.  Let's do that.
            var rowOffset = -1 * (minRow - maxDiff);
            var colOffset = -1 * (minCol - maxDiff);

            var rowRange = (maxRow - minRow) + (2 * maxDiff);
            var colRange = (maxCol - minCol) + (2 * maxDiff);

            int[,] cells = new int[rowRange, colRange];

            // key = coords ('1,2'), value = ID of the closest start.
            var newCoords = new Dictionary <Coords, int>();
            var coordId   = 0;

            foreach (var coord in coords)
            {
                newCoords.Add(new Coords(coord.Row + rowOffset, coord.Col + colOffset), coordId);
                coordId++;
            }

            // Figure out the closest start to each 0-cell.
            for (var row = 0; row < rowRange; row++)
            {
                for (var col = 0; col < colRange; col++)
                {
                    var tiedForBest = false;
                    var bestDist    = 999999;
                    var bestCoord   = new Coords();
                    foreach (var coord in newCoords.Keys)
                    {
                        var dist = Math.Abs(coord.Row - row) + Math.Abs(coord.Col - col);
                        if (dist < bestDist)
                        {
                            bestDist    = dist;
                            bestCoord   = coord;
                            tiedForBest = false;
                        }
                        else if (dist == bestDist)
                        {
                            tiedForBest = true;
                        }
                    }

                    cells[row, col] = (tiedForBest ? -1 : newCoords[bestCoord]);
                }
            }

            // Now we figure out what's NOT on the outside.
            // Key: cell ID.  value: count.  (use '0' if it's on the outside.)
            var cellCounts = new Dictionary <int, int>();

            foreach (var x in newCoords.Values)
            {
                cellCounts.Add(x, 0);
            }

            for (var row = 0; row < rowRange; row++)
            {
                for (var col = 0; col < colRange; col++)
                {
                    if (cells[row, col] != -1)
                    {
                        cellCounts[cells[row, col]]++;
                    }
                }
            }

            // Now zero out the borders.
            for (var row = 0; row < rowRange; row++)
            {
                if (cells[row, 0] != -1)
                {
                    cellCounts[cells[row, 0]] = 0;
                }

                if (cells[row, colRange - 1] != -1)
                {
                    cellCounts[cells[row, colRange - 1]] = 0;
                }
            }

            for (var col = 0; col < colRange; col++)
            {
                if (cells[0, col] != -1)
                {
                    cellCounts[cells[0, col]] = 0;
                }

                if (cells[rowRange - 1, col] != -1)
                {
                    cellCounts[cells[rowRange - 1, col]] = 0;
                }
            }

            return(cellCounts.Max(x => x.Value));
        }
示例#2
0
 private void SetSpot(Coords coord, Spot spot)
 {
     SetSpot(coord.Row, coord.Col, spot);
 }
示例#3
0
 private Spot GetSpot(Coords coord)
 {
     return(GetSpot(coord.Row, coord.Col));
 }
示例#4
0
 public Spot GetSpot(Coords coords)
 {
     return(GetSpot(coords.Row, coords.Col));
 }
示例#5
0
            public void MoveTowardsEnemy(Coords currLoc)
            {
                // Figure out what's on this square.
                var currUnit = this.GetSpot(currLoc.Row, currLoc.Col);

                // What are we looking for?
                var targetUnitTypes = (currUnit == Spot.Elf
                    ? new List <Spot> {
                    Spot.Goblin, Spot.GoblinResting
                }
                    : new List <Spot> {
                    Spot.Elf, Spot.ElfResting
                });

                // Do it the long way for now.
                // Get a list of all units of that type.  (Don't forget sleeping units.)
                var foundUnitCoords = new List <Coords>();

                for (int row = 0; row < spots.Count; row++)
                {
                    for (int col = 0; col < spots[row].Count; col++)
                    {
                        var spot = GetSpot(row, col);
                        if (targetUnitTypes.Contains(spot))
                        {
                            foundUnitCoords.Add(new Coords(row, col));
                        }
                    }
                }

                // Jump out if we didn't find any enemies.
                if (foundUnitCoords.Count == 0)
                {
                    return;
                }

                // Now get all empty adjacent spots.
                var adjacentSpots = new List <Coords>();

                foreach (var coord in foundUnitCoords)
                {
                    if (GetSpot(coord.Up()) == Spot.Space)
                    {
                        adjacentSpots.Add(coord.Up());
                    }
                    if (GetSpot(coord.Left()) == Spot.Space)
                    {
                        adjacentSpots.Add(coord.Left());
                    }
                    if (GetSpot(coord.Right()) == Spot.Space)
                    {
                        adjacentSpots.Add(coord.Right());
                    }
                    if (GetSpot(coord.Down()) == Spot.Space)
                    {
                        adjacentSpots.Add(coord.Down());
                    }
                }

                // Get the closest spots in the 'adjacentSpots' list.
                List <Coords> alreadyReached       = new List <Coords>();
                List <Coords> outerBounds          = new List <Coords>();
                List <Coords> newOuterBounds       = new List <Coords>();
                List <Coords> closestAdjacentSpots = new List <Coords>();

                outerBounds.Add(currLoc);
                var done = false;

                while (outerBounds.Count > 0 && !done)
                {
                    // Dont come back to these spots.
                    foreach (var coord in outerBounds)
                    {
                        alreadyReached.Add(coord);
                    }

                    newOuterBounds = new List <Coords>();
                    // Take a step in each direction.
                    foreach (var coord in outerBounds)
                    {
                        if (!alreadyReached.Contains(coord.Up()) && !newOuterBounds.Contains(coord.Up()))
                        {
                            if (GetSpot(coord.Up()) == Spot.Space)
                            {
                                newOuterBounds.Add(coord.Up());
                            }
                            else if (adjacentSpots.Contains(coord.Up()))
                            {
                                closestAdjacentSpots.Add(coord.Up());
                            }
                        }
                        if (!alreadyReached.Contains(coord.Left()) && !newOuterBounds.Contains(coord.Left()) && GetSpot(coord.Left()) == Spot.Space)
                        {
                            newOuterBounds.Add(coord.Left());
                        }
                        if (!alreadyReached.Contains(coord.Right()) && !newOuterBounds.Contains(coord.Right()) && GetSpot(coord.Right()) == Spot.Space)
                        {
                            newOuterBounds.Add(coord.Right());
                        }
                        if (!alreadyReached.Contains(coord.Down()) && !newOuterBounds.Contains(coord.Down()) && GetSpot(coord.Down()) == Spot.Space)
                        {
                            newOuterBounds.Add(coord.Down());
                        }
                    }
                }
            }
示例#6
0
 private Spot GetSpot(Coords coords)
 {
     return(this.spotGrid[coords.Row, coords.Col]);
 }