Thread: C Subroutine produces odd results

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    12

    C Subroutine produces odd results

    This program is basically a single line minesweeper game. All I have here is the process of selecting where to put mines and displaying them.... but the subroutine to do that is messed up somewhere....can anyone tell me where?

    It's meant to place:
    MMM, MM, MM, M, M, M at random in the array "grid"... there must be at least one space between them though
    all others are marked as E..... so I set them all to E and just changed certain ones to M.

    What happens is that they sometimes appear next to each other...even though they shouldnt... and I only get "MMM", "MM", and "M"..... but am missing two single Ms and one MM.

    Code follows:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    void placemines (char *grid, int number, int reps) {
    
    	int i, check = 0, minepos = 0, count, flag, endcheck;
    
    	for (count = 1; count <= reps; count++) {
    
    		int maxpos = 26 - number; // Sets maximum starting position
    
    		flag = number + 2;
    		endcheck = number + 1;
    
    		while (flag >= 1) {
    
    			srand((unsigned)time(NULL));
    			minepos = rand() % maxpos + 1; // Picks random start position
    
    			for (i = -1; i <= endcheck; i++) {
    
    				check = minepos + i;
    				if (grid[check] == 'E') flag--;
    				else if (grid[check] == 'M') flag++;
    
    			}
    
    		}
    
    		for (i = 0; i < number; i++) {
    
    			grid[minepos + i] = 'M'; // Set mines
    
    		}
    
    	}
    
    }
    
    int main () {
    
    	char grid[29], display[27]; // Set necessary arrays..
    	grid[28]='\0';
    	char play = 'y'; // Toggle for another game, yes by default 
    	int i, letter; // Set's necessary int variables
    
    	while (play == 'y') { // Enters playing loop.
    
    	    /* Initialisation Process */
    
    		for (i = 0; i <= 27; i++) {
    
    			grid[i]='E'; // Set's grid[0] to grid[27] to 'e' for 'empty'.
    
    		}
    
    		for (i = 1, letter = 'a'; i <= 26; i++, letter++) {
    
    			display[i] = letter; // Set up a-z display array.
    
    		}
    
    		placemines(grid,3,1); // Initialise mines, it's not pretty but it works
    		placemines(grid,2,2);
    		placemines(grid,1,3);
    
    
    		/* End Initialisation Process */
    
    		printf("Welcome To Entirely $$$$ 1D Minesweeper\n");
    
    		for (i = 1; i <= 26; i++) {
    
    			printf("  %c", display[i]); // Show letters
    
    		}
    
    		printf("\n");
    
    
    
    		for (i = 1; i <= 26; i++) {
    
    			printf("  %c", grid[i]); // Show grid
    
    		}
    
    		play = 'n'; // To stop it looping until I put in the exit option
    
    	}
    
    	return 0;
    
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    The real question is, why aren't you just using a two dimension array for your grid? You're making far too much work for yourself.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > srand((unsigned)time(NULL));
    Do NOT call this in a loop, all you're doing is making sure rand() returns the same answer until time actually changes (not likely in such a small loop).

    It should be
    Code:
    int main ( ) {
        /* declarations */
        srand((unsigned)time(NULL));
        /* rest of program */
    }
    > char grid[29], display[27];
    Magic numbers
    Your code is riddled with magic numbers, so much so that it's impossible to tell how they inter-relate

    For example, you would start with
    #define MAX_MINES 26
    If this is so, how do you get
    char grid[MAX_MINES+3]
    From what I can see, part of the problem seems to be related to you starting arrays at 1 rather than zero, but I doubt thats the whole story.

    If you choose a few suitable constants, you should make your code much more readable.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2003
    Posts
    12
    I dont see why a two dimensional grid would help............ anyway....

    Using minepos = rand() % maxpos + 1; on it's own without the srand() solves the problem, but it does give rise the new problem that the mines are always placed in the same positions.

    The usage of the display array is probably wrong, I agree, but I've deliberately used a larger grid so that I have a "space" at each end of the display.... i.e. [0] and [27] for use in the checking procedure.
    Doing this works around the fact that I would have to say "if it's at the end, dont check after or if it's at the start, dont check before"... and any problems likely to occur there.

    Also for simplicity....it's probably easier for me to use the same array numbers for display... as when someone enters a letter, I can refer to the same array position in both cases.

    Any idea how I can get the mines randomly placed? lol...

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > but it does give rise the new problem that the mines are always placed in the same positions.
    You did move srand() to main like I said, and didn't just delete it right?

    Post your latest code
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Nov 2003
    Posts
    12
    I just moved it further up the subroutine, instead of into main()... It seems to work now.

    Something is seriously wrong in my checking loop though, as occasionally I end up with "MMMM" or "MMMMM" etc... which should never happen.

    Code follows:

    Code:
    void placemines (char *grid, int number, int reps) {
    
    	srand((unsigned)time(NULL));
    
    	int i, check = 0, minepos = 0, count, flag, endcheck;
    
    	for (count = 1; count <= reps; count++) {
    
    		int maxpos = 26 - number; // Sets maximum starting position
    
    		flag = number + 2;
    		endcheck = number + 1;
    
    		while (flag >= 1) {
    
    			minepos = ((rand() % (maxpos + 1)) + 1);
    
    			printf("%d",minepos);
    			printf(",");
    			for (i = -1; i <= endcheck; i++) {
    
    				check = minepos + i;
    				if (grid[check] == 'E') flag--;
    				else if (grid[check] == 'M') flag++;
    
    			}
    
    		}
    
    		for (i = 0; i < number; i++) {
    
    			grid[minepos + i] = 'M'; // Set mines from start position
    
    		}
    
    	}
    
    }
    The main() etc is all the same.
    Last edited by IGAU; 11-22-2003 at 07:47 AM.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by IGAU
    I dont see why a two dimensional grid would help............ anyway....
    Why wouldn't it help? First off, a single dimension array is not a grid. It is a line or row. (Technicly it's a 1xN grid, but in reality, no one considers it such.) If you are using it as a grid, then how is it set up?

    xxxxxxx
    xxxxxxx
    xxxxxxx
    xxxxxxx

    Like so?

    xxxx
    xxxx
    xxxx
    xxxx
    xxxx
    xxxx
    xxxx

    Like so?

    What exactly? Also, if you are actually using it as a gid, then it makes much more sense to actually use something grid-like. (IE: A two dimension array!)

    Next, if it is just a single line, then it is very easy to see if there's a mine next to where you want and you can avoid that:
    Code:
    array[SIZE] = all Es.
    
    if( array[place_here -1] != 'E' || array[place_here] != 'E' || array[place_here +1] != 'E' )
        ...one of the three spaces is a M, which means there is a mine before, after or at the spot you're trying to use...
    There's a reason people use two dimension arrays for grids: Because they have 2 dimensions; astoundingly, so do grids.

    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Nov 2003
    Posts
    12
    Um...maybe I used the variable name "grid" badly, but I also said it's in a single row.... what I mean is........

    XXXXXXXXXXXXXXXXXXXXXXXXXX

    That's why it wont be much help

    Anyway..... I can deal with arrays ok, I think... the only problem I'm having is with the logic of the subroutine that places the mines themselves.....

    As described and shown above... it's supposed to check like so....
    for mines

    XXX

    it checks each side, to make sure there's a gap (i.e. it's supposed to check like so)

    CXXXC (Where C is checked but left alone, and X is where a mine is placed.)

    This is why I've left the array value at [0] open and added extras on the end... it ensures that there is always an "E" on 0 and 27, which simplifies the checking algorithm, as I dont have to include "if check < 1 dont look before" and all the rest.

    The only reason I'm doing this is to try and help someone who's learning (and as you can see, I'm not exactly an expert)....and this is as good an example as any, especially with all my screwups which we can both learn from

  9. #9
    Registered User
    Join Date
    Nov 2003
    Posts
    12
    Nevermind, figured it out now. Incrementing the flag wasn't enough, it needed to reset it to number + 2... works now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Odd results.. help?
    By MCyborg in forum C Programming
    Replies: 15
    Last Post: 11-14-2005, 07:24 PM
  2. Replies: 3
    Last Post: 07-11-2005, 03:07 AM
  3. _chdrive odd results
    By cyreon in forum Windows Programming
    Replies: 2
    Last Post: 06-23-2005, 05:35 PM
  4. Odd results for such a simple procedure.
    By tyouk in forum Windows Programming
    Replies: 2
    Last Post: 01-14-2005, 08:16 PM
  5. writing/reading from file produces double results.
    By stumon in forum C Programming
    Replies: 4
    Last Post: 03-20-2003, 04:01 PM