Thread: Pass variable from if to function

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    18

    Pass variable from if to function

    Hello, I had a class assingment to do to make the game "Mastermind" using my own functions. Now that's done, and I wanted to expand on it to feature a menu and multiplayer. I am fairly new to C programming so please be specific.

    I used to have every variable that called for a function in main, but now I have some inside if statements which are also inside main. For some reason, the data being passed from the if statements to the functions is just some random jiberrish. When I comment out all the if statements then the data is passed and returned normally. For example, it reads from a leaderboard text file. If the leader's name is Darko, it normally would print that out. But now that opening the file and storing that info in a variable and then passing it to a function which prints it out is in an if statement, it just prints out random stuff like ^( )!@5 ^!* or something lol.

    Any help would be appreciated!

    Thanks!

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Can you post your code?

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    Also what I have noticed is that all of my variables that are used in various functions have to be initialized outside of the if statements, even if the function that uses them is in the same if statement and I try to put them. If the variable is initialized in the if statement, devc++ gives me a ton of variable uninitialized errors

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    And yes, here is the (looooong) code. I have some variables right at the top of main already which i tried to put inside the if statements but it wouldn't let me.

    Code:
    #include <stdio.h>
    #include <time.h>
    
    // Constants used in the program.
    #define NUM_PEGS 4
    #define NUM_COLORS 6
    #define MAX_TURNS 10
    #define MARKED_BOARD -1
    #define MARKED_ANSWER -2
    
    // Functions used.
    void fillBoard(int board[]);
    int numPerfectMatches(int board[], int answer[]);
    void getUserGuess(int board[]);
    void copyArray(int dest[], int source[], int length);
    void markOutCorrect(int board[], int answer[]);
    int numWrongPlaceMatches(int board[], int answer[]);
    void greeting();
    void printArray(int array[], int length);
    void printWinner(int num_turns, int num_seconds);
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name);
    
    int main() {
    
        int multi, leader_minutes, leader_seconds, leader_time, leader_turns, answer[NUM_PEGS], board[NUM_PEGS];
        char leader_name[20];
        
        // Seed the random number generator.
        srand(time(0));
        
        // Set everything up.
        int num_turns = 0;    
        fillBoard(answer);
        int start = time(0);
    
        
        // ask if they are playing multiplayer or not
        printf("Are you wanting to play (type the number and press <ENTER>):\n");
        printf("1. Single Player\n2. Multiplayer\n");
        scanf("%d", &multi);
        
        if(multi != 1 && multi != 2) {
            
            // tell them they made an invalid choice
            printf("Invalid choice. Choose either 1 or 2 next time!\nGoodbye!\n");
            system("PAUSE");
            exit(0);
        
        }
        
        // do things based on their choice
        if(multi == 1) {
        
            // initialize leader variables
            int leader_minutes = 100, leader_seconds = 100, leader_time = 100, leader_turns = 100;
            char leader_name[20];
        
            // open leader file
            FILE *ifp;
            ifp = fopen("leader.txt", "r");
        
            // read in leader time and turns
            fscanf(ifp, "%d", &leader_minutes);
            fscanf(ifp, "%d", &leader_seconds);
            fscanf(ifp, "%d", &leader_turns);
            fscanf(ifp, "%s", leader_name);
    
            // convert time to seconds
            leader_time = (leader_minutes*60) + leader_seconds;
    
            // close file
            fclose(ifp);
        
            // Stores the real answer and the user's board, respectively.
            int answer[NUM_PEGS];
            int board[NUM_PEGS];
        
            // Set everything up.
            greeting();
            
        
        } else if(multi == 2) {
        
            // ask them on how to play online
            printf("To play multiplayer you must have someone else playing with you. Please read the following carefully:\n");
            printf("1. You must have an internet connection\n2. You must have someone else who is going to play");
            printf("3. You can choose from 2 modes:");
            printf("\t A. Digit chooser (you pick four numbers for the guesser to have to play with)\n\t B. Guesser (the one that tries to guess the four numbers)\n");
            printf("So which will it be??? Type 1 for \"Digit Chooser\" or 2 for \"Guesser\"\n");
            scanf("%d", &multi);
        
            if(multi == 1) {
                
                int a = 0, b = 0, c = 0, d = 0;
                // tell them how to choose
                printf("You must choose from 4 numbers from 0-5. If you choose a number outside that range, the game will shut down!\n");
                printf("Which four will it be partner??\n");
                scanf("%d%d%d%d", &a, &b, &c, &d);
                
                // if any numbers are out of the 0-5 range, then exit out
                if(a < 0 || b < 0 || c < 0 || d < 0 || a > 5 || b > 5 || c > 5 || d > 5) {
                    printf("You chose a number outside the 0-5 range.\nGoodbye!\n");
                    system("PAUSE");
                    exit(0);
                }
                
                // if all of their numbers are correct, then encrypt them and upload them
                a = a*5+38;
                b = b*7+25;
                c = c*3+12;
                d = d*9+14;
                
                // open file for writing and add the numbers
                FILE *ifp;
                ifp = fopen("chooser.txt", "w+");
                fprintf(ifp, "%d %d %d %d", c, b, a, d);
            
                // close file
                fclose(ifp);
                
                // execute batch file
                system("up.bat");
                
                // tell the user it's done, and they may exit
                printf("If you followed all of the rules, your numbers should be in our database for a guesser to play!\n");
                
                system("PAUSE");
                exit(0);
                
            } else if(multi == 2) {
                
                int a, b, c, d;
                
                // download the file
                system("down.bat");
                
                // open leader file
                FILE *ifp;
                ifp = fopen("chooser.txt", "r");
        
                // read in leader time and turns
                fscanf(ifp, "%d", &c);
                fscanf(ifp, "%d", &b);
                fscanf(ifp, "%d", &a);
                fscanf(ifp, "%d", &d);
    
                // close file
                fclose(ifp);
                
                // decrypt the numbers
                if(a-38 == 0)
                    a = 0;
                if(b-25 == 0)
                    b = 0;
                if(c-12 == 0)
                    c = 0;
                if(d-14 == 0)
                    d = 0;
                    
                if(a != 0)
                    a = a - 38 / 5;
                if(b != 0)
                    b = b - 25 / 7;
                if(c != 0)
                    c = c - 12 / 3;
                if(d != 0)
                    d = d - 14 / 9;
                
                // Stores the real answer and the user's board, respectively.
                int answer[NUM_PEGS];
                int board[NUM_PEGS];
        
                // Set everything up.  
                answer[0] = a;
                answer[1] = b;
                answer[2] = c;
                answer[3] = d;
                greeting();
                
            } else {
                
                // print invalid entry
                printf("Your choice was not valid. Next time choose either 1 or 2.\nGoodbye!\n");
                system("PAUSE");
                exit(0);
            
            }
        
        }
        
        
        
        // Loop through each turn, ending at 10 moves or a win.
        do {
            
            // Read in the user's guess.
            getUserGuess(board);
            
            // Figure out the number of matches.
            int num_perfect = numPerfectMatches(board, answer);
            int num_imperfect = numWrongPlaceMatches(board, answer);
            
            // Update for this turn.
            printf("You have %d perfect matches and %d imperfect matches.\n", num_perfect, num_imperfect);
            num_turns++;
            
        } while (num_turns < MAX_TURNS && numPerfectMatches(board, answer) < NUM_PEGS);
        
        // Winning case.
        if (numPerfectMatches(board, answer) == NUM_PEGS) {
            int end = time(0);
            newLeader(leader_time, leader_turns, num_turns, end-start, leader_name);
            printWinner(num_turns, end-start);
        }
        
        // Losing case.
        else {
            printf("Sorry, you have exceeded the maximum number of turns. You lose.\n");
            printf("Here is the winning board: ");
            printArray(answer, NUM_PEGS);
            printf("\n");
        }
        
        system("PAUSE");
        return 0;
    
    }
    
    // Pre-conditions: board is uninitialized and of size NUM_PEGS.
    // Post-conditions: board will be filled in randomly with values ranging from
    //                  0 to NUM_COLORS-1.
    void fillBoard(int board[]) {
        
        // initialize the variable
        int i;
        
        // fill board with random numbers from 0 to num_colors-1
        for(i=0; i<NUM_PEGS; i++)
            board[i] = rand()%NUM_COLORS;
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at the correct spots.
    int numPerfectMatches(int board[], int answer[]) {
        
        // initialize the variables
        int i, matches = 0;
        
        // if what the user guessed matches the answer exactly, add one to amount of matches
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i])
                matches++;
        }
        
        return matches;
            
    }
    
    // Pre-conditions: None.
    // Post-conditions: Prints out a greeting for the beginning of the game.
    void greeting() {
        
        // print the whole greeting
        printf("At each turn, you will enter your guess for the playing board.\n");
        printf("A valid guess has 4 values in between 0 and 5.\n");
        printf("Each guess will have each number within the guess separated by a space.\n");
        printf("When you are ready, enter your first guess.\n");
        printf("From that point on, you will be told how many perfect and imperfect matches you have.\n");
        printf("After this message, you should guess again. You have 10 chances, good luck!\n");
        
    }
    
    // Pre-conditions: board is of length NUM_PEGS
    // Post-conditions: NUM_PEGS integers are read in from the user and stored in
    //                  board in the natural order.
    void getUserGuess(int board[]) {
        
        // initialize the variable
        int i;
        
        // keep scanning for intigers for as many numbers as the array is long
        for(i=0; i<NUM_PEGS; i++){
            scanf("%d", &board[i]);
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at INCORRECT spots
    //                  after "erasing" those pegs that match at correct spots.
    int numWrongPlaceMatches(int board[], int answer[]) {
        
        // initialize the variables
        int tempboard[NUM_PEGS], tempanswer[NUM_PEGS], i, x, matches = 0, matching[NUM_COLORS]; 
          
        // Create temporary copies of both boards, since we'll need to make changes
        // to each during this process and we don't want to ruin the original
        // state of either board.
        copyArray(tempboard, board, NUM_PEGS);
        copyArray(tempanswer, answer, NUM_PEGS);
        
        // Mark out the spots on the board and answer that match up perfectly.
        markOutCorrect(tempboard, tempanswer);
        
        // Go through the board and try to match each peg on the board to
        // a spot on the answer. Hint: A double loop is needed.
        // Note: Remember to "mark" an answer when a match is found.
        
        // loop for each board and answer array integer
        for(i=0; i<NUM_PEGS; i++) {
            for(x=0; x<NUM_PEGS; x++) {
                
               // if the answers match and they are not marked, add one to matches and mark them
               if(tempboard[i] == tempanswer[x] && tempboard[i] >= 0){
                    matches++;
                    tempboard[i] = MARKED_BOARD;
                    tempanswer[x] = MARKED_ANSWER;
                }
                
            }
        }
        
        return matches;
        
    }
    
    // Pre-conditions: dest and source are both have the given length.
    // Post-conditions: All values from source are copied into the corresponding
    //                  locations in dest.
    void copyArray(int dest[], int source[], int length) {
        
        // initialize the variable
        int i;
        
        // for the length of the array, copy each number from source to dest    
        for(i=0; i<length; i++) {
            dest[i] = source[i];
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS.
    // Post-conditions: For each corresponding slot that matches in both boards,
    //                  the slots are changed to equal each board's appropriate
    //                  marker.
    void markOutCorrect(int board[], int answer[]) {
        
        // initialize the variable
        int i;
        
        // where the board number is same as the answer number, change both to their appropriate marker
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i]) {
                board[i] = MARKED_BOARD;
                answer[i] = MARKED_ANSWER;
            }
        }
        
    }
    
    // Pre-conditions: array has the given length.
    // Post-conditions: each value of array is printed, separated by a space.
    void printArray(int array[], int length) {
        
        // initialize the variable
        int i;
        
        // print each number in the array with a space after it
        for(i=0; i<length; i++){
            printf("%d ", array[i]);
        }
        
    }
    
    // Pre-conditions: num_turns is the number of turns it took the winner to win,
    //                 and num_seconds is the total amount of time they took to
    //                 win in seconds.
    // Post-conditions: A winning message is printed stating the number of moves
    //                  and amount of time taken to win in M:SS format.
    void printWinner(int num_turns, int num_seconds) {
         
         // initialize the variable
         int num_minutes;
         
         // calculate number of minutes and seconds
         num_minutes = num_seconds/60;
         num_seconds = num_seconds%60;
         
         // print out the congrats line
         printf("You have won the game in %d turns, and in %d:%02d!!!\n", num_turns, num_minutes, num_seconds);
         
    }
    
    
    
    // Pre-conditions: leader_time and leader_turns are passed along with num_turns and end-start 
    // Post-conditions: leader_time and end-start are compared to see which is bigger (if a new leader was set)
    // and if end-start is less, then the file is written to make that the new leader
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name) {
        
        int name;
        
        if(leader_turns > num_turns) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else if(leader_turns == num_turns && leader_time > time) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else {
            
            printf("The leader (%s) won the game in %d turns, and in %d:%02d!!!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            
        }
        
    }

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    This is actually how it was at first, and it didn't work because it said that all of the variables were undeclared, so i initialized some of the variables outside the if statements but then when the variables would be passed to a function from the if statements, they would just generate random things.

    Code:
    #include <stdio.h>
    #include <time.h>
    
    // Constants used in the program.
    #define NUM_PEGS 4
    #define NUM_COLORS 6
    #define MAX_TURNS 10
    #define MARKED_BOARD -1
    #define MARKED_ANSWER -2
    
    // Functions used.
    void fillBoard(int board[]);
    int numPerfectMatches(int board[], int answer[]);
    void getUserGuess(int board[]);
    void copyArray(int dest[], int source[], int length);
    void markOutCorrect(int board[], int answer[]);
    int numWrongPlaceMatches(int board[], int answer[]);
    void greeting();
    void printArray(int array[], int length);
    void printWinner(int num_turns, int num_seconds);
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name);
    
    int main() {
        
        int multi;
        
        // ask if they are playing multiplayer or not
        printf("Are you wanting to play (type the number and press <ENTER>):\n");
        printf("1. Single Player\n2. Multiplayer\n");
        scanf("%d", &multi);
        
        if(multi != 1 && multi != 2) {
            
            // tell them they made an invalid choice
            printf("Invalid choice. Choose either 1 or 2 next time!\nGoodbye!\n");
            system("PAUSE");
            exit(0);
        
        }
        
        // do things based on their choice
        if(multi == 1) {
        
            // initialize leader variables
            int leader_minutes = 100, leader_seconds = 100, leader_time = 100, leader_turns = 100;
            char leader_name[20];
        
            // open leader file
            FILE *ifp;
            ifp = fopen("leader.txt", "r");
        
            // read in leader time and turns
            fscanf(ifp, "%d", &leader_minutes);
            fscanf(ifp, "%d", &leader_seconds);
            fscanf(ifp, "%d", &leader_turns);
            fscanf(ifp, "%s", leader_name);
    
            // convert time to seconds
            leader_time = (leader_minutes*60) + leader_seconds;
    
            // close file
            fclose(ifp);
        
            // Seed the random number generator.
            srand(time(0));
        
            // Stores the real answer and the user's board, respectively.
            int answer[NUM_PEGS];
            int board[NUM_PEGS];
        
            // Set everything up.
            int num_turns = 0;    
            fillBoard(answer);
            greeting();
            int start = time(0);
        
        } else if(multi == 2) {
        
            // ask them on how to play online
            printf("To play multiplayer you must have someone else playing with you. Please read the following carefully:\n");
            printf("1. You must have an internet connection\n2. You must have someone else who is going to play");
            printf("3. You can choose from 2 modes:");
            printf("\t A. Digit chooser (you pick four numbers for the guesser to have to play with)\n\t B. Guesser (the one that tries to guess the four numbers)\n");
            printf("So which will it be??? Type 1 for \"Digit Chooser\" or 2 for \"Guesser\"\n");
            scanf("%d", &multi);
        
            if(multi == 1) {
                
                int a = 0, b = 0, c = 0, d = 0;
                // tell them how to choose
                printf("You must choose from 4 numbers from 0-5. If you choose a number outside that range, the game will shut down!\n");
                printf("Which four will it be partner??\n");
                scanf("%d%d%d%d", &a, &b, &c, &d);
                
                // if any numbers are out of the 0-5 range, then exit out
                if(a < 0 || b < 0 || c < 0 || d < 0 || a > 5 || b > 5 || c > 5 || d > 5) {
                    printf("You chose a number outside the 0-5 range.\nGoodbye!\n");
                    system("PAUSE");
                    exit(0);
                }
                
                // if all of their numbers are correct, then encrypt them and upload them
                a = a*5+38;
                b = b*7+25;
                c = c*3+12;
                d = d*9+14;
                
                // open file for writing and add the numbers
                FILE *ifp;
                ifp = fopen("chooser.txt", "w+");
                fprintf(ifp, "%d %d %d %d", c, b, a, d);
            
                // close file
                fclose(ifp);
                
                // execute batch file
                system("up.bat");
                
                // tell the user it's done, and they may exit
                printf("If you followed all of the rules, your numbers should be in our database for a guesser to play!\n");
                
                system("PAUSE");
                exit(0);
                
            } else if(multi == 2) {
                
                int a, b, c, d;
                
                // download the file
                system("down.bat");
                
                // open leader file
                FILE *ifp;
                ifp = fopen("chooser.txt", "r");
        
                // read in leader time and turns
                fscanf(ifp, "%d", &c);
                fscanf(ifp, "%d", &b);
                fscanf(ifp, "%d", &a);
                fscanf(ifp, "%d", &d);
    
                // close file
                fclose(ifp);
                
                // decrypt the numbers
                if(a-38 == 0)
                    a = 0;
                if(b-25 == 0)
                    b = 0;
                if(c-12 == 0)
                    c = 0;
                if(d-14 == 0)
                    d = 0;
                    
                if(a != 0)
                    a = a - 38 / 5;
                if(b != 0)
                    b = b - 25 / 7;
                if(c != 0)
                    c = c - 12 / 3;
                if(d != 0)
                    d = d - 14 / 9;
                
                // Stores the real answer and the user's board, respectively.
                int answer[NUM_PEGS];
                int board[NUM_PEGS];
        
                // Set everything up.
                int num_turns = 0;    
                answer[0] = a;
                answer[1] = b;
                answer[2] = c;
                answer[3] = d;
                greeting();
                int start = time(0);
                
            } else {
                
                // print invalid entry
                printf("Your choice was not valid. Next time choose either 1 or 2.\nGoodbye!\n");
                system("PAUSE");
                exit(0);
            
            }
        }
        
        
        
        // Loop through each turn, ending at 10 moves or a win.
        do {
            
            // Read in the user's guess.
            getUserGuess(board);
            
            // Figure out the number of matches.
            int num_perfect = numPerfectMatches(board, answer);
            int num_imperfect = numWrongPlaceMatches(board, answer);
            
            // Update for this turn.
            printf("You have %d perfect matches and %d imperfect matches.\n", num_perfect, num_imperfect);
            num_turns++;
            
        } while (num_turns < MAX_TURNS && numPerfectMatches(board, answer) < NUM_PEGS);
        
        // Winning case.
        if (numPerfectMatches(board, answer) == NUM_PEGS) {
            int end = time(0);
            newLeader(leader_time, leader_turns, num_turns, end-start, leader_name);
            printWinner(num_turns, end-start);
        }
        
        // Losing case.
        else {
            printf("Sorry, you have exceeded the maximum number of turns. You lose.\n");
            printf("Here is the winning board: ");
            printArray(answer, NUM_PEGS);
            printf("\n");
        }
        
        system("PAUSE");
        return 0;
    }
    
    // Pre-conditions: board is uninitialized and of size NUM_PEGS.
    // Post-conditions: board will be filled in randomly with values ranging from
    //                  0 to NUM_COLORS-1.
    void fillBoard(int board[]) {
        
        // initialize the variable
        int i;
        
        // fill board with random numbers from 0 to num_colors-1
        for(i=0; i<NUM_PEGS; i++)
            board[i] = rand()%NUM_COLORS;
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at the correct spots.
    int numPerfectMatches(int board[], int answer[]) {
        
        // initialize the variables
        int i, matches = 0;
        
        // if what the user guessed matches the answer exactly, add one to amount of matches
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i])
                matches++;
        }
        
        return matches;
            
    }
    
    // Pre-conditions: None.
    // Post-conditions: Prints out a greeting for the beginning of the game.
    void greeting() {
        
        // print the whole greeting
        printf("At each turn, you will enter your guess for the playing board.\n");
        printf("A valid guess has 4 values in between 0 and 5.\n");
        printf("Each guess will have each number within the guess separated by a space.\n");
        printf("When you are ready, enter your first guess.\n");
        printf("From that point on, you will be told how many perfect and imperfect matches you have.\n");
        printf("After this message, you should guess again. You have 10 chances, good luck!\n");
        
    }
    
    // Pre-conditions: board is of length NUM_PEGS
    // Post-conditions: NUM_PEGS integers are read in from the user and stored in
    //                  board in the natural order.
    void getUserGuess(int board[]) {
        
        // initialize the variable
        int i;
        
        // keep scanning for intigers for as many numbers as the array is long
        for(i=0; i<NUM_PEGS; i++){
            scanf("%d", &board[i]);
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at INCORRECT spots
    //                  after "erasing" those pegs that match at correct spots.
    int numWrongPlaceMatches(int board[], int answer[]) {
        
        // initialize the variables
        int tempboard[NUM_PEGS], tempanswer[NUM_PEGS], i, x, matches = 0, matching[NUM_COLORS]; 
          
        // Create temporary copies of both boards, since we'll need to make changes
        // to each during this process and we don't want to ruin the original
        // state of either board.
        copyArray(tempboard, board, NUM_PEGS);
        copyArray(tempanswer, answer, NUM_PEGS);
        
        // Mark out the spots on the board and answer that match up perfectly.
        markOutCorrect(tempboard, tempanswer);
        
        // Go through the board and try to match each peg on the board to
        // a spot on the answer. Hint: A double loop is needed.
        // Note: Remember to "mark" an answer when a match is found.
        
        // loop for each board and answer array integer
        for(i=0; i<NUM_PEGS; i++) {
            for(x=0; x<NUM_PEGS; x++) {
                
               // if the answers match and they are not marked, add one to matches and mark them
               if(tempboard[i] == tempanswer[x] && tempboard[i] >= 0){
                    matches++;
                    tempboard[i] = MARKED_BOARD;
                    tempanswer[x] = MARKED_ANSWER;
                }
                
            }
        }
        
        return matches;
        
    }
    
    // Pre-conditions: dest and source are both have the given length.
    // Post-conditions: All values from source are copied into the corresponding
    //                  locations in dest.
    void copyArray(int dest[], int source[], int length) {
        
        // initialize the variable
        int i;
        
        // for the length of the array, copy each number from source to dest    
        for(i=0; i<length; i++) {
            dest[i] = source[i];
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS.
    // Post-conditions: For each corresponding slot that matches in both boards,
    //                  the slots are changed to equal each board's appropriate
    //                  marker.
    void markOutCorrect(int board[], int answer[]) {
        
        // initialize the variable
        int i;
        
        // where the board number is same as the answer number, change both to their appropriate marker
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i]) {
                board[i] = MARKED_BOARD;
                answer[i] = MARKED_ANSWER;
            }
        }
        
    }
    
    // Pre-conditions: array has the given length.
    // Post-conditions: each value of array is printed, separated by a space.
    void printArray(int array[], int length) {
        
        // initialize the variable
        int i;
        
        // print each number in the array with a space after it
        for(i=0; i<length; i++){
            printf("%d ", array[i]);
        }
        
    }
    
    // Pre-conditions: num_turns is the number of turns it took the winner to win,
    //                 and num_seconds is the total amount of time they took to
    //                 win in seconds.
    // Post-conditions: A winning message is printed stating the number of moves
    //                  and amount of time taken to win in M:SS format.
    void printWinner(int num_turns, int num_seconds) {
         
         // initialize the variable
         int num_minutes;
         
         // calculate number of minutes and seconds
         num_minutes = num_seconds/60;
         num_seconds = num_seconds%60;
         
         // print out the congrats line
         printf("You have won the game in %d turns, and in %d:%02d!!!\n", num_turns, num_minutes, num_seconds);
         
    }
    
    
    
    // Pre-conditions: leader_time and leader_turns are passed along with num_turns and end-start 
    // Post-conditions: leader_time and end-start are compared to see which is bigger (if a new leader was set)
    // and if end-start is less, then the file is written to make that the new leader
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name) {
        
        int name;
        
        if(leader_turns > num_turns) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else if(leader_turns == num_turns && leader_time > time) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else {
            
            printf("The leader (%s) won the game in %d turns, and in %d:%02d!!!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            
        }
        
    }

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    One last thing to demonstrate what I mean. If you tried to compile that last code I put, then run it, press 1 for single player, then type 4 numbers in from 0 to 5 as a guess, it will just go straight to the fail clause and the numbers that it prints out for the winnings 4 numbers are all some crazy numbers in the 10,000s. Usually, it would keep asking you for guesses for 10 turns, and only THEN would it show the actual 4 answers, which are from 0 to 5.

  7. #7
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    If you look inside the first if clause you have:

    Code:
    int answer[NUM_PEGS];
    /*..... later inside the SAME if .... */
    
    fillBoard(answer);
    The answer array seems to be uninitialized.

    NEVERMIND my bad, you are initializing it in fillBoard at the beginning.
    Last edited by claudiu; 03-21-2010 at 12:04 AM. Reason: Mistake

  8. #8
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Ok here's why the program crashes. NUM_PEGS is 4!

    What you want is for answer[] and board[] to be of size 5! You are always initializing them as:

    Code:
    int answer[NUM_PEGS];
    int board[NUM_PEGS];
    Allocate NUM_PEGS + 1 instead; if you allocate 4 spots for an array that means you can use :

    array[0],array[1],array[2],array[3] --- EXACTLY 4 spots. NOT up to array[4] which would be 5 spots.

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    Quote Originally Posted by claudiu View Post
    Ok here's why the program crashes. NUM_PEGS is 4!

    What you want is for answer[] and board[] to be of size 5! You are always initializing them as:

    Code:
    int answer[NUM_PEGS];
    int board[NUM_PEGS];
    Allocate NUM_PEGS + 1 instead; if you allocate 4 spots for an array that means you can use :

    array[0],array[1],array[2],array[3] --- EXACTLY 4 spots. NOT up to array[4] which would be 5 spots.
    Thank you for your help but that is not the problem. They are only allowed to have 4 numbers that they guess, so 0, 1, 2 and 3 would be appropriate. Nothing in the functionality is wrong if I take the if statements out. If, for example, I take the first if out, which is if they press 1 for single player, and I just keep the statements that are inside, and comment out all of the other ifs, it will work fine in single player. If I just put an if statement around part of the code, it will just spit crazy numbers and not work. It has something to do with the extra functions not receiving the variables correctly, because when I was just making the program and I wasn't done with the functions, it would do the same thing, just spit out random numbers.

  10. #10
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    If I commented out the whole sections like I do in the following code, the code functions properly:

    Code:
    #include <stdio.h>
    #include <time.h>
    
    // Constants used in the program.
    #define NUM_PEGS 4
    #define NUM_COLORS 6
    #define MAX_TURNS 10
    #define MARKED_BOARD -1
    #define MARKED_ANSWER -2
    
    // Functions used.
    void fillBoard(int board[]);
    int numPerfectMatches(int board[], int answer[]);
    void getUserGuess(int board[]);
    void copyArray(int dest[], int source[], int length);
    void markOutCorrect(int board[], int answer[]);
    int numWrongPlaceMatches(int board[], int answer[]);
    void greeting();
    void printArray(int array[], int length);
    void printWinner(int num_turns, int num_seconds);
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name);
    
    int main() {
        
    //    int multi;
        
        // ask if they are playing multiplayer or not
    /*    printf("Are you wanting to play (type the number and press <ENTER>):\n");
        printf("1. Single Player\n2. Multiplayer\n");
        scanf("%d", &multi);
        
        if(multi != 1 && multi != 2) {
            
            // tell them they made an invalid choice
            printf("Invalid choice. Choose either 1 or 2 next time!\nGoodbye!\n");
            system("PAUSE");
            exit(0);
        
        }
        
        // do things based on their choice
        if(multi == 1) {
    */    
            // initialize leader variables
            int leader_minutes = 100, leader_seconds = 100, leader_time = 100, leader_turns = 100;
            char leader_name[20];
        
            // open leader file
            FILE *ifp;
            ifp = fopen("leader.txt", "r");
        
            // read in leader time and turns
            fscanf(ifp, "%d", &leader_minutes);
            fscanf(ifp, "%d", &leader_seconds);
            fscanf(ifp, "%d", &leader_turns);
            fscanf(ifp, "%s", leader_name);
    
            // convert time to seconds
            leader_time = (leader_minutes*60) + leader_seconds;
    
            // close file
            fclose(ifp);
        
            // Seed the random number generator.
            srand(time(0));
        
            // Stores the real answer and the user's board, respectively.
            int answer[NUM_PEGS];
            int board[NUM_PEGS];
        
            // Set everything up.
            int num_turns = 0;    
            fillBoard(answer);
            greeting();
            int start = time(0);
        
    /*    } else if(multi == 2) {
        
            // ask them on how to play online
            printf("To play multiplayer you must have someone else playing with you. Please read the following carefully:\n");
            printf("1. You must have an internet connection\n2. You must have someone else who is going to play");
            printf("3. You can choose from 2 modes:");
            printf("\t A. Digit chooser (you pick four numbers for the guesser to have to play with)\n\t B. Guesser (the one that tries to guess the four numbers)\n");
            printf("So which will it be??? Type 1 for \"Digit Chooser\" or 2 for \"Guesser\"\n");
            scanf("%d", &multi);
        
            if(multi == 1) {
                
                int a = 0, b = 0, c = 0, d = 0;
                // tell them how to choose
                printf("You must choose from 4 numbers from 0-5. If you choose a number outside that range, the game will shut down!\n");
                printf("Which four will it be partner??\n");
                scanf("%d%d%d%d", &a, &b, &c, &d);
                
                // if any numbers are out of the 0-5 range, then exit out
                if(a < 0 || b < 0 || c < 0 || d < 0 || a > 5 || b > 5 || c > 5 || d > 5) {
                    printf("You chose a number outside the 0-5 range.\nGoodbye!\n");
                    system("PAUSE");
                    exit(0);
                }
                
                // if all of their numbers are correct, then encrypt them and upload them
                a = a*5+38;
                b = b*7+25;
                c = c*3+12;
                d = d*9+14;
                
                // open file for writing and add the numbers
                FILE *ifp;
                ifp = fopen("chooser.txt", "w+");
                fprintf(ifp, "%d %d %d %d", c, b, a, d);
            
                // close file
                fclose(ifp);
                
                // execute batch file
                system("up.bat");
                
                // tell the user it's done, and they may exit
                printf("If you followed all of the rules, your numbers should be in our database for a guesser to play!\n");
                
                system("PAUSE");
                exit(0);
                
            } else if(multi == 2) {
                
                int a, b, c, d;
                
                // download the file
                system("down.bat");
                
                // open leader file
                FILE *ifp;
                ifp = fopen("chooser.txt", "r");
        
                // read in leader time and turns
                fscanf(ifp, "%d", &c);
                fscanf(ifp, "%d", &b);
                fscanf(ifp, "%d", &a);
                fscanf(ifp, "%d", &d);
    
                // close file
                fclose(ifp);
                
                // decrypt the numbers
                if(a-38 == 0)
                    a = 0;
                if(b-25 == 0)
                    b = 0;
                if(c-12 == 0)
                    c = 0;
                if(d-14 == 0)
                    d = 0;
                    
                if(a != 0)
                    a = a - 38 / 5;
                if(b != 0)
                    b = b - 25 / 7;
                if(c != 0)
                    c = c - 12 / 3;
                if(d != 0)
                    d = d - 14 / 9;
                
                // Stores the real answer and the user's board, respectively.
                int answer[NUM_PEGS];
                int board[NUM_PEGS];
        
                // Set everything up.
                int num_turns = 0;    
                answer[0] = a;
                answer[1] = b;
                answer[2] = c;
                answer[3] = d;
                greeting();
                int start = time(0);
                
            } else {
                
                // print invalid entry
                printf("Your choice was not valid. Next time choose either 1 or 2.\nGoodbye!\n");
                system("PAUSE");
                exit(0);
            
            }
        }
    */    
        
        
        // Loop through each turn, ending at 10 moves or a win.
        do {
            
            // Read in the user's guess.
            getUserGuess(board);
            
            // Figure out the number of matches.
            int num_perfect = numPerfectMatches(board, answer);
            int num_imperfect = numWrongPlaceMatches(board, answer);
            
            // Update for this turn.
            printf("You have %d perfect matches and %d imperfect matches.\n", num_perfect, num_imperfect);
            num_turns++;
            
        } while (num_turns < MAX_TURNS && numPerfectMatches(board, answer) < NUM_PEGS);
        
        // Winning case.
        if (numPerfectMatches(board, answer) == NUM_PEGS) {
            int end = time(0);
            newLeader(leader_time, leader_turns, num_turns, end-start, leader_name);
            printWinner(num_turns, end-start);
        }
        
        // Losing case.
        else {
            printf("Sorry, you have exceeded the maximum number of turns. You lose.\n");
            printf("Here is the winning board: ");
            printArray(answer, NUM_PEGS);
            printf("\n");
        }
        
        system("PAUSE");
        return 0;
    }
    
    // Pre-conditions: board is uninitialized and of size NUM_PEGS.
    // Post-conditions: board will be filled in randomly with values ranging from
    //                  0 to NUM_COLORS-1.
    void fillBoard(int board[]) {
        
        // initialize the variable
        int i;
        
        // fill board with random numbers from 0 to num_colors-1
        for(i=0; i<NUM_PEGS; i++)
            board[i] = rand()%NUM_COLORS;
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at the correct spots.
    int numPerfectMatches(int board[], int answer[]) {
        
        // initialize the variables
        int i, matches = 0;
        
        // if what the user guessed matches the answer exactly, add one to amount of matches
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i])
                matches++;
        }
        
        return matches;
            
    }
    
    // Pre-conditions: None.
    // Post-conditions: Prints out a greeting for the beginning of the game.
    void greeting() {
        
        // print the whole greeting
        printf("At each turn, you will enter your guess for the playing board.\n");
        printf("A valid guess has 4 values in between 0 and 5.\n");
        printf("Each guess will have each number within the guess separated by a space.\n");
        printf("When you are ready, enter your first guess.\n");
        printf("From that point on, you will be told how many perfect and imperfect matches you have.\n");
        printf("After this message, you should guess again. You have 10 chances, good luck!\n");
        
    }
    
    // Pre-conditions: board is of length NUM_PEGS
    // Post-conditions: NUM_PEGS integers are read in from the user and stored in
    //                  board in the natural order.
    void getUserGuess(int board[]) {
        
        // initialize the variable
        int i;
        
        // keep scanning for intigers for as many numbers as the array is long
        for(i=0; i<NUM_PEGS; i++){
            scanf("%d", &board[i]);
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS and store the player's
    //                 guess and the correct board, respectively.
    // Post-conditions: returns the number of pegs that match at INCORRECT spots
    //                  after "erasing" those pegs that match at correct spots.
    int numWrongPlaceMatches(int board[], int answer[]) {
        
        // initialize the variables
        int tempboard[NUM_PEGS], tempanswer[NUM_PEGS], i, x, matches = 0, matching[NUM_COLORS]; 
          
        // Create temporary copies of both boards, since we'll need to make changes
        // to each during this process and we don't want to ruin the original
        // state of either board.
        copyArray(tempboard, board, NUM_PEGS);
        copyArray(tempanswer, answer, NUM_PEGS);
        
        // Mark out the spots on the board and answer that match up perfectly.
        markOutCorrect(tempboard, tempanswer);
        
        // Go through the board and try to match each peg on the board to
        // a spot on the answer. Hint: A double loop is needed.
        // Note: Remember to "mark" an answer when a match is found.
        
        // loop for each board and answer array integer
        for(i=0; i<NUM_PEGS; i++) {
            for(x=0; x<NUM_PEGS; x++) {
                
               // if the answers match and they are not marked, add one to matches and mark them
               if(tempboard[i] == tempanswer[x] && tempboard[i] >= 0){
                    matches++;
                    tempboard[i] = MARKED_BOARD;
                    tempanswer[x] = MARKED_ANSWER;
                }
                
            }
        }
        
        return matches;
        
    }
    
    // Pre-conditions: dest and source are both have the given length.
    // Post-conditions: All values from source are copied into the corresponding
    //                  locations in dest.
    void copyArray(int dest[], int source[], int length) {
        
        // initialize the variable
        int i;
        
        // for the length of the array, copy each number from source to dest    
        for(i=0; i<length; i++) {
            dest[i] = source[i];
        }
        
    }
    
    // Pre-conditions: board and answer are of length NUM_PEGS.
    // Post-conditions: For each corresponding slot that matches in both boards,
    //                  the slots are changed to equal each board's appropriate
    //                  marker.
    void markOutCorrect(int board[], int answer[]) {
        
        // initialize the variable
        int i;
        
        // where the board number is same as the answer number, change both to their appropriate marker
        for(i=0; i<NUM_PEGS; i++) {
            if(board[i] == answer[i]) {
                board[i] = MARKED_BOARD;
                answer[i] = MARKED_ANSWER;
            }
        }
        
    }
    
    // Pre-conditions: array has the given length.
    // Post-conditions: each value of array is printed, separated by a space.
    void printArray(int array[], int length) {
        
        // initialize the variable
        int i;
        
        // print each number in the array with a space after it
        for(i=0; i<length; i++){
            printf("%d ", array[i]);
        }
        
    }
    
    // Pre-conditions: num_turns is the number of turns it took the winner to win,
    //                 and num_seconds is the total amount of time they took to
    //                 win in seconds.
    // Post-conditions: A winning message is printed stating the number of moves
    //                  and amount of time taken to win in M:SS format.
    void printWinner(int num_turns, int num_seconds) {
         
         // initialize the variable
         int num_minutes;
         
         // calculate number of minutes and seconds
         num_minutes = num_seconds/60;
         num_seconds = num_seconds%60;
         
         // print out the congrats line
         printf("You have won the game in %d turns, and in %d:%02d!!!\n", num_turns, num_minutes, num_seconds);
         
    }
    
    
    
    // Pre-conditions: leader_time and leader_turns are passed along with num_turns and end-start 
    // Post-conditions: leader_time and end-start are compared to see which is bigger (if a new leader was set)
    // and if end-start is less, then the file is written to make that the new leader
    void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name) {
        
        int name;
        
        if(leader_turns > num_turns) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else if(leader_turns == num_turns && leader_time > time) {
            
            char name[30];
            
            // print the congrats letter
            printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            printf("What is your name? (up to 30 characters long)\n");
            scanf("%s", name);
            
            // open file for writing and change times to new times
            FILE *ifp;
            ifp = fopen("leader.txt", "w+");
            fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
            
            // close file
            fclose(ifp);
            
        } else {
            
            printf("The leader (%s) won the game in %d turns, and in %d:%02d!!!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
            
        }
        
    }

    So what I commented out is everything commented out with the /* to */. If I comment that out, and just leave choice 1 without the if statements, it works fine. But if I had an if statement and chose choice 1, it would spit crazy numbers at the end

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Methinks you need to come up with a basic model of what you are trying to do so you can write a short, separate program to test the premises involved, rather than fooling around with masses of code this way. You may think that will be a waste of time but most likely you will save yourself some time and effort by doing it and make it easier for other people to provide advice.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So if you choose 1 for single player, you read in the leaderboard, fill in the answer board, and then, well, then you hit the close brace, so all your variables go out of scope. If you want (say) answer to still exist when you get to the part where you play the game, then don't declare it inside your smaller single-player loop up top.

  13. #13
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    Quote Originally Posted by tabstop View Post
    So if you choose 1 for single player, you read in the leaderboard, fill in the answer board, and then, well, then you hit the close brace, so all your variables go out of scope. If you want (say) answer to still exist when you get to the part where you play the game, then don't declare it inside your smaller single-player loop up top.
    Ohh okay, so my variables don't exist anymore when the if stops?? Should I just copy everything after the if statements inside each if statement?? Or is there a way to keep the variables going??

    Thanks!!

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Declare the variables in the scope you want them to exist. If you want answer[] to exist during the entire program, then declare it in that scope.

    EXCEPT: You already did! Right there, the first line of your program!

    So this comes down to: don't make another answer[] that only exists during that scope -- use the one that's already there.

  15. #15
    Registered User
    Join Date
    Jan 2010
    Posts
    18
    Quote Originally Posted by tabstop View Post
    Declare the variables in the scope you want them to exist. If you want answer[] to exist during the entire program, then declare it in that scope.

    EXCEPT: You already did! Right there, the first line of your program!

    So this comes down to: don't make another answer[] that only exists during that scope -- use the one that's already there.
    Ahhhh!!! You are right!! I was initializing it again within the if. I understand now why it wasn't working. Thanks so much!!! I now just have it initialize once at the beginning and then I erased where it was initializing inside the if statements and it works like a charm now. Thanks a lot again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  4. Need some help...
    By darkconvoy in forum C Programming
    Replies: 32
    Last Post: 04-29-2008, 03:33 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM