循环检查苹果的位置与蛇的身体位置
Loop to check apple position against snake body positions
我正试图弄清楚如何编写一个循环来检查圆形相对于可变数量的矩形的位置,这样苹果就不会放在蛇的顶部,但我有一点麻烦思考它。我试着:
do
apple.setPosition(randX()*20+10, randY()*20+10); // apple is a CircleShape
while (apple.getPosition() == snakeBody[i].getPosition());
虽然,在这种情况下,如果它检测到与蛇身体的一个矩形的碰撞,它最终可能只是把苹果放在身体的前一个位置。我如何让它同时检查所有的位置,这样它就不会自我修正只是为了有机会再次重复同样的问题?
有三种方法(我能想到的)生成满足需求的随机数:
-
第一种方法,也是最简单的方法,就是你想要做的:如果没有重试。
但是,您应该更改条件,以便它立即检查所有禁止的单元格:bool collides_with_snake(const sf::Vector2f& pos, //not sure if it's 2i or 2f const /*type of snakeBody*/& snakeBody, std::size_t partsNumber) { bool noCollision = true; for( std::size_t i = 0 ; i < partsNumber && noCollision ; ++i ) noCollision = pos != snakeBody[i].getPosition() return !noCollision; } //... do apple.setPosition(randX()*20+10, randY()*20+10); while (collides_with_snake(apple.getCollision(), snakeBody, /* snakeBody.size() ? */));
-
第二种方法是尝试生成更少的数字,并找到一个函数将这些数字映射到您想要的集合。例如,如果你的网格有
N
单元格,你可以在0
和N - [number of parts of your Snake]
之间生成一个数字,然后将这个数字X
映射到最小的数字Y
,这样这个整数就不是指蛇部分和X = Y + S
所占的单元格,其中S
是指蛇部分所占的单元格数,这个数字小于Y
。 -
第三种方法是"欺骗",选择一个更强的要求,更容易执行。例如,如果你知道细胞体是
N
个细胞长,那么只在距离蛇头N + 1
个细胞的细胞上生成苹果(你可以通过生成角度来实现)。
这个问题非常广泛,但假设snakeBody
是Rectangles
的向量(或从矩形派生),并且您有checkoverlap()
函数:
do {
// assuming that randX() and randY() allways return different random variables
apple.setPosition(randX()*20+10, randY()*20+10); // set the apple
} while (any_of(snakeBody.begin(), snakeBody.end(), [&](Rectangle &r)->bool { return checkoverlap(r,apple); } );
这依赖于标准算法 any_of()
来检查一个简单的表达式,如果任何蛇体元素与苹果重叠。如果有重叠,我们就再迭代一次,得到一个新的随机位置,直到合适为止。
如果snakebody是一个数组而不是标准容器,在上面的代码中使用snakeBody, snakeBody+snakesize
而不是snakeBody.begin(), snakeBody.end()
。
如果重叠检查与比较位置一样简单,则可以将上面代码中的return checkoverlap(r,apple);
替换为return r.getPosition()==apple.getPosition();
"天真"的方法是生成苹果,并对整个蛇测试它们的位置,直到我们找到一个空闲点:
bool applePlaced = false;
while(!applePlaced) { //As long as we haven't found a valid place for the apple
apple.setPosition(randX()*20+10, randY()*20+10);
applePlaced = true; //We assume, that we can place the apple
for(int i=0; i<snakeBody.length; i++) { //Check the apple position with all snake body parts
if(apple.getPosition() == snakeBody[i].getPosition()) {
applePlaced=false; //Our prediction was wrong, we could not place the apple
break; //No further testing necessary
}
}
}
更好的方法是将所有空闲位置存储在数组中,然后从该数组中选择一个位置(并从数组中删除它),因此不需要随机测试。如果蛇移动,还需要更新数组
- 编译时检查以确保结构中的任何位置都没有填充
- 在 c++ 中检查 if 条件中的向量位置范围
- 检查向量是否在某个位置未初始化
- 如何检查指针是否指向正确对齐的内存位置
- 如何检查鼠标单击位置是必需的应用程序
- 迭代矢量如何检查我的位置
- 如何检查以前是否C++找到过最大值位置
- C++健全性检查失败:几个变量/内存位置被更改为垃圾,即使我从未访问过它们
- 检查阵列位置在C++中是否为空的 CPU 高效方法
- qt检查文件中是否存在文件,如果它没有提示用户输入其位置,则将文件复制到程序工作目录
- 如何检查应用程序在OS X下的位置
- Win32 C++-检查窗口位置X/PositionY和宽度/高度是否已更改
- libvlc 检查媒体位置是否有效
- 使用 clang llvm 检查变量在任意源位置的作用域是否具有范围
- LPCSTR-如何检查第一个位置是否为空格" "
- 检查阵列位置是否为空/空
- 检查数组的X位置是否为char
- 如何使用GetPixel()来检查不同的位置
- 在PDCurses/NCurses中检查当前/给定位置的字符
- 检查阵列位置