#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <signal.h>

void print_choice(char *who, int choice);
int compare_choices(int my_choice, int other_choice); /*
	compare choices, return 0 on tie, 1 on my win, -1 on my loss */
void play_game(int my_choice_pipe, int result_pipe);

int main(int argc, char *argv[]) {
int pipe1[2], pipe2[2];
int pipe3[2], pipe4[2];
pid_t player1, player2;
int my_choice, other_choice, score = 0, tries = 0, result, result2;


if ((pipe(pipe1) == -1) || (pipe(pipe2) == -1)) {
	perror("Creating pipe");
	exit(1);
}

player1 = fork();
if (player1 == -1) {
	perror("Creating opponent");
	exit(1);
}
else if (player1 == 0) { /* child1 */
	close(pipe1[0]);
	close(pipe2[1]);
	play_game(pipe1[1], pipe2[0]);
	close(pipe1[1]);
	close(pipe2[0]);
	return 0;
}

/* parent continues here - close unused pipe ends */
close(pipe1[1]);
close(pipe2[0]);

/* create second child */
if ((pipe(pipe3) == -1) || (pipe(pipe4) == -1)) {
	perror("Creating pipe");
	/* terminate player 1 */
	kill(player1, SIGINT);
	exit(1);
}

player2 = fork();
if (player2 == -1) {
	perror("Creating opponent");
	/* terminate player 1 */
	kill(player1, SIGINT);
	exit(1);
}
else if (player2 == 0) { /* child1 */
	/* close pipes for parent communication with first child */
	close(pipe1[0]);
	close(pipe2[1]);

	/* close unused pipe ends */
	close(pipe3[0]);
	close(pipe4[1]);
	play_game(pipe3[1], pipe4[0]);
	close(pipe3[1]);
	close(pipe4[0]);
	return 0;
}

/* referree here */
for (tries = 0; tries < 10; tries++) {
	read(pipe1[0], &my_choice, sizeof(int));
	read(pipe3[0], &other_choice, sizeof(int));
	print_choice("player 1", my_choice);
	print_choice("player 2", other_choice);
	result = compare_choices(my_choice, other_choice);
	if (result == 0) printf("tie\n");
	else if (result > 0) printf("player 1 wins\n");
	else printf("player 2 wins\n");
	write(pipe2[1], &result, sizeof(int));
	result2 = -result;
	write(pipe4[1], &result2, sizeof(int));
	score += result;
}
if (score == 0) printf("Final result is a tie\n");
else if (score > 0) printf("player one wins by %d\n", score);
else printf("player two wins by %d\n", -score);
close(pipe1[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe4[1]);

wait(NULL);
wait(NULL);
return 0;
}

void print_choice(char *who, int choice) {
static char *descr[] = {"petra", "psalidi", "xarti", "AKYROS KWDIKOS"};
char *theDesc;

if ((choice >= 0) && (choice <= 2))
	theDesc = descr[choice];
else
	theDesc = descr[3];
printf("%s: %s\n", who, theDesc);
}


int compare_choices(int my_choice, int other_choice) {

if (my_choice == other_choice) return 0;
else if ((my_choice == 0 && other_choice == 1) ||
	 (my_choice == 1 && other_choice == 2) ||
	 (my_choice == 2 && other_choice == 0))
	return 1;
else return -1;
}


void play_game(int my_choice_pipe, int result_pipe) {
	/* play game sending my choices from my_choice_pipe and
	receiving referree decisions from result_pipe */
int my_choice, result, tries;
struct timeval tv;

gettimeofday(&tv, NULL);
srand(tv.tv_usec);

for (tries = 0; tries < 10; tries++) {
	my_choice = rand() % 3;
	write(my_choice_pipe, &my_choice, sizeof(int));
	read(result_pipe, &result, sizeof(int));
	if (result < 0) printf("child %ld: boo-hoo, i loose!\n", (long)(getpid()));
	else if (result == 0) printf("child %ld: could be worse!\n", (long)(getpid()));
	else printf("child %ld: yupiiiiie!\n", (long)(getpid()));
}
return;
}
