#c# #.net #for-loop #recursion
Вопрос:
У меня есть повторение в цикле — когда isAllowed
= true — затем продолжайте следующую итерацию, но когда isAllowed
значение false — тогда программа должна повторить генерацию случайных позиций, координат и проверить, верно ли значение isAllowed
до.
Как сделать рекурсию в этом цикле для достижения этой цели?
foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
var randomPositionX = new Random().Next(0, 9);
var randomPositionY = new Random().Next(0, 9);
var cords = int.Parse(randomPositionX.ToString() randomPositionY);
map.Location[cords].ActualFleetPosition = fleet.Key[i];
var isAllowed = IsPositionAllowed(map, cords);
if (isAllowed)
{
break;
}
else
{
randomPositionX = new Random().Next(0, 9);
randomPositionY = new Random().Next(0, 9);
cords = int.Parse(randomPositionX.ToString() randomPositionY);
map.Location[cords].ActualFleetPosition = fleet.Key[i];
isAllowed = IsPositionAllowed(map, cords);
if (isAllowed)
{
break;
}
else
{
//recursion
}
}
i ;
}
Комментарии:
1.
var randomPositionX = new Random().Next(0, 9); var randomPositionY = new Random().Next(0, 9);
не делайте этого, объявите случайные значения за пределами области, в которой они у вас есть, как статические (уровень класса), а затем используйте их в своем вызывающем коде.2. Я предлагаю вам использовать simple для и перемещать/увеличивать итератор/индексатор, когда вы хотите выполнить следующую итерацию, если она автоматически не повторяет цикл.
3. Вы не должны создавать новые
Random
экземпляры в цикле — вам также не нужны отдельные экземпляры для генерации 2 значений.
Ответ №1:
Может быть, вы хотите чего-то подобного:
var random = new Random();
foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
int coords;
do {
int randomPositionX = random.Next(0, 9);
int randomPositionY = random.Next(0, 9);
coords = 10 * randomPositionX randomPositionY;
} while (!IsPositionAllowed(map, coords));
map.Location[coords].ActualFleetPosition = fleet.Key[i ];
}
Т. е. вам нужна не рекурсия (т. Е. метод, который вызывает сам себя), а другой цикл, вложенный в первый.
Обратите внимание, что максимальное значение random.Next
является исключительным. Итак, если вам нужны числа до 9
, вы должны использовать верхнее значение 10
. Кроме того, если значение меньше 0
, вы можете просто написать random.Next(10)
.
Важно создать Random
объект только один раз, потому что в противном случае у вас могут возникнуть разные случайные объекты, генерирующие одну и ту же псевдослучайную последовательность. Использование статического поля в вашем классе даже лучше, чем использование локальной переменной
private static readonly _random = new Random();
Комментарии:
1. да — точно — это решает проблему — некоторое улучшение синтаксиса, и это будет работать
2. Но почему здесь операция = 10 * randompositionX randomPositionY? Намерение здесь — объединить как строку
3. пример, если a = 5 и b = 7 — тогда шнуров должно быть 57, но это вообще не имеет значения — координаты должны быть от 0 до 99
4. Что ж, 10 * 5 7 = 57. Не так ли? Если у вас есть координаты до 99, то используйте 100 * x y (= 507). Однако вместо этого вы можете использовать 2-мерный массив:
T[,] a = new T[With, Height];
и получить к нему доступa[x, y]
. так было бы проще.
Ответ №2:
Я думаю, это должно сработать (отредактировано с некоторыми вашими комментариями, я не хотел касаться других вещей, а не вопроса).:
var random = new Random();
foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
do
{
var randomPositionX = random.Next(0, 9);
var randomPositionY = random.Next(0, 9);
//Im not sure how you're managing this 'coords' map, but gonna just go to the point
var cords = int.Parse(randomPositionX.ToString() randomPositionY);
map.Location[cords].ActualFleetPosition = fleet.Key[i];
} while (!IsPositionAllowed(map, cords));
i ;
}
Если вы хотите, чтобы переменная ‘cords’ была доступна за пределами цикла do…while, вы можете смело объявить ее вне цикла (еще лучше, за пределами foreach).
Комментарии:
1. Вы уверены? — переменная cords находится внутри области видимости, поэтому она не определена вне {} в do while
2. ваше решение сработало как базовое — спасибо! — необходимо определить шнуры на один уровень выше.