Derby Pims
Derby Pims

Reputation: 15

What should I use to stop the sleep() function in C if a condition changes in that period of time (doesn't hold anymore)?

I'm an amateur in C and I have the following task: We are given a two-dimensional table with the player controlling an 'X' in the middle. The player should have the possibility to move the 'X' around. However, every 2 seconds a random character appears in a specific point near a border of the table, such that if all the boxes near the border have a character in them, the player loses.

I'm having problems with moving the 'X' around and at the same time random characters appearing every 2 seconds. If I press the button to move 'X' in any direction but the code is still 'sleeping', the change will happen only after the certain remaining time has passed which is nearly not good enough - 1 move per 2 seconds.

I want the sleep() function to stop when there is a keyboard input, print the changed position on the table and start again with the remaining time after that or at least just sleep again for 2 seconds. However, I am unable to understand all the complex stuff like multi-threading at the moment so could you please elaborate in simplistic terms your answer? My PC is using Windows.

Here is a part of my code:

void move()
{
    if (kbhit())
    {
        chkb = getch();//character from keyboard
        if ((int)chkb == 27)//if chkb is ESC
        {
            printf("\nGame Exited. We already miss you!");
            stop();
        }
        else
        {
            changeposition();
            printTable();
        }
    }
}

while (1)
    {
        move();
        switch (rand() % 4)
        {
        case 0:
            balls[p1][p2] = 'R';//array of chars
            break;
        case 1:
            balls[p1][p2] = 'G';
            break;
        case 2:
            balls[p1][p2] = 'B';
            break;
        case 3:
            balls[p1][p2] = 'Y';
            break;
        default:
            balls[p1][p2] = '?';
        }

        printTable();
        verifyLose();
        Sleep(2000);
        }
    }
    printTable();

I'm looking for something like:

Sleep(for a time, if some condition is true);
if(condition is false){
    ->make it true
    ->start sleep again with remaining time
}

Or something similar to that. Any ideas? Thanks in advance!

Upvotes: 1

Views: 957

Answers (2)

Weather Vane
Weather Vane

Reputation: 34585

I would not call either MS Sleep() or gcc sleep() but go for a non-blocking function, as you have with MS kbhit().

For a 1 second timer an example use is

clock_t target = clock() + CLOCKS_PER_SEC;
while(!kbhit() && clock() < target) {
    // some code if needed
}

The loop will end when a key is pressed, or after 1 second. You can check kbhit() again to find out which.

Upvotes: 3

Notice that the sleep function is not part of the C11 standard. You could check by reading n1570, the draft C11 standard. See also this C reference website.

But sleep is part of POSIX. Read for example sleep(3).

You could want to use some event looping library, such as Glib from GTK (cross-platform on Windows, Linux, MacOSX), or libev or libevent.

You could want to use a terminal interface library, such as ncurses.

You could consider writing a graphical application above cross-platform libraries such as GTK (or Qt, or FLTK; both requiring learning programming in C++)

You could decide to code a Windows-specific C program.

Be sure to then read the documentation of the WinAPI, e.g. here

I never coded on Windows myself, but I believe you could be interested in the Windows specific Sleep function.

I guess that for a game, you need some input-multiplexing function. On Linux, select(2) or poll(2) comes to mind. Perhaps you might be interested by Socket.Poll on Windows (but polling the keyboard or the mouse should be done otherwise).

For a game, I would recommend using libSFML.

Whatever API or library you would use, be sure to read its documentation.

Look also for existing open-source examples on github.

Read also the documentation of your C compiler (perhaps GCC) and of your debugger (maybe GDB). Enable all warnings and debug info in your compiler (with GCC, compile with gcc -Wall -Wextra -g). Consider using static analysis tools like Clang static analyzer or Frama-C. Read perhaps this draft report, and look (at end of 2020) into the DECODER European project, and recent papers to ACM SIGPLAN sponsored conferences (about compilers and static analysis).

Be aware that PC keyboards have various layouts (mine is AZERTY). You may want to use some library abstracting these.

Upvotes: 1

Related Questions