For solving such tasks good fits concept of channels - pipes that connect different thread. Standard C++ doesn't contain built-in channels but there are enough implementations in libraries.
I personally use [Cool](https://github.com/verri/cool), alternatives could be found in Github under [channel topic](https://github.com/topics/channels?l=c%2B%2B).
Algorithm of your game is really easy - first player sending number through one channel to second player. If he/she/it guessed answer will be 0, otherwise answer will contain number from second player. Repeat procedure until someone won.
Second player make the same actions but receive number first.
Complete code:
```
# include <iostream>
# include <thread>
# include <random>
# include <algorithm>
# include <iterator>
# include <mutex>
# include <chrono>
# include <cool/channel.hpp>
std::mutex mutex;
void player1(int id, int number, cool::ichannel<int> in, cool::ochannel<int> out)
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_device rd;
std::shuffle(v.begin(), v.end(), rd);
{
std::lock_guard<std::mutex> guard(mutex);
std::cout << "First player has number = " << number << "\nGuesses";
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
int answer = -1;
for(const int n : v)
{
out << n;
in >> answer;
if( !answer )
{
std::lock_guard<std::mutex> guard(mutex);
std::cout << "First won\n";
return;
}
if(answer == number)
{
out << 0;
std::lock_guard<std::mutex> guard(mutex);
std::cout << "First loose\n";
return;
}
}
}
void player2(int id, int number, cool::ochannel<int> out, cool::ichannel<int> in)
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
{
std::lock_guard<std::mutex> guard(mutex);
std::cout << "Second player has number = " << number << "\nGuesses";
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
int answer = -1;
for(const int n : v)
{
in >> answer;
if( !answer )
{
std::lock_guard<std::mutex> guard(mutex);
std::cout << "Second won\n";
return;
}
if(answer == number)
{
out << 0;
std::lock_guard<std::mutex> guard(mutex);
std::cout << "Second loose\n";
return;
}
out << n;
}
}
int main()
{
std::uniform_int_distribution<> dis(1, 10);
std::mt19937 g(std::chrono::high_resolution_clock::now().time_since_epoch().count());
auto ch1 = cool::channel<int>(1u);//send data from p1 to p2
auto ch2 = cool::channel<int>(1u);//send data from p2 to p1
auto thr1 = std::thread(player1, 0, dis(g), ch1, ch2);
auto thr2 = std::thread(player2, 1, dis(g), ch1, ch2);
thr1.join();
thr2.join();
}
```