Snake 程序无一例外地停止 运行
Snake Program stops running without exception
我正在尝试在控制台中对 snake 进行编程。在蛇采取随机步数后,会生成一个新的游戏对象(例如,使蛇生长的苹果或使蛇更快的蘑菇)。
我创建了一个随机游戏对象(在随机(左、上)坐标上,然后我需要检查该游戏对象是在 snakeBodyPart 顶部还是在另一个游戏对象顶部生成。如果是这样,我创建一个新的游戏对象,然后再试一次。只有当它不与另一个游戏对象或蛇发生碰撞时,它才会生成。
snakeElemnts = 一个列表,里面有所有的蛇- body-parts;
gameObjects = 包含所有现有游戏对象的列表;
如果 noCollisionAmount == snakeElements 和 GameObjects 的数量,则应该没有碰撞并且应该产生新的 GameObject。
不幸的是,在某一时刻(早期),蛇只是停止移动,什么也没有发生(没有例外或任何事情)。
我无法调试,因为我有一个 KeyboardWatcher 运行,它会检查是否按下了某个键。因此,当我按下 break 时,我只能检查 keyboardwatcher。
设置断点没有什么用,因为我遇到问题从来不断
if (this.randomStepNumber == 0)
{
int noCollision = 0; // this variable counts the amount of times there was no collision
GameObject validGameObject;
while (true)
{
validGameObject = this.snakeGameObjectFactory.Generate();
foreach (SnakeElements element in snakeElements)
{
if (validGameObject.XPosition != element.XPosition || validGameObject.YPosition != element.YPosition)
{
noCollision++;
}
else
{
break;
}
}
foreach (GameObject gameObject in gameObjects)
{
if (noCollision == snakeElements.Count) // if there was no collision of the new gameobject with an element of the snake, the gameobjects will get checked
{
if (validGameObject.XPosition != gameObject.XPosition || validGameObject.YPosition != gameObject.YPosition)
{
noCollision++;
}
else
{
break;
}
}
else
{
break;
}
}
if (noCollision == snakeElements.Count + gameObjects.Count) // if there was no collision at all, the check is ended
{
break;
}
else
{
noCollision = 0;
}
}
this.gameObjects.Add(validGameObject);
this.randomStepNumber = this.random.Next(10, 30);
}
我想你可能不明白"continue"是如何工作的。
if (noCollision > snakeElements.Count + gameObjects.Count)
{
continue;
}
你在 while 循环的开头有它。如果它被发现是真的,你将陷入无限循环。
其次,你有一个 While(true) 在那里永远不会让你保存有效的结果,因为它在循环之外。您应该将 while 替换为 do while 并在其末尾检查有效结果,然后在发生冲突时循环。
根据您关于删除此代码块导致问题停止的评论,我认为稍微清理一下代码并使用 continue 语句删除潜在的无限循环可能会很好。利用一点 LINQ Enumerable.Any 和一个 do-while 循环,我们可以简化上面代码的逻辑。确实不需要计算碰撞,因为代码的目的是创建一个新对象 iff 检测到碰撞。这意味着如果我们检测到与蛇的碰撞,那么我们想要生成一个新对象,或者如果我们检测到与另一个现有对象的碰撞,那么我们想要生成一个新对象。因此,我们不计算,而是使用 Any
语句来检查是否与蛇或现有对象发生任何碰撞。如果有,则生成一个新对象。如果不是,则使用该对象并继续。注意:为了使用 Enumerable.Any
,您需要为命名空间 System.Linq
.
添加 using
语句
if (randomStepNumber == 0)
{
GameObject validGameObject;
do
{
validGameObject = snakeGameObjectFactory.Generate();
}
while(snakeElements.Any(s => validGameObject.XPosition == s.XPosition && validGameObject.YPosition == s.YPosition) ||
gameObjects.Any(o => validGameObject.XPosition == o.XPosition && validGameObject.YPosition == o.YPosition));
gameObjects.Add(validGameObject);
randomStepNumber = random.Next(10, 30);
}
作为旁注。我删除了 this
关键字,因为看起来您并没有在代码中的所有情况下都使用它,如果您不必使用它,它会使代码更具可读性,因为它不那么冗长。如果由于变量冲突需要将其添加回去,那么我建议将变量重命名为具有相同名称的成员变量和局部变量,这在尝试调试某些内容时也会造成混淆。
补充说明 - 这是不使用 LINQ 的代码版本,以防您的家庭作业不允许这样做。
if (randomStepNumber == 0)
{
GameObject validGameObject = null;
while(validGameObject == null)
{
validGameObject = snakeGameObjectFactory.Generate();
foreach(var snake in snakeElements)
{
if (validGameObject.XPosition == snake.XPosition &&
validGameObject.YPosition == snake.YPosition)
{
validGameObject = null;
break;
}
}
if (validGameObject != null)
{
foreach(var gameObject in gameObjects)
{
if (validGameObject.XPosition == gameObject.XPosition &&
validGameObject.YPosition == gameObject.YPosition)
{
validGameObject = null;
break;
}
}
}
}
gameObjects.Add(validGameObject);
randomStepNumber = random.Next(10, 30);
}
我正在尝试在控制台中对 snake 进行编程。在蛇采取随机步数后,会生成一个新的游戏对象(例如,使蛇生长的苹果或使蛇更快的蘑菇)。
我创建了一个随机游戏对象(在随机(左、上)坐标上,然后我需要检查该游戏对象是在 snakeBodyPart 顶部还是在另一个游戏对象顶部生成。如果是这样,我创建一个新的游戏对象,然后再试一次。只有当它不与另一个游戏对象或蛇发生碰撞时,它才会生成。
snakeElemnts = 一个列表,里面有所有的蛇- body-parts; gameObjects = 包含所有现有游戏对象的列表;
如果 noCollisionAmount == snakeElements 和 GameObjects 的数量,则应该没有碰撞并且应该产生新的 GameObject。
不幸的是,在某一时刻(早期),蛇只是停止移动,什么也没有发生(没有例外或任何事情)。
我无法调试,因为我有一个 KeyboardWatcher 运行,它会检查是否按下了某个键。因此,当我按下 break 时,我只能检查 keyboardwatcher。
设置断点没有什么用,因为我遇到问题从来不断
if (this.randomStepNumber == 0)
{
int noCollision = 0; // this variable counts the amount of times there was no collision
GameObject validGameObject;
while (true)
{
validGameObject = this.snakeGameObjectFactory.Generate();
foreach (SnakeElements element in snakeElements)
{
if (validGameObject.XPosition != element.XPosition || validGameObject.YPosition != element.YPosition)
{
noCollision++;
}
else
{
break;
}
}
foreach (GameObject gameObject in gameObjects)
{
if (noCollision == snakeElements.Count) // if there was no collision of the new gameobject with an element of the snake, the gameobjects will get checked
{
if (validGameObject.XPosition != gameObject.XPosition || validGameObject.YPosition != gameObject.YPosition)
{
noCollision++;
}
else
{
break;
}
}
else
{
break;
}
}
if (noCollision == snakeElements.Count + gameObjects.Count) // if there was no collision at all, the check is ended
{
break;
}
else
{
noCollision = 0;
}
}
this.gameObjects.Add(validGameObject);
this.randomStepNumber = this.random.Next(10, 30);
}
我想你可能不明白"continue"是如何工作的。
if (noCollision > snakeElements.Count + gameObjects.Count)
{
continue;
}
你在 while 循环的开头有它。如果它被发现是真的,你将陷入无限循环。
其次,你有一个 While(true) 在那里永远不会让你保存有效的结果,因为它在循环之外。您应该将 while 替换为 do while 并在其末尾检查有效结果,然后在发生冲突时循环。
根据您关于删除此代码块导致问题停止的评论,我认为稍微清理一下代码并使用 continue 语句删除潜在的无限循环可能会很好。利用一点 LINQ Enumerable.Any 和一个 do-while 循环,我们可以简化上面代码的逻辑。确实不需要计算碰撞,因为代码的目的是创建一个新对象 iff 检测到碰撞。这意味着如果我们检测到与蛇的碰撞,那么我们想要生成一个新对象,或者如果我们检测到与另一个现有对象的碰撞,那么我们想要生成一个新对象。因此,我们不计算,而是使用 Any
语句来检查是否与蛇或现有对象发生任何碰撞。如果有,则生成一个新对象。如果不是,则使用该对象并继续。注意:为了使用 Enumerable.Any
,您需要为命名空间 System.Linq
.
using
语句
if (randomStepNumber == 0)
{
GameObject validGameObject;
do
{
validGameObject = snakeGameObjectFactory.Generate();
}
while(snakeElements.Any(s => validGameObject.XPosition == s.XPosition && validGameObject.YPosition == s.YPosition) ||
gameObjects.Any(o => validGameObject.XPosition == o.XPosition && validGameObject.YPosition == o.YPosition));
gameObjects.Add(validGameObject);
randomStepNumber = random.Next(10, 30);
}
作为旁注。我删除了 this
关键字,因为看起来您并没有在代码中的所有情况下都使用它,如果您不必使用它,它会使代码更具可读性,因为它不那么冗长。如果由于变量冲突需要将其添加回去,那么我建议将变量重命名为具有相同名称的成员变量和局部变量,这在尝试调试某些内容时也会造成混淆。
补充说明 - 这是不使用 LINQ 的代码版本,以防您的家庭作业不允许这样做。
if (randomStepNumber == 0)
{
GameObject validGameObject = null;
while(validGameObject == null)
{
validGameObject = snakeGameObjectFactory.Generate();
foreach(var snake in snakeElements)
{
if (validGameObject.XPosition == snake.XPosition &&
validGameObject.YPosition == snake.YPosition)
{
validGameObject = null;
break;
}
}
if (validGameObject != null)
{
foreach(var gameObject in gameObjects)
{
if (validGameObject.XPosition == gameObject.XPosition &&
validGameObject.YPosition == gameObject.YPosition)
{
validGameObject = null;
break;
}
}
}
}
gameObjects.Add(validGameObject);
randomStepNumber = random.Next(10, 30);
}