Function Help on Dice Game - c

I have a new problem. I got most of the things fixed. I need my (turnAgain) function fixed. I specifically need to fix my if else statement. I need it to let the player continue rolling if they type in 'r'. else if they type 'h' the other player gets to roll. And I need it to say try again type 'r' or 'h' if they type in something that is is not 'r' or 'h'. I just dont know how to do that. New to coding thanks!! I REALLY NEEEEEEEEEEEEEEEEEEEEEEED HELP.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define SIDES 6
typedef enum {doublesPoints, onesPoints, noPoints, singlesPoints} status;
void prnRules(void)
// function: prnRules
// pre: none
// post: prints the rules
{
printf("%s\n",
"The goal is to be the first player to reach 50 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 50 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;
}
void turnAgain(int status)
{
char rollDie;
do
{
printf("Would you like to roll again or hold(r/h)?");
scanf("%c",&rollDie);
} while(rollDie!='r'&&rollDie!='h');
if(rollDie=='r')
{
}
else
{
}
//to switch the current player when the turn is over
int switchPlayer(int currentPlayer)
{
if (currentPlayer == 1)
return 2;
else
return 1;
}
char gameAgain()
// function: gameAgain
// pre: none
// post: returns a valid (y or n) answer
{
char ans;
do
{
printf("Play another game (y or n)? ");
ans = getchar();
getchar();
}while (ans != 'y' && ans != 'n');
return ans;
}
int gameOver (int p1Total, int p2Total)
// function: gameOver
// pre: none
// post: returns a '1' if either total exceeds 50
{
if (p1Total || p2Total >= 50)
{
return 1;
}
else
{
return 0;
}
}
//The final print statement with all the totals
void finalOutput(int p1Total, int p2Total)
// function: finalOutput
// pre: gameOver returns a '1'
// post: returns the final scores of the game
{
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)
// function: pudatePlayerTotal
// pre: none
// post: returns the player total
{
printf("Player %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\n", playerTotal);
return playerTotal;
}
int main (void)
{//begin main
// 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 = 0; // status for choice to continue
srand(time(NULL)); // seed random # generator
do // play at least one game
{//Begin game loop
//give option to view the rules
printf("Welcome to the game of Fifty. Would you like to view the rules? (y or n)?\n");
answer = getchar();
getchar();
if (answer == 'y')
prnRules();
do // until game is won
{//Begin roll loop1
{ //Begin roll loop2
die1 = rollDie();
die2 = rollDie();
sum = (die1 + die2);
printf("Player %d:\n", currentPlayer);
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;
}
}while (status == 1 && (turnAgain(status) == 'y'));//end roll loop2 - while player continues roll
if (turnAgain(status) == 'n')//(answer == 'n')
{
total = (tempTotal + total);
if (currentPlayer == 1)
{
p1Total = updatePlayerTotal(currentPlayer, tempTotal, p1Total);
}
else
{
p2Total = updatePlayerTotal(currentPlayer, tempTotal, p2Total);
}
//switch players
currentPlayer = switchPlayer(currentPlayer);
}
}while (gameOver(p1Total, p2Total) != 1); //end loop1 - continue while game is not over
answer = gameAgain();
}while (answer != 'n'); //end game loop - loop while wanting to play again
return 0;
}//end main

int rollDie ()
// function: rollDie
// pre: none
// post: generates a random number for the die
{
int d;
d = rand() % SIDES + 1;
return d;
}
...
int turnAgain(int status)
---> you forget the left brace {
char rollDie; // Conflict, rollDie redeclared
Compile with warnings:
die1 = rollDie();
^
demo.c:60:10: note: declared here
char rollDie;

Related

Find Sum and Average function not returning actual value of Average

Here's my function that returns the Sum of all pair numbers in an array, and the Average of Odd numbers. Although it outputs the Average as zero for some reason.
#include <stdio.h>
int MoySom(int Tab[],float* Moyenne,int Length)
{
int S=0,C=0;
*Moyenne=0;
for(int i=0;i<Length;++i)
{
if(Tab[i] % 2 == 0)
{
S=S+Tab[i];
}
else if(Tab[i] % 2 != 0)
{
*Moyenne+=Tab[i];
++C;
}
}
*Moyenne=*Moyenne/C;
return S;
}
void main()
{
int Length,Tab[Length];
float Moyenne;
printf("Entrer la longeur de tableau: ");
scanf("%d",&Length);
for(int i=0;i<Length;++i)
{
printf("Entrer l'element %d: ",i);
scanf("%d",&Tab[i]);
}
printf("Somme est:%d\nMoyenne est: %.2f",
MoySom(Tab,&Moyenne,Length), Moyenne);
}
At least these problems:
Wrong declaration order
int Length,Tab[Length]; is junk. The declaration of Tab[Length] is happening, yet the value of Length is indeterminate.
Something more like the below. Declare Tab[] after Length is assigned.
int Length;
float Moyenne;
printf("Entrer la longeur de tableau: ");
scanf("%d",&Length);
int Tab[Length];
Better code checks the return value of scanf()
int cnt = scanf("%d",&Length);
if (cnt != 1 || Length <= 0) {
Report_Error_and_exit();
}
int Tab[Length];
Parameter evaluation order assumed
Calculate Moyenne, then used use it.
//printf("Somme est:%d\nMoyenne est: %.2f",
// MoySom(Tab,&Moyenne,Length), Moyenne);
printf("Somme est:%d\n", MoySom(Tab,&Moyenne,Length));
printf("Moyenne est: %.2f", Moyenne);
Potential /0
*Moyenne=*Moyenne/C; may attempt divide by zero. Better code would prevent that.
Unneeded test
if(Tab[i] % 2 == 0) {
S=S+Tab[i];
} else if(Tab[i] % 2 != 0) {
*Moyenne+=Tab[i];
simplifies to
if(Tab[i] % 2 == 0) {
S=S+Tab[i];
} else {
*Moyenne+=Tab[i];

This is my idea on roll dice in functions, is it good?

Write a code for a game called double dices.
Each player takes their turn to roll two dices. (So, player one rolls 2 dices then player 2 rolls two dices). To roll a dice player 1 presses the number 1 and player 2 presses the number 2. The dice numbers are from 1 to 6. If the sum of the two dices = 12 then that player is the winner
If the sum of the two dices = 10 the player gets a golden token 2 golden tokens without the any player reaching sum 12 will automatically make the player the winner. Create a module that checks for the winner and output who the winner is.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define Roll 2
// Function Declarition
void winner(int [], int []);
int main()
{
int player1[Roll], player2[Roll], p1sum=0, p2sum=0;
int i, j, dice, p1[0], p2[0];
srand(time(0));
// Prompts Player 1 to press enter.
printf("\n Player 1: Press Enter to roll your dice!!!\n");
getc(stdin);// collects the propmt.
//
for(i = 0; i < Roll; i++)
{
player1[i] = (rand() % 6) + 1;
p1sum += player1[i];
}
printf("\t Player 1 rolled %d dice\n\t The Sum of the two rolls are: %d\n", i + 0, p1sum);
printf("\n Player 2: Press Enter to roll your dice!!!\n");
getc(stdin);
for(j = 0; j < Roll; j++)
{
player2[j] = (rand() % 6) + 1;
p2sum += player2[j];
}
printf("\t Player 2 rolled %d dice\n\t The Sum of the two rolls are: %d\n", j + 0, p2sum);
// initializing an array to variable p1sum.
// Function Call.
winner(p1sum, p2sum);
return 0;
}
void winner(int p1sum [], int p2sum [])
{
int x, w;
//int p1sum = p1[0];
//int p2sum = p2[0];
p1sum[0];
p2sum[0];
for (w=0; w < Roll; w++)
{
if (p1sum == 12)
{
printf("\nPlayer 1, You've Won the prize");
}
else if (p2sum == 12)
{
printf("\nPlayer 2, You've Won the prize");
}
else if (p1sum == 10)
{
printf("\nPlayer 1 gets a golden token");
}
else if (p2sum == 10)
{
printf("\nPlayer 2 gets a golden token");
}
}
}
make methods like:
int rollDice(int rollCount);
boolean findWinner(int score1, int score2);
Then code something like this:
int sum1,sum2;
do {
sum1 = rollDice(2);
sum2 = rollDice(2);
}while(!findWinner(sum1, sum2))

C program - Faulty scores output

C program. IDE used is Xcode v12.2.
The problem I am facing:
Faulty scores output. For each round, the program should output the highest and lowest scores and the average score if the player chooses to do so.
Scores output after playing for 1 round:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 92/100
Highest score: 92/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Scores output after playing for 2 rounds:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 95/100
Highest score: 95/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Questions:
Why is 'Round 1' shown as 'Round 0'? And what does the 'inf' mean in the average score section? How do I turn 'inf' into a numerical output? After 2 rounds, the output 'Round 2' is still shown as 'Round 0' and the 'Average score' did not change to a numerical output.
What I have tried:
void quiz(char name[])
{
// function created to enclose quiz functionality apart from instructions
int rounds = 0;
int highest = 0;
int lowest = INT_MAX;
float allScore = 0;
float avg = 0;
int i, j, g = 0;
//char x;
struct struc test[MAX_TESTS];
srand((unsigned) time(NULL));
for (;;)
{
rounds++;
for (i = 0; i < MAX_TESTS; i++) // generate all questions
{
ctm_i(&test[i]);
for (j = 0; j < i; j++)
if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
//if question is already present
ctm_i(&test[i]); //then re-generate
}
//int ig = getchar();
char x;
x = getchar();
printf("\n Are you ready? Press Enter key to continue. ");
fflush(stdin);
while (x != '\n') {}
while (getchar() != '\n') {}
//getchar();
for (i = 1; i <= 5; i++)
{
printf( " *******************************************************************"
"**"
"***********\n");
printf( " ..................................................................."
".."
"...........\n");
}
// Take quiz
for (i = 0; i < MAX_TESTS; i++)
tcm_i(&test[i], i);
printf(" End\n\n");
bool done = false;
bool unsure = true;
bool showS = true;
while (unsure)
{
unsure = false;
puts("\n");
if (showS)
{
puts(" Enter 'S' to show results");
}
puts(" Enter 'P' to play another round");
//puts(" Enter 'Q' to quit");
puts(" Enter 'R' to return to main menu");
char choice;
printf(" ");
myread("%c", &choice);
if (choice == 'r' || choice == 'R')
{
done = true;
}
else if (choice == 'S' || choice == 's')
{
showS = false;
// calculate total score for current round
g = 0;
for (i = 0; i < MAX_TESTS; i++)
{
g += test[i].grade; //add score of each question
}
allScore += g; //add current round's score to total
avg = allScore / rounds; //average of all rounds
if (g > highest)
{
highest = g;
}
if (g < lowest)
{
lowest = g;
}
if (rounds == 1)
{
printf(" Final score: %d/100\n", g); //display round score
printf(" ******Player: %s ******\n", name);
}
else
{
//puts("Whoops! Looks like highest/lowest have not been adjusted!");
printf(" Round %d score: %d/100\n", rounds, g); //display round score
printf(" Highest score: %d/100\n", highest);
printf(" Lowest score: %d/100\n", lowest);
printf(" Average score: %f\n", avg);
printf(" ******Player: %s ******\n", name);
}
unsure = true;
//getchar();
}
else if (choice == 'P' || choice == 'p')
{
g = 0;
for (i = 0; i < MAX_TESTS; i++)
{
g += test[i].grade; //add score of each question
}
allScore += g; //add current round's score to total
if (g > highest)
{
highest = g;
}
if (g < lowest)
{
lowest = g;
}
}
else
{
puts(" Invalid input!");
unsure = true;
}
}
if (done)
break;
}
}
Why is 'Round 1' shown as 'Round 0'?
The value of variable rounds is printed as the round number. If the round number always prints as 0 then it follows that rounds always has value zero at the point where that printf() call is made. And indeed, a look at all the appearances of that variable in your code shows that it is initialized to zero in its declaration, and then never modified.
And what does the 'inf' mean in
the average score section?
It means "infinity", and before even looking at your code, I would take it as a sign that you have somewhere used the result of dividing a non-zero floating-point number by zero.
In particular, the problem seems to be the same one as the previous: you use rounds as the divisor in your average score computation, and it is always zero.
How do I turn 'inf' into a numerical
output?
Change the faulty computation into a correct one. Properly maintaining the value of the rounds variable may be enough.
After 2 rounds, the output 'Round 2' is still shown as 'Round
0' and the 'Average score' did not change to a numerical output.
That's consistent with my observations above.

C Pointers: Exception Thrown: Read access violation

I am writing a program in C that plays the game Craps. After my first roll, when I either land the point (win) or lose, the program just ends instead of calling is_win or is_loss.
But if it calls is_win or is_loss on my first roll, everything works fine.
I'm fairly certain this has something to do with the pointer pbal. I've been getting errors in the debugger saying unable to read memory, also Exception Thrown: Read access violation. I am still fairly new to pointers so I'm assuming this is the root cause of the problem.
# include "header.h"
int print_menu(void) {
int choice = 0;
printf("\n1. Enter balance\n2. Play game\n3. Get rules\n4. End game");
printf("\nEnter which you would like to do: ");
scanf("%d", &choice);
return choice;
}
void print_rules(void) {
printf("\nFirst Roll: If your die roll adds to 7 or 11, you win.\nIf it adds to 2, 3, or 12, you immediately lose.\nIf it adds to another number, that number becomes your 'point'");
printf("\nSecond Roll: If your die roll adds to your point, you win. If it adds to 7, you lose.\nKeep rolling until you get one of these.\n\n");
}
int get_balance(balance) {
printf("\nEnter how much money you would like to add (whole dollars): ");
scanf("%d", &balance);
return balance;
}
int prompt_bet(balance) {
int bet = 0;
do {
printf("\nEnter how much you would like to bet for this game: ");
scanf("%d", &bet);
} while (bet > balance); //repeats until its false that bet>bal
return bet;
}
int roll_dice(void) {
srand((unsigned int)time(NULL));
int enter = 1;
printf("\nEnter a 0 to roll your dice: ");
scanf("%d", &enter);
int die1 = rand() % 6 + 1;
int die2 = rand() % 6 + 1;
int dice = die1 + die2;
printf("You rolled a %d and a %d, with a total of %d.\n", die1, die2, dice);
return dice;
}
int calc_first_roll(int dice, int bet, int balance, int * pbal) {
int result0 = 0;
if (dice == 7 || dice == 11) {
is_win(bet, balance, pbal);
}
else if (dice == 2 || dice == 3 || dice == 12) {
is_loss(bet, balance, pbal);
}
else {
printf("Your point is %d", dice);
int point = dice;
int done = 1;
do {
dice = roll_dice();
done = calc_other_rolls(point, dice, balance, bet, *pbal);
} while (!done);
}
return result0;
}
void is_win(int bet, int balance, int *pbal) {
/* the pointer *pbal is pointing to mainbalance. I had to pass it
through everything to get it to affect mainbal the way I wanted it to.
Think of mainbalance as the permanent memory for keeping their bets & money right,
and int balance is just a messenger that doesn't get in the way of me trying
to use a pointer on mainbalance. */
*pbal = balance + bet;
printf("You win! Your new balance is %u\n", *pbal);
}
void is_loss(int bet, int balance, int *pbal) {
*pbal = balance - bet;
printf("You lost. Your new balance is %u\n", *pbal);
}
int calc_other_rolls(int point, int dice, int balance, int bet, int *pbal) {
int done = 0;
if (dice == 7) { //Goes straight to is_l / is_w instead of looping back to calc_first
is_loss(bet, balance, *pbal);
done = 0;
}
else if (dice == point) {
is_win(bet, balance, *pbal);
done = 0;
}
else {
done = 0;
}
return done;
}
# include "header.h"
int main(void) {
int mainbalance = 0;
int choice = 0;
int *pbal = &mainbalance;
do {
choice = print_menu();
if (choice == 1) {
mainbalance = get_balance();
printf("Your balance is: %d\n", mainbalance);
choice = 8; //reprints menu
}
if (choice == 3) {
print_rules();
choice = 8;
}
if (choice == 4)
exit(1);
if (choice == 2) {
int bet = prompt_bet(mainbalance);
int dice = roll_dice();
int x = calc_first_roll(dice, bet, mainbalance, pbal);
choice = 8;
}
} while (choice > 4 || choice < 1); //keeps running code until test becomes false.
return 0;
}
In this section:
if (dice == 7) { //Goes straight to is_l / is_w instead of looping back to calc_first
is_loss(bet, balance, *pbal);
done = 0;
}
else if (dice == point) {
is_win(bet, balance, *pbal);
done = 0;
}
You're not passing is_loss and is_win the pointer, you're passing the integer value, that pbal points to. * outside of a declaration is always dereferencing.
So if calc_other_rolls gets int *pbal as an argument and you wanna pass it to another function that takes int * then you should do func(pbal) and not func(*pbal), since the second one passes the value not the pointer.
Edit: As #hollow pointed out, this gets flagged by the compiler if you enable warnings, so use them.

srand function is returning same values

Hey guys take a look at this program.
/* The craps game, KN king page 218 */
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>
int roll_dice(void);
bool play_game(void);
int roll_dice(void)
{
int roll;
getchar();
srand((unsigned) time(NULL));
roll = rand() % 13;
if(roll == 0)
roll = roll + 1;
return roll;
}
bool play_game()
{
int sum = 0, wins = 0, loss = 0, point;
sum = roll_dice();
printf("You rolled: %d", sum);
if(sum == 7 || sum == 11)
{
printf("\nYou won!\n");
return true;
}
if(sum == 2 || sum == 3 || sum == 12)
{
printf("\nYou lost!!");
return false;
}
point = sum;
printf("\n\nYour point is: %d", point);
do
{
sum = roll_dice();
printf("\nYou rolled: %d", sum);
}while(sum != point);
if(sum == point)
{
printf("\nYou won!!!");
return true;
}
}
int main()
{
char c, wins = 0, losses = 0;
bool check;
do
{
check = play_game();
if(check == true)
wins++;
else if(check == false)
losses++;
printf("\nPlay Again? ");
scanf("%c", &c);
}while(c == 'Y' || c == 'y');
printf("\nWins: %d Losses: %d", wins, losses);
return 0;
}
The srand function keeps returning, same value 3 or 4 times, y is that?
I want different values each time when i roll the dice, copy the code and run it to see what i mean
srand() is a function that sets the seed for the rand() function. What you are doing here is setting the seed to the current time before every rand() you call, which, if called fast enough, will get you the same value (since it will reset to the same seed, which if fast enough will be the same time value).
What you'll want to do is call srand() once, when the program starts (at the start of your main() function)
Then call rand() every time you want a random number, like you are doing currently, but without calling srand() every time.

Resources