-1

I'm developing a game that has a word falling to the bottom of the screen and the user typing that word before it hits the bottom. So you'll be able to type input while the word is falling. Right now I have a timer that waits 5 seconds, prints the word, runs timer again, clears the screen, and prints the word down 10 units.

int main()
{
  for (int i = 0; i < 6; i++)
   {
    movexy(x, y);
    cout << "hello\n";
    y = y + 10;
    wordTimer();
   }
}

Very basic I know. Which is why I thought multithreading would be a good idea so that way I could have the word falling while I still type input at the bottom. This is my attempt at that so far:

vector<std::thread> threads;

for (int i = 0; i < 5; ++i) {
    threads.push_back(std::thread(task1, "hello\n"));
    threads.push_back(std::thread(wordTimer));
}

for (auto& thread : threads) {
    thread.join();
}

However this only prints hello 4 times to the screen, then prints 55, then prints hello again, then counts-down 3 more times. So any advice on how to correctly do this? I've already done research. Just a few of the links I checked out that didn't help:

Multithreaded console I/O

C++11 Multithreading: Display to console

Render Buffer on Screen in Windows

Threading console application in c++

Create new console from console app? C++

Console output from thread

https://msdn.microsoft.com/en-us/library/975t8ks0.aspx?f=255&MSPPError=-2147217396

http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm

EDIT: Here is wordTimer()

int wordTimer()
{
    _timeb start_time;
    _timeb current_time;

    _ftime_s(&start_time);
    int i = 5;
    for (; i > 0; i--)
    {
        cout << i << endl;

        current_time = start_time;
        while (elapsed_ms(&start_time, &current_time) < 1000)
        {
            _ftime_s(&current_time);
        }

        start_time = current_time;
    }
    cout << " 5 seconds have passed." << endl;
    return 0;
}

this is also necessary for wordTimer()

unsigned int elapsed_ms(_timeb* start, _timeb* end)
{
    return (end->millitm - start->millitm) + 1000 * (end->time - start->time);
}

and task1

void task1(string msg)
{
    movexy(x, y);
    cout << msg;
    y = y + 10;
}

and void movexy(int x, int y)

void movexy(int column, int line)
{
    COORD coord;
    coord.X = column;
    coord.Y = line;
    SetConsoleCursorPosition(
        GetStdHandle(STD_OUTPUT_HANDLE),
        coord
        );
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
user2073308
  • 57
  • 2
  • 10
  • what is `task1`? that is `wordtimer`? Please post a code example with your problem that we can compile ourselves. – Marinos K Mar 14 '16 at 00:56
  • @Marinos_K Sorry >.< task 1 changes the cursor position and takes in a string that it will display then adds 10 to the y unit. WordTimer prints out a countdown for 5 seconds – user2073308 Mar 14 '16 at 01:03
  • " this only prints hello 4 times to the screen, then prints 55, then prints hello again, then counts-down 3 more times." - what were you expecting it to do? – user253751 Mar 14 '16 at 01:13
  • @immibis No I was expecting it to print hello then countdown, print hello then countdown, etc. I would like it to run those threads in that order while having another thread running continuously that checks input to be equal to the string you type in. – user2073308 Mar 14 '16 at 01:19
  • @immibis thank you for the quick response! – user2073308 Mar 14 '16 at 01:19
  • @user2073308 Do you know how to make a program run things in order? It's pretty simple - you actually don't have to do anything special! But threads can run in any order relative to other threads - by putting all of those things in their own thread, you *told* the computer it can run them in any order. Perhaps you just want one thread that does the printing and counting down. – user253751 Mar 14 '16 at 01:22
  • @immibis Thanks for the advice! I didn't reaIize was telling it to run them in any order. I will combine those two threads. Is there a way to have that string falling towards the bottom without changing the cursor position? This way I can keep the cursor at the bottom for the user to input text. – user2073308 Mar 14 '16 at 01:30
  • @user2073308 I have no idea about that, and that's a different question anyway. – user253751 Mar 14 '16 at 01:32
  • @user2073308 "I didn't reaIize was telling it to run them in any order." - the *entire point* of threads is that they get run in any order. – user253751 Mar 14 '16 at 01:32
  • @immibis I thought it was to run processes at the same time. But would you mind answering this here? This is my second attempt at rephrasing this question and I can't ask again today. – user2073308 Mar 14 '16 at 01:36
  • @user2073308 Well, imagine if the OS had to run threads in the order you started them. Then each thread would have to wait for the last thread to finish, and so it wouldn't be allowed to run them at the same time as each other. – user253751 Mar 14 '16 at 01:53

1 Answers1

1

Threads do not run in any particular order - the operating system can schedule them whenever it feels like it. Your code starts ten threads - five that print "Hello", and five that count down. So the most likely outcome is that your program will try to print "Hello" five times at the same time, and also count down five times at the same time.

If you want to do things in a particular order, don't do them all in separate threads. Just have one thread that does the things in the right order.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • That does make a lot of sense! So would you mind telling me is there a way to have a string falling towards the bottom of the screen without changing the cursor position? Like just treating that falling string as a sprite? – user2073308 Mar 14 '16 at 01:57
  • @user2073308 I thought I already said I didn't know that. (Here I just posted what I said in my comments, but as an answer, seeing as it was actually an answer) – user253751 Mar 14 '16 at 02:03
  • Well thanks for your help! I know more about threads now. I'll look elsewhere. – user2073308 Mar 14 '16 at 02:15