The goal of this program is to use thread programming together with synchronization constructs available to simulate a simple multi-player game in the language C.
Each game has a dealer (who is not involved in the game), and N players (we denote them as Player 0, Player 1, ... Player N-1).
The dealer will start generating random numbers between 1-40 and put them into a FIFO queue. The dealer will generate a total of T numbers (which is pre-defined before the start of the game). Every time a number is generated, the dealer will look at the queue, if there is not more than N numbers in the queue, it will insert the number at the end of the queue. Otherwise, it will wait until there are no more than N numbers.
Once there are number(s) in the queue, the players will try to grab the number at the front of the queue. When a player (call him/her player k) grab hold of that number, he/she will rest for a short period of time, and then determine whether he/she will score and whether he/she will need to put the number back to the (end of the) queue: (we denote the number as x)
The game ends when there is no more number left (either on the queue or in the player's hand). The player with the highest total score wins.
Notice that there is no "player 1's turn", player 2s turn etc (do not impose player orders). Once there is a number in the queue, every player is eligible to try to grab the number. The only exception is that once one gets the number, he/she has to wait till you either discard it or put the required number back on the queue before he can get the next number available. If he/she do it fast enough, he/she can the next number. However, there is no two (or more) players can simultaneously get the same number.
A couple of sample runs of the game is available for you to examine.
For the base case, you are to implement the game via threads and synchronization constructs.
Main process - dealer
The main process of your program should serve as the dealer. It will take two command line parameters (via argc, argv). The first one is N (number of players) and the second one is T (the number of numbers generated). Your main thread should follow logic similar to described below:
Do all necessary pre-processing
Create all threads
Signal the game to start
Repeat
If the queue currently has N or fewer numbers
Generate a new number and add it to the queue
Until T numbers generated
Wait for all threads to finish
Print the final score for each player
Threads - player
Each player should be represented by a thread. The logic of each thread should be as follows
Do all necessary pre-processing
Wait for the game start signal
Repeat
If the queue is non-empty
Get the next number (call it x)
Sleep for 1 + x millseconds (use the function nanosleep())
Process scoring, and put a number back to the queue if necessary
Until game ends
Exit
One requirement for each thread: once a thread obtained a number, it cannot block other threads from obtaining the next number before it sleeps.
Output
Your program should output what is being output in the sample runs. Namely
The base part allows one game to be played. In this part you are going to simulate playing multiple games with different players.
In this part you program should read in a name of a file via the command line parameter. Then the program should read that file. The file format is the following:
The program now consists of a list of games. The main program, in addition to being the dealer, will have to facilitate multiple games.
In this part, you should consider each thread is a slot for a player to play in the game. The main program will start by assigning players to the slots, and once all the slots are filled, then play a game among them (T is the number of numbers generated per game). At the end of each game, the winner will leave, opening up a slot for the next player to fill in to start a new game.
The main process' logic will now be like this:
Do all necessary pre-processing
Create all threads
Create a list of all players
Assign the first N players to a slot
Repeat
Play a game (using the logic of base part)
Print the winner of that game (and the score)
Replace that player with the next one
Until no more players left in the list
One note: You should not pre-assign players to slots. Also, the player should join the game in the order of players in the file.
The logic of each thread will also need to be adjusted (left to you to figure it out).
Output
In additional to the output for the base case. You need to output two more things:
Number of threads : 4 | Number of objects : 10
Thread 0 started
Thread 1 started
Thread 2 started
The dealer inserted : 13
Thread 3 started
( 13 )
Thread 0 (0, 1) popped x = 13 (1). Matched. Need to push 3/5 * x back on queue
( )
The dealer inserted : 22
( 22 )
Thread 1 (1, 2) popped x = 22 (2). Matched. Need to push 3/5 * x back on queue
( )
The dealer inserted : 33
( 33 )
Thread 3 (3, 0) popped x = 33 (1). Not matched. Need to push x - 2 back on queue
( )
The dealer inserted : 36
( 36 )
Thread 2 (2, 3) popped x = 36 (0). Not matched. Need to push x - 2 back on queue
( )
The dealer inserted : 19
( 19 )
The dealer inserted : 38
( 19 38 )
The dealer inserted : 17
( 19 38 17 )
The dealer inserted : 10
( 19 38 17 10 )
Thread 0 score : 5 total : 5
Thread 0 pushed 8 to back of the queue
( 19 38 17 10 8 )
Thread 0 (0, 1) popped x = 19 (3). Not matched. Need to push x - 2 back on queue
( 38 17 10 8 )
Thread 1 score : 8 total : 8
Thread 1 pushed 14 to back of the queue
( 38 17 10 8 14 )
Thread 1 (1, 2) popped x = 38 (2). Matched. Need to push 3/5 * x back on queue
( 17 10 8 14 )
Thread 3 pushed 31 to back of the queue
( 17 10 8 14 31 )
Thread 3 (3, 0) popped x = 17 (1). Not matched. Need to push x - 2 back on queue
( 10 8 14 31 )
Thread 2 pushed 34 to back of the queue
( 10 8 14 31 34 )
Thread 2 (2, 3) popped x = 10 (2). Matched. Need to push 3/5 * x back on queue
( 8 14 31 34 )
Thread 0 pushed 17 to back of the queue
( 8 14 31 34 17 )
Thread 0 (0, 1) popped x = 8 (0). Matched. Need to push 3/5 * x back on queue
( 14 31 34 17 )
Thread 2 score : 4 total : 4
Thread 2 pushed 6 to back of the queue
( 14 31 34 17 6 )
Thread 1 score : 15 total : 23
Thread 3 pushed 15 to back of the queue
( 14 31 34 17 6 15 )
Thread 2 (2, 3) popped x = 14 (2). Matched. Need to push 3/5 * x back on queue
( 31 34 17 6 15 )
Thread 1 pushed 23 to back of the queue
( 31 34 17 6 15 23 )
Thread 3 (3, 0) popped x = 31 (3). Matched. Need to push 3/5 * x back on queue
( 34 17 6 15 23 )
Thread 1 (1, 2) popped x = 34 (2). Matched. Need to push 3/5 * x back on queue
( 17 6 15 23 )
Thread 0 score : 3 total : 8
Thread 0 pushed 5 to back of the queue
( 17 6 15 23 5 )
Thread 0 (0, 1) popped x = 17 (1). Matched. Need to push 3/5 * x back on queue
( 6 15 23 5 )
Thread 2 score : 5 total : 9
Thread 2 pushed 9 to back of the queue
( 6 15 23 5 9 )
Thread 2 (2, 3) popped x = 6 (2). Matched. Need to push 3/5 * x back on queue
( 15 23 5 9 )
Thread 3 score : 12 total : 12
Thread 3 pushed 19 to back of the queue
( 15 23 5 9 19 )
Thread 3 (3, 0) popped x = 15 (3). Matched. Need to push 3/5 * x back on queue
( 23 5 Thread 1 score : 13 total : 36
9 19 )
Thread 1 pushed 21 to back of the queue
( 23 5 9 19 21 )
Thread 1 (1, 2) popped x = 23 (3). Not matched. Need to push x - 2 back on queue
( 5 9 19 21 )
Thread 0 score : 6 total : 14
Thread 0 pushed 11 to back of the queue
( 5 9 19 21 11 )
Thread 0 (0, 1) popped x = 5 (1). Matched. Need to push 3/5 * x back on queue
( 9 19 21 11 )
Thread 2 score : 2 total : 11
Thread 2 pushed 4 to back of the queue
( 9 19 21 11 4 )
Thread 2 (2, 3) popped x = 9 (1). Not matched. Need to push x - 2 back on queue
( 19 21 11 4 )
Thread 3 score : 6 total : 18
Thread 1 pushed 21 to back of the queue
( 19 21 11 4 21 )
Thread 3 pushed 9 to back of the queue
( 19 21 11 4 21 9 )
Thread 1 (1, 2) popped x = 19 (3). Not matched. Need to push x - 2 back on queue
( 21 11 4 21 9 )
Thread 3 (3, 0) popped x = 21 (1). Not matched. Need to push x - 2 back on queue
( 11 4 21 9 )
Thread 0 score : 2 total : 16
Thread 0 pushed 3 to back of the queue
( 11 4 21 9 3 )
Thread 0 (0, 1) popped x = 11 (3). Not matched. Need to push x - 2 back on queue
( 4 21 9 3 )
Thread 2 pushed 7 to back of the queue
( 4 21 9 3 7 )
Thread 2 (2, 3) popped x = 4 (0). Final bonus for object : no need to push back.
( 21 9 3 7 )
Thread 3 pushed 19 to back of the queue
( 21 9 3 7 19 )
Thread 1 pushed 17 to back of the queue
( 21 9 3 7 19 17 )
Thread 3 (3, 0) popped x = 21 (1). Not matched. Need to push x - 2 back on queue
( 9 3 7 19 17 )
Thread 1 (1, 2) popped x = 9 (1). Matched. Need to push 3/5 * x back on queue
( 3 7 19 17 )
Thread 0 pushed 9 to back of the queue
( 3 7 19 17 9 )
Thread 0 (0, 1) popped x = 3 (3). Final bonus for object : no need to push back.
( 7 19 17 9 )
Thread 2 score : 4 total : 15 (*)
Thread 2 (2, 3) popped x = 7 (3). Matched. Need to push 3/5 * x back on queue
( 19 17 9 )
The dealer inserted : 20
( 19 17 9 20 )
Thread 1 score : 3 total : 39
Thread 1 pushed 6 to back of the queue
( 19 17 9 20 6 )
Thread 1 (1, 2) popped x = 19 (3). Not matched. Need to push x - 2 back on queue
( 17 9 20 6 )
Thread 3 pushed 19 to back of the queue
( 17 9 20 6 19 )
Thread 3 (3, 0) popped x = 17 (1). Not matched. Need to push x - 2 back on queue
( 9 20 6 19 )
Thread 0 score : 3 total : 19 (*)
Thread 0 (0, 1) popped x = 9 (1). Matched. Need to push 3/5 * x back on queue
( 20 6 19 )
The dealer inserted : 6
( 20 6 19 6 )
Thread 2 score : 2 total : 17
Thread 2 pushed 5 to back of the queue
( 20 6 19 6 5 )
Thread 2 (2, 3) popped x = 20 (0). Not matched. Need to push x - 2 back on queue
( 6 19 6 5 )
Thread 1 pushed 17 to back of the queue
( 6 19 6 5 17 )
Thread 1 (1, 2) popped x = 6 (2). Matched. Need to push 3/5 * x back on queue
( 19 6 5 17 )
Thread 3 pushed 15 to back of the queue
( 19 6 5 17 15 )
Thread 3 (3, 0) popped x = 19 (3). Matched. Need to push 3/5 * x back on queue
( 6 5 17 15 )
Thread 0 score : 3 total : 22
Thread 0 pushed 6 to back of the queue
( 6 5 17 15 6 )
Thread 0 (0, 1) popped x = 6 (2). Not matched. Need to push x - 2 back on queue
( 5 17 15 6 )
Thread 2 pushed 18 to back of the queue
( 5 17 15 6 18 )
Thread 2 (2, 3) popped x = 5 (1). Not matched. Need to push x - 2 back on queue
( 17 15 6 18 )
Thread 1 score : 2 total : 41
Thread 1 pushed 4 to back of the queue
( 17 15 6 18 4 )
Thread 1 (1, 2) popped x = 17 (1). Matched. Need to push 3/5 * x back on queue
( 15 6 18 4 )
Thread 3 score : 7 total : 25
Thread 3 pushed 12 to back of the queue
( 15 6 18 4 12 )
Thread 3 (3, 0) popped x = 15 (3). Matched. Need to push 3/5 * x back on queue
( 6 18 4 12 )
Thread 0 pushed 4 to back of the queue
( 6 18 4 12 4 )
Thread 0 (0, 1) popped x = 6 (2). Not matched. Need to push x - 2 back on queue
( 18 4 12 4 )
Thread 2 pushed 3 to back of the queue
( 18 4 12 4 3 )
Thread 2 (2, 3) popped x = 18 (2). Matched. Need to push 3/5 * x back on queue
( 4 12 4 3 )
Thread 1 score : 6 total : 47
Thread 1 pushed 11 to back of the queue
( 4 12 4 3 11 )
Thread 1 (1, 2) popped x = 4 (0). Final bonus for object : no need to push back.
( 12 4 3 11 )
Thread 3 score : 6 total : 31
Thread 3 pushed 9 to back of the queue
( 12 4 3 11 9 )
Thread 3 (3, 0) popped x = 12 (0). Matched. Need to push 3/5 * x back on queue
( 4 3 11 9 )
Thread 0 pushed 4 to back of the queue
( 4 3 11 9 4 )
Thread 0 (0, 1) popped x = 4 (0). Final bonus for object : no need to push back.
( 3 11 9 4 )
Thread 2 score : 7 total : 24
Thread 2 pushed 11 to back of the queue
( 3 11 9 4 11 )
Thread 2 (2, 3) popped x = 3 (3). Final bonus for object : no need to push back.
( 11 9 4 11 )
Thread 1 score : 4 total : 51 (*)
Thread 1 (1, 2) popped x = 11 (3). Not matched. Need to push x - 2 back on queue
( 9 4 11 )
Thread 3 score : 4 total : 35
Thread 3 pushed 8 to back of the queue
( 9 4 11 8 )
Thread 3 (3, 0) popped x = 9 (1). Not matched. Need to push x - 2 back on queue
( 4 11 8 )
Thread 0 score : 4 total : 26 (*)
Thread 0 (0, 1) popped x = 4 (0). Final bonus for object : no need to push back.
( 11 8 )
Thread 2 score : 3 total : 27 (*)
Thread 2 (2, 3) popped x = 11 (3). Matched. Need to push 3/5 * x back on queue
( 8 )
Thread 1 pushed 9 to back of the queue
( 8 9 )
Thread 1 (1, 2) popped x = 8 (0). Not matched. Need to push x - 2 back on queue
( 9 )
Thread 3 pushed 7 to back of the queue
( 9 7 )
Thread 3 (3, 0) popped x = 9 (1). Not matched. Need to push x - 2 back on queue
( 7 )
Thread 0 score : 4 total : 30 (*)
Thread 0 (0, 1) popped x = 7 (3). Not matched. Need to push x - 2 back on queue
( )
Thread 2 score : 4 total : 31
Thread 2 pushed 7 to back of the queue
( 7 )
Thread 2 (2, 3) popped x = 7 (3). Matched. Need to push 3/5 * x back on queue
( )
Thread 1 pushed 6 to back of the queue
( 6 )
Thread 1 (1, 2) popped x = 6 (2). Matched. Need to push 3/5 * x back on queue
( )
Thread 3 pushed 7 to back of the queue
( 7 )
Thread 3 (3, 0) popped x = 7 (3). Matched. Need to push 3/5 * x back on queue
( )
Thread 0 pushed 5 to back of the queue
( 5 )
Thread 0 (0, 1) popped x = 5 (1). Matched. Need to push 3/5 * x back on queue
( )
Thread 2 score : 2 total : 33
Thread 2 pushed 5 to back of the queue
( 5 )
Thread 2 (2, 3) popped x = 5 (1). Not matched. Need to push x - 2 back on queue
( )
Thread 1 score : 2 total : 53
Thread 1 pushed 4 to back of the queue
( 4 )
Thread 1 (1, 2) popped x = 4 (0). Final bonus for object : no need to push back.
( )
Thread 3 score : 2 total : 37
Thread 3 pushed 5 to back of the queue
( 5 )
Thread 3 (3, 0) popped x = 5 (1). Not matched. Need to push x - 2 back on queue
( )
Thread 0 score : 2 total : 32
Thread 0 pushed 3 to back of the queue
( 3 )
Thread 0 (0, 1) popped x = 3 (3). Final bonus for object : no need to push back.
( )
Thread 2 pushed 3 to back of the queue
( 3 )
Thread 2 (2, 3) popped x = 3 (3). Final bonus for object : no need to push back.
( )
Thread 1 score : 4 total : 57 (*)
Thread 3 pushed 3 to back of the queue
( 3 )
Thread 1 (1, 2) popped x = 3 (3). Final bonus for object : no need to push back.
( )
Thread 0 score : 3 total : 35 (*)
Thread 2 score : 3 total : 36 (*)
Thread 1 score : 3 total : 60 (*)
Final score for thread 0 : 35
Final score for thread 1 : 60
Final score for thread 2 : 36
Final score for thread 3 : 37