简体   繁体   中英

How to generate random fruit for C++ 2D Snake game

I am having trouble generating random fruit for my Snake game. (I am very new to programming and this is my first language).

When I run my code all works fine so far (except from some minor issues). I'm using Visual Studio C++ in an empty project. Here is my full code (I'm not displaying my #includes ):

using namespace std;
bool gameOver = false;
int gameScore;
int fruitX;
int fruitY;

string bGameW = "###########";
string bGameL = "#         #\n";

class gameStart
{
public:
void start() 
{   

    cout << bGameW;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameL;
    cout << bGameW; 

}

void generateFruit() 
{
    srand(time(NULL));
    fruitX = rand() % 21;
    fruitY = rand() % 21;

    bGameW.insert(fruitX, "F");
    bGameL.insert(fruitY, "F");

}

void clearscreen() 
{
    system("cls");
}
private:
};


 int main () 
 {  
 gameStart gameObj;

 gameObj.generateFruit();
 gameObj.clearscreen();
 gameObj.start();

 return 0;
 }

To generate the random the random fruit for the string. I use a string to make the game board, then I create random values for the fruit (X and Y) then I append them into my game board.

But the issue is: I want to make only one fruit with a random X and Y and append it into my game board to display it. But my current code is this:

bGameW.insert(fruitX, "F");
bGameL.insert(fruitY, "F");

This code makes 2 fruits with 1 at a random X and 1 at a random Y. I want to turn these 2 fruits into 1 fruit, with 1 random X and 1 random Y.

There's a whole host of things worth commenting on. Here goes:

  1. bGameW has no \n
  2. bGameW and bGameL are 10 and 11 characters long (both with be 11 after you add the other \n ). Your RNG is generating numbers between 0 and 20... if you ever generate a number > 11 (and you will), Bad Things will happen (and probably have).
  3. Snake games like this let you eat multiple fruit, which is why people brought up the whole "don't call srand more than once" thing, as you'll be calling generate fruit every time someone eats the old one. OTOH, that mostly removes the "calling srand multiple times per second can return the same value" problem too.
  4. Rather than writing out those two lines, bGameW and bGameL, I recommend that you build a character array that holds your entire game display (NOT your game state, just the display of that state). You then clear it and redraw it every move. You'll need a game area, walls, something that tracks where your snake is, and the current fruit. You then 'render' all these things into your character-array-game-display. Don't forget to clear it every time you redraw it or you'll get all kinds of problems.
  5. Rather than redrawing everything, you could use something like the "curses" library to clear and redraw specific character locations on the screen. You'd then face problems 'clearing' and redrawing different spots.

As far as programming style goes, you will find that so called "magic numbers" (like 21 in your case) can lead to bugs. What people generally do instead is to define a const with the appropriate value, and then define things in terms of that const.

// constants are often named in ALL_UPPER_CASE_WITH_UNDERSCORES
// to help you recognize them.
const int PLAY_AREA_HEIGHT = 10;
const int PLAY_AREA_WIDTH = 10;
const char EMPTY_PLAY_SQUARE = '.';
// have you learned about 2d arrays yet?  Arrays at all?  
char playAreaDisplay[PLAY_AREA_HEIGHT][PLAY_AREA_WIDTH];

void wipePlayArea()
{
  for (int heightIdx = 0; heightIdx < PLAY_AREA_HEIGHT; ++heightIdx)
  {
    for (int widthIdx = 0; widthIdx < PLAY_AREA_WIDTH; ++widthIdx)
    {
      playAreaDisplay[heightIdx][widthIdx] = EMPTY_PLAY_SQUARE;
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM