User:Gregory.Szorc/EECS 338 Homework 2

 
//Gregory Szorc <gregory.szorc@case.edu>
//EECS 338 HW 2
//2005-09-29
 
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
 
void parentGameCoordinator();
void childGamePlayer(int inputPipe[], int outputPipe[]);
int getNextResponse(int inputPipe[]);
int getProcessId(int inputPipe[]);
int getWeapon(int inputPipe[]);
char * getWeaponName(int weapon);
 
//the protocol between the parent and children consists of two fields
//1) the action type of the message
//2) the value of the message
 
//specifies a packet containing the round result
const char * actionRoundResult = "0";
 
//query packet for what child process wants to do
const char * actionNextQuery = "1";
 
//response from above query packet
const char * actionNextResponse = "2";
 
//the chosen weapon
const char * actionRoundSelection = "3";
 
//the process id
const char * actionProcessId = "4";
 
//from parent to child telling to terminate
const char * actionEnd = "5";
 
const char * actionGetProcessId = "6";
const char * actionGetWeapon = "7";
 
const char * roundResponseNext = "0";
const char * roundResponseEnd = "1";
 
const char * roundResultWon = "0";
const char * roundResultLost = "1";
const char * roundResultDraw = "2";
 
const int weaponRock = 0;
const int weaponPaper = 1;
const int weaponScissors = 2;
 
int main(int argc, char *argv[])
{
  parentGameCoordinator();
 
  return EXIT_SUCCESS;
}
 
void parentGameCoordinator() {
  int roundNumber = 1;
 
  int player1InputPipe[2];
  int player1OutputPipe[2];
  pid_t player1Pid;
  int player1Process;
  int player1InputPipeStatus;
  int player1OutputPipeStatus;
  double player1Score = 0;
  
  int player2InputPipe[2];
  int player2OutputPipe[2];
  pid_t player2Pid;
  int player2Process;
  int player2InputPipeStatus;
  int player2OutputPipeStatus;
  double player2Score = 0;
  
  int player1Continue = 1;
  int player2Continue = 1;
  
  int player1Weapon;
  int player2Weapon;
  
  char read1Action[2];
  char read2Action[2];
  int read1Value;
  int read2Value;
  
  int winner = 0;
  
  //create the pipes
  player1InputPipeStatus = pipe(player1InputPipe);
  if (player1InputPipeStatus == -1) {
    perror("Player 1 input pipe not created");
    exit(EXIT_FAILURE);
  }
  
  player1OutputPipeStatus = pipe(player1OutputPipe);
  if (player1OutputPipeStatus == -1) {
    perror("Player 1 output pipe not created");
    exit(EXIT_FAILURE);
  }
  
  player2InputPipeStatus = pipe(player2InputPipe);
  if (player2InputPipeStatus == -1) {
    perror("Player 2 input pipe not created");
    exit(EXIT_FAILURE);
  }
  
  player2OutputPipeStatus = pipe(player2OutputPipe);
  if (player2OutputPipeStatus == -1) {
    perror("Player 2 output pipe not created");
    exit(EXIT_FAILURE);
  }
  
  
  player1Pid = fork();
  
  switch (player1Pid) {
    case -1:
        perror("fork of player 1 failed");
        exit(1);
    case 0:
        //inside child process
        childGamePlayer(player1InputPipe, player1OutputPipe);
        exit(EXIT_SUCCESS);
        //never reached
    default:
        //inside parent process
        player2Pid = fork();
        
        switch (player2Pid) {
          case -1:
            perror("fork of player 2 failed");
            exit(EXIT_FAILURE);
          case 0:
            //inside child process
            childGamePlayer(player2InputPipe, player2OutputPipe);
            exit(EXIT_SUCCESS);
            //never reached
          default:
          //inside parent process
          //both children processes have been forked now
          
          //ask the children for their process number
          write(player1InputPipe[1], actionGetProcessId, 2);
          write(player2InputPipe[1], actionGetProcessId, 2);
          
          player1Process = getProcessId(player1OutputPipe);
          player2Process = getProcessId(player2OutputPipe);
          
          player1Process = player1Pid;
          player2Process = player2Pid;
          
          while (player1Continue && player2Continue) {
            //start by asking the children what they want to do
            if (write(player1InputPipe[1], actionNextQuery, 2) == -1) {
                perror("failed to write to player 1\n");
            }
            
            if (write(player2InputPipe[1], actionNextQuery, 2) == -1) {
                perror("failed to write to player 2\n");
            }
            
            
            read1Value = getNextResponse(player1OutputPipe);
            read2Value = getNextResponse(player2OutputPipe);
            
            if (read1Value != atoi(roundResponseNext)) {
                player1Continue = 0; 
            }
            
            if (read2Value != atoi(roundResponseNext)) {
                player2Continue = 0;
            }
            
            //if both want to play the game
            if (player1Continue && player2Continue) {
                printf("Round #%i\n", roundNumber);
                roundNumber++;
                write(player1InputPipe[1], actionGetWeapon, 2);
                write(player2InputPipe[1], actionGetWeapon, 2);
                
                player1Weapon = getWeapon(player1OutputPipe);
                player2Weapon = getWeapon(player2OutputPipe);
                
                printf("Player %d: %s\n", player1Process, getWeaponName(player1Weapon));
                printf("Player %d: %s\n", player2Process, getWeaponName(player2Weapon));
                
                winner = -1;
                
                if (player1Weapon == weaponRock) {
                    if (player2Weapon == weaponScissors) winner = player1Process;
                    if (player2Weapon == weaponPaper) winner = player2Process;
                }
                
                if (player1Weapon == weaponScissors) {
                    if (player2Weapon == weaponRock) winner = player2Process;
                    if (player2Weapon == weaponPaper) winner = player1Process;
                }
                
                if (player1Weapon == weaponPaper) {
                    if (player2Weapon == weaponRock) winner  = player1Process;
                    if (player2Weapon == weaponScissors) winner = player2Process;
                }
                
                write(player1InputPipe[1], actionRoundResult, 2);
                write(player2InputPipe[1], actionRoundResult, 2);
                
                if (winner == -1) {
                    printf("Draw\n");
                    player1Score += 0.5;
                    player2Score += 0.5;
                    
                    write(player1InputPipe[1], roundResultDraw, 2);
                    write(player2InputPipe[1], roundResultDraw, 2);
                    
                }
                else {
                    printf("Player %d Win\n", winner);
                    
                    if (winner = player1Process) {
                        player1Score += 1;
                        write(player1InputPipe[1], roundResultWon, 2);
                        write(player2InputPipe[1], roundResultLost, 2);
                    }
                    else if (winner = player2Process) {
                        player2Score += 1;
                        write(player1InputPipe[1], roundResultLost, 2);
                        write(player2InputPipe[1], roundResultWon, 2);
                    }
                }
                
                
                
                printf("\n");
            }
            //else the while loop doesn't repeat
            
          }
          
          //printf("a child has requested to stop\n");
          //tell the players to end
          write(player1InputPipe[1], actionEnd, 2);
          write(player2InputPipe[1], actionEnd, 2);
          
          printf("Final Score:\n");
          printf("Player %d: %.1f\n", player1Process, player1Score);
          printf("Player %d: %.1f\n", player2Process, player2Score);
          
        }
        
  }
  
}
 
int getNextResponse(int inputPipe[]) {
    char inputAction[2];
    char inputValue[2];
    
    while (read(inputPipe[0], inputAction, 2) > 0) {
        if (strcmp(inputAction, actionNextResponse) == 0) {
            while (read(inputPipe[0], inputValue, 2) > 0) {
            
                return atoi(inputValue);
            }
        }
    }
    
    return -1;
}
 
int getProcessId(int inputPipe[]) {
    char inputAction[2];
    char inputValue[2];
    
    while (read(inputPipe[0], inputAction, 2) > 0) {
        if (strcmp(inputAction, actionProcessId) == 0) {
            while (read(inputPipe[0], inputValue, 2) > 0) {
                return atoi(inputValue);
            }
        }
    }
    
    return -1;
}
 
int getWeapon(int inputPipe[]) {
    char inputAction[2];
    char inputValue[2];
    
    while (read(inputPipe[0], inputAction, 2) > 0) {
        if (strcmp(inputAction, actionRoundSelection) == 0) {
            while (read(inputPipe[0], inputValue, 2) > 0) {
                return atoi(inputValue);
            }
        }
    }
    
    return -1;
}
 
char* getWeaponName(int Weapon) {
    if (Weapon == weaponRock) {
        return "rock";
    }
    else if (Weapon == weaponPaper) {
        return "paper"; 
    }
    else if (Weapon == weaponScissors) {
        return "scissors";
    }
    else {
        return "UNKNOWN";
    }
}
 
//inputPipe gets input from parent
//outputPipe writes to the parent
void childGamePlayer(int inputPipe[], int outputPipe[]) {
  pid_t process;
  char processString[16];
  
  int readStatus;
  int writeStatus;
  
  //holds data from pipe (one byte larger than necessary)
  char readAction[2];
  char readValue[2];
  
  int roundsToPlay = 0;
  int roundsPlayed = 0;
  int drawsPlayed = 0;
  
  int chosenWeapon = 0;
  char chosenWeaponString[16];
  
  int lastRoundResult = 0;
  int opponentWeapon = 0;
  
  int opponentRockCount = 0;
  int opponentPaperCount = 0;
  int opponentScissorCount = 0;
  
  int opponentRockFollowPaperCount = 0;
  int opponentRockFollowScissorCount = 0;
  int opponentRockFollowRockCount = 0;
  
  int opponentPaperFollowPaperCount = 0;
  int opponentPaperFollowScissorCount = 0;
  int opponentPaperFollowRockCount = 0;
  
  int opponentScissorFollowPaperCount = 0;
  int opponentScissorFollowScissorCount = 0;
  int opponentScissorFollowRockCount = 0;
  
  int opponentSameFollowDrawCount = 0;
  
  int opponentLastWeapon = 0;
  
  int selectRock = 0;
  int selectPaper = 0;
  int selectScissors = 0;
  
  process = getpid();
  sprintf(processString, "%d", getpid());
  
  //at most play 100 rounds
  roundsToPlay = 10 + ((rand() * process) % 90);
  
  
  //close uncessary part of pipes
  close(inputPipe[1]);
  close(outputPipe[0]);
  
  printf("in player process\n");
 
  
  //enter an infinite loop
  while (1) {
    //read the action code from the input pipe
    while ((readStatus = read(inputPipe[0], readAction, 2)) > 0) {
        //printf("Read action byte = %s\n", readAction);
        
        //if the parent is telling us to stop execution
        if (strcmp(readAction, actionEnd) == 0) {
            //printf("Child terminating\n");
            exit(EXIT_SUCCESS);
        }
        
        if (strcmp(readAction, actionNextQuery) == 0) {
            //printf("parent asking what to do\n");
            
            write(outputPipe[1], actionNextResponse, 2);
            
            if (roundsPlayed < roundsToPlay) {
                roundsPlayed++;
                //printf("child wants to play more\n");
                write(outputPipe[1], roundResponseNext, 2);
            }
            else {
                //printf("we don't want to play anymore\n");
                write(outputPipe[1], roundResponseEnd, 2);
            }
        }
        
        if (strcmp(readAction, actionGetProcessId) == 0) {
            //printf("parent asking for process id\n");
            
            write(outputPipe[1], actionProcessId, 2);
            write(outputPipe[1], processString, 2);
            
        }
        
        
        if (strcmp(readAction, actionGetWeapon) == 0) {
            //printf("parent asking for our weapon\n");
            
            //let's select a weapon based upon what our opponent has done
            //we give points to a certain weapon based upon previous results
            //the weapon with the most points wins the selection process
            
            //reset the scores to 0
            selectRock = 0;
            selectPaper = 0;
            selectScissors = 0;
            
            //we assign 5 points to every weapon for each time it could have won a round
            selectRock += 5 * (roundsPlayed - opponentScissorCount);
            selectPaper += 5 * (roundsPlayed - opponentRockCount);
            selectScissors += 5 * (roundsPlayed - opponentPaperCount);
            
            //handle points based on the last weapon
            if (opponentLastWeapon == weaponRock) {
                //if there is a good chance that a certain weapon will follow the rock
                if (opponentRockFollowRockCount / roundsPlayed > 0.2) {
                    selectPaper += 50 * opponentRockFollowRockCount / roundsPlayed;
                }
                
                if (opponentPaperFollowRockCount / roundsPlayed > 0.2) {
                    selectScissors += 50 * opponentPaperFollowRockCount / roundsPlayed;
                }
                
                if (opponentScissorFollowRockCount / roundsPlayed > 0.2) {
                    selectRock += 50 * opponentScissorFollowRockCount / roundsPlayed;
                }
            }
            else if (opponentLastWeapon == weaponPaper) {
                if (opponentRockFollowPaperCount / roundsPlayed > 0.2) {
                    selectPaper += 50 * opponentRockFollowPaperCount / roundsPlayed;
                }
                
                if (opponentPaperFollowPaperCount / roundsPlayed > 0.2) {
                    selectScissors += 50 * opponentPaperFollowPaperCount / roundsPlayed;
                }
                
                if (opponentScissorFollowPaperCount / roundsPlayed > 0.2) {
                    selectRock += 50 * opponentScissorFollowPaperCount / roundsPlayed;
                }
            }
            else if (opponentLastWeapon == weaponScissors) {
                if (opponentRockFollowScissorCount / roundsPlayed > 0.2) {
                    selectPaper += 50 * opponentRockFollowScissorCount / roundsPlayed;
                }
                
                if (opponentPaperFollowScissorCount / roundsPlayed > 0.2) {
                    selectScissors += 50 * opponentPaperFollowScissorCount / roundsPlayed > 0.2;
                }
                
                if (opponentScissorFollowScissorCount / roundsPlayed > 0.2) {
                    selectRock += 50 * opponentScissorFollowScissorCount / roundsPlayed;
                }
            }
            
            //if the last round was a chosenWeapon = ((rand() * process) ^ 2 * process) % 3;draw
            if (lastRoundResult == atoi(roundResultDraw)) {
                //if the opponent is likely to repeat the same weapon on a draw
                if (drawsPlayed && (opponentSameFollowDrawCount / drawsPlayed > 0.5)) {
                    if (opponentLastWeapon == weaponRock) {
                        selectPaper += 20 * drawsPlayed;
                    }
                    
                    if (opponentLastWeapon == weaponPaper) {
                        selectScissors += 20 * drawsPlayed;
                    }
                    
                    if (opponentLastWeapon == weaponScissors) {
                        selectRock += 20 * drawsPlayed;
                    }
                }
            }
            
            //randomness is part of every game
            selectRock += (rand() * process ^ (rand() % 10)) % (2 * roundsPlayed);
            selectPaper += (rand() * process ^ (rand() % 10)) % (2 * roundsPlayed);
            selectScissors += (rand() * process ^ (rand() % 10)) % (2 * roundsPlayed);
            
            //printf("Rock: %d\nPaper: %d\nScissors: %d\n", selectRock, selectPaper, selectScissors);
            
            //if rock is a clear winner
            if (selectRock > selectPaper && selectRock > selectScissors) {
                chosenWeapon = weaponRock;
            }
            //if paper is a clear winner
            else if (selectPaper > selectRock && selectPaper > selectScissors) {
                chosenWeapon = weaponPaper;
            }
            //if scissors is a clear winner
            else if (selectScissors > selectRock && selectScissors > selectPaper) {
                chosenWeapon = weaponScissors;
            }
            else {
                //if there is a tie
                //we just chose a random weapon
                chosenWeapon = (process ^ (rand() % 10) * process) % 3;
                
            }
            
            sprintf(chosenWeaponString, "%d", chosenWeapon);
            
            write(outputPipe[1], actionRoundSelection, 2);
            write(outputPipe[1], chosenWeaponString, 2);
        }
        
        if (strcmp(readAction, actionRoundResult) == 0) {
            read(inputPipe[0], readValue, 2);
            
            lastRoundResult = atoi(readValue);
            
            if (strcmp(readValue, roundResultWon) == 0) {
              if (chosenWeapon == weaponRock) opponentWeapon = weaponScissors;
              if (chosenWeapon == weaponPaper) opponentWeapon = weaponRock;
              if (chosenWeapon == weaponScissors) opponentWeapon = weaponPaper;
            }
            else if (strcmp(readValue, roundResultLost) == 0) {
              if (chosenWeapon == weaponRock) opponentWeapon = weaponPaper;
              if (chosenWeapon == weaponPaper) opponentWeapon = weaponScissors;
              if (chosenWeapon == weaponScissors) opponentWeapon = weaponRock;
            }
            else if (strcmp(readValue, roundResultDraw) == 0) {
              opponentWeapon = chosenWeapon;
              drawsPlayed++;
              
              if (opponentWeapon == opponentLastWeapon) {
                opponentSameFollowDrawCount++;
              }
            }
            
            //now collect some statistics
            
            if (opponentWeapon == weaponRock) {
                opponentRockCount++;
            }
            
            if (opponentWeapon == weaponScissors) {
                opponentScissorCount++;
            }
            
            if (opponentWeapon == weaponPaper) {
                opponentPaperCount++;
            }
            
            if (opponentLastWeapon == weaponRock) {
                if (opponentWeapon == weaponRock) {
                    opponentRockFollowRockCount++;
                }
                
                if (opponentWeapon == weaponPaper) {
                    opponentPaperFollowRockCount++;
                }
                
                if (opponentWeapon == weaponScissors) {
                    opponentScissorFollowRockCount++;
                }
            }
            else if (opponentLastWeapon == weaponPaper) {
                if (opponentWeapon == weaponRock) {
                    opponentRockFollowPaperCount++;
                }
                
                if (opponentWeapon == weaponPaper) {
                    opponentPaperFollowPaperCount++;
                }
                
                if (opponentWeapon == weaponScissors) {
                    opponentScissorFollowPaperCount++;
                }
            }
            else if (opponentLastWeapon == weaponScissors) {
                if (opponentWeapon == weaponRock) {
                    opponentRockFollowScissorCount++;
                }
                
                if (opponentWeapon == weaponPaper) {
                    opponentPaperFollowScissorCount++;
                }
                
                if (opponentWeapon == weaponScissors) {
                    opponentScissorFollowScissorCount++;
                }
            }
            
            
            
            opponentLastWeapon = opponentWeapon;
        }
        
        /*
        //data comes in pairs, so read the 2nd byte
        while ((readStatus = read(inputPipe[0], readValue, 1)) > 0) {
            //do our action
            
            printf("Read value byte = %s\n", readValue);
        }
        */
    }
  }
  
  
}
 
This page has been accessed 1,445 times.
This page was last modified 14:16, October 20, 2005 by Gregory Szorc.
About | Disclaimers