When doing a flowchart, you do not need to mess around with the technicalities of do/while/for.
Write the flow of the code as it makes most sense. Then we translate it into code.
How does the logic look for this -
crazychileCode:BEGIN MAIN declare variables give option to view rules if the game is not over or we are playing again BEGIN LOOP1 BEGIN LOOP2 roll dice print outcome, calculate points, determine status END LOOP2 If status = 1, then ask to play another round if answer is yes, then begin loop again if answer is no then switch player and BEGIN LOOP1 as other player else if status = 0 switch players and BEGIN LOOP1 as other player if the game is over print totals for both players END LOOP1 give option to play again if yes, then begin LOOP1 if no, then STOP END MAIN
I think you are beginning to get somewhere, but I am concerned because you seem to have lots of conditions all over the place. It is never a good thing.
There is something about the logic that I cannot quite puzzle... especially that first...
"if the game is not over or we are playing again"
...is it really necessary?
The green bit really really really really really really really really needs to be inside LOOP2 -- since currently LOOP2 never stops, and of course you can't repeat it once you've left it. Similarly, the conditions for restarting LOOP1 aren't that complicated, nor should they appear in a bunch of different places -- you restart LOOP1 unless they say "no I don't want to play another game". So that's your check on that loop. And again, that needs to be inside LOOP1, because you can't repeat it once you've left it. So you have LOOP1 that works on the game level, LOOP2 that gets you through a single turn, and you probably need to have LOOP3 that repeats turns until somebody wins.Code:BEGIN MAIN declare variables give option to view rules if the game is not over or we are playing again BEGIN LOOP1 BEGIN LOOP2 roll dice print outcome, calculate points, determine status END LOOP2 If status = 1, then ask to play another round if answer is yes, then begin loop again if answer is no then switch player and BEGIN LOOP1 as other player else if status = 0 switch players and BEGIN LOOP1 as other player if the game is over print totals for both players END LOOP1 give option to play again if yes, then begin LOOP1 if no, then STOP END MAIN
Thank you.
The way I currently have it written the green stuff actually was inside that loop for the turn.
I have revised my chart a bit. I'm not really sure about the 3rd loop. I think I am essentially doing the same thing with two loops, but maybe not. It may be a matter of placing the final print statement.
My revised diagram:
Thanks for the guidance,Code:BEGIN MAIN declare variables give option to view rules if the game is not over or we are playing again BEGIN GAME LOOP BEGIN TURN LOOP roll dice print outcome, calculate points, determine status If status = 1, then ask to play another round if answer is yes, then begin loop again END TURN LOOP if answer is no , or status = 0, switch player and BEGIN TURNLOOP if the game is over print totals for both players END GAME LOOP BEGIN GAME LOOP unless condition is no END MAIN
crazychile
I would be looking at something like this.Code:BEGIN MAIN declare variables give option to view rules BEGIN GAME LOOP BEGIN TURN LOOP roll dice print outcome, calculate points, determine status IF status = 1 ask to play another round if answer is yes, then BEGIN TURNLOOP IF answer is no, switch player and BEGIN TURNLOOP ELSE switch player and BEGIN TURNLOOP END IF END TURN LOOP if the game is over print totals for both players LOOP WHILE user wants to play again END MAIN
I am still confused as to what the Turn loop does.
I do not know what status is, and regardless of what happens, the loop begins anew again. Should the user not be able to choose if to play another round or not, and if not, another round should not be played?
Points are awarded per the roll combination. There are combinations where no points are awarded and the roll automatically goes to the other player. In cases where the roll yields a scoring combination, the player must decide if they want to continue. If they choose not to continue they keep all the points earned for the round and it goes to the next player. If they continue and then roll a non-scoring combination, they lose any points they had gained for the round and the turn passes to the other player.
The status (1) is a way to trigger a function to offer another roll for that player (it returns y/n). If the status is (0) then the function to offer another roll does not return a value and it goes to the next player. I coded the status in the various if/else statements in that loop.
So my thinking was to use something like "while (turnAgain(status) == 'y')" to re-execute the loop for another roll, and if(turnAgain(status) == 'n'), then it would just total up the amount for the round and change to the other player.
It seems simple enough but I always get compiler errors when I try this. (usually it expects something more before the closing brackets).
I've probably spent 50-60 hours on this project and its due on Tuesday (whats worse is that I have to present it to the class) So the pressure is pretty intense at this point. I think if I can get it to switch players under these conditions then I should be able to figure out the rest. All of my functions are written and should need minimal tweaking to work once I get my loop structure down.
Thanks for all your guidance everyone.
crazychile
Do you have a current version that you can post up?
Well, then how about:
This looks more like a flowchart that is not complex nor hard to implement.Code:BEGIN MAIN declare variables give option to view BEGIN GAME LOOP BEGIN ROLL LOOP 1 BEGIN ROLL LOOP 2 roll dice print outcome, calculate points, determine status IF roll was a scoring combination, ask to play another round LOOP IF users wants to play another round Switch user LOOP IF loop has executed 2 times if the game is over print totals for both players LOOP WHILE user wants to play again END MAIN
Of course, you can change the whole switch player to two loops if that makes it easier for you.
You have to think in how you would do it in real life instead of in code!
Code comes after you have thought out the flowchart.
Does this flow make sense to you?
Thanks Elysia, the flow does make sense.
Here is the current code: (yes, I know the spacing is messed up)
Code:#include <stdio.h> // for interactive input and output #include <stdlib.h> // for the rand() function #include <ctype.h> // for tolower() macro #define SIDES 6 typedef enum {doublesPoints, onesPoints, noPoints, singlesPoints} status; // function: prnRules // pre: none // post: prints the rules void prnRules(void) { printf("%s\n", "The goal is to be the first player to reach 100 points.\n\n" "On a turn, a player rolls the two dice repeatedly until either a 1 is rolled \n" "or the player chooses to hold and stop rolling.\n\n" "If a 1 is rolled, that player's turn ends and no points are earned for the round.\n" "If the player chooses to hold, all of the points rolled during that round are added to their score.\n\n" "If a player rolls double 1s, that counts as 25 points.\n" "Other doubles are worth 2x double points, so that a 2-2 is worth 8 points; 3-3 is worth 12; \n" "4-4 is worth 16; 5-5 is worth 20; and 6-6 is worth 24.\n\n" "When a player reaches a total of 100 or more points, the game ends and that player is the winner.\n"); } int rollDie () // function: rollDie // pre: none // post: generates a random number for the die { int d; d = rand() % SIDES + 1; return d; } status turnPoints(int die1, int die2) // function: turnStatus // pre: dice have been rolled // post: returns the status of the roll (doublesPoints, onesPoints, no Points, singlesPoints) { if (die1 == die2 && !(die1 == 1 && die2 == 1)) return doublesPoints; else if (die1 == 1 && die2 == 1) return onesPoints; else if ((die1 == 1 || die2 == 1) && !(die1 == 1 && die2 == 1)) return noPoints; else return singlesPoints; } int turnAgain(int status) // function: turnAgain // pre: Player must have rolled a non disqualifying point combination // post: returns a valid (y or n) answer { char ans; if (status == 1) { printf("TURNAGAIN Would you like to risk the points for this round and continue? (y or n)? "); getchar(); ans = getchar(); } //while (tolower(ans) != 'y' && tolower(ans) != 'n'); return tolower(ans); } //to switch the current player when the turn is over int switchPlayer(int currentPlayer) { if (currentPlayer == 1) return 2; else return 1; } char playAgain(int choice) // function: playAgain // pre: none // post: returns a valid (y or n) answer { char ans; do { if (choice == 1) printf("PLAYAGAIN-Play another game (y or n)? "); if (choice == 2) printf("PLAYAGAIN-Do you want to risk it all and roll again (y or n)? "); ans = getchar(); getchar(); } while (tolower(ans) != 'y' && tolower(ans) != 'n'); return tolower(ans); } // function: gameOver // pre: none // post: returns a '1' if either total exceeds 100 int gameOver (int p1Total, int p2Total) { if (p1Total || p2Total >= 100) { return 1; } else { return 0; } } //The final print statement with all the totals void finalOutput(int p1Total, int p2Total) { printf("\n"); printf("WE HAVE A WINNER!!!\n"); printf("Player 1 your final score was %d\n", p1Total); printf("Player 2 your final score was %d\n", p2Total); } int updatePlayerTotal(int currentPlayer, int turnTotal, int playerTotal) { printf("UPDATEPLAYERTOTALPlayer %d, your total at the start of this turn was %d .\n", currentPlayer, playerTotal); playerTotal = playerTotal + turnTotal; printf("Your total at the end of this turn is %d.\n", playerTotal); return playerTotal; } int main (void) { // variable declarations int sum; // for sum of two dice char answer; // for yes/no questions int tempTotal = 0; // temporary player total for the round int p1Total = 0; // running total for player 1 int p2Total = 0; // running total for player 2 int total = 0; // player total after each round int die1 = 0; // the roll value of die1 int die2 = 0; // the roll value of die2 int currentPlayer = 1; // start with Player 1 int status = 1; // ability to choose to continue int gameStatus = 1; srand(time(NULL)); // seed random # generator //do // play at least one game { //give option to view the rules printf("Welcome to the game of Pig. Would you like to view the rules? (y or n)?\n"); answer = getchar(); getchar(); if (answer == 'y') prnRules(); while (turnAgain(status) == 'y') { die1 = rollDie(); die2 = rollDie(); sum = (die1 + die2); printf("Die 1 is a %d.\n", die1); printf("Die 2 is a %d.\n", die2); //award points (rolled a double but not double 1's) if (turnPoints(die1, die2) == doublesPoints) { printf(" Player %d, you rolled a double %d!\n ", currentPlayer, die1); printf(" That's worth %d points.\n", (sum * 2)); tempTotal = (tempTotal + total + (sum * 2)); status = 1; } //award points (rolled double 1's) else if (turnPoints(die1, die2) == onesPoints) { printf(" Player %d, You rolled a double 1!\n ", currentPlayer); printf(" That's worth 25 points.\n"); tempTotal = (tempTotal + total + 25); status = 1; } //award no points (one of the two dice = 1) else if (turnPoints(die1, die2) == noPoints) { printf("Sorry Player %d, you rolled a single 1. You do not earn any points this round\n", currentPlayer); printf("Your current total is %d\n", total); tempTotal = 0; total = total + tempTotal; status = 0; } //award points (rolled singles) else if (turnPoints(die1, die2) == singlesPoints) { printf("Player %d, your roll totals %d points.\n", currentPlayer, sum); tempTotal = tempTotal + (total + sum); status = 1; } } if (turnAgain(status) == 'n')//(answer == 'n') { total = (tempTotal + total); if (currentPlayer == 1) { p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total); } else { p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total); } currentPlayer = switchPlayer(currentPlayer); } //answer = playAgain(2); //total the points for the player and switch to other player /* (turnAgain(status) == 'n')//(answer == 'n') { total = (tempTotal + total); if (currentPlayer == 1) { p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total); } else { p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total); } currentPlayer = switchPlayer(currentPlayer); }*/ // if (gameOver(p1Total, p2Total) == 1) // finalOutput (p1Total, p2Total); // see if they want to play another game //answer = playAgain(1); }while (answer != 'n'); return 0; }