John Smith
John Smith

Reputation: 21

Struggles with TicTacToe

I have written a program in C, that when runs, is supposed to allow the user to play a game of tic tac toe - or noughts and crosses, whether it be against the computer, or another user. I have nearly completed it, and it prints the grid out perfectly fine. However, when I go to input which row/column I want to place the symbol in, instead of inserting the symbol, it just removes a space in the grid, aligning it incorrectly. I have tried to put a loop in the main method which fills the grid in with spaces to try and prevent null values. If anyone could suggest anything it would be much appreciated. Thanks in advance!

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

    void user_prompt();
    void clear_board(char gameBoard[3][3]);
    void display_board(char gameboard[3][3]);
void user_move(char gameBoard[3][3]);
void computer_move(char gameBoard[3][3]);
int detect_win(char gameBoard[3][3]);

int gameMode;
char symbol1;
char symbol2;
char nickname1[10];
char nickname2[10] = "TicTacBot";
char gameBoard[3][3];
char playerTurn[10];

int main(void){
    int i, j;
    char gameBoard [3][3];

    clear_board(gameBoard);

    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            gameBoard[i][j] = ' ';
        }
    }
    i = 0;
    j = 0;

    user_prompt();
    display_board(gameBoard);

    if(gameMode == 2){
        for(i = 0; i < 9; i++){
            user_move(gameBoard);
            display_board(gameBoard);
            if(detect_win(gameBoard) == 1){
                printf("The winner is %s!!!\n", nickname1);
            }

            if(detect_win(gameBoard) == 2){
                printf("The winner is %s!!!\n", nickname2);
            }
        }
    }

    else{
        user_move(gameBoard);
        display_board(gameBoard);
        for(i = 0; i < 4; i++){
            printf("TicTacBot's move.\n");
            computer_move(gameBoard);
            display_board(gameBoard);
            if(detect_win(gameBoard) == 1){
                printf("The winner is %s!!!\n", nickname1);
            }
            user_move(gameBoard);
            display_board(gameBoard);
            if(detect_win(gameBoard) == 1){
                printf("The winner is %s!!!\n", nickname2);
            }
        }
    }
    if(detect_win(gameBoard) == 0){
        ("The game ended in stalemate!\n");
    }



    return 0;
}

/*
    Prompts the user to enter a nickname, what symbol they would like to use, and whether they'd rather play against the computer or another user.
*/

void user_prompt(void){

    printf("Please choose whether you would rather play against the computer (enter '1'),or another user (enter '2'): \n");
    scanf("%d", &gameMode);
    getchar();

    while(gameMode != 1 && gameMode != 2){
        printf("Please enter a valid digit: \n");
        scanf("%d", &gameMode);
        getchar();
    }

    if(gameMode == 1){
        printf("Please choose whether you would rather play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
        scanf(" %c", &symbol1);
        getchar();
        if(symbol1 == 'x') {
            symbol2 == 'o';
        }
        else{
            symbol2 == 'x';
        }
    }

    else{
        printf("Player 1, would you like to play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
        scanf(" %c", &symbol1);
        getchar();

    while(symbol1 != 'x' &&  symbol1 != 'o'){
        printf("Please enter a valid symbol: \n");
        scanf(" %c", &symbol1);
        getchar();
    }

        if(symbol1 == 'x'){
            symbol2 == 'o';
        }

        else{
            symbol2 == 'x';
        }   
    }

    if(gameMode == 1){
        printf("Please enter a nickname: \n");
        fgets(nickname1, 10, stdin);
        getchar();
    }
    else{
        printf("Please enter a nickname for player 1: \n");
        fgets(nickname1, 10, stdin);
        getchar();
        printf("Please enter a nickname for player 2: \n");
        fgets(nickname2, 10, stdin);
        getchar();
    }


}

/*
    Resets the game board.
*/

void clear_board(char gameBoard[3][3]){
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            gameBoard[i][j] = 0;
        }
    }
}

/*
    Displays the game board and all symbols within it.
*/

void display_board(char gameBoard[3][3]){
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            printf(" %c ", gameBoard[i][j]);
            if(j == 2){
                printf("\n");
            }
            if(j != 2){
                printf("|");
            }
        }
        if(i != 2){
            printf("---+---+---\n");
        }

    }

}

/*
    Takes input of a position on the board from the user, then places the user's symbol into that space on the game board.
*/

void user_move(char gameBoard[3][3]){
    int row;
    int column;
    if(playerTurn == nickname1){
    printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol1);
    scanf("%d", &row);
    getchar();

    printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol1);
    scanf("%d", &column);
    getchar();

    }
    else{
    printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol2);
    scanf("%d", &row);
    getchar();

    printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol2);
    scanf("%d", &column);
    getchar();

    }

    if(row < 1 || row > 3){
        printf("Please enter a valid row number: \n");
        scanf("%d", &row);
        getchar();
    }

    if(column < 1 || column > 3){
        printf("Please enter a valid column number: \n");
        scanf("%d", &row);
        getchar();
    }

    if(gameBoard[row-1][column-1] != ' '){  
        printf("The position you entered is already taken. Try again! \n");
        display_board(gameBoard);
        user_move(gameBoard);
    }

    else if(gameBoard[row-1][column-1] != ' '){
        printf("The position you entered is already taken. Try again! \n");
        display_board(gameBoard);
        user_move(gameBoard);
    }   

    else{
        if(playerTurn == nickname1){
            gameBoard[row-1][column-1] = symbol1;
        }
        else{
            gameBoard[row-1][column-1] = symbol2;
        }
    }
    printf("%c", symbol2);

    if(gameMode == 2){
        return;
    }

    if(strcmp(playerTurn, nickname1)==0){
        strcpy(playerTurn, nickname2);
    }
    else if(strcmp(playerTurn, nickname2)==0){
        strcpy(playerTurn, nickname1);
    }
}

/*
    Automates a strategic move from the computer, aiming to win the game, or at the least prevent the user from winning
*/


void computer_move(char gameBoard[3][3]){
    int row;
    int column;
    int endTurn = 0;

    row = rand() % 3 + 0;
    column = rand() % 3 + 0;

    if(gameBoard[row][column] != symbol1 && gameBoard[row][column] != symbol2){
        gameBoard[row][column] = symbol2;
        endTurn = 1;
    }

}

/*
    Detects a win on the game board. Checks if there are three identical symbols in a row, or if there are no more spaces on the game board. 
*/

int detect_win(char gameBoard[3][3]){
    for(int row = 0; row < 3; row++){
        if(gameBoard[row][0] == gameBoard[row][1] && gameBoard[row][1] == gameBoard[row][2]){
            if(gameBoard[row][0] == symbol1){
                return 1;
            }
            if(gameBoard[row][0] == symbol2){
                return 2;
            }
        }
    }

    for(int column = 0; column < 3; column++){
        if(gameBoard[0][column] == gameBoard[1][column] && gameBoard[1][column] == gameBoard[2][column]){
            if(gameBoard[0][column] == symbol1){
                return 1;
            }
            if(gameBoard[0][column] == symbol2){
                return 2;
            }
        }
    }

    if(gameBoard[0][0] == gameBoard[1][1] && gameBoard[1][1] == gameBoard[2][2]){
        if(gameBoard[1][1] == symbol1){
            return 1;
        }
        if(gameBoard[1][1] == symbol2){
            return 2;
        }
    }

    if(gameBoard[0][2] == gameBoard [1][1] && gameBoard[1][1] == gameBoard[2][0]){
        if(gameBoard[1][1] == symbol1){
            return 1;
        }
        if(gameBoard[1][1] == symbol2){
            return 2;
        }
    }
    return 0;


}

Upvotes: 1

Views: 382

Answers (1)

GoodDeeds
GoodDeeds

Reputation: 8527

There's a small logical error:

In line 98, 101, 117, and 121, (and perhaps other places - please check) you have used == (operator for equality check) instead of the = used for assignment.

For example,

symbol2 == 'o';

should be replaced with

symbol2 = 'o';

Hence, it just checks for equality, throws away the result, and continues; with no changes made to symbol2.

Upvotes: 3

Related Questions