Search code examples
cwindowsconsolecursor-position

SetConsoleCursorPosition : Getting black rows in console upon use


Following my previous question about making a snake program more fluid, I went and tried ANSI escape sequences and console functions to put back the text cursor on the top left corner.

I want to get the cursor on the top left corner of the screen, but while it does so I get black stripes across the screen every other line.

I am working in a windows environment making this program for the windows console.

Here is the painting function :

    void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
    //system("cls");
    //printf("\033[1;1H");
    COORD destCoord;
    destCoord.X = 0;
    destCoord.Y = 0;
    SetConsoleCursorPosition(hconsole, destCoord);
    for (int i = 0; i < ligneMax; i++)
    {
        for (int j = 0; j < colonneMax; j++)
        {
            printf("%c", tab[i][j]);
        }
        printf("\n");
    }
}

I tried putting the escape code and console function in the main right before calling the paint function but I got the same results.

here is the whole program if someone wants to test :

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>

void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
    //system("cls");
    //printf("\033[1;1H");
    COORD destCoord;
    destCoord.X = 0;
    destCoord.Y = 0;
    SetConsoleCursorPosition(hconsole, destCoord);
    for (int i = 0; i < ligneMax; i++)
    {
        for (int j = 0; j < colonneMax; j++)
        {
            printf("%c", tab[i][j]);
        }
        printf("\n");
    }
}

void create(int tab[28][120], int Nbligne, int Nbcolonne, 
            int randligne, int randcols)
{
    for (int i = 0; i < Nbligne; i++)
    {
        for (int j = 0; j < Nbcolonne; j++)
        {
            tab[i][j] = ' ';
            if (i == 0 || i == Nbligne - 1)
                tab[i][j] = 205;
            if (j == 0 || j == Nbcolonne - 1)
                tab[i][j] = 186;
            if (i == 0 && j == 0)
                tab[i][j] = 201;
            if (i == 0 && j == Nbcolonne - 1)
                tab[i][j] = 187;
            if (i == Nbligne - 1 && j == 0)
                tab[i][j] = 200;
            if (i == Nbligne - 1 && j == Nbcolonne - 1)
                tab[i][j] = 188;
            if (i == 14 && j == 60)
                tab[i][j] = 219;
            if (i == 14 && j == 59)
                tab[i][j] = 79;
            if (i == 14 && j == 58)
                tab[i][j] = 35;
            if (i == randligne && j == randcols)
                tab[i][j] = 176;
        }
    }
}

void destroyTail(int tab[28][120], int Nbligne, int Nbcolonne) 
{
    for (int i = 0; i < Nbligne; i++)
    {
        for (int j = 0; j < Nbcolonne; j++)
        {
            if (tab[i][j] == 35)
            {
                tab[i][j] = ' ';
                if (tab[i][j + 1] == 79)
                    tab[i][j + 1] = 35;
                else if (tab[i][j - 1] == 79)
                    tab[i][j - 1] = 35;
                else if (tab[i + 1][j] == 79)
                    tab[i + 1][j] = 35;
                else if (tab[i - 1][j] == 79)
                    tab[i - 1][j] = 35;
                goto stop;
            }
        }
    }
    stop: NULL;
}

void translate(int tab[28][120], char direction, int Nbligne, int Nbcolonne)
{
    for (int i = 0; i < Nbligne; i++)
    {
        for (int j = 0; j < Nbcolonne; j++)
        {
            if (tab[i][j] == 219)
            {
                if (direction == 'R')
                {
                    tab[i][j] = 79;
                    tab[i][j + 1] = 219;
                }
                if (direction == 'D')
                {
                    tab[i][j] = 79;
                    tab[i + 1][j] = 219;
                }
                if (direction == 'L')
                {
                    tab[i][j] = 79;
                    tab[i][j - 1] = 219;
                }
                if (direction == 'U')
                {
                    tab[i][j] = 79;
                    tab[i - 1][j] = 219;
                }
                goto stop;
            }
        }
    }
    stop: NULL;
}

int checkExpand(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
    for (int i = 0; i < Nbligne; i++)
    {
        for (int j = 0; j < Nbcolonne; j++)
        {
            if ((direction == 'R' && tab[i][j] == 219 && tab[i][j + 1] == 176) ||
                (direction == 'L' && tab[i][j] == 219 && tab[i][j - 1] == 176) ||
                (direction == 'U' && tab[i][j] == 219 && tab[i - 1][j] == 176) ||
                (direction == 'D' && tab[i][j] == 219 && tab[i + 1][j] == 176))
                return 1;
        }
    }
    return 0;
}

int checkDeath(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
    for (int i = 0; i < Nbligne; i++)
    {
        for (int j = 0; j < Nbcolonne; j++)
        {
            if ((direction == 'R' && tab[i][j] == 219 && (tab[i][j + 1] == 186 || tab[i][j + 1] == 79)) ||
                (direction == 'L' && tab[i][j] == 219 && (tab[i][j - 1] == 186 || tab[i][j - 1] == 79)) ||
                (direction == 'U' && tab[i][j] == 219 && (tab[i - 1][j] == 205 || tab[i - 1][j] == 79)) ||
                (direction == 'D' && tab[i][j] == 219 && (tab[i + 1][j] == 205 || tab[i + 1][j] == 79)))
                return 1;
        }
    }
    return 0;
}

int main()
{
    HANDLE  hConsole;
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, 241);

    int tab[28][120];
    int randligne = rand() % 26 + 1;
    int randcols = rand() % 118 + 1;
    create(tab, 28, 120, randligne, randcols);
    paint(tab, 28, 120, hConsole);
    char i = '1';
    char direction = 'R';
    int eaten = 0;
    int expand = 0;
    int death = 0;
    while(i != 'k')
    {
        if (kbhit())
            i = getch();
        switch(i) {
            case 'z':
                if (direction != 'D')
                    direction = 'U';
                break;
            case 's':
                if (direction != 'U')
                    direction = 'D';
                break;
            case 'd':
                if (direction != 'L')
                    direction = 'R';
                break;
            case 'q':
                if (direction != 'R')
                    direction = 'L';
                break;
        }
        randligne = rand() % 26 + 1;
        randcols = rand() % 118 + 1;
        death = checkDeath(tab, 28, 120, direction);
        if (death == 1)
            break;
        translate(tab, direction, 28, 120);
        expand = checkExpand(tab, 28, 120, direction);
        if (expand == 0)
            destroyTail(tab, 28, 120);
        else
        {
            while (tab[randligne][randcols] != ' ')
            {
                randligne = rand() % 26 + 1;
                randcols = rand() % 118 + 1;
            }
            tab[randligne][randcols] = 176;
            eaten++;
        }
        printf("Number of biscuits eaten : %d ; direction : %c ; expand : %d", eaten, direction, expand);
        paint(tab, 28, 120, hConsole);
        Sleep(100);
    }
    while(i != 'k')
    {
        if (kbhit())
            i = getch();
    }
}

Solution

  • Too much code to take in quickly. If you have Windows console ouput for the snake, can't you simply printf the next line and leave it at that?

    If you want to hide the cursor (instead of trying to park it out of sight) you can make it invisible by calling SetConsoleCursorInfo and the struct passed is shown here.