1

I have a C++ code here that will make a game where it will generate random number base on keyboard input, if the number is even, score will increase. If the score is 10, you win and you can restart or exit the game.

using namespace std;
int score = 0, run = 1;
char inp = 'z';

void the_game() {
    int x = 0;
    while (run) {
        if ('a' <= inp && inp <= 'j') {  
            srand((unsigned)time(NULL));
            x = (rand() % 11) * 2;  //if 'a' <= inp <= 'j', x is always even
            cout << "Number: " << x << endl;
        }
        else {                      // and if not, x is random
            srand((unsigned)time(NULL));
            x = (rand() % 11);
            cout << "Number: " << x << endl;
        }

        if (x % 2 == 0) {
            score++;
            cout << "Current Score: " << score << "\n";
        }
        if (score == 10) {
            run = 0; 
            cout << "You Win! press R to restart and others to exit" ;
        }
        Sleep(1000);
    }
}
void ExitGame(HANDLE t) {
    system("cls");
    TerminateThread(t, 0);
}

In main, I use a thread to run the game while taking input from keyboard like below

int main() {
    thread t1(the_game);
    HANDLE handle_t1 = t1.native_handle();
    cout << "The we_are_even game\n";

    while (true) {
        inp = _getch();
        if (run == 1) 
            ResumeThread(handle_t1);
        else{   //run == 0
            if (inp == 'r') {
                system("cls");
                cout << "The we_are_even game\n";
                run = 1; //restart game
            }
            else {  //if inp != 'r', exit the game
                ExitGame(handle_t1);
                t1.join();
                return 0;
            }
        }
    }
}

The problem is, after i win the game and press 'r' to restart, the thread do not run again although it should be resumed. Where did i make a mistake here? How can i fix it? I have tried to suspend it when run = 0 and resume again but to no avail.

Halsey
  • 119
  • 1
  • 8
  • 3
    You cannot terminate C++ threads like that. This is undefined behavior. No wonder your thread crashes. C++ threads can only be terminated by having the thread return from the thread function. You cannot use an operating system-specific system call to terminate a C++ thread. This results in memory corruption and undefined behavior. Additionally, the shown code completely lacks synchronization for updating the shared state. You need [a good C++ textbook to learn how to correctly implement C++ threads](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Jun 15 '20 at 14:19
  • Additional useful reading: [srand() — why call it only once?](https://stackoverflow.com/questions/7343833/srand-why-call-it-only-once) – user4581301 Jun 15 '20 at 14:58

1 Answers1

1

When you set r to zero, the while loop will stop and the thread function (in your case, the_game) will exit, which means that the thread will stop. That is, when the player wins, your code stops the thread instead of suspending it. And you won't be able to revive the thread by calling ResumeThread on it.

You can either wait on a condition variable or if you use WinAPI, on an Event object. When the player wins, you stop the loop by making it wait for such an object to be notified/set.

On second thought, the easiest approach would be simply recreating the thread when the user presses R. Just replace the ResumeThread call with code that recreates the thread.

kol
  • 27,881
  • 12
  • 83
  • 120
  • Thanks for your clear explanation, this is my first time working with thread and this sure helps me a lot. Now knowing that the thread stopped instead of being suspended, i replaced the `while(run)` in the_game function with `while(true)` and `if (run == 1)` for the whole game and it worked just fine. – Halsey Jun 16 '20 at 12:46