Выбор шестиугольников вокруг радиуса
У меня есть карта из шестиугольников. При нажатии на шестиугольник, в котором находится отряд, другие шестиугольники вокруг выбранного должны быть выделены на основе переменной диапазона отряда.
Я попробовал довольно много методов самостоятельно, но потерпел неудачу. Я не могу получить список с выделенными правильными. В этом примере я буду использовать отряд из 2 плиток.
Метод, который я попытался реализовать, состоит в следующем: есть 3 списка.
- Открытый список содержит узлы, которые должны быть расширены на 1
- Закрытый список содержит узлы, которые будут выделены
- список удаления содержит узлы, которые уже были расширены
Я следовал следующему алгоритму:
Добавьте начальный узел во все списки.
Разверните узлы в открытом списке на 1 плитку.
Удалите узлы в открытом списке, используя список удаления.
добавить узлы открытого списка в закрытый список.
очистить список удаления.
скопировать содержимое открытого списка, чтобы удалить список.
Повторите для любого диапазона войск.
Моя цель состоит в том, чтобы выделить шестигранные плитки радиуса r вокруг плитки, на которую нажали; r = диапазон войск.
Я совершенно потерян, и я, вероятно, делал некоторые очевидные ошибки. Любая помощь будет оценена!
(Ниже код, который я сделал)
private List<string> expand(List<string> open, bool odd)
{
List<string> newopen = new List<string>();
int oddEven = 1;
if (odd == false)
{
oddEven = -1;
}
foreach (string s in open)
{
string[] rc = s.Split('.'); //row + col of the current hex
int Row = int.Parse(rc[0]);
int Col = int.Parse(rc[1]);
for (int r = 1; r >= -1; r--)
{
for (int c = -1; c <= 1; c++)
{
if (!((r == oddEven && c != 0) || (r== 0 && c == 0)))
{
if (((Row + r) > -1 && (Col + c) > -1) && ((Row + r) < 9 && (Col + c) < 18)) //mapcheck
{
if (Hexmap[Row + r, Col + c] == '-') //mapcheck
{
newopen.Add((Row + r).ToString() + "." + (Col + c).ToString());
}
}
}
}
}
}
return newopen;
}
private void Remove(ref List<string> rem, ref List<string> open)
{
foreach (string s in rem)
{
open.Remove(s);
}
}
private void Add(ref List<string> closed, ref List<string> open)
{
foreach (string s in open)
{
closed.Add(s);
}
}
private void TroopSelect(int row, int col, int range)
{
bool odd = true;
if ((row % 2) == 0)
{
odd = false;
}
List<string> open = new List<string>();
List<string> close = new List<string>();
List<string> remove = new List<string>();
open.Add(row.ToString() + "." + col.ToString());
close.Add(row.ToString() + "." + col.ToString());
remove.Add(row.ToString() + "." + col.ToString());
for (int i = 0; i < range; i++)
{
open = expand(open, odd); //row and col of the current point being checked --- REMOVE ROW COL, find it out from the list within the function
Remove(ref remove, ref open); //remove from open the remove hex values
Add(ref close, ref open); //add to closed what's in open
remove.Clear(); //clear remove
remove = open; //set remove the same as open
}
foreach (string s in close)
{
string[] rc = s.Split('.'); //row + col of the current hex
int Row = int.Parse(rc[0]);
int Col = int.Parse(rc[1]);
Hexagons.Add(new PointF(Row, Col));
}
}
private void CheckTroop(int row, int col)
{
if (Hexmap[row, col] == 'o') //it's a friendly troop
{
foreach (Troops t in playertroops)
{
if (t.row == row && t.column == col)
{
TroopSelect(row, col, t.range);
this.battlegrid.Invalidate();
}
}
}
}
private void battlegrid_MouseClick(object sender, MouseEventArgs e)
{
int row, col;
PointToHex(e.X, e.Y, HexHeight, out row, out col); //gets the hex in the x/y position
CheckTroop(row, col);
//this.Invalidate();
}
Ниже также два изображения: (Игнорируйте камень на заднем плане!)
Первый из диапазона войск = 1, работает нормально
Второе изображение диапазона войск = 2, не работает нормально
Еще раз спасибо за любую помощь.