Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

Hey guys I need some help with my snek program on c++.

+1 vote
asked Aug 25, 2020 by ZX228 (400 points)
//Snek
//08-18-2020
#include <stdio.h>
#include <iostream>
#include <curses.h>
#include <chrono>
#include <thread>
#include <unistd.h> //usleep(milliseconds);
using namespace std;
int level_num;
static int base[ 20 ][ 30 ] = {
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}
};
string direction;
int length = 1;
int head_pos[2] = {10, 16};
string level = "easy";
int dist_moved = 0;
bool alive = true;
bool touching_self = false;
namespace setup {
    void ask_level() {
        cout << "Easy, medium, or hard?" << endl;
        cin >> level;
        while ((level != "easy") && (level != "medium") && (level != "hard")) {
            cout << "\aPlease enter only \"easy\", \"medium\", or \"hard\" (no caps)." << endl;
            cin >> level;
        }
        if (level == "easy") {level_num = 1;}
        if (level == "medium") {level_num = 2;}
        if (level == "hard") {level_num = 3;}
        for (int z = 25; z > 0; z--) {
            cout << "\033[F                                                               ";
        }
        cout << "\r";
        base[10][16] = 2;
    }
    void set_up() {
        for (int r = 0; r < 20; r++) {
            for (int c = 0; c < 30; c++) {
                if (base[ r ][ c ] == 5) {cout << " |";}
                if (base[ r ][ c ] == 4) {cout << "| ";}
                if (base[ r ][ c ] == 3) {cout << "--";}
                if (base[ r ][ c ] == 2) {cout << "[]";}
                if (base[ r ][ c ] == 1) {cout << "{}";}
                if (base[ r ][ c ] == 0) {cout << "  ";}
            }
        cout << endl;
        }
    }
}
char c = 'w';
char d;
namespace sense {
    using namespace sense;
    void change_direction() {
        if ((c == 'd') && (direction != "left")) {direction = "right";}
        if ((c == 'a') && (direction != "right")) {direction = "left";}
        if ((c == 'w') && (direction != "down")) {direction = "up";}
        if ((c == 's') && (direction != "up")) {direction = "down";}
    }
    void sense_keypress() {
        if ((c == 'a') || ((c == 'd') || ((c == 's') || ((c == 'w')) {d = c;}
        initscr();
        timeout(100);
        c = getch();
        endwin();
        if ((c != 'd') && (c != 'a') && (c != 'w') && (c != 's')) {c = d;}
        cout << c;
        if ((c == 'd') && (direction != "left")) {direction = "right";}
        if ((c == 'a') && (direction != "right")) {direction = "left";}
        if ((c == 'w') && (direction != "down")) {direction = "up";}
        if ((c == 's') && (direction != "up")) {direction = "down";}
        cout << direction;
    }
}
int doit = (100000 - (level_num^10));
int dist_2 = 0;
namespace run {
    using namespace run;
    using namespace setup;
    using namespace this_thread; // sleep_for, sleep_until
    using namespace chrono; //nanoseconds, system_clock, seconds
    using namespace sense;
    using namespace setup;
    void move_right() {
        if ((head_pos[1] < 28) && (touching_self == false) && (dist_moved == dist_2)) {
            if (length == 1) {base[head_pos[0]][head_pos[1]] = 0;}
            dist_2++;
            head_pos[1]++;
            base[head_pos[0]][head_pos[1]] = 2;
        }
    }
    void move_left() {
        if ((head_pos[1] > 1) && (touching_self == false) && (dist_moved == dist_2)) {
            if (length == 1) {base[head_pos[0]][head_pos[1]] = 0;}
            dist_2++;
            head_pos[1]--;
            base[head_pos[0]][head_pos[1]] = 2;
        }
    }
    void move_up() {
        if ((head_pos[0] > 1) && (touching_self == false) && (dist_moved == dist_2)) {
            if (length == 1) {base[head_pos[0]][head_pos[1]] = 0;}
            dist_2++;
            head_pos[0]--;
            base[head_pos[0]][head_pos[1]] = 2;
        }
    }
    void move_down() {
        if ((head_pos[0] < 18) && (touching_self == false) && (dist_moved == dist_2)) {
            if (length == 1) {base[head_pos[0]][head_pos[1]] = 0;}
            dist_2++;
            head_pos[0]++;
            base[head_pos[0]][head_pos[1]] = 2;
        }
    }
    void move() {
        usleep(doit);
        sense_keypress();
        if (direction == "right") {
            move_right();
            usleep(10000);
            dist_moved++;
        }
        if (direction == "left") {
            move_left();
            usleep(10000);
            dist_moved++;
        }
        if (direction == "up") {
            move_up();
            usleep(10000);
            dist_moved++;
        }
        if (direction == "down") {
            move_down();
            usleep(10000);
            dist_moved++;
        }
        for (int z = 25; z > 0; z--) {
            cout << "\033[F                                                               ";
        }
        cout << "\r";
        for (int r = 0; r < 20; r++) {
            for (int c = 0; c < 30; c++) {
                if (base[ r ][ c ] == 5) {cout << " |";}
                if (base[ r ][ c ] == 4) {cout << "| ";}
                if (base[ r ][ c ] == 3) {cout << "--";}
                if (base[ r ][ c ] == 2) {cout << "[]";}
                if (base[ r ][ c ] == 1) {cout << "{}";}
                if (base[ r ][ c ] == 0) {cout << "  ";}
            }
        cout << endl;
        }
    }
}
using namespace this_thread; // sleep_for, sleep_until
using namespace chrono; //nanoseconds, system_clock, seconds
using namespace setup;
using namespace sense;
using namespace run;
int main() {
    ask_level();
    set_up();
    while (alive == true) {
        move();
    }
}

1 Answer

+1 vote
answered Aug 25, 2020 by Peter Minarik (86,040 points)
edited Aug 26, 2020 by Peter Minarik

There is a compilation error online 80. Wrong parenthesis.

This is the fix:

if ((c == 'a') || (c == 'd') || (c == 's') || (c == 'w')) {d = c;}

After this, the program starts to run, but does not seem to work as a proper snake game.

  • the "snake" does not change direction as a reaction of the WSAD keys.
  • the "snake" stops when it reaches the top of the screen. (Is this intentional? Game over? Or do you want to wrap around and come in from the bottom of the screen?)

What exactly do you need help with?

Update

Some bugs I've found:

A to the power of B

If you want to raise level_num to to power of 10 (10, 100, 1000, based on level_num = 1, 2, 3), then the below is wrong:

int doit = (100000 - (level_num^10));

The ^ operator is a bitwise xor (exclusive or) operator. If you want to raise A to the power of B you need to use pow() function in the <cmath> header:

int doit = 100000 - pow(level_num, 10);

getch() returns -1

I haven't used <curses.h> in any project, but it seems to me that getch() from <curses.h> returns -1, when I try to press the WSAD keys.

It would be worthwhile to look into why this is happening.

commented Aug 25, 2020 by ZX228 (400 points) 1 flag
So basically this code is supposed to change the direction when a key is pressed, but it doesn't. I fixed the parenthesis problem, but I'm lost as to how to get char d to change from 'w' when I press a, s, or d, or get char c to stay as the last key (of these four: w, a, s, d) pressed until a new key is pressed.

void sense_keypress() {
        if ((c == 'a') || (c == 'd') || (c == 's') || (c == 'w')) {d = c;}
        initscr();
        timeout(100);
        c = getch();
        endwin();
        
        if ((c != 'd') && (c != 'a') && (c != 'w') && (c != 's')) {c = d;}
        cout << c;
        if ((c == 'd') && (direction != "left")) {direction = "right";}
        if ((c == 'a') && (direction != "right")) {direction = "left";}
        if ((c == 'w') && (direction != "down")) {direction = "up";}
        if ((c == 's') && (direction != "up")) {direction = "down";}
        
        cout << direction;
    }
commented Aug 25, 2020 by ZX228 (400 points)
Also, if you're wondering about the edge thing, I fixed it.


void move_up() {
        if ((head_pos[0] > 1) && (touching_self == false) && (dist_moved == dist_2)) {
            if (length == 1) {base[head_pos[0]][head_pos[1]] = 0;}
            dist_2++;
            head_pos[0]--;
            
            base[head_pos[0]][head_pos[1]] = 2;
            
        }
        else alive = false;
    }
commented Aug 26, 2020 by ZX228 (400 points)
Thx for the help. I've been trying to figure out the getch, and I've noticed that in this program, it actually does work. Also, the length of the timeout doesn't have any effect on the functionality of the getch.

#include <stdio.h>
#include <curses.h>
#include <iostream>

using namespace std;
string direction = "left";
int main()
{
    
    initscr();
    timeout(10000);
    char c = getch();
    cout << c;
    endwin();
    
    if ((c == 'd') && (direction != "left")) {direction = "right";}
    if ((c == 'a') && (direction != "right")) {direction = "left";}
    if ((c == 'w') && (direction != "down")) {direction = "up";}
    if ((c == 's') && (direction != "up")) {direction = "down";}
    cout << c << endl;
    cout << direction;
    
}
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...