0

I want to create a simple snake game using console C++. I'm currently creating the tail part of the snake. When the snake eats the fruit, it adds a section to its tail. The problem is that the game runs well until the 3rd fruit. At this moment, though a tail section is added to the snake, it will move awkwardly and will shift the right wall.

here's the code :

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include<time.h>

using namespace std;

// ===========  VARIABLES ===========

bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
enum eDirection {STOP = 0, LEFT, RIGHT, UP, DOWN};
eDirection dir;
//arrays

int tailx[50],taily[50];
int ntail=0;


// ===========  INITIALIZATION ===========
void setup()
{
    gameOver = false;
    //snake is not moving
    srand(time(0));

    dir = STOP ;
    // center the snake on the map
    x = width/2;
    y = height/2;

    // randomize fruit position
    fruitX = rand()%width;
    fruitY = rand()%height;

    score = 0;
}


void Draw()
{
    //clear screen
    system("cls");


    // ======== DRAW MAP ========

    //display top border of map
    for (int i =0; i< width; i++)
        cout << "#" ;
    cout<<endl;

    for (int i = 0; i<height; i++)
    {

        for (int j=0; j<width; j++)
        {
            if (j == 0)
                cout <<"#";

            //display the head
            if (x==j && y==i)

                cout << "o";

            // display the fruit

            else if (fruitX == j && fruitY == i)
                cout << "F";

            else
            {
                bool print = false;
                for (int k = 0; k < ntail ; k++)
                {

                    if (tailx[k]== j && taily[k] == i)
                    {
                        cout << "o";
                        print = true;
                    }

                }
                    if(!print)
                    cout << " ";

            }
            if (j == width-1)
                cout << "#";
        }
        cout<<endl;
    }

    //display bottom border
    for (int i =0; i< width+2; i++)
        cout << "#" ;
    cout<<endl;

    //display score
    cout<< "Score : " << score<<endl;

    //debug
    cout << "ntail : " << ntail << endl ;
    cout << "width : "  << width << endl ;



}

void Input()
{
    if (_kbhit())
    {

        //leyboard control input
        switch (_getch())
        {
        case 'q':
            dir = LEFT;
            break;
        case 'z':
            dir = UP;
            break;
        case 's':
            dir = DOWN;
            break;
        case 'd':
            dir = RIGHT;
            break;
        case 'x':
            gameOver = true;
            break;
        default :
            break;
        }
    }
}

void logic()
{
    //remember previous position
    int prevx = tailx[0];
    int prevy = taily[0];

    int prev2x,prev2y;

    tailx[0] = x;
    taily[0] = y;

    for (int i=1; i<ntail; i++)
    {

        //remember current position
        prev2x = tailx[i];
        prev2y = taily[i];

        // change value

        tailx[i] = prevx;
        taily[i] = prevy;

        prevx = tailx[i];
        prevy = taily[i];



    }



    // movement management
    switch  (dir)
    {
    case DOWN :

        if (y<=height)
            y++;
        break;

    case UP:
        if (y>=0)
            y--;
        break;

    case LEFT:
        if (x>=0)
            x--;
        break;

    case RIGHT:
        if (x<=width)
            x++;
        break;
    default :
        break;
    }

    // if the snake hits the wall
    //if (x == width || y =z= height || x == 0 || y == 0)
    //    gameOver = true;

    //if the snake eats a fruit


    // score display and new fruit apparition
    if (x==fruitX && y==fruitY)
    {
        score += 10;
        fruitX = rand()%width;
        fruitY = rand()%height;
        ntail++;

    }
}

int main()
{
    setup();

    while (!gameOver)
    {
        Draw();
        Input();
        logic();

        Sleep(100);

    }

    return 0;
}
  • 1
    So in your Draw() function, `for (int k ` loop what would happen if somehow 2 segments of the tail were at the same location? Perhaps that shouldn't happen, so add an extra check there and if it did happen work back to why? – Gem Taylor Jul 24 '19 at 17:52
  • Don't use `system()`! Its bad for many reasons. See here: https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c. –  Jul 24 '19 at 18:27
  • With `_kbhit` and `_getch` in place this is clearly platform-specific code. Whatever we may think of that choice, it does mean `system("cls")` is at least dependable. Though yes it does bear mentioning that this is not pure C++ – Lightness Races in Orbit Jul 25 '19 at 11:01

1 Answers1

0

Got it in void logic() function, it should've been :

 for (int i=1; i<ntail; i++)
    {
        //remember current position
        prev2x = tailx[i];
        prev2y = taily[i];

        // change value

        tailx[i] = prevx;
        taily[i] = prevy;

        prevx = prev2x;
        prevy = prev2y;
    }

instead of

 for (int i=1; i<ntail; i++)
    {
        //remember current position
        prev2x = tailx[i];
        prev2y = taily[i];

        // change value

        tailx[i] = prevx;
        taily[i] = prevy;

        prevx = tailx[i];
        prevy = taily[i];
    }