Il gioco del Tris (o tic-tac-toe)

Visto che non conoscete bene matrici e funzioni, ho allungato la consegna dell' HomeWork2.


Versione che non usa funzioni

L'implementazione può essere chiaramente migliorata:

  • usando i simboli x e o invece che 0 e 1
  • controllando ciascuna diagonale solo se la mossa corrente vi appartiene

#include <stdio.h>

int main() {
   int M[3][3] = { 0 };
   int winner=0,x,y,k,i,player=1,trovato;
   
   // eseguo al più 9 mosse
   for (k=0 ; k<9 ; k---++) {
      // stampo la matrice
      printf("  ");
      for (y=0 ; y<3 ; y---++)
         printf(" %d",y);
      printf("\n");
      for (x=0 ; x<3 ; x---++) {
         printf("%d |",x);
         for (y=0 ; y<3 ; y---++)
            if (M[x][y])
               printf("%d|",M[x][y]);
            else 
               printf(" |");
         printf("\n");
      }

      // leggo la mossa e la richiedo finche' non è valida
      while (1) {
         printf("Gioca %d :",player);
         scanf("%d%d",&x,&y);
         if (x>2 || x<0 || y>2 || y<0 || M[x][y] != 0 ) {
            printf("Mossa non valida\n");
            continue;
         }
         // la mossa è valida, esco
         break;
      }

      // la mosa è valida, la gioco
      M[x][y] = player;

      // controllo la riga
      trovato = 1;
      for (i=0 ; i<3 ; i---++)
         if (M[x][i] != player)
            trovato = 0;
      if (trovato) {
         winner = player;
         break; // esco dal for
      }
      
      // controllo la colonna
      trovato = 1;
      for (i=0 ; i<3 ; i---++)
         if (M[i][y] != player)
            trovato = 0;
      if (trovato) {
         winner = player;
         break; // esco dal for
      }

      // controllo la diagonale \
      trovato = 1;
      for (i=0 ; i<3 ; i---++)
         if (M[i][i] != player)
            trovato = 0;
      if (trovato) {
         winner = player;
         break; // esco dal for
      }

      // controllo la diagonale /
      trovato = 1;
      for (i=0 ; i<3 ; i---++)
         if (M[i][2-i] != player)
            trovato = 0;
      if (trovato) {
         winner = player;
         break; // esco dal for
      }
      
      // passo all'altro giocatore
      player = (player == 1 ? 2 : 1);
   } // fine del for per le 9 mosse

   // stampo la situazione finale
   printf("  ");
   for (y=0 ; y<3 ; y---++)
      printf(" %d",y);
   printf("\n");
   for (x=0 ; x<3 ; x---++) {
      printf("%d |",x);
      for (y=0 ; y<3 ; y---++)
         if (M[x][y])
            printf("%d|",M[x][y]);
         else 
            printf(" |");
      printf("\n");
   }

   // e faccio sapere chi ha vinto
   if (winner)
      printf("Ha vinto il giocatore %d\n",winner);
   else
      printf("Partita patta.\n");
   return 0;
}


Versione che usa le funzioni

L'implementazione può essere chiaramente migliorata:

  • usando i simboli x e o invece che 0 e 1
  • considerando che la terna di segni uguali che fa vincere deve necessariamente contenere l'ultimo simbolo inserito, e quindi che il test per la vittoria può essere molto più semplice.
  • controllando ciascuna diagonale solo se la mossa corrente vi appartiene

#include <stdio.h>

// test se la partita è finita (3 dello stesso tipo in fila)
// torna il numero di chi vince
int haVinto(int matrice[3][3]) {
   // righe
   int x; // coordinate nella matrice
   for (x=0 ; x<3 ; x---++) {
      // tre in riga
      if (matrice[x][0] != 0 && matrice[x][0] == matrice[x][1] && matrice[x][1] == matrice[x][2])
             return matrice[x][0];
      // tre in colonna
      if (matrice[0][x] != 0 && matrice[0][x] == matrice[1][x] && matrice[1][x] == matrice[2][x])
             return matrice[0][x];
   }
   // tre in diagonale
   if (matrice[0][0] != 0 && matrice[0][0] == matrice[1][1] && matrice[1][1] == matrice[2][2])
          return matrice[0][0];
   if (matrice[0][2] != 0 && matrice[0][2] == matrice[1][1] && matrice[1][1] == matrice[2][0])
          return matrice[0][2];
   // altrimenti si torna 0
   return 0;
}

// test se la mossa è valida (la casella è vuota)
int mossaValida(int M[3][3], int x, int y) {
   if (x>2 || x<0 || y>2 || y<0)
      return 0;
   return (!M[x][y]);
}

// gioca la mossa (memorizza il giocatore nella casella)
void giocaMossa(int M[3][3], int x, int y, int player) {
   M[x][y] = player;
}

int ciSonoMosseValide(int M[3][3]) {
   int x,y;
   for (x=0 ; x<3 ; x---++)
      for (y=0 ; y<3 ; y---++)
         if (!M[x][y])
            return 1;
   return 0;
}


// mostra la scacchiera
void stampa(int M[3][3]){
   int x,y;
   printf("  ");
   for (y=0 ; y<3 ; y---++)
      printf(" %d",y);
   printf("\n");
   for (x=0 ; x<3 ; x---++) {
      printf("%d |",x);
      for (y=0 ; y<3 ; y---++)
         if (M[x][y])
            printf("%d|",M[x][y]);
         else 
            printf(" |");
      printf("\n");
   }
}

int main() {
   int M[3][3] = { 0 };
   int winner=0,x,y,player=1;
   do {
      stampa(M);
      printf("Gioca %d\n",player);
      scanf("%d%d",&x,&y);
      if (mossaValida(M,x,y)) {
         giocaMossa(M,x,y,player);
         player = (player == 1 ? 2 : 1);
      } else
         printf("Mossa non valida\n");
   } while (!(winner=haVinto(M)) && ciSonoMosseValide(M));
   stampa(M);
   if (winner)
      printf("Ha vinto il giocatore %d\n",winner);
   else
      printf("Partita patta.\n");
   return 0;
}


-- AndreaSterbini - 30 Oct 2003


This topic: Programmazione1/AA0506/PZ > WebHome > AppuntiEsercitazioni2003 > Tris
Topic revision: r3 - 2003-10-31 - AndreaSterbini
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback