Thread: Craps Program with Local Variables

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12

    Craps Program with Local Variables

    I'm having extremely difficult problems with getting used to not using global variables. I'm trying to write this craps game so that it only uses local variables, but I am having difficult getting all my seperate functions to use variables they all depend on.

    My sample code is below, but let me explain my problem a little more in detail. If you see, I have the functions getWager() and adjustBalance(). Both these functions need to be able to read both the variables balance and wager, and modify them accordingly. Not only that, but adjustBalance() is also dependant on gameStatus, a part of the playGame() function.

    How can I use only local variables to get my program to be able to read and modify things like balance and wager while depending on things like gameStatus with just the expressions and statements I have here. I've tried looking elsewhere, but I've been unable to get an explanation that helps me out very much. My book for my class is also a total piece of garbage when it comes to something like this. Anyone help me out. I'd really appreciate it. Thanks.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> /* contains prototype for function time */
    
    /* enumeration constants represent game status */
    enum Status { CONTINUE, WON, LOST };
    
    int rollDice( void ); /* function prototype */
    int getWager(); /* getWager function prototype */
    int playGame(); /* playGame function prototype */
    void getYesOrNo(); /* getYesOrNo function prototype  */
    
    int main()
    {
      playGame();
      return 0;
    }
    
    
    /* PRE: none
       POST: returns to the caller one of the enumatered constants WON or LOST */
    
    int playGame ()
    { 
       int sum;        /* sum of rolled dice */
       int myPoint;    /* point earned */
    
       enum Status gameStatus; /* can contain CONTINUE, WON, or LOST */
    
       /* randomize random number generator using current time */
       srand( time( NULL ) );
    
       sum = rollDice(); /* first roll of the dice */
    
       /* determine game status based on sum of dice */
       switch( sum ) {
    
          /* win on first roll */
          case 7: 
          case 11:          
             gameStatus = WON;
             break;
    
          /* lose on first roll */
          case 2: 
          case 3: 
          case 12:  
             gameStatus = LOST;
             break;
    
          /* remember point */
          default:                  
             gameStatus = CONTINUE;
             myPoint = sum;
             printf( "Point is %d\n", myPoint );
             break; /* optional */
       } /* end switch */
    
       /* while game not complete */
       while ( gameStatus == CONTINUE ) {    
          sum = rollDice(); /* roll dice again */
    
          /* determine game status */
          if ( sum == myPoint ) { /* win by making point */
             gameStatus = WON; /* game over, player won */
          } /* end if */
          else {
    
             if ( sum == 7 ) { /* lose by rolling 7 */
                gameStatus = LOST; /* game over, player lost */
             } /* end if */
           
          } /* end else */
    
       } /* end while */
    
       /* display won or lost message */
       if ( gameStatus == WON ) { /* did player win? */
          printf( "Player wins\n" );
       } /* end if */
       else { /* player lost */ 
          printf( "Player loses\n" );
       } /* end else */
       
       if (balance > 0)
         {
           getYesOrNo();
         }
       else
         {
           printf("Your final balance is $%d.00", balance);
         }
       return balance;
    }
    
    
    /* roll dice, calculate sum and display results */
    int rollDice( void )
    {
       int die1;    /* first die */
       int die2;    /* second die */
       int workSum; /* sum of dice */
    
       die1 = 1 + ( rand() % 6 ); /* pick random die1 value */
       die2 = 1 + ( rand() % 6 ); /* pick random die2 value */
       workSum = die1 + die2;     /* sum die1 and die2 */
    
       /* display results of this roll */
       printf( "Player rolled %d + %d = %d\n", die1, die2, workSum );
       
       return workSum; /* return sum of dice */
    
    } /* end function rollRice */
    
    
    /* PRE: player inputs a dollar amount to wager on next game
       POST: function checks wager, if wager is invalid, prompt user to enter new wager. when valid
       wager is entered, returns to the calling function */
    
    /*
    int getWager()
    {
      int wager;
    
      printf("Balance = $%d.00\n",balance);
    
      printf("Enter wager: ");
      scanf("%d", &wager);
    
      while (wager > balance || wager <= 0)
        {
          printf("Your wager must not exceed your current balance.\n");
          printf("Enter a new wager: ");
          scanf("%d", &wager);
        }
      return wager;
    }
    */
      
    
    /* PRE: checks whether or not the last game was WON or LOST
       POST: either adds or subtracts the wager from the player's current balance */
    
    void adjustBalance()
    {
      int balance;    /* user's current balance */
    
      balance = 1000;
    
      if (gameStatus = WON)
        {
          balance = balance + wager;
        }
      else
        {
          balance = balance - wager;
        }
    }
    
    
    /* PRE: asks if the user desires to play another game of craps
       POST: function checks the response to make sure it is either 'y' or 'n'.
       the function will repeatedly ask until one of these conditions is satisfied
       and upon a valid answer, return to the calling function */
    
    void getYesOrNo()
    {
      printf("Do you want to play another game? (y or n): ");
    
      char ch;
    
      ch = getchar();
      while (getchar() != '\n');
      
      if (ch == 'y')
        {
          playGame();
        }
      else if
        (ch == 'n')
        {
          /*  printf("Your final balance is $%d.00", theBalance); */
        }
      else
        {
          printf("You must answer y or n.\n\n");
          getYesOrNo();
        }
    }

  2. #2
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    Pass the variable by pointer.
    Means pass the address of variable to functions which wil modify the original value.
    Search the board for example codes.
    Long time no C. I need to learn the language again.
    Help a man when he is in trouble and he will remember you when he is in trouble again.
    You learn in life when you lose.
    Complex problems have simple, easy to understand wrong answers.
    "A ship in the harbour is safe, but that's not what ships are built
    for"

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    So, pass this value into the functions (modify them to accept an argument). The argument will probably need to be a pointer since it appears you want to change the value in the called function.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12
    I've modified my code as follows but still have a few problems that need help. The first problem is that balance never changes, I know why this is, but I really don't know how to fix it.

    The second problem is that whenever a game ends, it prompts the user if he wants to play another to which 'y' or 'n' can be read. It no longer reads it though, and no matter what is entered, it treats it as an invalid character, re-prompting the user. The strange part is, is that the second time it prompts the user, it works correctly..

    Anyone help me out?

    Thanks.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> /* contains prototype for function time */
    
    /* enumeration constants represent game status */
    enum Status { CONTINUE, WON, LOST };
    
    int rollDice( void ); /* function prototype */
    int getWager(); /* getWager function prototype */
    int playGame(); /* playGame function prototype */
    void getYesOrNo(); /* getYesOrNo function prototype  */
    int Balance();
    int adjustBalance();
    
    int main()
    {
      getWager();
      playGame();
      getYesOrNo();
      return 0;
    }
    
    
    /* PRE: none
       POST: returns to the caller one of the enumatered constants WON or LOST */
    
    int playGame ()
    { 
       int sum;        /* sum of rolled dice */
       int myPoint;    /* point earned */
       int balance;
    
       balance=Balance();
    
       enum Status gameStatus; /* can contain CONTINUE, WON, or LOST */
    
       /* randomize random number generator using current time */
       srand( time( NULL ) );
    
       sum = rollDice(); /* first roll of the dice */
    
       /* determine game status based on sum of dice */
       switch( sum ) {
    
          /* win on first roll */
          case 7: 
          case 11:          
             gameStatus = WON;
             break;
    
          /* lose on first roll */
          case 2: 
          case 3: 
          case 12:  
             gameStatus = LOST;
             break;
    
          /* remember point */
          default:                  
             gameStatus = CONTINUE;
             myPoint = sum;
             printf( "Point is %d\n", myPoint );
             break; /* optional */
       } /* end switch */
    
       /* while game not complete */
       while ( gameStatus == CONTINUE ) {    
          sum = rollDice(); /* roll dice again */
    
          /* determine game status */
          if ( sum == myPoint ) { /* win by making point */
             gameStatus = WON; /* game over, player won */
          } /* end if */
          else {
    
             if ( sum == 7 ) { /* lose by rolling 7 */
                gameStatus = LOST; /* game over, player lost */
             } /* end if */
           
          } /* end else */
    
       } /* end while */
    
       /* display won or lost message */
       if ( gameStatus == WON ) { /* did player win? */
          printf( "Player wins\n" );
       } /* end if */
       else { /* player lost */ 
          printf( "Player loses\n" );
       } /* end else */
       return gameStatus;
    }
    
    
    /* roll dice, calculate sum and display results */
    int rollDice( void )
    {
       int die1;    /* first die */
       int die2;    /* second die */
       int workSum; /* sum of dice */
    
       die1 = 1 + ( rand() % 6 ); /* pick random die1 value */
       die2 = 1 + ( rand() % 6 ); /* pick random die2 value */
       workSum = die1 + die2;     /* sum die1 and die2 */
    
       /* display results of this roll */
       printf( "Player rolled %d + %d = %d\n", die1, die2, workSum );
       
       return workSum; /* return sum of dice */
    
    } /* end function rollRice */
    
    
    /* PRE: player inputs a dollar amount to wager on next game
       POST: function checks wager, if wager is invalid, prompt user to enter new wager. when valid
       wager is entered, returns to the calling function */
    
    
    int getWager()
    {
      int wager;
      int balance;
    
      balance = Balance();
    
      printf("Balance = $%d.00\n",balance);
    
      printf("Enter wager: ");
      scanf("%d", &wager);
    
      while (wager > balance || wager <= 0)
        {
          printf("Your wager must not exceed your current balance.\n");
          printf("Enter a new wager: ");
          scanf("%d", &wager);
        }
      return wager;
    }
    
      
    
    /* PRE: checks whether or not the last game was WON or LOST
       POST: either adds or subtracts the wager from the player's current balance */
    
    int adjustBalance()
    {
      int balance;    /* user's current balance */
      int wager;
      
      enum Status gameStatus;
    
      wager = getWager();
      balance = Balance();
      gameStatus = playGame();
    
      if (gameStatus == WON)
        {
          balance = balance + wager;
        }
      else
        {
          balance = balance - wager;
        }
      return balance;
    }
    
    
    /* PRE: asks if the user desires to play another game of craps
       POST: function checks the response to make sure it is either 'y' or 'n'.
       the function will repeatedly ask until one of these conditions is satisfied
       and upon a valid answer, return to the calling function */
    
    void getYesOrNo()
    {
      printf("Do you want to play another game? (y or n): ");
    
      char ch;
      int balance;
    
      balance = Balance();
    
      ch = getchar();
      while (getchar() != '\n');
      
      if (ch == 'y' || ch == 'n')
        {
          if (ch == 'y')
    	{
          playGame();
    	}
          else
    	{
    	  printf("Your final balance is $%d.00\n", balance);
    	}
        }
      else
        {
          printf("You must answer y or n.\n\n");
          getYesOrNo();
        }
    }
    
    int Balance()
    {
      int balance;
    
      balance = 1000;
    
      return balance;
    }
    --
    growl.

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    A new line character is left in stdin after getWager is called. This is picked up by getch(), which is why your yes/no prompt always fails the first time.

    The way you have it structured right now the most a user will ever be able to play is twice.

    You call playGame()
    then you call getYesOrNo() which lets the user play one more time.

    Trying to keep main simple is a good idea, but you have it too simple.

    You should ask the user in main if they want to keep playing
    Code:
    while(keepplaying) {
       getWager();  //getWager could be called in playGame instead
       playGame();
       keepplaying = wantToKeepPlaying();
    }
    you have balance delcared locally in each function. You should declare it in main and pass it to each function.

    you never even call adjustBalance, even if you did it wouldn't work because of above.

    getWager is useless too. You delcare wager locally to getWager, return it, but never do anything with it.

    maybe you need something like
    Code:
    wager = getWager(); //return wager
    balance = playGame(wager, balance);  //depending on win or lose adjust balance by wager amount

    It looks like you're doing everything you can to avoid passing paramters to your functions.
    You call playGame() in adjustBalance()

    Either make everything global (DON'T DO THIS), or learn how to pass and return parameters.
    Last edited by spydoor; 11-08-2005 at 01:08 PM.

  6. #6
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12
    I've only been programming about a week, so a lot of this is really new to me. I have pretty much zero past programming experience, so not being able to use global variables after just learning them is a pain in the ass to me.

    As far as fixing my program so that the user can play multiple games, I did that, by moving getYesOrNo() into my playGame() function. So that part works now, correctly reading 'y' or 'n' right away instead of failing on the first attempt.

    I can't make everything global, but with the code I have now, I don't understand how to pass variable values between functions. How can I get adjustBalance() to work if balance and wager are both local variables in two different functions? This is really the part I don't understand. Any example would be useful, even if it was just how to pass balance to adjustBalance() I'm pretty sure it would help me in figuring out how to pass wager from getWager() into adjustBalance() too.

    The same goes for getting adjustBalance() to read gameStatus from playGame()...
    --
    growl.

  7. #7
    C Programming Newbie
    Join Date
    Nov 2005
    Posts
    12
    I got a little bit of help from a guy on another forum and have re-written my program, but am still having some difficulty. I've
    re-written most of the program as the following code shows (read after for problems) :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> /* contains prototype for function time */
    
    #define beginbalance 1000
    
    /* enumeration constants represent game status */
    enum Status { CONTINUE, WON, LOST };
    
    int rollDice(void); /* rollDice function prototype */
    int playGame(void); /* playGame function prototype */
    int getWager(void);
    int adjustBalance(int balance, int wager);
    void getYesOrNo(int balance);
    
    int main()
    {
      playGame();
      return 0;
    
    }
    
    /* PRE: none
       POST: returns to the caller one of the enumatered constants WON or
    LOST */
    
    int playGame (void)
    {
       int sum;        /* sum of rolled dice */
       int myPoint;    /* point earned */
       int result = 0; /* integer defining whether or not last game was WON
    or LOST */
       int balance = beginbalance;
    
       printf("Balance = $%d.00\n",balance);
    
       int wager = getWager();
    
       enum Status gameStatus; /* can contain CONTINUE, WON, or LOST */
    
       /* randomize random number generator using current time */
       srand( time( NULL ) );
    
       sum = rollDice(); /* first roll of the dice */
    
       /* determine game status based on sum of dice */
       switch( sum ) {
    
          /* win on first roll */
          case 7:
          case 11:
             gameStatus = WON;
             break;
    
          /* lose on first roll */
          case 2:
          case 3:
          case 12:
             gameStatus = LOST;
             break;
    
          /* remember point */
          default:
             gameStatus = CONTINUE;
             myPoint = sum;
             printf( "Point is %d\n", myPoint );
             break; /* optional */
       } /* end switch */
    
       /* while game not complete */
       while ( gameStatus == CONTINUE ) {
          sum = rollDice(); /* roll dice again */
    
          /* determine game status */
          if ( sum == myPoint ) { /* win by making point */
             gameStatus = WON; /* game over, player won */
          } /* end if */
          else {
    
             if ( sum == 7 ) { /* lose by rolling 7 */
                gameStatus = LOST; /* game over, player lost */
             } /* end if */
    
          } /* end else */
    
       } /* end while */
    
       /* display won or lost message */
       if ( gameStatus == WON ) { /* did player win? */
          printf( "Player wins\n" );
          result = 1;
       } /* end if */
       else { /* player lost */
          printf( "Player loses\n" );
          result = -1;
       } /* end else */
    
       adjustBalance(balance, wager);
       getYesOrNo(balance);
    
       return result;
    
    }
    
    /* roll dice, calculate sum and display results */
    int rollDice(void)
    {
       int die1;    /* first die */
       int die2;    /* second die */
       int workSum; /* sum of dice */
    
       die1 = 1 + ( rand() % 6 ); /* pick random die1 value */
       die2 = 1 + ( rand() % 6 ); /* pick random die2 value */
       workSum = die1 + die2;     /* sum die1 and die2 */
    
       /* display results of this roll */
       printf( "Player rolled %d + %d = %d\n", die1, die2, workSum );
    
       return workSum; /* return sum of dice */
    
    } /* end function rollRice */
    
    /* PRE: player inputs a dollar amount to wager on next game
       POST: function checks wager, if wager is invalid, prompt user to
    enter new wager. when valid
       wager is entered, returns to the calling function */
    
    int getWager(void)
    {
      int amount = 0;
    
      printf("Enter wager:  ");
      scanf("%d", &amount);
    
      return amount;
    
    }
    
    /* PRE: checks whether or not the last game was WON or LOST
       POST: either adds or subtracts the wager from the player's current
    balance */
    
    int adjustBalance(int balance, int wager)
    {
      int newbalance = balance;
    
      if (wager)
        {
          if (wager <= balance)
            {
            newbalance = balance + wager * playGame();
            }
          else
            {
            printf("Your wager must not exceed your current balance.\n");
            getWager();
            }
        }
    
      printf("Balance = $%d.00\n",newbalance);
    
      return newbalance;
    
    }
    
    /* PRE: asks if the user desires to play another game of craps
       POST: function checks the response to make sure it is either 'y' or
    'n'.
       the function will repeatedly ask until one of these conditions is
    satisfied
       and upon a valid answer, return to the calling function */
    
    void getYesOrNo(int balance)
    {
      char ch;
    
      printf("Do you want to play another game?  (y or n):  ");
    
      ch = getchar();
      while (getchar() != '\n');
    
      if (getchar() == 'y')
        {
          playGame();
        }
      else if (getchar() == 'n')
        {
          printf("\n\nYour final balance is $%d.00",balance);
        }
      else
        {
          printf("You must answer y or n.");
          getYesOrNo(balance);
        }
    
    }
    This code, if you compile it, introduces some problems.
    1. getYesOrNo doesn't function properly either reading the user input,
    or showing up after each game at the appropriate time. A little
    difficult understanding my wording, more obvious if compiled.

    2. If balance < wager, program does not output current balance on next
    game.

    3. Balance, despite my best efforts with your code, doesn't seem to
    ever change, staying at $1000. I'm sure this is due to some poor
    writing on my part trying to do things your way.
    --
    growl.

  8. #8
    Sr. Software Engineer filker0's Avatar
    Join Date
    Sep 2005
    Location
    West Virginia
    Posts
    235
    I think that you need to better understand how variables are allocated and how they're passed. I'll give you some hints, though, by example:
    Code:
    /* add a value to the accumulator */
    void add(int *accum, int add_this)
    {
        *accum += add_this;
    }
    
    /* increment value in accumulator by 1 */
    void incr_by_one(int *accum)
    {
        add(accum, 1);  /* note that accum is a pointer to the accumulator */
    }
    
    int main()
    {
        int accumulator;
    
        accumulator = 10;
        printf("Initialized accumulator to %d\n", accumulator);
        add(&accumulator, accumulator); /* add the value of accumulator to accumulator */
        printf("accumulator * 2 = %d\n", accumulator);
        incr(&accumulator);  /* increment the value of accumulator */
        printf("accumulator after increment by 1 = %d\n", accumulator);
        return 0;
    }
    The code example is contrived and trivial, but shows passing a pointer to a variable local to main() to a few functions so that the value of the variable can be modified. The function add() takes a pointer to the destination and a value to be added to the value in the destination. The function incr() takes a pointer to the destination value and calls add() to add 1 to it.

    The code samples I've seen in previous replies all forget to pass the argument to be modified as a pointer to the value as opposed to the value itself.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. esbo's data sharing example
    By esbo in forum C Programming
    Replies: 49
    Last Post: 01-08-2008, 11:07 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Replies: 4
    Last Post: 06-17-2005, 08:54 AM
  4. where does the compiler store the local variables?
    By debuger2004 in forum C Programming
    Replies: 1
    Last Post: 06-23-2003, 08:19 PM
  5. Global Vs Local Variables
    By Waldo2k2 in forum C++ Programming
    Replies: 17
    Last Post: 11-11-2002, 07:51 PM