Thread: Why is my program not replicating the desired output?

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    11

    Exclamation Why is my program not replicating the desired output?

    I have been trying to make a program which assists with a game called "Mastermind". If you are not familiar with this game it simply goes like this: there is a code which needs to be guessed, one player makes this code while another player tries to guess it, based on the guess the player gets a black peg for each of the letters he guessed which were in the right place, a white peg of each letter which was in the wrong place and belongs somewhere else in the pattern and finally no peg if the letter does not occur at all.
    My program is supposed to take in the guess, the number of white pegs and the number of black pegs and output all possible solutions. Plus one of the requirements is that the program must use recursion.

    Sample of how program should run:


    Enter the pattern length: 3
    Input the guess pattern: abc
    Enter the number of black pegs in the feedback: 2
    Enter the number of white pegs in the feedback: 0
    The possible key patterns are:
    aac
    aba
    abb
    abd
    abe
    abf
    acc
    adc
    aec
    afc
    bbc
    cbc
    dbc
    ebc
    fbc

    As you will be able to see by running the code I wrote my program obviously does not give the same output. (By the way i also converted the char array inputted to an int array and printed the contents as char)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    void userEnter(int*pattern, int n);
    void print( int * s, int n);
    void recurs( int * s, int * a, int n, int wpegs, int bpegs);
    bool Done (int*s);
    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n);
    bool wPegs(int* modcom, int* modoriginal, int*s, int wpegs, int w);
    void change(int*modoriginal, int*modcom, int i, int k, int w);
    
    int main(void)
    {
        int i, n, bpegs, wpegs;
        
        printf("Enter the pattern length: ");
        scanf("%d",&n);
        int *a = (int*)malloc((n)*(sizeof(int)));
        printf("Input the guess pattern: ");
        int pattern[n];
        userEnter(pattern, n);    
        printf("Enter the number of black pegs in the feedback: ");
        scanf("%d",&bpegs);
        printf("Enter the number of white pegs in the feedback: ");
        scanf("%d",&wpegs);
        printf("The possible key patterns are: ");
        for(i=0; i<=n-1; i++)
        {
            a[i]=0;
        }
        print(a, n);
        recurs(a, pattern, n, wpegs, bpegs);
            
    }
    
    
    void userEnter(int*pattern, int n)
    {
        char input[n];
        scanf("%s", input);
     
        int i;
        for(i = 0; i < n-1; i++)
        {
            pattern[i] = input[i]-65;
        }
    }
     
    void print( int * s, int n)
    {
        int i; 
        printf( "\n" );
        for( i = n-1; i >= 0; i-- )
        {
            printf( "%c", ( s[ i ] + 65 ) );
        }
    }
    
    
    void recurs( int * s, int * a, int n, int wpegs, int bpegs)
    {
       
        int i;
    
    
       
        if(Done(s))
        {
            print( s, n);
            printf( "\nAccomplisshed!\n" );
        }
    
    
        else{
            s[ 0 ] += 1;
            for( i = 0; i < n-1; i++ )
            {
                if( s[ i ] == 6 ){
                    s[ i ] = 0;
                    s[ i + 1 ] += 1;
                }
            }
            if(bPegs(a ,s, bpegs, wpegs, n))
            {
            print( s, n);
            }
            recurs(s, a, n, wpegs, bpegs);
        }
    }
    
    
    bool Done (int*s)
        {
            int i;
            bool done=true;
            for (i=0;i<=11;i++)
            {
                if(s[i]!=5)
                {
                    done=false;
                }
            }
            return done;
        }
        
        
    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n)
    {
        int i,j,c=0;
        bool d = false;
        for(i=0; i<n-1; i++)
        {
            if(a[i]=s[i])
            {
                c++;
            }
        }
        int x =n-c;
        int* modcom; 
        int*modoriginal;
        modcom=(int*)malloc((x)*(sizeof(int)));
        modoriginal=(int*)malloc((x)*(sizeof(int)));
        int w=0;
        for(j=0; j<n-1; j++)
        {
            if(a[j]!=s[j])
            {
                modcom[w]=s[j];
                modoriginal[w]=a[j];
                w++;
            }        
        }
        if(c=bpegs)
        {
            d = wPegs(modcom, modoriginal, s, wpegs, w);
        }
        
        return d;
        
    }
    
    
    bool wPegs(int*modcom, int*modoriginal, int*s, int wpegs, int w)
    {
        int i, k, count=0;
        for(i=0; i<=w; i++)
        {
            for(k=0; k<=w; k++)
            {
                if (modoriginal[i]==modcom[k])
                {
                    count++;
                    change(modoriginal, modcom, i, k, w);
                }
            }
        }
        if(wpegs=count)
        {
            return true;
        }
        
    }
    
    
    void change(int*modoriginal, int*modcom, int i, int k, int w)
    {
        int c, o;
        for(c=i-1; c<w-1; c++)
        {
            modoriginal[c]=modoriginal[c+1];
        }
        for(o=k-1;o<w-1;o++)
        {
            modcom[o]=modcom[o+1];
        }
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Compile with your warnings turned up (for gcc, use the "-Wall" option, other compilers, read the documentation):
    Code:
    $ make mastermind
    gcc -Wall -Werror -ggdb3 -std=c99 -pedantic  -lm -lpthread -lefence  mastermind.c   -o mastermind
    mastermind.c: In function ‘bPegs’:
    mastermind.c:114:9: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
    mastermind.c:134:5: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
    mastermind.c: In function ‘wPegs’:
    mastermind.c:158:5: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
    mastermind.c:163:1: error: control reaches end of non-void function [-Werror=return-type]
    cc1: all warnings being treated as errors
    make: *** [mastermind] Error 1
    Lines 114, 134 and 158: One = is assignment, two == is for comparison. You probably want two.
    Line 163: What happens if wpegs != count? You don't return anything, which will produce undefined behavior, IIRC. Make sure your code always has a path to a valid return statement. You probably just want a return false; at the end of the function.

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Thank you so much for all the corrections but now that I have fixed them and I run the program I get a "segmentation fault".

    Here's the updated code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    
    
    
    void userEnter(int*pattern, int n);
    void print( int * s, int n);
    void recurs( int * s, int * a, int n, int wpegs, int bpegs);
    bool Done (int*s);
    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n);
    bool wPegs(int* modcom, int* modoriginal, int*s, int wpegs, int w);
    void change(int*modoriginal, int*modcom, int i, int k, int w);
    
    
    int main(void)
    {
        int i, n, bpegs, wpegs;
        
        printf("Enter the pattern length: ");
        scanf("%d",&n);
        int *a = (int*)malloc((n)*(sizeof(int)));
        printf("Input the guess pattern: ");
        int pattern[n];
        userEnter(pattern, n);    
        printf("Enter the number of black pegs in the feedback: ");
        scanf("%d",bpegs);
        printf("Enter the number of white pegs in the feedback: ");
        scanf("%d",wpegs);
        printf("The possible key patterns are: ");
        for(i=0; i<=n-1; i++)
        {
            a[i]=0;
        }
        print(a, n);
        recurs(a, pattern, n, wpegs, bpegs);
            
    }
    
    
    void userEnter(int*pattern, int n)
    {
        char input[n];
        scanf("%s", input);
     
        int i;
        for(i = 0; i < n-1; i++)
        {
            pattern[i] = input[i]-65;
        }
    }
     
    void print( int * s, int n)
    {
        int i; 
        printf( "\n" );
        for( i = n-1; i >= 0; i-- )
        {
            printf( "%c", ( s[ i ] + 65 ) );
        }
    }
    
    
    void recurs( int * s, int * a, int n, int wpegs, int bpegs)
    {
       
        int i;
    
    
        if(Done(s))
        {
            print( s, n);
            printf( "\nAccomplisshed!\n" );
        }
    
    
        else{
            s[ 0 ] += 1;
            for( i = 0; i < n-1; i++ )
            {
                if( s[ i ] == 6 ){
                    s[ i ] = 0;
                    s[ i + 1 ] += 1;
                }
            }
            if(bPegs(a ,s, bpegs, wpegs, n))
            {
            print( s, n);
            }
            recurs(s, a, n, wpegs, bpegs);
        }
    }
    
    
    bool Done (int*s)
        {
            int i;
            bool done=true;
            for (i=0;i<=11;i++)
            {
                if(s[i]!=5)
                {
                    done=false;
                }
            }
            return done;
        }
        
        
    bool bPegs(int*a ,int*s, int bpegs, int wpegs, int n)
    {
        int i,j,c=0;
        bool d = false;
        for(i=0; i<n-1; i++)
        {
            if(a[i]==s[i])
            {
                c++;
            }
        }
        int x =n-c;
        int* modcom; 
        int*modoriginal;
        modcom=(int*)malloc((x)*(sizeof(int)));
        modoriginal=(int*)malloc((x)*(sizeof(int)));
        int w=0;
        for(j=0; j<n-1; j++)
        {
            if(a[j]!=s[j])
            {
                modcom[w]=s[j];
                modoriginal[w]=a[j];
                w++;
            }        
        }
        if(c==bpegs)
        {
            d = wPegs(modcom, modoriginal, s, wpegs, w);
        }
        
        return d;
        
    }
    
    
    bool wPegs(int*modcom, int*modoriginal, int*s, int wpegs, int w)
    {
        int i, k, count=0;
        for(i=0; i<=w; i++)
        {
            for(k=0; k<=w; k++)
            {
                if (modoriginal[i]==modcom[k])
                {
                    count++;
                    change(modoriginal, modcom, i, k, w);
                }
            }
        }
        if(wpegs==count)
        {
            return true;
        }
        else
        {
            return false;
        }
        
    }
    
    
    void change(int*modoriginal, int*modcom, int i, int k, int w)
    {
        int c, o;
        for(c=i-1; c<w-1; c++)
        {
            modoriginal[c]=modoriginal[c+1];
        }
        for(o=k-1;o<w-1;o++)
        {
            modcom[o]=modcom[o+1];
        }
    }

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You should learn to use a debugger, they're a great programming tool:
    Code:
    $ gdb ./mastermind
    GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i686-linux-gnu".
    For bug reporting instructions, please see:
    <http://bugs.launchpad.net/gdb-linaro/>...
    Reading symbols from /home/cgarvin/sandbox/cprogramming/mastermind...done.
    (gdb) run
    Starting program: /home/cgarvin/sandbox/cprogramming/mastermind
    Enter the pattern length: 3
    Input the guess pattern: abc
    Enter the number of black pegs in the feedback: 2
    Enter the number of white pegs in the feedback: 0
    The possible key patterns are:
    
    
    Program received signal SIGSEGV, Segmentation fault.
    0xb7e980ac in _int_malloc (av=0xb7fc7440, bytes=12) at malloc.c:3415
    3415    malloc.c: No such file or directory.
    (gdb) backtrace
    #0  0xb7e980ac in _int_malloc (av=0xb7fc7440, bytes=12) at malloc.c:3415
    #1  0xb7e9addc in __GI___libc_malloc (bytes=12) at malloc.c:2924
    #2  0x08048899 in bPegs (a=0xbffff590, s=0x804b008, bpegs=2, wpegs=0, n=3) at mastermind.c:122
    #3  0x080487bf in recurs (s=0x804b008, a=0xbffff590, n=3, wpegs=0, bpegs=2) at mastermind.c:84
    #4  0x080487fc in recurs (s=0x804b008, a=0xbffff590, n=3, wpegs=0, bpegs=2) at mastermind.c:88
    #5  0x080487fc in recurs (s=0x804b008, a=0xbffff590, n=3, wpegs=0, bpegs=2) at mastermind.c:88
    ...
    #44367  0x080487fc in recurs (s=0x804b008, a=0xbffff590, n=3, wpegs=0, bpegs=2) at mastermind.c:88
    ...
    That line starts the debugger with your program, ./mastermind
    That line runs your program, as though you ran it from the command line.
    Those lines are the input and output for the program, just like when you run it form the command line.
    Those lines are the debugger telling you there was a seg fault in malloc.c.
    That line tells the debugger to print a backtrace.
    Those lines are the backtrace, i.e. they show the state of all the function calls when your program crashed.

    I got tired of holding down "enter" to view the rest of the back trace. You have over 44,000 recursive calls to recurs with no end in sight. You keep calling recurs, but you never seem to move towards your done case, i.e. you never change any parameters in a way that will bring the recursion to an end. On top of that, each call to recurs calls bPegs, which in turn calls malloc, but never calls free. This is a memory leak, and part of your problem. Every call to malloc should have a corresponding call to free. Check out tools like valgrind (link) to help detect memory leaks.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Sorry this is coming through in spurts. A few more things:

    Your Done() function should probably take the pattern length as a parameter, so you only check valid spots in the array to see if you're done. No point in checking s[6] if you only have 3 elements in your pattern.

    Also, your for loop usage is inconsistent. I recommend the common C idiom of using < (not <=) and the length of the array (not length-1), when processing:
    Code:
    for (i = 0; i < N; i++)     // GOOD - covers all elements of an array of length N
    for (i = 0; i <= N-1; i++)  // OKAY - equivalent to the above, but atypical, and slightly more confusing to most people
    for (i = 0; i < N-1; i++)   // BAD - omits the last element
    for (i = 0; i <= N; i++)    // BAD - overflow, accesses one element past the end of the array, giving undefined behavior


    Though technically not required for C99 or later, I would consider it good form to actually return a value from main, since you (correctly) declared it to return an int. Try return 0; or return EXIT_SUCCESS;
    Last edited by anduril462; 11-16-2012 at 11:25 AM.

  6. #6
    Registered User
    Join Date
    Nov 2012
    Posts
    11

    Smile

    Well thanks a lot for your help and i'll definitely use a debugger next time before posting a question. Also i noticed that in my edited code I some how

    took out the & symbols from this piece of code.

    Code:
    
    scanf("%d",bpegs);
        printf("Enter the number of white pegs in the feedback: ");
        scanf("%d",wpegs);
    

    For now i'm just going to go back and fix all the problems you have pointed out.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 18
    Last Post: 08-31-2012, 10:17 AM
  2. Not Getting Desired Output
    By DevoAjit in forum C Programming
    Replies: 2
    Last Post: 03-09-2012, 05:46 AM
  3. Much desired program.
    By MannyCalavera in forum Projects and Job Recruitment
    Replies: 10
    Last Post: 09-23-2005, 05:40 PM
  4. Replies: 3
    Last Post: 01-08-2004, 09:43 PM
  5. not getting the desired output. WHY???
    By KristTlove in forum C++ Programming
    Replies: 4
    Last Post: 11-06-2003, 02:08 PM

Tags for this Thread