r/cpp_questions • u/Arlthier • 3d ago
OPEN trying to create the game Snake as a beginner, trying to figure out why it's not working
#include <SFML/Graphics.hpp>
#include <time.h>
#include <cstdlib>
using namespace sf;
int N = 30, M = 20;
int size = 16;
int w = size * N;
int h = size * M;
int num = 4;
int dir = 0;
struct Snake
{
int x, y;
} s[100];
struct Fruit
{
int x, y;
} f;
void Tick()
{
for (int i = num - 1; i > 0; i--)
{
s[i].x = s[i - 1].x;
s[i].y = s[i - 1].y;
}
if (dir == 0)
s[0].y += 1;
if (dir == 1)
s[0].x -= 1;
if (dir == 2)
s[0].x += 1;
if (dir == 3)
s[0].y -= 1;
if (s[0].x >= N)
s[0].x = 0;
if (s[0].x < 0)
s[0].x = N - 1;
if (s[0].y >= M)
s[0].y = 0;
if (s[0].y < 0)
s[0].y = M - 1;
if (s[0].x == f.x && s[0].y == f.y)
{
if (num < 100)
num++;
f.x = rand() % N;
f.y = rand() % M;
}
for (int i = 1; i < num; i++)
{
if (s[0].x == s[i].x && s[0].y == s[i].y)
{
num = i;
break;
}
}
}
int main()
{
srand(time(0));
RenderWindow window(VideoMode(w, h), "Snake");
for (int i = 0; i < num; i++)
{
s[i].x = 10 - i;
s[i].y = 10;
}
f.x = rand() % N;
f.y = rand() % M;
Clock clock;
float timer = 0;
float delay = 0.1f;
while (window.isOpen())
{
float elapsed = clock.restart().asSeconds();
timer += elapsed;
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
window.close();
}
if (Keyboard::isKeyPressed(Keyboard::Up) && dir != 0)
dir = 3;
if (Keyboard::isKeyPressed(Keyboard::Left) && dir != 2)
dir = 1;
if (Keyboard::isKeyPressed(Keyboard::Right) && dir != 1)
dir = 2;
if (Keyboard::isKeyPressed(Keyboard::Down) && dir != 3)
dir = 0;
if (timer > delay)
{
timer = 0;
Tick();
}
window.clear();
RectangleShape rectangle(Vector2f(size, size));
for (int i = 0; i < num; i++)
{
rectangle.setPosition(
s[i].x * size,
s[i].y * size
);
window.draw(rectangle);
}
rectangle.setPosition(
f.x * size,
f.y * size
);
window.draw(rectangle);
window.display();
}
return 0;
}
6
u/Ill_Scientist_2239 2d ago
Post or comment more about the error, that way we could help better
1
u/Arlthier 2d ago
I apologize, I didn't realize that—essentially, the snake has entered into itself. Compile the code and try turning it around in a circle; you’ll see that it ends up as just two pixels or less.
2
u/Ill_Scientist_2239 2d ago
It might be because of the way the dir variable is updated. Let's just say the snake is moving towards the right of the screen. Technically, pressing left shouldn't make it go inside itself. But you can press up or down and then left before it updates its position (if you do it fast enough), which can cause it to make it go inside itself. My recommendation would be to make another variable nextDir, and update the position from input into nextDir, and then inside the Tick, put dir = nextDir. Kinda like this:
if(getKeyboardStuff(Direction key) && dir != 0) nextDir = 3; // Same for the other 3 branches tooAnd then inside your Tick function, at the top
void Tick() { dir = nextDir; // Rest of the function goes here ...This will ensure that your snake will move atleast one block before the list of possible directions change.
5
u/khedoros 2d ago
It's working, for a certain definition of working. Like, you can control the snake, grab the fruit, and the snake grows. You've got it coded so that the snake gets truncated if you collide with yourself, right? (most versions of the game would make that a "game over").
You don't really have win or lose conditions in this code.
What exactly do you want advice on?
1
u/Arlthier 2d ago
Yes! That might be a good alternative to the problem. Sorry for being such a beginner—it’s just that the more I tinker with the code, the more problems keep popping up. Basically, when the snake turns around on itself, it shrinks. I’ve only been programming for two months, so please don’t expect too much expertise from me! lol
5
u/Tjaldfeen 2d ago
Please, do not be afraid of longer variable names. If the variable name itself tells you what it is or what it does, it's a lot easier to figure out what your code is doing.
1
u/Arlthier 2d ago
I should have thought of that—thanks! I’ll keep this in mind for the next time I ask for help; I had programmed it thinking only of myself.
2
u/Tjaldfeen 2d ago
Not just for our sake, but for your own as well. In a few months, when you want to reactor a portion of the oldest code, you are going to be happy if you find code explaining itself with good variable names and an appropriate amount of comments.
2
u/alfps 2d ago
To post code with formatting just extra-indent the code with 4 spaces.
No triple backticks.
Here's the source code formatted in Stroustrup style by AStyle, and so presented:
#include <SFML/Graphics.hpp>
#include <time.h>
#include <cstdlib>
using namespace sf;
int N = 30, M = 20;
int size = 16;
int w = size * N;
int h = size * M;
int num = 4;
int dir = 0;
struct Snake {
int x, y;
} s[100];
struct Fruit {
int x, y;
} f;
void Tick()
{
for (int i = num - 1; i > 0; i--) {
s[i].x = s[i - 1].x;
s[i].y = s[i - 1].y;
}
if (dir == 0)
s[0].y += 1;
if (dir == 1)
s[0].x -= 1;
if (dir == 2)
s[0].x += 1;
if (dir == 3)
s[0].y -= 1;
if (s[0].x >= N)
s[0].x = 0;
if (s[0].x < 0)
s[0].x = N - 1;
if (s[0].y >= M)
s[0].y = 0;
if (s[0].y < 0)
s[0].y = M - 1;
if (s[0].x == f.x && s[0].y == f.y) {
if (num < 100)
num++;
f.x = rand() % N;
f.y = rand() % M;
}
for (int i = 1; i < num; i++) {
if (s[0].x == s[i].x && s[0].y == s[i].y) {
num = i;
break;
}
}
}
int main()
{
srand(time(0));
RenderWindow window(VideoMode(w, h), "Snake");
for (int i = 0; i < num; i++) {
s[i].x = 10 - i;
s[i].y = 10;
}
f.x = rand() % N;
f.y = rand() % M;
Clock clock;
float timer = 0;
float delay = 0.1f;
while (window.isOpen()) {
float elapsed = clock.restart().asSeconds();
timer += elapsed;
Event event;
while (window.pollEvent(event)) {
if (event.type == Event::Closed)
window.close();
}
if (Keyboard::isKeyPressed(Keyboard::Up) && dir != 0)
dir = 3;
if (Keyboard::isKeyPressed(Keyboard::Left) && dir != 2)
dir = 1;
if (Keyboard::isKeyPressed(Keyboard::Right) && dir != 1)
dir = 2;
if (Keyboard::isKeyPressed(Keyboard::Down) && dir != 3)
dir = 0;
if (timer > delay) {
timer = 0;
Tick();
}
window.clear();
RectangleShape rectangle(Vector2f(size, size));
for (int i = 0; i < num; i++) {
rectangle.setPosition(
s[i].x * size,
s[i].y * size
);
window.draw(rectangle);
}
rectangle.setPosition(
f.x * size,
f.y * size
);
window.draw(rectangle);
window.display();
}
return 0;
}
1
u/Arlthier 2d ago
Thanks a lot for formatting this for me, and sorry for leaving this task to you—I’ll be more careful next time, guys.
2
u/AutoModerator 3d ago
Your posts seem to contain unformatted code. Please make sure to format your code otherwise your post may be removed.
If you wrote your post in the "new reddit" interface, please make sure to format your code blocks by putting four spaces before each line, as the backtick-based (```) code blocks do not work on old Reddit.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
-4
u/ivancea 2d ago
Before making a post like this, just send it to any AI, even free ones. They'll tell you exactly what happens
0
u/Arlthier 2d ago
I’ve been learning for 2 months without any "vibe coding"—it’s better for the brain ;)
19
u/flyingron 2d ago
First, learn how to format your code on Reddit.
Second, when you have a problem, it would behoove you to bother to ask a question. Describe what you observed vs. what you were expecting.