#c#
#c#
Вопрос:
foreach (Point p in Snake.Body)
if (p.X == Food.Point.X amp;amp; p.Y == Food.Point.Y)
{
Points ;
Food = new FoodSpawn();
Snake.Grow(Points 4);
}
Ошибка при его использовании= «Коллекция была изменена; операция перечисления может не выполняться»
Комментарии:
1. Вы ожидали, что будет больше одной точки, чтобы соответствовать координатам для еды?
2. Нет, мне нужна только одна точка. Проблема в том, что когда я преобразую его в цикл for, p.X и p.Y становятся необъявленными
3. Змея. Body — это экземпляр объекта из другого класса
Ответ №1:
Я предполагаю, что вы хотите найти Змею.Тело сбора Очков содержит Еду.Укажите, измените свои свойства, а затем остановите цикл. (В противном случае у вас могут возникнуть серьезные проблемы с правильным обходом вашей коллекции и увеличением ее размера)
Итак, предположим, что Тело представляет собой массив точек
for(int x = 0; x < Snake.Body.Length; x )
{
Point p = Snake.Body[x];
if (p.X == Food.Point.X amp;amp; p.Y == Food.Point.Y)
{
Points ;
Food = new FoodSpawn();
Snake.Grow(Points 4);
break;
}
}
Если Змея.Тело — это List<Point>
тогда нам нужно изменить цикл for на
for(int x = 0; x < Snake.Body.Count(); x )
Или с помощью LINQ
int cnt = Snake.Body.Count(x => x.X == Food.Point.X amp;amp; p.Y == Food.Point.Y);
if(cnt != 0)
{
Points ;
Food = new FoodSpawn();
Snake.Grow(Points 4);
}
Комментарии:
1. Почему вы используете
Count
метод Linq вместоAny
? (Не то чтобы это действительно имело значение здесь для игры со змеями, хотя …) Или вы намеревались использовать цикл for сcnt
или иным образом использоватьcnt
для вычисления роста змеи?2. Вы правы.
Any
было бы лучше, потому что это остановило бы поиск передCount
Ответ №2:
Самым простым способом было бы
foreach (Point p in Snake.Body.ToArray())
Ответ №3:
Проблема в вашем случае заключается в том, что вы пытаетесь работать с общим количеством точек в теле змеи,
foreach (Point p in Snake.Body)
но в конце этого цикла (или в середине) точки меняются. Они увеличиваются или уменьшаются. Как только они это делают, они вызывают эту ошибку в перечислении. В вашем коде этот пункт
Points ;
Это увеличивает количество баллов и, таким образом, вызывает ошибку. И после этой строки кода,
Snake.Grow(Points 4);
Это заставляет Snake
объект расти до заданных значений. Это то самое место, где ошибка. На самом деле это не ошибка, но вместо этого это место, которое при вызове ошибки запускается в следующем цикле.
Итак, что вы можете сделать, так это создать простую int
переменную to и затем работать с ней.
Комментарии:
1. Я предполагаю,
Snake.Grow
добавляет один в коллекцию, которую он перечисляет.2. @TimSchmelter, точно. Я думаю, у него есть метод Grow как
void Grow (Snake snake) { snake.Points }
увеличение роста, спасибо и за совет. 🙂
Ответ №4:
Во-первых, как уже упоминалось, вы пытаетесь изменить свою коллекцию (заставляя свою змею расти) во время перечисления, что недопустимо, потому что это оставляет перечислитель не знающим, с чего продолжить, или (что еще хуже) пропускающим что-то, что было бы добавлено ранее на итерации.
Лучшим способом подхода к этому конкретному случаю может быть выполнение проверки, а затем выполнение вашей логики роста после этой проверки или выполнение логики, основанной на .Любая функция Linq
if(Snake.Body.Any(p => p.X == Food.Point.X amp;amp; p.Y == Food.Point.Y))
{
Points ;
Food = new FoodSpawn();
Snake.Grow(Points 4);
}
или, если вы хотите, чтобы подача происходила несколько раз в одном цикле (доступно несколько продуктов), используйте .Где функция
foreach(var p in Snake.Body
.Where(p => p.X == Food.Point.X amp;amp; p.Y == Food.Point.Y)
.ToArray()) // This caches the result and avoids those pesky errors
{ ... }
Это предотвратит модификацию до перечисления