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.
Related
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.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(0));
int random = 0, guess, guesses = 1;
random = rand() % 100 + 1;
printf("The number has been generated. Input 0 to quit.\n");
do {
scanf("%d", &guess); //takes user input for guess
if (guess > random && guess != 0)
printf("Lower!\n");
else
if (guess < random && guess != 0)
printf("Higher!\n");
else
if (guess == random) {
printf("Bingo!");
return 0;
} else
if (guess == 0) {
printf("Thanks for playing, the number was %d\n", &random);
return 0;
}
guesses++;
} while (guesses != 6); //maximum of 5 guesses
printf("Thanks for playing, the number was %d\n", &random);
return 0;
}
Whenever I display the random variable when it has already generated a number a garbage value will be outputted. But the code snippet works of checking the comparison between the guess and the random number, I just can't seem to output the random number correctly.
%d in printf expects an argument of int data type. You are passing int * data type (&random).
Remove & before random in last two printfs.
printf("Thanks for playing, the number was %d\n", random);
You should pass the value of random instead of its address:
printf("Thanks for playing, the number was %d\n", random);
Note also that you should check the return value of scanf(): if you type a letter, the program will have undefined behavior, it may exit after iterating 5 times, or iterate forever or do something else entirely...
Here is an improved version:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int random, guess, guesses;
srand(time(0));
random = rand() % 100 + 1;
printf("The number has been generated. Input 0 to quit.\n");
for (guesses = 0; guesses < 5; guesses++) {
// take user input for guess
if (scanf("%d", &guess) != 1 || guess == 0)
break;
if (guess > random) {
printf("Lower!\n");
} else
if (guess < random) {
printf("Higher!\n");
} else {
printf("Bingo!\n");
return 0;
}
}
printf("Thanks for playing, the number was %d\n", random);
return 0;
}
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;
First, here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define NUM_SUITS 4
#define NUM_RANKS 13
bool in_hand[NUM_SUITS][NUM_RANKS] = {false};
bool newcard = {false};
int num_cards, rank, suit, totrank;
const char rank_code[] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K',};
const char suit_code[] = {'C','D','H','S'};
int main_hand ()
{
suit = rand() % NUM_SUITS;
rank = rand() % NUM_RANKS;
if (!in_hand[suit][rank]) {
in_hand[suit][rank] = true;
num_cards--;
if (suit == 0){
printf("%c of Clubs \n", rank_code[rank]);
}
else if (suit == 1){
printf("%c of Diamonds \n", rank_code[rank]);
}
else if (suit == 2){
printf("%c of Hearts \n", rank_code[rank]);
}
else if (suit == 3){
printf("%c of Spades \n", rank_code[rank]);
}
}
}
int print_hand (suit)
{
}
int totrank_check (totrank)
{
if (totrank > 21) {
printf ("You lose!");
}
else if (totrank == 21) {
printf ("You win!");
}
}
int main()
{
bool stay = {false};
srand((unsigned) time(NULL));
totrank = 0;
num_cards = 2;
printf("Your hand: ");
while (num_cards > 0) {
main_hand();
totrank = totrank + (rank + 1);
}
printf("Total rank: %d\n", totrank);
totrank_check(totrank);
printf("\n");
while (totrank < 24 && stay == false) {
printf("Another card? 1. Yes 0. No\n");
scanf("%d", &newcard);
if(!newcard) {
main_hand();
}
totrank = totrank + (rank + 1);
totrank_check(totrank);
printf("Total rank: %d\n", totrank);
printf("Stay? 1. Yes 0. No\n");
scanf("%d", &stay);
}
return 0;
}
Basically it's a code that "simulates" and hand of blackjack.
It starts, rand() chooses two numbers, the rank and the suit of the cards, that are set as true in a matrix so that they can't be chosen again in the same combination and then printed.
There's a check for the total rank of the cards (so that if it exceeds 21 you automatically lose) and then you are asked if you want another card or you want to stay.
Here's the error: if you choose that you want another cards, this new card will be the same as the last one.
Basically, you get a Ace of Spades, the and Two of Diamonds, then you want another card and you get another Two of Diamonds. And the another, and another. If you remove the rank check in the second while you can see that the rank grows based on the rank of the last card.
Before, the printfs were in that print_hand() function, and you could see that you always got the same card, now I moved them in the main_hand() function because I thought that it might be the problem (it wasn't) and because having a separate function for the print was redundant. But you can see that technically, the if(!in_hand[suit][rank]) works, because, since the card is the same, it doesn't enter the if and it doesn't get printed.
I don't know what's causing this problem. Any idea?
Please note I'm already using srand((unsigned) time(NULL)); to seed rand().
scanf("%d", &newcard); and scanf("%d", &stay); are a problem as the variables are bool, but the format specifier is for int. In 2 places, change like:
// scanf("%d", &newcard);
int t;
scanf("%d", &t);
newcard = !!t;
3 functions return int but do not return anything. Change to void functions.
// int main_hand() {
void main_hand() {
There appears to be other logic issues too.
1) Code sometimes exists without knowing if won/loss
2) #Jongware comment above correct:
Lastly: If the same random sequence is still coming up, strip code to a bare main srand time printf rand and see if that works. time(), if not working always returns -1.
Or simple add the following and verify srand() called with different values.
int main(void) {
unsigned now = (unsigned) time(NULL);
printf("now = %u\n", now);
srand(now);
First, here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define NUM_SUITS 4
#define NUM_RANKS 13
bool in_hand[NUM_SUITS][NUM_RANKS] = {false};
bool newcard = {false};
int num_cards, rank, suit, totrank;
const char rank_code[] = {'A','2','3','4','5','6','7','8','9','T','J','Q','K',};
const char suit_code[] = {'C','D','H','S'};
int main_hand ()
{
suit = rand() % NUM_SUITS;
rank = rand() % NUM_RANKS;
if (!in_hand[suit][rank]) {
in_hand[suit][rank] = true;
num_cards--;
if (suit == 0){
printf("%c of Clubs \n", rank_code[rank]);
}
else if (suit == 1){
printf("%c of Diamonds \n", rank_code[rank]);
}
else if (suit == 2){
printf("%c of Hearts \n", rank_code[rank]);
}
else if (suit == 3){
printf("%c of Spades \n", rank_code[rank]);
}
}
}
int print_hand (suit)
{
}
int totrank_check (totrank)
{
if (totrank > 21) {
printf ("You lose!");
}
else if (totrank == 21) {
printf ("You win!");
}
}
int main()
{
bool stay = {false};
srand((unsigned) time(NULL));
totrank = 0;
num_cards = 2;
printf("Your hand: ");
while (num_cards > 0) {
main_hand();
totrank = totrank + (rank + 1);
}
printf("Total rank: %d\n", totrank);
totrank_check(totrank);
printf("\n");
while (totrank < 24 && stay == false) {
printf("Another card? 1. Yes 0. No\n");
scanf("%d", &newcard);
if(!newcard) {
main_hand();
}
totrank = totrank + (rank + 1);
totrank_check(totrank);
printf("Total rank: %d\n", totrank);
printf("Stay? 1. Yes 0. No\n");
scanf("%d", &stay);
}
return 0;
}
Basically it's a code that "simulates" and hand of blackjack.
It starts, rand() chooses two numbers, the rank and the suit of the cards, that are set as true in a matrix so that they can't be chosen again in the same combination and then printed.
There's a check for the total rank of the cards (so that if it exceeds 21 you automatically lose) and then you are asked if you want another card or you want to stay.
Here's the error: if you choose that you want another cards, this new card will be the same as the last one.
Basically, you get a Ace of Spades, the and Two of Diamonds, then you want another card and you get another Two of Diamonds. And the another, and another. If you remove the rank check in the second while you can see that the rank grows based on the rank of the last card.
Before, the printfs were in that print_hand() function, and you could see that you always got the same card, now I moved them in the main_hand() function because I thought that it might be the problem (it wasn't) and because having a separate function for the print was redundant. But you can see that technically, the if(!in_hand[suit][rank]) works, because, since the card is the same, it doesn't enter the if and it doesn't get printed.
I don't know what's causing this problem. Any idea?
Please note I'm already using srand((unsigned) time(NULL)); to seed rand().
scanf("%d", &newcard); and scanf("%d", &stay); are a problem as the variables are bool, but the format specifier is for int. In 2 places, change like:
// scanf("%d", &newcard);
int t;
scanf("%d", &t);
newcard = !!t;
3 functions return int but do not return anything. Change to void functions.
// int main_hand() {
void main_hand() {
There appears to be other logic issues too.
1) Code sometimes exists without knowing if won/loss
2) #Jongware comment above correct:
Lastly: If the same random sequence is still coming up, strip code to a bare main srand time printf rand and see if that works. time(), if not working always returns -1.
Or simple add the following and verify srand() called with different values.
int main(void) {
unsigned now = (unsigned) time(NULL);
printf("now = %u\n", now);
srand(now);