Home > Back-end >  Save a connect four game and load it in c
Save a connect four game and load it in c

Time:12-02

I want to make a file and save it and then just have an option that will load the saved file of the connect four game in the choice2 switch statement. I tried it like this in the code that I wrote which is in the while loop of the game but I am not sure what to write so I could save the whole board and the results of the game.

My question is how to store and reload this datastructure?

Here is the code:

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

#define ROWS    6
#define COLS    7

char scores[ROWS][COLS];
int column = 0;
char disc = 'X';

void init_scores();
void test_scores();
void print_board();
void choose();
void fill_column();
void save();
int check(char disc);

int main()
{
    char response, newline;
    int choice, choice2, save;

    while(1){
        printf("====================\n");
        printf("-------MENU---------\n");
        printf("====================\n");
        printf("1.Play a new game\n");
        printf("2.Load already saved game\n");
        printf("3.Exit the game\n");
        printf("Enter your choice: \n");
        scanf("%d", &choice);
        newline=getchar();

        switch(choice){
            case 1:
                do
                {
                    init_scores();
                    test_scores();
                    print_board();

                    while(1){
                        printf("Player %c, your turn!\n", disc);
                        choose();
                        printf("\n\n");
                        print_board();
                        if (check('X')){
                            printf("\n\nPlayer X wins!\n\n");
                            break;
                        }
                        if (check('O')){
                            printf("\n\nPlayer O wins!\n\n");
                            break;
                        }
                        printf("Would you like to save this game? Press 0\n");
                        scanf("%d", &save);

                        if(save == '0'){
                            FILE *fPointer;
                            fPointer = fopen("game.txt", "r");
                            fprintf(fPointer, " ");
                            fclose(fPointer);
                            printf("Game saved!\n");
                            break;
                        }

                    }
                    printf("Thanks for playing!\n");
                    printf("Would you like to play again? Y/N \n");
                    scanf("%c", &response);
                    newline=getchar();
                } while(response == 'Y' || response == 'y');

                break;
            case 2:
                printf("1. List all saved games\n");
                printf("2. List all saved games for a particular player\n");
                printf("3. Show the board of one of the saved games\n");
                printf("4. Load a game\n");
                printf("5. Return to main menu\n");
                printf("Enter your choice: \n");
                scanf("%d", &choice2);
                newline=getchar();

                switch(choice2){
                    case 1:
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        break;
                    case 5:
                        break;
                }

            case 3:
                exit(0);
                break;
            default:
                printf("INVALID INPUT\n");
        }
    }


    return 0;
}


void init_scores()
{
    int i, j;
    for (i = 0; i < ROWS; i  )
    {
        for (j = 0; j < COLS; j  )
        {
            scores[i][j] = ' ';
        }
    }
}

void test_scores()
{
    int i, j;

    for (i = 0; i < ROWS; i  )
    {
        for (j = 0; j < COLS; j  )
        {
            printf("%c ", scores[i][j]);
        }
        printf("\n");
    }
}

void print_board()
{
    puts("  A   B   C   D   E   F   G  ");
    puts("|---|---|---|---|---|---|---|");

    int i, j;
    for (i = 0; i < ROWS; i  )
    {
        for (j = 0; j < COLS; j  )
        {
            printf("| %c ", scores[i][j]);
        }
        printf("|\n");
        puts("|---|---|---|---|---|---|---|");
    }
    }

    void choose()
    {
    char letter, newline;

    while (1)
    {
        printf("\nChoose column: ");
        scanf(" %c", &letter);
        newline=getchar();

        switch(letter)
        {
            case 'A':
            case 'a':
                column = 0;
                break;
            case 'B':
            case 'b':
                column = 1;
                break;
            case 'C':
            case 'c':
                column = 2;
                break;
            case 'D':
            case 'd':
                column = 3;
                break;
            case 'E':
            case 'e':
                column = 4;
                break;
            case 'F':
            case 'f':
                column = 5;
                break;
            case 'G':
            case 'g':
                column = 6;
                break;
            default:
                column = 100;
                printf("\nWrong letter! Try again.\n\n");
                print_board();
        }
        if ((column >= 0 && column <= 6) && (scores[0][column] == ' '))
        {
            fill_column();
            disc = (disc == 'X') ? 'O' : 'X';
            break;
        }
    }
}

void fill_column()
{
    int level;

    for (level = ROWS - 1; level >= 0; level--)
    {
        if (scores[level][column] == ' ')
        {
            scores[level][column] = disc;
            break;
        }
    }
}

int check(char disc)
{
    int i, j, k;
    int count;
    int ways = 4;

    for (i = 0; i < ROWS;   i)
    {
        for (j = 0; j < ways;   j)
        {
            count = 0;
            for (k = 0; k < 4;   k)
            {
                if (scores[i][j   k] == disc) count  ;
            }
            if (count == 4) return 1;
        }
    }

    ways = 3;
    for (j = 0; j < COLS;   j)
    {
        for (i = 0; i < ways;   i)
        {
            count = 0;
            for (k = 0; k < 4;   k)
            {
                if (scores[i   k][j] == disc) count  ;
            }
            if (count == 4) return 1;
        }
    }

    int ii, jj;
    for (i = 1; i < ROWS-1; i  )
    {
        for (j = 1; j < COLS-1; j  )
        {
            count = 0;
            for (ii = i, jj = j; (ii >= 0) || (jj >= 0); ii--, jj--)
            {
                if (scores[ii][jj] == disc)
                {
                    count  ;
                    if (count == 4) return 1;
                }
                else
                    break;
            }

            for (ii = i 1, jj = j 1; (ii <= ROWS-1) || (jj <= COLS-1); ii  , jj  )
            {
                if (scores[ii][jj] == disc)
                {
                    count  ;
                    if (count == 4) return 1;
                }
                else
                    break;
            }


            count = 0;

            for (ii = i, jj = j; (ii <= ROWS-1) || (jj >= 0); ii  , jj--)
            {
                if (scores[ii][jj] == disc)
                {
                    count  ;
                    if (count == 4) return 1;
                }
                else
                    break;
            }

            for (ii = i-1, jj = j 1; (ii >= 0) || (jj <= COLS-1); ii--, j  )
            {
                if (scores[ii][jj] == disc)
                {
                    count  ;
                    if (count == 4) return 1;
                }
                else
                    break;
            }
        }
    }

    return 0;
}

void save(){
}

CodePudding user response:

I like this little game you are trying to make.

One small note, before we get started:
I think you could have spent a bit more time thinking about what you want to achieve, and then break it down into smaller steps. You know that you can use fopen to read or modify files, so think a bit more about how it can be used to save the state of a Connect 4 game.

Let's start:

  1. We have decided that we will use files to save and load the games. So, we'll need to know how to access files. Here is a brief recap:
    1. fopen(name, "r") opens a file for reading. You read it using fscanf.
    2. fopen(name, "w") opens a file for writing. You write to it using fprintf.
  2. The information about your board is stored in a variable called scores. Don't think of it as Connect 4 game. Just think of it as some data which you have, which you would like to save and load.

    Imagine you are writing a program whose only job is to describe the data you want to store and writes it to its output.
    Imagine another program whose job is to look at the output of the first program and figure out what data it was trying to describe.

    The first program can simply call print_board and exit.
    The second can cleverly use scanf to look at the output of the first and identify the characters which make up the board, and populate the variable scores with them.
  3. Once you have these programs ready, you just need to use fprintf and fscanf to make the program read from and write to a different location.

The process by which your 1st imaginary program describes the data you want to save is called 'serialisation'
The process by which your 2nd imaginary program figures out what the 1st was trying to describe is called 'deserialisation'.

I will share some code for saving and loading the board of a different and simpler game.
The functions named save and load are the important bits. They are the imaginary programs which serialise and deserialise the information about the board.
The variables filename and filenum decide which file is read or written to.
In your case, you also need to store if the game is completed, who won, else whose turn it is, etc. That I would like you to solve yourself.

Small closing notes:

  • In your code, in line 60, variable save is an int, and you are comparing it with a char.
  • In your code, in line 64, a file you are saving into should be opened with "w".
  • In your code, line 60 along with save being int will cause a minor issue when I enter a character instead of a number. You can fix it yourself.
  • Next time, think about your problem and break them into steps as small as possible, think about these small pieces or google them, and ask questions only about the pieces which you had difficulty figuring out.
#include <stdio.h>

#define N 3

char board[N][N];

void initBoard();
void showBoard();

int save(char*);
int load(char*);

int main()
{
    initBoard();

    printf("Please enter a string of %d chars:\n", N*N);
    for (int i = 0; i < N; i  )
        for (int j = 0; j < N; j  )
            scanf("%c", &board[i][j]);

    puts("\n---------------------------------------------");
    puts("Your board is :");
    showBoard();

    char filename[12] = "board__.txt";
    int filenum;

    puts("\n---------------------------------------------");

    printf("Enter a board number to save as (0 to 9):\n");
    scanf("%d", &filenum);
    filename[6] = '0'   filenum;
    printf("Board will be saved in %s\n", filename);

    if (save(filename) == 0)
        puts("Board saved !");
    else
        puts("Could not save board !");

    puts("\n---------------------------------------------");
    printf("Enter a board number to load (0 to 9):\n");
    scanf("%d", &filenum);
    filename[6] = '0'   filenum;
    printf("Loading board saved in %s\n", filename);

    if (load(filename) == 0)
        puts("Board loaded !");
    else
        puts("Could not load board ! (Maybe such a file does not exist)");
    
    puts("\n---------------------------------------------");
    puts("Your final board is : (same as old board if new one could not be loaded)");
    showBoard();

    return 0;
}

void initBoard()
{
    for (int i = 0; i < N; i  )
        for (int j = 0; j < N; j  )
            board[i][j] = ' ';
}

void showBoard()
{
    for (int i = 0; i < N; i  )
    {
        for (int j = 0; j < N; j  )
            printf("| %c ", board[i][j]);
        puts("|");
    }
}

int save(char *filename)
{
    FILE *file = fopen(filename, "w");
    if (file == NULL)
        return -1;
    else
    {
        for (int i = 0; i < N; i  )
            for (int j = 0; j < N; j  )
                fprintf(file, "%c", board[i][j]);
    }
    fclose(file);
}

int load(char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
        return -1;
    else
    {
        for (int i = 0; i < N; i  )
            for (int j = 0; j < N; j  )
                fscanf(file, "%c", &board[i][j]);
    }
    fclose(file);
}

CodePudding user response:

There were a few lines of your program that needed to be fixed before implementing the saved game functionality.

Firstly, your if statement for save needs to be changed to check for an int not a char

if(save == 0)

Your fopen line needs to be changed to "w" for writing to the file, and scores needs to be changed to *scores to access it correctly.

fPointer = fopen("game.txt", "w"); //mbf
fprintf(fPointer, *scores);

In your choice2 switch statement, case 4 needs to have the loading functionality implemented. This can be done like so

case 4:
    printf("Enter the saved game's file name:\n");
    scanf("%s", &saved);
    FILE *fPointer = fopen(saved, "r");
    for(int i = 0; i <= 42; i  )
    {
        ch = fgetc(fPointer);
        if(!isspace(ch))
        {
            scores[i][i%7] = ch;
        }
        else
        {
            scores[i][i%7] = ' ';
        }
    }
    fclose(fPointer);
    choice = 1;
    break;

Lastly, you will need to correctly fix the logic in your switch(choice) which accounts for starting of a loaded game.

  •  Tags:  
  • c
  • Related