CSc 3320: System Level Programming, homework 5

As you are aware, we have lab assignments due every week. We also will have several homework assignments this semester, and this is one of those. While the labs are directed, the homework assignments present larger problems that you should break down into smaller problems. You should spend some time thinking about and planning your homework solutions before coding them.

Program Description

Purpose:
This assignment will help you conceptualize, utilize, and implement inter-process communication (IPC). Understanding how a program can be forked into multiple processes, and how those processes can communicate with each other, form a cornerstone of system-level programming.

Getting Started
Page 503 in your Unix book begins a section on pipes. Refer to the "talk.c" program on page 505. You should try it out yourself, then use it as a template to build your solution.

Task:
Create a program that sets up three processes. Two of the processes will play the Iterated Prisoner's Dilemma (a "tournament"). The other process, the parent, will coordinate the tournament, like a referee. Upon start-up, the parent will:

Next, the parent will: Finally, the parent will: Communication is done with pipes. Thus, "Tell the players" means writing a message on the pipe to player 1, and writing a message on the pipe to player 2. "Get the choice from each player" means reading the pipe from player 1 and reading the pipe from player 2.

Remember to break the problem down into smaller tasks, and work on the tasks one by one.

The Iterated Prisoner's Dilemma

The Prisoner's Dilemma is a classic game-theory model for interactions. In it, two players must choose between cooperate (with each other) and defect (against the other). Since the choice is simultaneous, each one does not know what the other will choose.

The following table shows a typical pay-off matrix. The pay-offs, or scores, are what each player gets at the end of the round. For example, if player 1 cooperates and player 2 defects, player 1 scores 0 while player 2 scores 5.

Player 2 CooperatesPlayer 2 Defects
Player 1 Cooperates3/30/5
Player 1 Defects5/01/1
You could have a single round of the Prisoner's Dilemma, however, the "Iterated" version means that the two players will play for several rounds. The scores will accumulate over the course of the rounds.

IPC

Create a program that forks twice. The two child processes will communicate with the parent process via pipes. Each child process needs 2 pipes, one to send data to the parent, and the other to receive data from the parent. Thus, your program will need to implement a minimum of 4 pipes. The child processes will play the Iterated Prisoner's Dilemma, with the parent process coordinating the tournament, and keeping track of the scores. Each message will be a single character.

The parent will send one of the following to the child processes.

CharMeaningResult
Rget ReadyChild process replies with Y
PPlayChild process replies with move (C or D)
QQuitChild process exits
0ZeroThe child process scored 0 that round
1OneThe child process scored 1 that round
3ThreeThe child process scored 3 that round
5FiveThe child process scored 5 that round
The parent process should "wait()" for each child to exit before returning (or exiting) itself.

Each player sends "Y" to indicate that it is ready, only after receiving "R". Each player sends either "C" or "D", to cooperate or defect, only after receiving "P". Each player will receive "0", "1", "3", or "5" shortly after sending its cooperate/defect choice. This allows the player to know the result, and indirectly, what the other player chose. Each player should quit when it receives "Q". It does not send anything back to the player at that point.

How should the players decide what move to make? You can determine this. Your players could base their next moves on the score(s) from the last round(s), or they could ignore the score. (They are required to read it, however.) See strategies for a list of strategies that you can use.
According to your first and last name, implement the strategies below.
Name starts with, strategy to implement for one side
A-D, Unconditional Cooperator
E-K, Unconditional Defector
L-O, Random
P-R, Probability p Cooperator
S-T, Tit for Tat
U-Y, Tit for Two Tats
Z, One of the others on the list

i.e. a student named David Smith should implement Unconditional Cooperator for one player, and Tit for Tat for the other.

Running Your Program

When running your program, the user might pass "-h" as a command-line argument. If so, your program should print a "help" message about what the program does, and quit. It does not matter which argument is "-h"; if it is there, your program should print a "help" message about what the program does, and quit.

When running your program, the user might pass a number as a command-line argument. If so, your program should use that as the number of iterations. You should use "strtoimax" to convert the number from a string.

Any unusual command-line argument should be noted. Your program should indicate that the argument does not make sense and repeat the argument back, (i.e. "Argument "YOLO" does not make sense") print a "help" message about what the program does, and quit.

Criteria:
The ultimate goal is to have a program that solves the problem. Each task should have a test associated with it, to verify that it works. When all tasks have working solutions, they should all work together to solve the problem. Keep in mind that we will check to see what tasks are completed, and if your program does not solve the problem, it will still receive partial credit.