简体   繁体   中英

optimization Tic Tac Toe Game in C

I'm beginner learner in C and one of the assignments I got was to write a Tic Tac Toe game. I have the game running but every time you place X on O position or vice versa it overwrites it. I would also appreciate comments on optimizing the code, because I'm a beginner and don't know a lot of concepts. Thank you! this is what I've got so far

#include<stdio.h>

void redrawBoard(char array[]);
void markBoard (int x, int o, char array[]);
int checkForWin(char array[]);

int checkForWin(char array[])
{   
int a;
char x = 'X';
char o = 'O';

 if (array[0] == x && array[4] == x && array[8] == x)  // winning cases for x 
    return 1;
 if (array[2] == x && array[4] == x && array[6] == x)
    return 1;
 if (array[0] == x && array[1] == x && array[2] == x)
    return 1;
 if (array[3] == x && array[4] == x && array[5] == x)
    return 1;
 if (array[6] == x && array[7] == x && array[8] == x)
    return 1;
 if (array[0] == x && array[3] == x && array[6] == x)
    return 1;
 if (array[1] == x && array[4] == x && array[7] == x)
    return 1;
 if (array[2] == x && array[5] == x && array[8] == x)
    return 1;

 if (array[1] == x && array[4] == x && array[6] == x && array[8] ==x) //checking for draw with x combinations 1st pattern
    return 3;
 if (array[0] == x && array[2] == x && array[4] == x && array[7] ==x)
    return 3;
 if (array[0] == x && array[4] == x && array[5] == x && array[6] ==x)
    return 3;
 if (array[2] == x && array[3] == x && array[4] == x && array[8] ==x)
    return 3;

 if (array[1] == x && array[4] == x && array[5] == x && array[6] ==x) //checking for draw with x combinations 2nd pattern
    return 3;
 if (array[0] == x && array[4] == x && array[5] == x && array[7] ==x)
    return 3;
 if (array[2] == x && array[3] == x && array[4] == x && array[7] ==x)
    return 3;
 if (array[1] == x && array[3] == x && array[4] == x && array[8] ==x)
    return 3;



 if (array[0] == o && array[4] == o && array[8] == o) //// winning cases for o
    return 2;
 if (array[2] == o && array[4] == o && array[6] == o)
    return 2;
 if (array[0] == o && array[1] == o && array[2] == o)
    return 2;
 if (array[3] == o && array[4] == o && array[5] == o)
    return 2;
 if (array[6] == o && array[7] == o && array[8] == o)
    return 2;
 if (array[0] == o && array[3] == o && array[6] == o)
    return 2;
 if (array[1] == o && array[4] == o && array[7] == o)
    return 2;
 if (array[2] == o && array[5] == o && array[8] == o)
    return 2; 

 if (array[1] == o && array[4] == o && array[6] == o && array[8] == o) //checking for draw with o combinations 1st pattern
    return 3;
 if (array[0] == o && array[2] == o && array[4] == o && array[7] == o)
    return 3;
 if (array[0] == o && array[4] == o && array[5] == o && array[6] == o)
    return 3;
 if (array[2] == o && array[3] == o && array[4] == o && array[8] == o)
    return 3;

 if (array[1] == o && array[4] == o && array[5] == o && array[6] == o) //checking for draw with o combinations 2nd pattern
    return 3;
 if (array[0] == o && array[4] == o && array[5] == o && array[7] == o)
    return 3;
 if (array[2] == o && array[3] == o && array[4] == o && array[7] == o)
    return 3;
 if (array[1] == o && array[3] == o && array[4] == o && array[8] == o)
    return 3;
 


 else
    return 0;

 return(a);
}

 void markBoard (int x, int o, char array[])
{
int i = 0;
char j = 'X';
char k = 'O';

while( x >= 1 && x <= 9) 
{
    array[x - 1] = j;
    redrawBoard(array);
    break;
}
while (o >= 1 && o <= 9)
{
    array[o - 1] = k;
    redrawBoard(array);
    break;
}

}

void redrawBoard(char array[])
{
printf(" Player 1 is X;       Player 2 is O;\n\n");
printf("              |      |        \n");
printf("           %c  |  %c   |  %c    \n",array[0],array[1],array[2]);
printf("        ______|______|______  \n");
printf("              |      |        \n");
printf("           %c  |  %c   |  %c    \n",array[3],array[4],array[5]);
printf("        ______|______|______  \n");
printf("              |      |        \n");
printf("           %c  |  %c   |  %c    \n",array[6],array[7],array[8]);
printf("              |      |        \n");
}

int main()
{
int x;
int o;
char array[9] = {'1', '2','3','4','5','6','7','8','9'};

printf("tic tac toe game\n");
redrawBoard(array);


while (checkForWin(array) == 0)
{
    printf("P1 start \n");
    scanf("%d",&x);
    markBoard(x,o,array);

    printf("P2 go on\n");
    scanf("%d", &o);
    markBoard(x,o,array);
}
if (checkForWin(array) == 1)
    printf("P1 won\n");
if (checkForWin(array) == 2)
    printf("P2 won\n");
if (checkForWin(array) == 3)
    printf("draw \n");
return 0;
}
  • The problem you mentioned is that you do not have a test when you already have a value in this cell.

  • About optimization:

  1. Avoid a lot of if cases . Think about better check for checking who is winner, For example: look at this check:

     char winnerIs(char** Board, int i, int j) { if (Board[i][j] == Board[i][(j+1)%3] && Board[i][j] == Board[i][(j+2)%3]) { // got a column return Board[i][j]; } else if (Board[i][j] == Board[(i+1)%3][j] && Board[i][j] == Board[(i+2)%3][j]) { // got a row return Board[i][j]; } else if (i == j && Board[i][j] == Board[(i+1)%3][(j+1)%3] && Board[i][j] == Board[(i+2)%3][(j+2)%3]) { // got the forward diagonal return Board[i][j]; } else if (i+j == 2 && Board[i][j] == Board[(i+2)%3][(j+1)%3] && Board[i][j] == Board[(i+1)%3][(j+2)%3]) { // got the reverse diagonal return Board[i][j]; } else { // got nothing return 0; }
  2. Avoid a lot of printing, Better use one structure for the game, for example a board - which is char board[][] or better char** Board if you want a dynamic game. And print the whole board once.

  3. Instead of next code:

     printf("P1 start \n"); scanf("%d",&x); markBoard(x,o,array); printf("P2 go on\n"); scanf("%d", &o); markBoard(x,o,array);

Make something like this:

    int player = 1;
    char row, col; 
    player = (player % 2) ? 1 : 2;
    scanf("%c %c", &row, &col);
    markBoard(row, col, board);

Like that you don't need to duplicate a same code and it is automatic knows each turn, who's turn now.

  1. Instead of next code:

     if (checkForWin(array) == 1) printf("P1 won\n"); if (checkForWin(array) == 2) printf("P2 won\n"); if (checkForWin(array) == 3) printf("draw \n");

Connect some conditions, like that:

    if (checkForWin(array) == 1 || checkForWin(array) == 2) {
        printf("Congratulations %c!\n", winner);
    } else {
        printf("Game ends in a draw.\n");
    }
  1. To make more "beauty" code, you can added a structs which will manage the whole game, for example:

     typedef struct { int size; int **board; // the board /* scores of all options */ int *rowScores; int *colScores; int topLeftBottomRightDiagonalScores; int topRightBottomLeftDiagonalScores; } Game; typedef struct { // position on the board int x; int y; } Position;
  2. Your void markBoard (int x, int o, char array[]) function makes to much iterations to print the whole board. Better create the whole board once and after that run on the whole board.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM