Thread: Program stop running after I undo

  1. #1
    Registered User
    Join Date
    Nov 2017
    Posts
    10

    Question Program stop running after I undo

    Hi!
    I wrote the game "connect four", and I want to add the option to undo the last move, and for some reason when I try to use it the program crush.

    I made a 3D array that will store all the 2D arrays by turns, and then when I want to undo a move I make the current board as the one before 2 turns..

    can u tell me what I did wrong here?

    Code:
    #include <stdio.h>#include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    
    #define ROW  6
    #define COL  6
    
    
    int makeMove(char *theBoard , int player, const char *PIECES, int turn, char *savedGameBoard);
    void printBoard(char theBoard [ROW][COL]);
    int horizontalCheck(char *board);
    int verticalCheck(char *board);
    int diagonalCheck(char *board);
    int checkFour(char *board, int a, int b, int c, int d);
    int checkWin(char *board);
    
    
    
    
    int main(void)
    {
        // Message to start the game
        printf("welcome!\n\n");
    
    
        char gameBoard[ROW][COL];
        char savedGameBoard[100][ROW][COL];
    
    
        // Reset the board before we start the game
        memset(gameBoard, ' ', ROW * COL);
    
    
        const char *PIECES = "XO";
        int turn;
        int endGame = 0;
    
    
        for(turn = 0; turn < ROW * COL && !endGame; turn++)
        {
            strcpy( savedGameBoard[turn], gameBoard);
            printBoard(gameBoard);
    
    
            while(!makeMove(gameBoard, turn % 2, PIECES, turn, savedGameBoard))
            {
                printBoard(gameBoard);
                printf("Invalid input, this column is full. Please choose another one:\n");
            }
    
    
            endGame = checkWin(gameBoard);
        }
    
    
        printBoard(gameBoard);
        if(turn == ROW * COL && !endGame)
        {
            printf("It's a tie!");
        }
        else
        {
            turn--;
            printf("Player %d (%c) wins!\n", turn % 2 + 1, PIECES[turn % 2]);
        }
    
    
        return 0;
    }
    
    
    int makeMove(char *theBoard , int player, const char *PIECES, int turn, char *savedGameBoard)
    {
        int row, col = 0;
        bool flag=false;
    
    
        printf("Player %d (%c):\nEnter number coordinate: (0 to undo move) ", player + 1, PIECES[player]);
    
    
       while(1)
       {
            // Check if it's an integer
            if(1 != scanf("%d", &col))
            {
                printf("\nInvalid input, bye-bye!\n");
                exit(0);
            }
    
    
            // Check if entered 0
            if(col==0)
                flag=true;
    
    
            // Check if it's in bound
            if(col < 1 || col > 7 )
            {
                while(getchar() != '\n');
                printBoard(theBoard);
                printf("Invalid input, the number must be between 1 to 7:\n");
            }
            else
            {
                break;
            }
        }
    
    
        // If entered 0, and it's not the first turn bring back the previous board
        if(flag)
        {
            if(turn==0)
            {
                printf("You can't undo the move.");
            }
            else
            {
                strcpy(theBoard, savedGameBoard[turn-1]);
                printf("You undo the last move, \n");
                printBoard(theBoard);
                return 1;
            }
          }
    
    
        // Enter the new char to the board
        col--;
    
    
        for(row = ROW - 1; row >= 0; row--)
        {
            if(theBoard[COL * row + col] == ' ')
            {
                theBoard[COL * row + col] = PIECES[player];
                return 1;
            }
        }
    
    
       return 0;
    }
    
    
    // This function print the board currently status
    void printBoard(char theBoard [ROW][COL])
    {
        int countCol[7] = { 1, 2, 3, 4, 5, 6, 7 };
        int i,j,t;
    
    
        printf("\n\nThe board status is: \n");
    
    
        for(i=0;i<ROW;i++)
        {
            for(j=0;j<COL;j++)
            {
                printf("| %c |", theBoard[i][j]);
            }
            printf("\n");
        }
    
    
        printf("  1    2    3    4    5    6    7\n");
    }
    
    
    int horizontalCheck(char *board){
        int row, col, idx;
        const int WIDTH = 1;
    
    
        for(row = 0; row < ROW; row++){
           for(col = 0; col < COL - 3; col++){
              idx = COL * row + col;
              if(checkFour(board, idx, idx + WIDTH, idx + WIDTH * 2, idx + WIDTH * 3)){
                 return 1;
              }
           }
        }
        return 0;
    
    
    }
    
    
    int verticalCheck(char *board){
        int row, col, idx;
        const int HEIGHT = 7;
    
    
        for(row = 0; row < ROW - 3; row++){
           for(col = 0; col < COL; col++){
              idx = COL * row + col;
              if(checkFour(board, idx, idx + HEIGHT, idx + HEIGHT * 2, idx + HEIGHT * 3)){
                  return 1;
              }
           }
        }
        return 0;
    
    
    }
    
    
    int diagonalCheck(char *board){
       int row, col, idx, count = 0;
       const int DIAG_RGT = 6, DIAG_LFT = 8;
    
    
       for(row = 0; row < ROW - 3; row++){
          for(col = 0; col < COL; col++){
             idx = COL * row + col;
             if(count <= 3 && checkFour(board, idx, idx + DIAG_LFT, idx + DIAG_LFT * 2, idx + DIAG_LFT * 3) || count >= 3 && checkFour(board, idx, idx + DIAG_RGT, idx + DIAG_RGT * 2, idx + DIAG_RGT * 3)){
                return 1;
             }
             count++;
          }
          count = 0;
       }
       return 0;
    
    
    }
    
    
    
    
    int checkFour(char *board, int a, int b, int c, int d){
        return (board[a] == board[b] && board[b] == board[c] && board[c] == board[d] && board[a] != ' ');
    
    
    }
    
    
    
    
    int checkWin(char *board){
        return (horizontalCheck(board) || verticalCheck(board) || diagonalCheck(board));
    
    
    }
    Last edited by zzxx5556; 12-14-2017 at 12:35 PM.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    You have not included all of the necessary code; you're missing some includes and defines.
    Your code is also sloppy. Be sure to properly format and indent your code.

    I took the liberty neatening up your code, adding the necessary includes and defines, and declaring the functions before main (and defining them afterwards).

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define ROW  6
    #define COL  6
    
    int makeMove(char *theBoard , int player, const char *PIECES, int turn, char *savedGameBoard);
    void printBoard(char theBoard [ROW][COL]);
    
    int main(void)
    {
        // Message to start the game
        printf("welcome!\n\n");
    
        char gameBoard[ROW][COL];
        char savedGameBoard[100][ROW][COL];
    
        // Reset the board before we start the game
        memset(gameBoard, ' ', ROW * COL);
    
        const char *PIECES = "XO";
        int turn;
        int endGame = 0;
    
        for(turn = 0; turn < ROW * COL && !endGame; turn++)
        {
            strcpy( savedGameBoard[turn], gameBoard);
            printBoard(gameBoard);
    
            while(!makeMove(gameBoard, turn % 2, PIECES, turn, savedGameBoard))
            {
                printBoard(gameBoard);
                printf("Invalid input, this column is full. Please choose another one:\n");
            }
    
            endGame = checkWin(gameBoard);
        }
    
        printBoard(gameBoard);
        if(turn == ROW * COL && !endGame)
        {
            printf("It's a tie!");
        }
        else
        {
            turn--;
            printf("Player %d (%c) wins!\n", turn % 2 + 1, PIECES[turn % 2]);
        }
    
        return 0;
    }
    
    int makeMove(char *theBoard , int player, const char *PIECES, int turn, char *savedGameBoard)
    {
        int row, col = 0;
        bool flag=false;
    
        printf("Player %d (%c):\nEnter number coordinate: (0 to undo move) ", player + 1, PIECES[player]);
    
       while(1)
       {
            // Check if it's an integer
            if(1 != scanf("%d", &col))
            {
                printf("\nInvalid input, bye-bye!\n");
                exit(0);
            }
    
            // Check if entered 0
            if(col==0)
                flag=true;
    
            // Check if it's in bound
            if(col < 1 || col > 7 )
            {
                while(getchar() != '\n');
                printBoard(theBoard);
                printf("Invalid input, the number must be between 1 to 7:\n");
            }
            else
            {
                break;
            }
        }
    
        // If entered 0, and it's not the first turn bring back the previous board
        if(flag)
        {
            if(turn==0)
            {
                printf("You can't undo the move.");
            }
            else
            {
                strcpy(theBoard, savedGameBoard[turn-1]);
                printf("You undo the last move, \n");
                printBoard(theBoard);
                return 1;
            }
          }
    
        // Enter the new char to the board
        col--;
    
        for(row = ROW - 1; row >= 0; row--)
        {
            if(theBoard[COL * row + col] == ' ')
            {
                theBoard[COL * row + col] = PIECES[player];
                return 1;
            }
        }
    
       return 0;
    }
    
    // This function print the board currently status
    void printBoard(char theBoard [ROW][COL])
    {
        int countCol[7] = { 1, 2, 3, 4, 5, 6, 7 };
        int i,j,t;
    
        printf("\n\nThe board status is: \n");
    
        for(i=0;i<ROW;i++)
        {
            for(j=0;j<COL;j++)
            {
                printf("| %c |", theBoard[i][j]);
            }
            printf("\n");
        }
    
        printf("  1    2    3    4    5    6    7\n");
    }
    You should be compiling with maximum warnings:

    Code:
    main.c||In function 'main':|
    main.c|28|warning: passing argument 1 of 'strcpy' from incompatible pointer type|
    \include\string.h|45|note: expected 'char *' but argument is of type 'char (*)[8]'|
    main.c|28|warning: passing argument 2 of 'strcpy' from incompatible pointer type|
    \include\string.h|45|note: expected 'const char *' but argument is of type 'char (*)[8]'|
    main.c|31|warning: passing argument 1 of 'makeMove' from incompatible pointer type|
    main.c|8|note: expected 'char *' but argument is of type 'char (*)[8]'|
    main.c|31|warning: passing argument 5 of 'makeMove' from incompatible pointer type|
    main.c|8|note: expected 'char *' but argument is of type 'char (*)[8][8]'|
    main.c|37|warning: implicit declaration of function 'checkWin'|
    main.c||In function 'makeMove':|
    main.c|78|warning: passing argument 1 of 'printBoard' from incompatible pointer type|
    main.c|9|note: expected 'char (*)[8]' but argument is of type 'char *'|
    main.c|96|warning: passing argument 2 of 'strcpy' makes pointer from integer without a cast|
    \include\string.h|45|note: expected 'const char *' but argument is of type 'char'|
    main.c|98|warning: passing argument 1 of 'printBoard' from incompatible pointer type|
    main.c|9|note: expected 'char (*)[8]' but argument is of type 'char *'|
    main.c||In function 'printBoard':|
    main.c|122|warning: unused variable 't'|
    main.c|121|warning: unused variable 'countCol'|
    ||=== Build finished: 0 errors, 10 warnings ===|
    Last edited by Matticus; 12-14-2017 at 12:26 PM.

  3. #3
    Banned
    Join Date
    Aug 2017
    Posts
    861
    you posted invalid code. look at your top line.
    int makeMove(char *theBoard , int player, const char *PIECES, int turn, char *savedGameBoard){int row, col = 0;
    you're missing stuff

    edit
    Matticus posted what I was already working on, goodie.

  4. #4
    Registered User
    Join Date
    Nov 2017
    Posts
    10
    Sorry didn't think that the missing function is needed..
    I edited and post all the code

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    The idea is to post a complete, compilable program (or an attempted complete program along with any compilation errors). If possible, a simplified version of the program that exhibits the problem is even better - this allows us to focus more on the problem parts, and you might even find the problem yourself in the process of simplifying it.

    Have you read through the warnings?
    Do you understand them?

  6. #6
    Registered User
    Join Date
    Nov 2017
    Posts
    10
    Quote Originally Posted by Matticus View Post
    The idea is to post a complete, compilable program (or an attempted complete program along with any compilation errors). If possible, a simplified version of the program that exhibits the problem is even better - this allows us to focus more on the problem parts, and you might even find the problem yourself in the process of simplifying it.

    Have you read through the warnings?
    Do you understand them?
    yap, I was looking at the warnings all of them related to the strcpy() function.
    The idea was to take a 2d array and put it in the 3d arrays an that's the best option I found to do so..
    I was trying this and it's working alone but still in the program it's not working for some reason

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    strcpy is certainly not the right tool for the job.
    Consider perhaps a function like memcpy.

  8. #8
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Code:
    The board status is: 
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    | X ||   ||   ||   ||   ||   |
      1    2    3    4    5    6    7
    Player 1 (X):
    Enter number coordinate: (0 to undo move) 0
    
    
    The board status is: 
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    | X ||   ||   ||   ||   ||   |
      1    2    3    4    5    6    7
    Invalid input, the number must be between 1 to 7:
    is this the effect you're looking for? printout wise, it still is not replacing last move, but it compiles and runs again.

    it also looks like ti needs work still on the vert.

    question 2
    you started decaliring your 2d arrays properly in your functions params then stopped doing so, using a pointer instead of your [size] [ size], what happened?

    Note:

    I removed your 3d array and made it a 2d array to get the results you see here.
    Last edited by userxbw; 12-14-2017 at 01:06 PM.

  9. #9
    Registered User
    Join Date
    Nov 2017
    Posts
    10
    Quote Originally Posted by Matticus View Post
    strcpy is certainly not the right tool for the job.
    Consider perhaps a function like memcpy.
    Thx! i fixed the problem

    Quote Originally Posted by userxbw View Post
    Code:
    The board status is: 
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    | X ||   ||   ||   ||   ||   |
      1    2    3    4    5    6    7
    Player 1 (X):
    Enter number coordinate: (0 to undo move) 0
    
    
    The board status is: 
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    |   ||   ||   ||   ||   ||   |
    | X ||   ||   ||   ||   ||   |
      1    2    3    4    5    6    7
    Invalid input, the number must be between 1 to 7:
    is this the effect you're looking for? printout wise, it still is not replacing last move, but it compiles and runs again.

    it also looks like ti needs work still on the vert.

    question 2
    you started decaliring your 2d arrays properly in your functions params then stopped doing so, using a pointer instead of your [size] [ size], what happened?

    Note:

    I removed your 3d array and made it a 2d array to get the results you see here.
    I don't know why I did this with the array, I change it and call it like Array[ROW][COL].
    thx!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undo a pipe. It is possible?
    By JOCAAN in forum C Programming
    Replies: 4
    Last Post: 01-16-2011, 05:47 PM
  2. Why my code will stop running? Thanks!
    By ljin in forum C Programming
    Replies: 7
    Last Post: 08-25-2009, 01:41 AM
  3. undo bitshift
    By young turk in forum C Programming
    Replies: 6
    Last Post: 04-28-2009, 10:08 AM
  4. Stop program from running twice?
    By Abda92 in forum C Programming
    Replies: 19
    Last Post: 03-17-2008, 01:35 PM
  5. Replies: 0
    Last Post: 04-27-2003, 02:04 AM

Tags for this Thread