Alignement

A 4th year Computer Science project, the goal was to use 2 child processes to play a game of Alignement. The rule of the game is fairly simple: 2 player play against each other on a 6 by 6 grid. Each turn, a player places a token anywhere on the grid that hasn’t been taken. The game continues until the grid is full, then the points are tallied. 2 aligned tokens are worth 5 points, 3 10 points, 4 are worth 20, 5 40, and 6 80 points. The winner is the player that has the most points.

By using forks, the main process creates 2 child processes that will play the game. The communication between the 2 processes are done by changing the standard output of a command using tubes. This is to make sure one of the child process is waiting for the other to be done its turn. The read() and write() commands are very important for this project. When the read() function has been called by a process, it just waits. This allows the player to take its time and think of its next move. That’s why the beginning of the player’s process starts with a read() function and ends with the write(). Once the grid is filled, one of the process tallies the points and writes the results that are then read by the father’s standard input. Finally, the father process calls the winner.

Code


  /*Simon Chiasson-St-Coeur
   *A00160309
   *esc7425
   */
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctime>

  using namespace std;

bool caseOccup;
int x, y;


//Affichage de la grille
void afficherGrille(char tab[][6])
{
  printf("%c|%c|%c|%c|%c|%c\n-----------\n",
	 tab[0][5],
	 tab[1][5],
	 tab[2][5],
	 tab[3][5],
	 tab[4][5],
	 tab[5][5]);
  printf("%c|%c|%c|%c|%c|%c\n-----------\n",
	 tab[0][4],
	 tab[1][4],
	 tab[2][4],
	 tab[3][4],
	 tab[4][4],
	 tab[5][4]);
  printf("%c|%c|%c|%c|%c|%c\n-----------\n",
	 tab[0][3],
	 tab[1][3],
	 tab[2][3],
	 tab[3][3],
	 tab[4][3],
	 tab[5][3]);
  printf("%c|%c|%c|%c|%c|%c\n-----------\n",
	 tab[0][2],
	 tab[1][2],
	 tab[2][2],
	 tab[3][2],
	 tab[4][2],
	 tab[5][2]);
  printf("%c|%c|%c|%c|%c|%c\n-----------\n",
	 tab[0][1],
	 tab[1][1],
	 tab[2][1],
	 tab[3][1],
	 tab[4][1],
	 tab[5][1]);
  printf("%c|%c|%c|%c|%c|%c\n",
	 tab[0][0],
	 tab[1][0],
	 tab[2][0],
	 tab[3][0],
	 tab[4][0],
	 tab[5][0]);
}


//Humain: O, Machine: X
void placerJeton(int x, int y, char pion, char tab[][6])
{
  tab[x][y] = pion;
}



int coup_Gagnant(char jeton, char tab[][6])
{
  int cur_count = 1;
  int max_length = 1;
  int point = 0;


  //Compte les point des lignes
  for(int i = 0; i < 6; i++)
    {
      for (int j = 0; j < 5; j++)
    	{
	  if(tab[j][i] == jeton && tab[j+1][i] == jeton)
	    cur_count++;

	  else
            {
	      switch(cur_count){
	      case 2: point = point + 5; break;
	      case 3: point = point + 10;break;
	      case 4: point = point + 20;break;
	      case 5: point = point + 40;break;
	      case 6: point = point + 80;break;
	      default: break;
	      }
	      cur_count = 1;
            }
    	}
    }


  //Compte les point sur les colonnes
  for(int i = 0; i < 6; i++)
    {
      for (int j = 0; j < 5; j++)
    	{
	  if(tab[i][j] == jeton && tab[i][j+1] == jeton)
	    cur_count++;

	  else
            {
	      switch(cur_count){
	      case 2: point = point + 5; break;
	      case 3: point = point + 10;break;
	      case 4: point = point + 20;break;
	      case 5: point = point + 40;break;
	      case 6: point = point + 80;break;
	      default: break;
	      }
	      cur_count = 1;
            }
    	}
    }

  return point;
};//coup_Gagnant


int main()
{
  int i, j, n, status, count, pointJoueur, pointMachine;
  pid_t fils1, fils2, pid;
  int p[2];
  pipe(p);
  bool cont = false;
  srand(time(nullptr));

  int n = 6;
  char grille[n][n];

  //Initialisation de la grille
  for(i = 0; i < n; i++)
    for(j=0; j<n; j++)
      grille[i][j] = ' ';
  count=0;

  if((fils1 = fork()) < 0 ){
    printf("Erreur au premier fork\n");
    exit(1);
  }

  //processus de la machine
  else if (fils1 == 0)
    {
      while(count < 36)
        {
	  do{
            x = rand()%6;
            y = rand()%6;

            if(grille[x][y] == ' ')
	      caseOccup = false;
            else
	      caseOccup = true;

	  }while(caseOccup); //Tant que la case est occupe, on en choisi une autre

	  write(p[1], &x, sizeof(x));
	  write(p[1], &y, sizeof(y));
	  write(p[1], &count, sizeof(count));
	  placerJeton(x, y, 'X', grille); //ecriture du jeton de la machine dans la grille de la machine

	  sleep(2);//sleep a des fin de synchronisation.
	  read(p[0], &i, sizeof(x));
	  read(p[0], &j, sizeof(y));
	  read(p[0], &count, sizeof(count));

	  placerJeton(i, j, 'O', grille);//ecriture du jeton du joueur dans la grille de la machine
	  count++;//inc. du count afin de savoir si la grille est pleine.
	}//while

      exit(0);
    }//elseif

  if ((fils2 = fork()) < 0)
    {
      printf("Erreur au 2ieme fork\n");
      exit(1);
    }

  //processus du joueur
  else if(fils2 == 0)
    {
      while(count < 35)
        {
	  read(p[0], &x, sizeof(x));
	  read(p[0], &y, sizeof(y));
	  read(p[0], &count, sizeof(count));

	  placerJeton(x, y, 'X', grille);//ecriture du jeton machine dans la grille du joueur
	  count++;//inc. du count afin de savoir si la grille est pleine
	  afficherGrille(grille);


	  do{
            printf("Entrez une coordonner:\n");

	    //COMMENT OUT THIS LINE IF YOU WOULD LIKE TO AUTOMATE THE TEST
            scanf("%d", &i); scanf("%d", &j);


   	    //UN-COMMENT THIS LINE IF YOU WOULD LIKE TO AUTOMATE THE TEST
	    //i = (rand()+5*8/4)%6; j = rand()%6;
            
	    
	    
	    if(grille[i][j] == ' ')
	      caseOccup = false;
            else if(i > 5 || j > 5)
	      {
                printf("La case doit etre entre 0 et 5\n");
                caseOccup = true;
	      }
            else
	      {
		printf("La case est deja choici, veuillez en prendre une autre\n");
		caseOccup = true;
	      }
	  }while(caseOccup); //Tant que la case est occupe, on demande d'en choisir une autre

	  write(p[1], &i, sizeof(i));
	  write(p[1], &j, sizeof(j));
	  write(p[1], &count, sizeof(count));
	  placerJeton(i, j, 'O', grille);//ecriture du jeton du joueur dans la grille du joueur

	  sleep(2);//Sleep a des fins de synchronisation.
        }//while

      //Calcul des pointages
      x = coup_Gagnant('O', grille);
      y = coup_Gagnant('X', grille);


      //Ecriture des pointages
      write(p[1], &x, sizeof(x));
      write(p[1], &y, sizeof(y));
      afficherGrille(grille);
      exit(0);
    }//elseif


  //Le pere attend qu’une partie se termine.
  pid = wait(&status);
  pid = wait(&status);

  //Match est termine, lecture des pointage
  read(p[0], &pointJoueur, sizeof(pointJoueur));
  read(p[0], &pointMachine, sizeof(pointMachine));

  //Affichage du gagnant
  if(pointJoueur > pointMachine)
    printf("HUMAIN\n");
  else if(pointJoueur < pointMachine)
    printf("ORDINATEUR\n");
  else
    printf("EGAL\n");

  exit(0);
} // main()