0

I am trying to write the code of the board game "Mastermind"(homework). I am almost finished writing the main part. Unfortunately, I have an unstable if statement that I can't explain by debugging with Netbeans.

In the following code the if statement of line 58, doesn't always work. The game is like this:

  1. The user enters the number of colours that wants to be "randomly" generated
  2. The user tries to guess (break the code) the colors.
  3. If N=4(for example), then the user enters a sequence of 4 colours trying to guess them. 4.The program checks if he was right or not and gives back feedback.

The 6 colors are: W:White, B:Blue, G:Green, Y:Yellow, P:Purple and R:Red.

The following code is only a portion of the whole. Please forgive me for using gets and for declaring variables not used in this portion. There are also some "stupid" parts, but they will be changed after the code works as it should :) Could you please help me debug this if statement of line 58? (You will see the comment next to it).

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char *colour(char *xr, int N);
int RandomInteger(int low, int high);

int main()
{
    int i,j,q,N,w,z,k,A[6][4],win;
    char *xr,*xrx,temp[1],sur[]="SURRENDER";

    printf("Gimme number from 1-100");
    scanf("%d",&N);
    getchar();

    for(i=0; i<6; i++) A[i][1]=0;
    for(i=0; i<6; i++) A[i][2]=0;
    for(i=0; i<6; i++) A[i][3]=0;
    A[0][0]=87,A[1][0]=66,A[2][0]=71,A[3][0]=89,A[4][0]=80,A[5][0]=82;
    xr=malloc(N*sizeof(char));
    xrx=malloc(N*sizeof(char));
    xr=colour(xr,N);

    printf("\nxr: %s",xr);
    i=0;
    q=0;
    z=1;
    printf("\nGimme the color sequence: ");
    gets(xrx);
    //if(strcmp(xrx,sur)==0) goto end;

    while(xrx[i])
    {
   if(xrx[i]!=87 && xrx[i]!=66 && xrx[i]!=71 && xrx[i]!=89 && xrx[i]!=80 && xrx[i]!=82)               
       {z=0;}
       if(z==0) 
       {
           printf("\nGimme the color sequence: ");
           gets(xrx);
           i=0; 
           z=1;
       }
       else i++;
    }

    i=k=q=0;
    while(xr[i])
    {
    if(xr[i]==xrx[i]) 
    {
            q++;
            for(w=0; w<=5; w++)
            {
                     if(xr[i]==A[w][0]) //SOMETIMES IT DOESN'T WORK
                     {
                             printf("\nhere:");
                             A[w][3]=1;
                             printf("%d",A[w][3]);
                             break;
                     }
            } 
    }
    i++;
    }
    printf("\nColor and position correct: %d",q);
    for(i=0; i<=5; i++) printf("\n%d",A[i][3]); //PERIERGO


   // end:
   printf("!!BYE!!");
   return 0;
}

char *colour(char *xr, int N)
{
    int r,i,j,number;
    char *str,temp[2];

    str=calloc(N,sizeof(char));
    srand((int)time(NULL));
    for(j=0; j<N; j++)
    {
       r=RandomInteger(0,5);
       if(r==0)
       {
           temp[0]='W';
           temp[1]='\0';
           strcat(str,temp);
       }
       else if(r==1)
       {
       temp[0]='B';
       temp[1]='\0';
       strcat(str,temp);
       }
       else if(r==2)
       {
           temp[0]='G';
           temp[1]='\0';
           strcat(str,temp);
       }
       else if(r==3)
       {
           temp[0]='Y';
           temp[1]='\0';
           strcat(str,temp);
       }
       else if(r==4)
       {
           temp[0]='P';
           temp[1]='\0';
           strcat(str,temp);
       }
       else if(r==5)
       {
           temp[0]='R';
           temp[1]='\0';
           strcat(str,temp);
       }
    }
    return str;
}

int RandomInteger(int low, int high)
{
    int k;
    double d;
    d=(double)rand()/((double)RAND_MAX+1);
    k=(int)(d*(high-low+1));
    return (low+k);
}
alex777
  • 167
  • 5
  • 14
  • Please explain `SOMETIMES IT DOESN'T WORK`: exactly what should it do, and what does it do instead? – ppeterka Jan 10 '13 at 08:58
  • What values does xr[i] and a[w][0] have when the problem occurs? And what's the problem that occurs, does it crash? does the if give the wrong result? – dutt Jan 10 '13 at 08:59
  • Why hello memory leaks. You `malloc` `xr` and then set it to the result of a function that allocates new memory. – chris Jan 10 '13 at 09:00
  • SOMETIMES: I don't get the correct values. – alex777 Jan 10 '13 at 09:16

1 Answers1

4

This is accessing beyond the bounds of the array, causing undefined behaviour:

for(i=0; i<5; i++) A[i][3]=0;

as A has dimensions [5][3]. Array indexes run from 0 to N - 1 where N is the number of elements in the array. There other occurrences of out of bounds accesses:

A[5][0]=82;

and within function color():

char *str,temp[1];
str=malloc(N*sizeof(char)); /*Note sizeof(char) is guaranteed to be 1: omit.*/

/* snip */
temp[1]='\0';

str needs to be larger by one (unsure why temp even exists).

Instead of looping to set all elements in array A to zeroes use an aggregate initializer:

int A[5][3] = { { 0 } };

See Why is the gets function so dangerous that it should not be used?

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • Ahh :s but I don't get any warning... thanks for that!! This is why I wouldn't get the column number 3 in the variables section of the debugger!!! – alex777 Jan 10 '13 at 09:01
  • Yeah but A[i][0] has not zeros! – alex777 Jan 10 '13 at 09:06
  • 1
    @alex777, you could type out the entire initializer: `int A[5][3] = { { 87, /* 0, 0, 0, 0 */ }, { 66 }, etc } ;` – hmjd Jan 10 '13 at 09:09
  • temp is a raw way to make the strcat between a char and a string. If you have a better way please tell me!!! – alex777 Jan 10 '13 at 09:11
  • 1
    @alex777, `str` is not initialized so the initial `strcat()` will fail (as `strcat()` will search for last null terminator in the destination buffer). `str` also needs one more element to store the terminating null and it should be `temp[2]`. – hmjd Jan 10 '13 at 09:14
  • I did calloc istead of malloc for str(in order to initialize it) and I changed temp!! – alex777 Jan 10 '13 at 09:19
  • Thanks a lot for the gets function link and for the overall help!! – alex777 Jan 10 '13 at 09:25