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)); }
private void SetSpot(Coords coord, Spot spot) { SetSpot(coord.Row, coord.Col, spot); }
private Spot GetSpot(Coords coord) { return(GetSpot(coord.Row, coord.Col)); }
public Spot GetSpot(Coords coords) { return(GetSpot(coords.Row, coords.Col)); }
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()); } } } }
private Spot GetSpot(Coords coords) { return(this.spotGrid[coords.Row, coords.Col]); }