2015-10-24 3 views
1

J'essaye de faire un vérificateur de condition pour un jeu de Tic Tac Toe pour annoncer quand le joueur a gagné. J'ai créé la fonction ci-dessous. Cependant, quand je l'appelle et j'essaie d'appliquer les conditions gagnantes, rien ne se passe. Je sais que c'est une fonction fastidieuse, mais je suis confus sur la façon de le rendre efficace et efficient.Est-ce une fonction de vérification de condition gagnante de Tic Tac Toe valide?

Fonction:

int checker_o(char aray[3][3]){ 

     if(aray[0][0]=='O'&& aray[0][1]=='O'|| aray[0][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[1][0]=='O'&& aray[1][1]=='O' && aray[1][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[2][0]=='O'&& aray[2][1]=='O'&& aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[0][0]=='O'&& aray[1][0]=='O' && aray[2][0]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[0][1]=='O'&& aray[1][1]=='O' && aray[2][1]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[0][2]=='O'&& aray[1][2]=='O' && aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[0][0]=='O'&& aray[1][1]=='O' && aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 

     if(aray[0][2]=='O'&& aray[1][1]=='O' && aray[2][0]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 1; 
     } 
} 

CODE ENTIER:

#include<stdio.h> 
#include<stdlib.h> 
#include<time.h> 


void map(char a[3][3]){ 

    int row, column; 

    for(row=0;row<3;row++){ 

     for(column=0;column<3;column++){ 

      printf ("%c  ", a[row][column]); 

     } 
     printf("\n \n \n \n \n"); 
} 
} 
float getRand() { 

    return ((rand()/(RAND_MAX+1.0))*8)+1; 
} 

int control(int ui, int kb){ 

    if (kb=='b'){ 
     ui--; 
    } 
    if(kb=='c' && 0<ui &&ui<4){ 
      ui+=5; 
    } 
    else{ 

     if(kb=='c' && 3<ui &&ui<7){ 
        ui--; 
     } 
     else{ 

      if(kb=='c' && 6<ui &&ui<10){ 
          ui-=7; 
      } 
     } 
    } 
return ui; 

} 

int checker_o(char aray[3][3]){ 

     if(aray[0][0]=='O'&& aray[0][1]=='O'&& aray[0][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 


     } 

     if(aray[1][0]=='O'&& aray[1][1]=='O' && aray[1][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 

     if(aray[2][0]=='O'&& aray[2][1]=='O'&& aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 

     } 
     if(aray[0][0]=='O'&& aray[1][0]=='O' && aray[2][0]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 
     if(aray[0][1]=='O'&& aray[1][1]=='O' && aray[2][1]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 
     if(aray[0][2]=='O'&& aray[1][2]=='O' && aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 
     if(aray[0][0]=='O'&& aray[1][1]=='O' && aray[2][2]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 
     if(aray[0][2]=='O'&& aray[1][1]=='O' && aray[2][0]=='O'){ 
      system("cls"); 
      printf("Player 'O' Wins!"); 
      getchar(); 
      return 0; 
     } 
} 
int checker_x(char aray[3][3]){ 

     if(aray[0][0]=='X'&& aray[0][1]=='X'&& aray[0][2]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 

     if(aray[1][0]=='X'&& aray[1][1]=='X' && aray[1][2]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 

     if(aray[2][0]=='X'&& aray[2][1]=='X'&& aray[2][2]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 


     } 
     if(aray[0][0]=='X'&& aray[1][0]=='X' && aray[2][0]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 
     if(aray[0][1]=='X'&& aray[1][1]=='X' && aray[2][1]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 
     if(aray[0][2]=='X'&& aray[1][2]=='X' && aray[2][2]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 
     if(aray[0][0]=='X'&& aray[1][1]=='X' && aray[2][2]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 

     } 
     if(aray[0][2]=='X'&& aray[1][1]=='X' && aray[2][0]=='X'){ 
      system("cls"); 
      printf("Player 'X' Wins!"); 
      getchar(); 
      return 0; 
     } 
} 
int main(){ 

    int r,c,ui,cntr,cntr2,ran,g,x; 
    char kb, aray[3][3]={{'.','.','.'},{'.','.','.'},{'.','.','.'}}; 

    srand(time(NULL)); 
    getRand(); 


    map(aray); 
    printf("Which keyboard method would u prefer? \n \n \n"); 
    printf("(a)\t \t (b)\t \t (c)\n \n easy \t \t mobile \t #Pad \n \n 0 1 2 \t \t 1 2 3 \t \t 7 8 9\n \n"); 
    printf(" 3 4 5 \t \t 4 5 6 \t \t 4 5 6 \n \n 6 7 8 \t \t 7 8 9 \t \t 1 2 3 \n \n \n"); 


    scanf("%c", &kb); 
    system("cls"); 
    map(aray); 
    do{ 


     printf("Your Move! \n \n"); 
     scanf("%i", &ui); 
     ui=control(ui,kb); 
     r=ui/3; 
     c=ui%3; 
     if(aray[r][c]=='X'|| aray[r][c]=='O'){ 
      printf("'X/O' Already exists there \n"); 
      getchar(); 
      getchar(); 
      return 0; 
     } 
     else{ 
      aray[r][c]='X'; 
      system("cls"); 
      map(aray); 
      checker_x(aray); 
     } 



      ran=getRand(); 
      g=ran/3; 
      x=ran%3; 
      if(aray[g][x]=='.'){ 
       aray[g][x]='O'; 
       system("cls"); 
       map(aray); 
      }else{ 
       do{ 
        ran=getRand(); 
        g=ran/3; 
        x=ran%3; 
        }while (aray[g][x]!='.'); 
       aray[g][x]='O'; 
       system("cls"); 
       map(aray); 
     checker_o(aray); 
      } 

    } while (checker_x(aray)!=1 || checker_o(aray)!=1); 

    getchar(); 
} 
+0

Peut aider à supprimer le même code dans chacun des blocs if en les déplaçant dans une fonction séparée pour le rendre plus propre et plus facile à lire. le modèle pour refactoriser devrait devenir plus facile de voir les conditions communes ... – t0mm13b

+0

Vous pouvez également le faire dans trois boucles 'for' (vérifier les lignes, vérifier les cols, vérifier les diagonales) et comparer' array [i] [0] == array [i] [1] == array [i] [2] 'et ensuite juste' printf ("Player \ '% c \' Wins!", tableau [i] [0]) '... –

Répondre

2

Après tout, si les déclarations que vous devez placer déclaration

return 0; 

Sinon, la fonction a un comportement non défini.

vous avez également une faute de frappe inj cette déclaration

if (aray[0][0]=='O'&& aray[0][1]=='O'|| aray[0][2]=='O'){ 
            ^^^ 

Il doit y avoir

if (aray[0][0]=='O'&& aray[0][1]=='O'&& aray[0][2]=='O'){ 
            ^^^ 

prendre en compte que ce bout de code

 system("cls"); 
     printf("Player 'O' Wins!"); 
     getchar(); 
     return 1; 

est dupliqué.

Vous pouvez réécrire la fonction de manière à ce que cet extrait de code ne soit présent qu'une seule fois dans la fonction.

Par exemple

const size_t N = 3; 
int winner = 0; 

for (size_t i = 0; !winner && i < N; i++) 
{ 
    size_t j = 0; 
    while (aray[i][j] == 'O' && j < N) j++; 

    winner = j == N; 
} 
//... 

if (winner) 
{ 
     system("cls"); 
     printf("Player 'O' Wins!"); 
     getchar(); 
} 

return winner; 

Vous pouvez introduire un paramètre supplémentaire pour le caractère qui sera vérifié. Il est préférable de ne pas utiliser de nombres magiques et d'autres littéraux dans le programme. Donnez-leur des noms significatifs. Notez qu'il est préférable d'utiliser le mot anglais array au lieu de aray.

+0

La chose est Je fais un cours de codage à Uni et je n'ai pas étudié la plupart de ce que vous avez inclus ci-dessus, merci beaucoup pour cette coupe claire à travers. – CcoderBeginner

+0

@CcoderBeginner Je n'ai inclus que des foops. spécificateur de nom de taille size_t vous pouvez substituer int. –

1

Ce que vous avez écrit n'est pas particulièrement bon pour l'écrire. Les 4 lignes

system("cls"); 
printf("Player 'O' Wins!"); 
getchar(); 
return 1; 

sont répétées - peut-être qu'elles devraient être dans une fonction. Vous avez une longue série de tests pour 'O'; vous auriez un ensemble presque identique de tests pour 'X', je présume. Vous devriez être en mesure d'utiliser une fonction qui est passée soit 'O' ou 'X' comme un argument et trouve si cela a gagné. Vous passerez également cela à la fonction de rapport. Vous pouvez alors décider si les 8 tests peuvent être améliorés ou non; ça ne vaut peut-être pas la peine de le faire.

Vous pouvez également utiliser:

if ((row1 win) || (row2 win) || … || (top-right to bottom-left win)) 
{ 
    report win 
} 

(avec les 8 essais en une seule instruction if, chacune étant séparée de la suivante par ||, auquel cas vous pouvez utiliser juste le un bloc de code pour signaler la Essayez d'éviter la répétition dans votre code, c'est une opportunité pour les bogues de se glisser dedans.

Comme Vlad from Moscow aussi points out, vous devriez retourner 0 de la fonction s'il n'y a pas de victoire.

Ces changements conduisent à:

int check_winner(char aray[3][3], char x_o) 
{ 
    assert(x_o == 'X' || x_o == 'O'); 
    if ((aray[0][0] == x_o && aray[0][1] == x_o && aray[0][2] == x_o) || 
     (aray[1][0] == x_o && aray[1][1] == x_o && aray[1][2] == x_o) || 
     (aray[2][0] == x_o && aray[2][1] == x_o && aray[2][2] == x_o) || 
     (aray[0][0] == x_o && aray[1][0] == x_o && aray[2][0] == x_o) || 
     (aray[0][1] == x_o && aray[1][1] == x_o && aray[2][1] == x_o) || 
     (aray[0][2] == x_o && aray[1][2] == x_o && aray[2][2] == x_o) || 
     (aray[0][0] == x_o && aray[1][1] == x_o && aray[2][2] == x_o) || 
     (aray[0][2] == x_o && aray[1][1] == x_o && aray[2][0] == x_o)) 
    { 
     system("cls"); 
     printf("Player '%c' Wins!\n", x_o); 
     getchar(); 
     return 1; 
    } 
    return 0; 
} 

Vous pourriez appeler avec:

if (check_winner(board, 'X') || check_winner(board, 'O')) 
    break; 

Je pense que vous devriez envisager de réécrire la fonction de sorte qu'il ne vérifie et ne signale pas le résultat:

int check_winner(char aray[3][3], char x_o) 
{ 
    assert(x_o == 'X' || x_o == 'O'); 
    if ((aray[0][0] == x_o && aray[0][1] == x_o && aray[0][2] == x_o) || 
     (aray[1][0] == x_o && aray[1][1] == x_o && aray[1][2] == x_o) || 
     (aray[2][0] == x_o && aray[2][1] == x_o && aray[2][2] == x_o) || 
     (aray[0][0] == x_o && aray[1][0] == x_o && aray[2][0] == x_o) || 
     (aray[0][1] == x_o && aray[1][1] == x_o && aray[2][1] == x_o) || 
     (aray[0][2] == x_o && aray[1][2] == x_o && aray[2][2] == x_o) || 
     (aray[0][0] == x_o && aray[1][1] == x_o && aray[2][2] == x_o) || 
     (aray[0][2] == x_o && aray[1][1] == x_o && aray[2][0] == x_o)) 
     return 1; 
    return 0; 
} 

qui pourrait effectivement être réduit à:

int check_winner(char aray[3][3], char x_o) 
{ 
    assert(x_o == 'X' || x_o == 'O'); 
    return ((aray[0][0] == x_o && aray[0][1] == x_o && aray[0][2] == x_o) || 
      (aray[1][0] == x_o && aray[1][1] == x_o && aray[1][2] == x_o) || 
      (aray[2][0] == x_o && aray[2][1] == x_o && aray[2][2] == x_o) || 
      (aray[0][0] == x_o && aray[1][0] == x_o && aray[2][0] == x_o) || 
      (aray[0][1] == x_o && aray[1][1] == x_o && aray[2][1] == x_o) || 
      (aray[0][2] == x_o && aray[1][2] == x_o && aray[2][2] == x_o) || 
      (aray[0][0] == x_o && aray[1][1] == x_o && aray[2][2] == x_o) || 
      (aray[0][2] == x_o && aray[1][1] == x_o && aray[2][0] == x_o)); 
} 

Je ne suis pas sûr de vous le recommander pour le moment. Mais vous pouvez utiliser:

if (check_winner(board, player)) 
{ 
    system("cls"); 
    printf("Player '%c' Wins!\n", player); 
    getchar(); 
} 

mais vous pouvez également utiliser la fonction pour vérifier si un mouvement possible est un coup gagnant sans avoir la fonction crier dehors avant que vous êtes prêt.

En outre, si vous éprouvez le débogage de difficulté, une étape est de vous assurer que le conseil d'administration (tableau) contient ce que vous attendez, ont donc une fonction d'impression pour montrer la carte aussi:

static void dump_board(char aray[3][3]) 
{ 
    for (int i = 0; i < 3; i++) 
    { 
     for (j = 0; j < 3; j++) 
      putchar(aray[i][j]); 
     putchar('\n'); 
    } 
} 

Et utilisez-le pour vérifier que ce que vous avez est correct. Notez également comment les similitudes et les différences entre les 8 tests sont clairement visibles. Vous pouvez facilement repérer des problèmes comme un || où il devrait y avoir un && parce que cela ressortirait comme un pouce endolori.