# Dice game: How to handle 2 players and separate totals?

• 10-18-2008
crazychile
Dice game: How to handle 2 players and separate totals?
As a school project I'm writing a C program that is a dice game with two players. I think I have most of the logic of the game worked out but I'm having problems knowing how to handle the switching between two players when a condition is met, and keeping the separate totals for each player. For example, I'm wanting to write the code for playerX, where X is player 1 or 2. How do write it so I'm not hard coding it for 1 or 2, but that the program executes for 1 then 2 and back and forth until a final condition is met (someone wins)?

Thank you for any help,
crazychile
• 10-18-2008
MK27
It's difficult to say without seeing how exactly how you've done this so far, but probably you want to have a function that accepts the player number as an argument:

For example:
Code:

```int rolldice (int player) {       [some code here] } int main () {     int roll, player;     player=2;     roll=rolldice(player); }```
If there's anything that's going to occur more than once, you might as well make it a function. To play until someone wins (a condition) use a looping conditional construct:

Code:

```int main (int argc, char *[argv]) {     int roll, nofplayers=atoi(argv[1]), player, total[nofplayers], i;     for (i=0;i<nofplayers;i++) total[i]=0;     player=1;     while (total[player-1] < 21) {           roll=rolldice();           total[player-1]+=roll;     } }```
In this example "rolldice" does not need a player number argument.
• 10-18-2008
crazychile
Thanks for the help. To clarify, here is a part of my code. Its practically still pseudocode at this point so i wanted to get the player number thing down before I refine it.

Code:

```         int pigCalc(int)         {       die1 = rand() % 6 + 1;              die2 = rand() % 6 + 1;              sum = die1 + die2;       printf("Die 1 is a %d.\n", die1);                 printf("Die 2 is a %d.\n", die1);               if ((die1 == 1 || die2 == 1) && !(die1 == 1 && die2 == 1))       {           printf("Sorry, you rolled a 1. You do not earn any points this round\n");                         printf("Your current total is %d\n", total);           roundOver = 1;       }                 if (die1 == 1 && die2 == 1)       {           printf(" You rolled a double 1!");                         printf(" That's worth 25 points. \n");                         tempTotal = (total + 25);                         printf(" Would you like to stop and total this round or take a chance by continuing? \n");                         printf(" Enter 's' to stop, or 'c' to continue \n");                                   answer = getchar();                         getchar();                                                         if (answer = 's');                                         total = tempTotal;                                         printf("Your current total is %d\n", total);                                         roundOver = 1;                                                                 if (answer = 'c');                                         roundOver = 0;       }```
This was just part of the conditions, but whats happenning is the game is fixed at 2 players. A player rolls the dice. if a certain combination is rolled then the person loses his turn and loses his points for the round. If he rolls other combinations he gets a certain amount of points but has to decide if he wants to roll again and risk his points. The game goes until someone hits a specified number of points

So basically I'm trying to figure out how to make it switch to the other player when a turn is lost or the player chooses to hold for the round. Then the players points are calculated accordingly.

Thanks for all the help,
crazychile
• 10-18-2008
MK27
What is the purpose of roundOver? It looks like you are trying to set a variable that will cause something to happen when it changes. This is actually impossible to do (well, you could include an if statement right after you change the variable, but in this case that would be kind of like "I just said the round is over. If I said the round is over, do this". Why not just say "do this"?)

Since the function is almost complete, just have it return when the round is over with the player's score for that round (substitute "return score;" for these "roundOver" lines. If you are doing this in a loop instead of a function, you can exit a loop arbitrarily with break) Total that up and start the rountine again, using the second player's score:

Code:

```int p1_score=0, p2_score=0; while ((p1_score<100) && (p2_score<100)) {     p1_score+=pigCalc(p1_score);     p2_score+=pigCalc(p2_score); }```
By submitting the score as an argument to pigCalc, you can include a check after each roll to see if the player has already won. If you add points to that and return a total, use =, not +=.
• 10-19-2008
crazychile
Thank you MK27.

As to the significance of roundOver, I put that in mostly as a temporary place holder to let me know that if a condition was satisfied then it would equal 1 and then trigger something that switched to the other player. If it was 0 the same player would continue rolling the dice. From your explanation it sounds like I went down the wrong path on that one.

I think I understand your latest code as far as keeping track of the totals for the two players and then triggering the end of the game once the total reaches a certain level. That wasn't the issue I was having problems with. I'm guessing that I dont want to hard code something to actually mention player1 or player2, but instead use something like (player) except when I actually assign a total. I guess my main question is how to write the code in a non specific way to track (player), and even more so, what sort of commands in the code would actually trigger the switch?

I guess I was originally thinking something like:

if roundOver
add up the total for player x
player++;

Meaning that if the round was over, total the score, and increment to the next player. (I'm not sure if increment is the correct way to do it, but I need something to change to the next player and thats what I know at this point of my learning experience).

Thank you for your help and patience.
crazychile
• 10-19-2008
MK27
Quote:

Originally Posted by crazychile
I guess I was originally thinking something like:

if roundOver
add up the total for player x
player++;

You could do it this way (I wouldn't tho; bear with me...). In this case, you either call the function again the same way it is initially called, or, if you are using a loop, you can call continue, which breaks out of the loop and starts it again. At the point where you want the player to be switched, something like if (player==1) player=2; else player=1; might do, depending on how you eventually decide to keep track of the player numbers and the corresponding scores.

Using that method (a loop and switching variable values), you could write the entire program in main() with no additional functions (it sounds to me like you kind of want to do that or are stuck thinking about it that way). The reason I wouldn't do this is because is because it will be clumsy, and the longer the program gets as the game becomes more complex, the more clumsy it will get. By clumsy, I mean that I don't think there could end up being any kind of performance advantage (eg, with regard to memory use, speed of calculations, etc.) and you will lack the structure that functions provide. In my opinion, the more you can break a code sequence down into discrete sets of functions, the happier you will be and the smoother your programming will go. Most C books or tutorials will tell you something similar. There are other advantages related to this; besides the fact that you won't have to repeat yourself unnecessarily, it makes debugging easier (whether you are using an actual debugger or just adding in printf lines to see at what point a segfault occurs) and it makes minor revamps much easier. For example, if later you decide to make the game include an optional 3rd and 4th player, you're going to be in for a lot more work the other way (that's a guess -- if you get to the point where you see what I mean and agree, then I've accomplished something ;)). It's also easier to deal with smaller individual sets of local variables than one large set, and functions add more immediate "non-linear" possibilities (read: flexability) than just adjusting variables.

Going back to you and your pig program:

"I'm guessing that I dont want to hard code something to actually mention player1 or player2, but instead use something like (player) except when I actually assign a total."

Again this seems to me like an unintentional obfuscation, which is to say you're slightly confused about what you're doing. When and why do you have to refer to any player or (player) at all? You do not in your previous code, because the concept of the player is an abstraction. A dice roll (die1 = rand() &#37; 6 + 1) is actual. The only significance of the two players in the program is that they have two seperate scores. I'll flesh out what I was trying to explain in my previous post a bit more.

Code:

``` int pigCalc (int score) {         /* it does not matter who the player is in here         whenever the dice are rolled, add that to "score"         and check if the score has equalled a win:*/         if (score>=100) return score;         /* or, if they roll a single one         just*/return score; } int main() {         int p1_score=0, p2_score=0, winner;         while (1) {        // an infinite loop                     p1_score=pigCalc(p1_score);                 if (p1_score>=100) {winner=1;break;}                     p2_score=pigCalc(p2_score);                 if (p2_score>=100) {winner=2;break;}         }         printf("Player %d is the winner!\n",winner); }```
Do you see the logic in this?

while (1) is a loop who's condition is always true, so the only way to end it is by exiting the program or using break. Every time it goes around, each player gets a turn. pigCalc() recieves the player's score and adds to that, returning the new total when the turn is over. If someone reaches 100 on a roll, pigCalc() ends the turn and returns the score, which causes the break in the "main loop", ending the game.
• 10-19-2008
crazychile
Thank you MK27.

And yes I am confused (and inexperienced). I think most of my problem is not being able to articulate what I'm trying to do. I was trying to be general in my descriptions to keep it simple

Unfortunately I cannot write the whole program in main as a finished project. Part of the requirements is that I have to demonstrate the use of functions. I wanted to do the initial draft using a main until I got the two player thing worked out and then figure out what to break out as a function(s). I'm not too comfortable with functions at this point and wanted to get down what I knew first before I went into new territory. I know my code showed the concept of the player more as an abstraction, but that was for lack of knowing what to do at this state.
I do see the logic in most of your examples and that confirms some of what I knew as well as showed a different way to do this, but ultimately I'll need my output to be more specific regarding the players.

My initial plan was to specifically state the individual players in the output statements for clarity to the persons playing the game. So you would see something like this:

"Player 1, you rolled a xxx, and a xxx. which is worth xx points. Would you like to stop and total this round or take a chance by continuing?"
.
.
.
"Congratulations, player 2 you win with xxx points!
Sorry player 1 your total was xx , better luck next time"

I sort of cornered myself by committing to this level of specificity in my design document. I'd probably get dinged on points if I made those statements too general. Plus it would be more confusing to the people playing the game. (was it my turn or yours?) I have a meeting with my professor tomorrow so I can ask him about the handling of players then, but I'd wanted to be a little farther along by then if possible.

Thank you so much for your help. I know you put a lot of time and thought into helping me on this.
crazychile
• 10-20-2008
MK27
Code:

```int pigCalc (int score, char *player) {         /*call a player by name*/         printf("Hey %s!\n",player);                if (score>=100) return score;         /* or, if they roll a single one         just*/return score; } int main() {         int p1_score=0, p2_score=0, winner;         while (1) {        // an infinite loop                     p1_score=pigCalc(p1_score, "Player1");                 if (p1_score>=100) {winner=1;break;}                     p2_score=pigCalc(p2_score, "Player2");                 if (p2_score>=100) {winner=2;break;}         }         printf("Player %d is the winner!\n",winner); }```
You weren't asking for much this time (there's that re-vampable flexability). Good luck.