Thread: Array fills with junk - help

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    7

    Array fills with junk - help

    I'm writing a program that simulates the game mastermind. I'm working on implementing the last function and tweaking the other function before implementing the main game loop. But for some reason my array randomly generated by the computer fills with a weird sequence:

    Code:
     
    Enter max letter:
    D
    68  70Enter game dimension:
    3
    Enter the seed:
    1
    The right answer is: 6Starting game. . .
    You have 6 guesses left!
    Answer Sequeince: BBAv¿Enter Guess(3 chars):
    Am I trashing memory or is my random char generator and the filling sequence for the Answer array faulty? I highlighted the areas where I suspect mistakes.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define MAX_DIM 6
    #define MIN_DIM 3
    #define MAX_GUESSES 12
    #define MAXCHAR 'F'
    
    /* TODO - Declare the Guess structure here.
     *        The code should then compile.
     */
     typedef struct
    	{
    	char letters[MAX_DIM]; 	/*string that holds the characters of the guess*/
    	int exact;	/*int that holds the number of exact matches*/
    	int inexact;	/*int that holds the number of inexact matches*/
    	} Guess;
    
    /* This function already implemented.
     * Compile with "gcc mastermind.c util.o" to use it.
     * Otherwise, implement the function yourself and just compile with "gcc mastermind.c"
     */
    int calcMatches(char answer[], int dim, Guess guess, int *exact, int *inexact);
    
    /* Prototypes for functions you must implement */
    char getRandChar(char maxchar);
    void getGuess(char letters[], int dim, char maxChar);
    void printBoard(Guess guesses[], int tries, int dim);
    
    int main(void)
    {
       /* TODO - declare variables here */
    	char maxChar;
    	int Dim, seed, numGuess, i, ex, inex;
    	char Answer[3];
    	Guess Guesses;
    	
    	
    	
    
       /* TODO - get the max letter */
    	printf("Enter max letter:\n");
    	scanf(" %c", &maxChar);
    	printf("%d  %d", maxChar, MAXCHAR);
    	
    	while(maxChar > MAXCHAR)
    	{
    		printf("Max letter must be between A and F\n");
    		printf("Enter max letter:\n");
    		scanf(" %c", &maxChar);
    	}
    		
    
       /* TODO - get the dimension */
       printf("Enter game dimension:\n");
       scanf("%d", &Dim);
       
       while(MIN_DIM > Dim || Dim > MAX_DIM)
       {
    	   printf("Dimension must be between %d and %d\n", MIN_DIM, MAX_DIM);
    	   scanf("%d", &Dim);
       }
    
       
       /* TODO - get the seed and set up the random number generator */
       	printf("Enter the seed:\n");
       	scanf("%d", &seed);
       	srand(seed);
       
       /* TODO - determine maximum guesses based on max letter and dimension */
       	numGuess = ceil(Dim * ((MAXCHAR - 'A')+1)/3);
       	printf("The right answer is: %d", numGuess);
    
    
       /* TODO - main game loop here */
       	printf("Starting game. . .\n");
       	printf("You have %d guesses left!\n", numGuess);
       
        for(i=0; i<Dim; i++)
        	Answer[i] = getRandChar(maxChar);
        printf("Answer Sequeince: %s", Answer);  
       	
       	getGuess(Guesses.letters, Dim, maxChar); /*Get the guess*/
    	printf("The Guess is: %s\n", Guesses.letters);
    	
    	
    	calcMatches(Answer, Dim, Guesses, &ex, &inex);
    	printf("The exact and inexact matches: (%d,%d)", ex, inex);
    	
    	
    	
    
    	
       return 0;
    }
    
    /* TODO - Implement this function.
     * Use the rand() function to return a random character
     *    inbetween 'A' and the maxChar.
     */
    char getRandChar(char maxChar)
    {
       return (rand()%(maxChar-'A')+'A');  /* CHANGE THIS to rand()% 'maxChar' + 'A' */
    }
    
    /* TODO - Implement this function.
     * Prompt the user for characters to fill in the letters array.
     * Make sure all input characters are between 'A' and maxChar.
     * "dim" indicates how many letters to get.
     *
     * HINT: Do a "dummy" scanf before you start scanning chars,
     *       like we discussed in class.
     */
    void getGuess(char letters[], int dim, char maxChar)
    {
    int i;
    	printf("Enter Guess(%d chars):", dim);
    	scanf("%s", letters);
    	
    	for(i=0; i<2; i++)
    		while(letters[i]>'F')
    			{
    				printf("One or more chars out of range A-F, try again:");
    				scanf("%s", letters);
    			}
    }
     
    /* TODO - Implement this function.
     * Display the mastermind board according to the following example:
     *
     *       XXXX
     *       ----
     * (0,2) ABCD
     * (0,3) ABBD
     * (3,0) BEDE
     *
     * "tries" indicates how many guessess are in the Guess array.
     * "dim" indicates how many letters are in each Guess.
     */
    void printBoard(Guess guesses[], int tries, int dim)
    {
    	int i;
    	for(i=0; i < tries; i++)
    	{
    		printf("      XXXX\n");
    		printf("      ____\n");
    		printf("(%d,%d) %s", guesses[i].exact, guesses[i].inexact, guesses[i].letters);
    	}
    }
    
    
    
    int calcMatches(char answer[], int dim, Guess guess, int *exact, int *inexact)
    {
    	int j, count = 0, decount = 0;
    	/*inexact matches algorithm*/
    	if(dim == 3)
    	{
    		if(answer[0] == guess.letters[1]) /*first term*/
    			*inexact = count + 1;                     /*first term*/ 
    		if(answer[0] == guess.letters[2]) /*first term*/
    			*inexact = count + 1;                     /*first term*/ 
    		
    		if(answer[1] == guess.letters[0]) /*2nd term*/
    			*inexact++;                     /*2nd term*/
    		if(answer[1] == guess.letters[2]) /*2nd term*/
    			*inexact++;                     /*2nd term*/
    			
    		if(answer[2] == guess.letters[0])
    			*inexact++;
    		if(answer[2] == guess.letters[1])
    			*inexact++;		
    	}
    	
    	if(dim == 4)
    	{
    		if(answer[0] == guess.letters[1]) /*first term*/
    			*inexact++;                     /*first term*/ 
    		if(answer[0] == guess.letters[2]) /*first term*/
    			*inexact++;                     /*first term*/ 
    		if(answer[0] == guess.letters[3])
    			*inexact++;	
    		
    		if(answer[1] == guess.letters[0]) /*2nd term*/
    			*inexact++;                     /*2nd term*/
    		if(answer[1] == guess.letters[2]) /*2nd term*/
    			*inexact++;                     /*2nd term*/						
    		if(answer[1] == guess.letters[3])
    			*inexact++;
    		
    		if(answer[2] == guess.letters[0])
    			*inexact++;
    		if(answer[2] == guess.letters[1])
    			*inexact++;	
    		if(answer[2] == guess.letters[3])
    			*inexact++;
    			
    		for(j=0; j<(dim-1); j++)
    			if(answer[3] == guess.letters[j])
    				*inexact++;			
    	}
    		
    
    	if(dim == 5)
    	{
    		for(j=1; j<dim; j++)
    			if(answer[0] == guess.letters[j]) 		/*first term*/
    				*inexact++;
    	
    		if(answer[1] == guess.letters[0]) 			/*2nd term*/
    				*inexact++;
    		for(j=2; j<dim; j++)
    			if(answer[1] == guess. letters[j])
    				*inexact++;
    			
    		if(answer[2] == guess.letters[0])
    			*inexact++;
    		if(answer[2] == guess.letters[1])		/*3rd term*/
    			*inexact++;	
    		for(j=3; j<dim; j++)
    			if(answer[2] == guess.letters[j])
    				*inexact++;
    				
    		for(j=0; j<3; j++)
    			if(answer[3] == guess.letters[j])	/*4th term*/	
    				*inexact++;
    		if(answer[3] == guess.letters[4])
    			*inexact++;
    		
    		for(j=0; j<(4); j++)
    			if(answer[4] == guess.letters[j]) /*5th term*/
    				*inexact++;	
    	}
    	
    	
    	if(dim == 6)
    	{
    		for(j=1; j<dim; j++)
    			if(answer[0] == guess.letters[j]) 		/*first term*/
    				*inexact++;
    				
    		if(answer[1] == guess.letters[0]) 			/*2nd term*/
    				*inexact++;
    		for(j=2; j<dim; j++)
    			if(answer[1] == guess.letters[j])
    				*inexact++;
    				
    		if(answer[2] == guess.letters[0])
    			*inexact++;
    		if(answer[2] == guess.letters[1])		/*3rd term*/
    			*inexact++;	
    		for(j=3; j<dim; j++)
    			if(answer[2] == guess.letters[j])
    				*inexact++;
    				
    		for(j=0; j<(3); j++)
    			if(answer[3] == guess.letters[j])	/*4th term*/	
    				*inexact++;
    		if(answer[3] == guess.letters[4])
    			*inexact++;
    		if(answer[3] == guess.letters[5])
    			*inexact++;	
    			
    		for(j=0; j<4; j++)
    			if(answer[4] == guess.letters[j]) /*5th term*/
    				*inexact++;	
    		if(answer[4] == guess.letters[5])
    			*inexact++;
    			
    		for(j=0; j<5; j++)
    			if(answer[5] == guess.letters[j]) /*6th term*/
    				*inexact++;	
    	}
    	
    
    	/*exact matches algorithm*/
    	for(j=0; j<dim; j++)
    		if(answer[j] == guess.letters[j])
    			*exact = decount + 1;	
    }

    Thanks for the help!

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    First, I havent read your second post yet. This is regarding your first question.

    Answer Sequeince: BBAv¿Enter Guess(3 chars):
    Code:
        for(i=0; i<Dim; i++)
        	Answer[i] = getRandChar(maxChar);
        printf("Answer Sequeince: %s", Answer);
    Well its setting the 3 chars just fine, as you can see. The problem is that you didnt terminate the string, so when you print it, it will print the 3 characters then continue until it sees a '\0' somewhere in memory adjacent to the end of the string/char array. So after you fill up the array you have to terminate the string, so after the for loop do
    Code:
    Answer[Dim-1] = '\0';
    This means your string is actually only holding Dim-1 = 3-1=2 printable characters. If you want it to hold 3 printable characters, declare it as "char Answer[4]" instead of "[3]".

    Also, you should either hard code the size of the array or ask for the dimension of the array--not both. Right now you declare it as, again, "char Answer[3]", then ask how many characters to put in it ("Dim"). If I enter 1000, your program will let me and will then write to memory past this array, probably resulting in a segmentation fault. So either hard code the value to 3 (or whatever) and dont ask for it, or make it a pointer then ask for the size. Something like
    Code:
    char * Answer;
    // ask for size and store in Dim, as you are now.  Increase Dim by 1 to account for the null terminating character
    // then allocate Dim bytes of memory
    Answer = malloc( Dim );
    // its good practice to check if malloc returned NULL (i.e if Answer == NULL), which means it couldnt allocate Dim bytes of memory
    // fill in array with your for loop, then terminate it like:
    Answer[Dim-1] = '\0';

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  2. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  3. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM
  4. two dimensional dynamic array?
    By ichijoji in forum C++ Programming
    Replies: 6
    Last Post: 04-14-2003, 04:27 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM