Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

Tie Tac Toe Game in C

+1 vote
asked Dec 13, 2023 by Andre Davis (320 points)
I need assistance coding a Tic Tae Toe game in C it's allowing me to output the names, but I'm getting a glitch afterward. Could someone assist in fixing it? The game is supposed to load and save to a new text file, and or should be able to continue from the start. Thanks in advance.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

typedef struct

{

  char board[3][3];

  char current_player;

} TicTacToeBoard;

// Function Prototype to display the Tic Tac Toe board

void display_board (TicTacToeBoard * board);

// Function Prototype to initialize the Tic Tac Toe board with empty cells

void initialize_board (TicTacToeBoard * board);

// Function Prototype to make a move on the Tic Tac Toe board

int make_move (TicTacToeBoard * board, int row, int col);

// Function Prototype to check if a player has won

int check_win (TicTacToeBoard * board, char player);

// Function Prototype to check if the game is a draw

int check_draw (TicTacToeBoard * board);

// Function Prototype to save the game state to a file

void save_board_to_file (TicTacToeBoard * board, char *file_path);

// Function Prototype to load the game state from a file

void load_board_from_file (TicTacToeBoard * board, char *file_path);

int main ()

{   //Initialize

  char *file_path = "tic_tac_toe_board.txt";

  TicTacToeBoard board;

  char player1[50], player2[50];

    //Player Name input

  printf ("Enter Player 1 name: ");

  scanf ("%s", player1);

  printf ("Enter Player 2 name: ");

  scanf ("%s", player2);

    //Load Previous Game

  char choice;

  printf ("Do you want to continue the previous game? (y/n): ");

  scanf (" %c", &choice);

  if (choice == 'y' || choice == 'Y')

    {

      load_board_from_file (&board, file_path);

      printf ("Loaded the previous game board:\n");

      display_board (&board);

    }

  int row, col;

  while (1)

    {

// Your code here

// 1. Initialize Board

void initialize_board (TicTacToeBoard * board);

// 2. Ask for move (row, col)

int make_move (TicTacToeBoard * board, int row, int col);

// 3. Check if valid move using make_move

int make_move (TicTacToeBoard * board, int row, int col);

// Provided: use similar method for the rest.

      int move_result = make_move (&board, row, col);

      if (move_result == 0)

{

  printf ("Cell is already occupied or invalid input. Try again.\n");

  continue;

}

// 4. Display board

      void display_board (TicTacToeBoard * board);

// 5. Save board after every move.

      save_board_to_file (&board, file_path);

// 6. Check for a win.

      int player_won = check_win (&board, 'X');

      int opponent_won = check_win (&board, 'O');

      int is_draw = check_draw (&board);

// Construct if statements based on the returned values from

        

// check_win and check_draw

    }

    

}

// Function to display the Tic Tac Toe board

void display_board (TicTacToeBoard * board)

{

    printf("\n");

    for (int i = 0; i < 3; i++) {

    for (int j = 0; j < 3; j++) {

    printf(" %c ", board->board[i][j]);

    if (j != 2) {

        printf("|");

    }

}

    printf("\n");

    if (i != 2) {

        printf("-----------\n");

        }

    }

    printf("\n");

}

// Function to make a move on the Tic Tac Toe board

int make_move (TicTacToeBoard * board, int row, int col)

{

    if (row < 0 || row > 2 || col < 0 || col > 2) {

        printf("Invalid input. Try again.\n");

        return 0;

    }

    if (board -> board[row][col] == 'X' || board -> board[row][col] == 'O') {

        printf("That cell is already taken. Try again.\n");

        return 0;

    }

    board->board[row][col] = 'X'; // assuming player X is making the move

    return 1;

}

// Function to initialize the Tic Tac Toe board with empty cells

void initialize_board (TicTacToeBoard * board)

{

 for (int i = 0; i < 3; i++) {

        for (int j = 0; j < 3; j++) {

            board->board[i][j] = ' ';

        }

    }   

}

// Function to check if a player has won

int check_win (TicTacToeBoard * board, char player)

{

    for (int i = 0; i < 3; i++) {

        if (board->board[i][0] == player && board->board[i][1] == player && board->board[i][2] == player) {

            return 1;

        }

    }

    for (int i = 0; i < 3; i++) {

        if (board->board[0][i] == player && board->board[1][i] == player && board->board[2][i] == player) {

            return 1;

        }

    }

    if (board->board[0][0] == player && board->board[1][1] == player && board->board[2][2] == player) {

        return 1;

    }

    if (board->board[0][2] == player && board->board[1][1] == player && board->board[2][0] == player) {

        return 1;

    }

    return 0;

}

// Function to check if the game is a draw

int check_draw (TicTacToeBoard * board)

{

 int i, j;

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

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

            if (board->board[i][j] == ' ') {

                return 0;

            }

        }

    }

    return 1;

}

// Function to save the game state to a file

void save_board_to_file (TicTacToeBoard * board, char *file_path)

{

    FILE *fp;

    fp = fopen(file_path, "wb");

    if (fp == NULL) {

        printf("Error opening file.\n");

        return;

    }

    fprintf(board, sizeof(TicTacToeBoard), 1, fp);

    fclose(fp);

}

// Function to load the game state from a file

void load_board_from_file (TicTacToeBoard * board, char *file_path)

{

    FILE *fp;

    fp = fopen(file_path, "rb");

    if (fp == NULL) {

        printf("Error opening file.\n");

        return;

    }

    fscanf(board, sizeof(Tic

1 Answer

0 votes
answered Dec 13, 2023 by Peter Minarik (86,240 points)
edited Dec 13, 2023 by Peter Minarik

Your Issue

The code you copied here is unfinished and would not even compile.

Could you, please, instead link your project? You can click the orange SHARE button (3 to the right from RUN) and post the "share code" from there.

It is also a good idea to

  1. list the exact steps taken to produce the issue
  2. what you expected to happen
  3. what happened instead

What I've Found (So Far...)

I looked at the code provided so far and tried to make some sene of it and finish whatever you missed in your post to make the code compile and do whatever it's supposed to do.

I've found you've got quite a lot of things to do.

This also looks like a homework or some kind of assignment and the best way you can learn is by doing it yourself, so I'm not going to provide you a finished code, but I'm going to point out some significant mistakes and I'll let you fix these and similar ones and allow you to progress with your code.

Problem #1 - Calling a function

In the main() function you're trying to call methods but instead of calling a method, you're just declaring them again.

// 1. Initialize Board
void initialize_board (TicTacToeBoard * board);

The above is not a function call, it's a declaration of a function where you state the signature (name, return value, parameters, etc) of the function. If you want to call the function, you need to provide the name and the arguments to the compiler.

The above function would be called correctly like this:

initialize_board(&board);

So we provided the name of the function and the arguments in parenthesis. Since initialize_board expects a pointer to TicTacToeBoard, and board is of type TicTacToeBoard, we need to use the & (address of) operator to get the pointer to the TicTacToeBoard.

Apply the same logic across all your code when you're calling functions.

Problem #2 - Reading/Writing a file

In save_board_to_file() and load_board_from_file() you used the functions fprintf() and fscanf() respectively. This may even work, however, the arguments you provided did not match expected parameters. You could instead use the fwrite() and fread() functions respectively and they would have the arguments in the order you provided them.

Problem #3 - make_move()

In this function you always put an X into the given row/column, regardless of which player is playing. You can utilize board->current_player to see which player is active. However, no one maintains the current_player field of the TicTacToeBoard, so you should start flipping it between player 1 and player 2 every time a new turn is taken. The best place for this would be probably in the main() in the while loop.

Another problem with this function is that you'd need to ask the user to provide the row and column. So you'd either need to create a new function that will ask the user for this information and pass the user input to make_move(), or you completely remove row and col parameters and the make_move() function itself will just get this from the user.

And keep remember you have to keep repeating asking for rows and columns until a valid input is provided, i.e. the return value of make_move() is not 0.

Final Words

There are still some lesser issues in your code that I haven't addressed, but I think first you need to fix these major problems to have a functional game. When everything works, you can focus on cleaning your code of warnings and other subtle problems.

Good luck and ask further questions if you need help. But don't forget to link your code, it's easier than copying things here (and potentially missing some part of the code).

commented Dec 13, 2023 by Andre Davis (320 points)
asked Dec 13, 2023 by Andre Davis (320 points) Link to Code
commented Dec 14, 2023 by Peter Minarik (86,240 points)
Thank you for sharing the code. It looks like my assumptions about the missing few lines were correct.

Please, consider my suggestions above, apply the fixes, and see how your code works after these suggested changes.

If things still do not work quite well, add a comment here with the changed code and the further questions or just create a new question on OnlineGDB.

Good luck! :)
commented Dec 14, 2023 by Andre Davis (320 points)
https://onlinegdb.com/UYAzZ9ByW

I tried changed major error no # 2 and attempted to changed major error #1 but there is an debugging error, i did not complete major #3 until error #1 is functioning properly.
commented Dec 15, 2023 by Peter Minarik (86,240 points)
By the look of it, the file handling should work.

The compilation error is because you changed the function declarations on lines 20-38. That's not what I meant. The function declarations (where you state the signature of your functions) are fine, restore them.

You need to change how you call the function in the main(), in the while loop, i.e. lines 62-68. See the example I provided in my original post.

Let me know how you go.
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...