循环检查苹果位置对抗蛇体位置

时间:2015-08-02 20:08:43

标签: c++ position sfml

我试图弄清楚如何编写一个循环来检查圆圈相对于可变数量的矩形的位置,这样苹果就不会放在蛇的顶部,但是我有思考它有点麻烦。我试过了:

do 
   apple.setPosition(randX()*20+10, randY()*20+10); // apple is a CircleShape
while (apple.getPosition() == snakeBody[i].getPosition());

虽然在这种情况下,如果它检测到与蛇体的一个矩形的碰撞,它可能最终只是将苹果放在身体的先前位置。如何让它同时检查所有位置,这样它才能纠正自己只是为了有机会再次重复同样的问题?

3 个答案:

答案 0 :(得分:1)

生成符合要求的随机数有三种方法(我能想到):

  • 第一种方式,也就是更简单,就是您要尝试做的事情:如果不这样做,请重试。
    但是,您应该更改条件,以便一次检查所有禁用的单元格:

    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个单元格,则可以生成0N - [number of parts of your Snake]之间的数字,然后将此数字X映射到最小数字Y这个整数并不是指蛇形部分所占据的单元格而X = Y + S其中S是由蛇形部分占据的单元格数量,由小于Y的数字引用。
    但它更复杂。

  • 第三种方式是&#34;作弊&#34; 并选择更强大的要求,这更容易执行。例如,如果您知道细胞体长度为N个细胞,那么只会在距离蛇头N + 1个细胞的细胞上产生苹果(您可以通过生成角度来实现)

答案 1 :(得分:1)

问题非常广泛,但假设snakeBodyRectangles的向量(或从Rectanges派生),并且您有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();

答案 2 :(得分:0)

“幼稚”的方法是生成苹果并测试他们对整条蛇的位置,直到找到一个免费点:

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
        }
    }
}

更好的方法是将所有自由位置存储在一个数组中,然后从该数组中选择一个位置(并从数组中删除它),这样就不需要进行随机测试。如果蛇移动,它还需要更新数组。