# Ceelo game using C Assignment Solution

## 2 Player Dice Game

Two players (in our case, one human, once CPU) roll three dice each until both have a recognized dice combination. Whoever rolls the better combination wins! A tie results in both player and CPU rerolling their three dice until they both have a recognized combination. Recognized combinations are ranked below from best to worst:

• 4-5-6: The die values are 4, 5, and 6 (order doesn’t matter).

1

• Trips: The three die values are all the same. If both players roll trips, the higher trips (larger dice value) beats the lower trips.
• Point: A pair is rolled. The non-matching dice is the ”point”. A higher point beats a lower point (so 1-1-5 beats 6-3-6).
• 1-2-3: The die values are 1, 2, and 3 (order doesn’t matter).

Note that a tie in terms of Trips would be both players rolling the same trips numbers (i.e. 3-3-3 and 3-3-3), and a tie in terms of points would be both players rolling the same point (i.e. 6-2-6 and 3-3-2).

A single game of Cee-lo is both players rolling a recognized combination and NOT tying (that is, one player’s combination beats the other player’s combination).

Write a program (called ceelo.c) that implements Cee-lo according to the above rules. The game should also allow for wagering. This means that you need to prompt the user for an initial bank balance (we assume they’re honest!) from which their winnings or losings will be added or subtracted. Before each game, prompt the user for a wager. Re-ask for a wager if their wager is not valid (if they don’t have enough money to make their wager). Once a game is won or lost, the bank balance should be adjusted, and, if the player has a non-zero balance, the player should be able to choose if they want to play another game or cash out their winnings (quit the program).

Several functions have been implemented for you in the template provided.

1. void print_game_rules(void) – Prints out the rules of the game.
2. void is_number_in_die(int die, int num) – Returns a 1 if num is one of the three values in the die array and a 0 if not.
3. void has_pair(int die) – Returns the value of the unmatched die if a pair exists in the 3 die, or a 0 if no pair exists.

You will need to use the below functions to help you write the game logic. You may define more than just these, but these functions must be defined as described below:

1. double get_bank_balance(void) – Prompts the player for an initial bank balance and re- turns it.
2. double get_wager_amount(void) – Prompts the player for a wager on a particular game of Cee-lo. The wager is returned.
3. int check_wager_amount(double wager, double balance) – Checks to see if the wager is within the limits of the player’s available balance. If the wager exceeds the player’s balance, then 0 is returned; otherwise, 1 is returned.
4. void roll_die(int die) – Rolls three die. This function should randomly generate a value between 1 and 6 inclusive for each dice value in the die array. Here we are using an array to hold a player’s three dice. Remember that a function can change the values in an array that is passed in as an argument. To generate a random number, you use the rand() function. By itself, rand() will generate a random number between 0 and some maximum integer value, usually 32767. In other words
5. int x = rand(); In the above example, x is now some random integer between 0 and 32767. What you’ll need to figure out is how to get a random number between 1 and 6 inclusive. Note that rand() takes no arguments, so there is no way for you to tell the function to generate specific values. Hint: use the mod operator and some other math.
6. intget_rank(int die)–Returnstherankofthecombinationforthedicevaluespassed in. If the combination is 4-5-6, this function should return a 4; if the combination is Trips, this function should return a 3; if the combination is Point, this function should return a 2; if the combination is 1-2-3, this function should return a 1; if the combination is not one of the previous four (aka it is not a recognized combination), this function should return a 0. You will need to use the is_number_in_die() and has_pair() functions in this function.

2

1. int user_won_lost_or_neither(int user_die, int cpu_die) – Returns a 1 if the user has won, a 0 if the user has lost, and a -1 if there was a tie game. This function will need to call the get_rank() function for both the player and the CPU's dice. If the user’s combination ranks higher than the CPU's, the user has won; if the CPU's combination ranks higher than the user’s, the user has lost. If the combination ranks are the same, you will need to check for the case of Trips and Point whether there was truly a tie or not. For example, if both user and CPU rolled trips, the get_rank() function will return 3 for both. However, it is only a tie game if both CPU and player had matching trips. If they didn’t, the result of the game depends on the trip's value. The same goes for the Point combination.
2. doubleadjust_balance(double balance, double wager, int add_or_subtract) – If add_or_subtractis 1, then the wager is added to the balance and the sum is returned. If add_or_subtractis 0, then the wager is subtracted from the balance and the difference is returned. Otherwise, the balance remains unchanged and is returned.
3. Does not need to be implemented as a function, but various printf() statements in main() indicate the status of the game: at minimum, the bank balance at the start of a game, the dice rolls during the game, whether the player won or lost, and the player’s resulting balance at the end of each game.
4. A main() function that makes use of the above functions in order to play the game of Cee-lo. The program should play multiple games of Cee-lo if the player’s bank balance allows for it (the program should print out a message and quit if the player loses all their money). It should also allow the player to “cash-out” at the end of a game (i.e. quit) even if they still have money to wager.

All functions should be prototyped above the main and defined below it. There is a lot to this assignment, but a good approach is to implement the functions as they’re described above (except for main()) and make sure they function as they should (by writing tests in main(). Once you know each function behaves as it should begin work on main(). Write this function in steps: write it to play a single game of Cee-lo with no wagering, then add wagering (but still one game), then add the ability to play multiple games. You don’t have to break it down like this, but many students have found it helpful to approach this assignment like this in the past.

```#include < stdio.h> #include < time.h> #include < stdlib.h> void print_game_rules(void); int is_number_in_die(int die, int num); int has_pair(int die); // Add other function prototypes below here but above main(). int main(void) { // The line below sets the seed of the random number generator. srand(time(0)); print_game_rules(); // Your game logic goes here. return 0; } // It is good practice to define all functions after the body of the main() // function. void print_game_rules(void) { printf("Cee-lo rules:\n" "This is a battle of the player against the CPU. Both roll three\n" "dice each until both have a recognized combination. Whoever rolls\n" 3 } ```

4-5-6:

Trips:

The die values are 4, 5, and 6 (any order)

The three die values are all the same. Higher trips

beat lower trips (but still note that trips beat "point"

(see below).

A pair is rolled. The non-matching dice is the

Point:

```"the better combination wins! A tie results in both player and CPU\n" "rerolling their die until they each have a new combination.\n" "Combinations are ranked from best to worst as:\n" "\t4-5-6:\n\t\tThe die values are 4, 5, and 6 (any order)\n" "\tTrips:\n\t\tThe three die values are all the same. Higher trips\n" "\t\tbeats lower trips (but still note that trips beats \"point\"\n" "\t\t(see below).\n" "\tPoint:\n\t\tA pair is rolled. The non-matching dice is the\n" "\t\t\"point\". A higher point beats a lower point (so 1-1-5 beats\n" "\t\t6-3-6)\n" "\t1-2-3:\n\t\tThe die values are 1, 2, and 3 (any order)\n" "The above are the only recognized combinations. A player must\n" "reroll until they have one of the above combinations\n"); int is_number_in_die(int die, int num) { for (int i = 0; i< 3; i++) { if (num == die[i]) return 1; } return 0; } int has_pair(int die) { if (die == die) return die; else if (die == die) return die; else if (die == die) return die; else return 0; } ```

// Add your other function definitions below here

The following illustrates an example of the program described above. Your program can display the game output however you would like as long as the necessary information is there (see #8 above). Your dice rolls will likely be different.

Antonio.Ledesma:solution\$ ./a.out

Cee-lo rules:

This is a battle of the player against the CPU. Both roll three

dice each until both have a recognized combination. Whoever rolls

the better combination wins! A tie results in both player and CPU

rerolling their die until they each have a new combination.

Combinations are ranked from best to worst as:

4

1-2-3:

"point". A higher point beats a lower point (so 1-1-5 beats

6-3-6)

The die values are 1, 2, and 3 (any order)

The above are the only recognized combinations. A player must

reroll until they have one of the above combinations

Enter in an initial bank balance (in dollars): 100

Your current balance is \$100.00

Enter in a wager amount (in dollars): 500

Enter in a wager amount (in dollars): 400

Enter in a wager amount (in dollars): 50

You rolled (5, 4, 3) (unrecognized combo)

You rolled (6, 3, 4) (unrecognized combo)

You rolled (3, 2, 1)

CPU rolled (5, 2, 4) (unrecognized combo)

CPU rolled (4, 4, 6)

You lost!

Do you want to continue playing or quit and take your money (\$50.00)

(’c’ for continue, ’q’ for quit): c

Your current balance is \$50.00

Enter in a wager amount (in dollars): 50

You rolled (1, 5, 6) (unrecognized combo)

You rolled (1, 2, 1)

CPU rolled (4, 1, 4)

You won!

Do you want to continue playing or quit and take your money (\$100.00)

(’c’ for continue, ’q’ for quit): c

Your current balance is \$100.00

Enter in a wager amount (in dollars): 100

You rolled (2, 4, 6) (unrecognized combo)

You rolled (6, 4, 6)

CPU rolled (1, 6, 1)

You lost!

You left with \$0.00.

Better luck next time.

Solution:

``` #include < stdio.h> #include < time.h> #include < stdlib.h> /* Function prototypes */ void print_game_rules(void); int is_number_in_die(int die, int num); int has_pair(int die); double get_bank_balance(void); double get_wager_amount(void); int check_wager_amount(double wager, double balance); int get_rank(int die); int user_won_lost_or_neither(int user_die, int cpu_die); double adjust_balance(double balance, double wager, int add_or_subtract); void print_roll(const char *label, int die); void roll_die(int die); /* Entry point of the program */ int main(int argc, char *argv[]) { double balance, wager; int user_die, cpu_die; int roll_result; char response; /* Initialize the random generator, rules, and starting balance*/ srand((unsigned) time(0)); print_game_rules(); balance = get_bank_balance(); printf("Your current balance is \$%.2f\n", balance); /* Now we play the game */ while (balance > 0) { /* Get a valid wager */ wager = get_wager_amount(); while (!check_wager_amount(wager, balance)) wager = get_wager_amount(); /* We play the game make a valid roll */ roll_die(user_die); print_roll("You rolled", user_die); while (get_rank(user_die) == 0) { printf(" (unrecognized combo)\n"); roll_die(user_die); print_roll("You rolled", user_die); } printf("\n"); /* CPU's turn to roll */ roll_die(cpu_die); print_roll("CPU rolled", cpu_die); while (get_rank(cpu_die) == 0) { printf(" (unrecognized combo)\n"); roll_die(cpu_die); print_roll("CPU rolled", cpu_die); } printf("\n"); /* Check who won and adjust the user's balance */ roll_result = user_won_lost_or_neither(user_die, cpu_die); if (roll_result == 1) { printf("You won!\n"); balance = adjust_balance(balance, wager, 1); } else if (roll_result == 0) { printf("You lost!\n"); balance = adjust_balance(balance, wager, 0); } else { printf("Tie!\n"); } printf("You left with \$%.2f\n", balance); /* Auto terminate if the user lost all his money, otherwise ask if they want to play again. */ if (balance <= 0) { printf("Better luck next time.\n"); } else { printf("Do you want to continue playing or quit and take your money (\$%.2f)\n", balance); printf("('c' for continue, 'q' for quit): "); scanf(" %c", &response); while (response != 'c' && response != 'q') { printf("Do you want to continue playing or quit and take your money (\$%.2f)\n", balance); printf("('c' for continue, 'q' for quit): "); scanf("%c", &response); } if (response == 'q') break; } } return 0; } /* Display the game rules */ void print_game_rules() { printf("Cee-lo rules:\n" "This is a battle of the player against the CPU. Both roll three\n" "dice each until both have a recognized combination. Whoever rolls\n" "the better combination wins! A tie results in both player and CPU\n" "rerolling their die until they each have a new combination.\n" "Combinations are ranked from best to worst as:\n" "\t4-5-6:\n\t\tThe die values are 4, 5, and 6 (any order)\n" "\tTrips:\n\t\tThe three die values are all the same. Higher trips\n" "\t\tbeats lower trips (but still note that trips beats \"point\"\n" "\t\t(see below).\n" "\tPoint:\n\t\tA pair is rolled. The non-matching dice is the\n" "\t\t\"point\". A higher point beats a lower point (so 1-1-5 beats\n" "\t\t6-3-6)\n" "\t1-2-3:\n\t\tThe die values are 1, 2, and 3 (any order)\n" "The above are the only recognized combinations. A player must\n" "reroll until they have one of the above combinations\n"); } /* Returns a 1 if num is one of the three values in the die array and a 0 if not */ int is_number_in_die(int die, int num) { for (int i = 0; i < 3; i++) if (num == die[i]) return 1; return 0; } /* Returns the value of the unmatched die if a pair exists in the 3 die, or a 0 if no pair exists. */ int has_pair(int die) { if (die == die) return die; if (die == die) return die; if (die == die) return die; return 0; } /* Prompts the player for an initial bank balance and returns it. */ double get_bank_balance() { double balance; while (1) { printf("Enter in an initial bank balance (in dollars): "); scanf("%lf", &balance); if (balance > 0) break; } return balance; } /* Prompts the player for a wager on a particular game of Ceelo. The wager is returned. */ double get_wager_amount() { double wager; while (1) { printf("Enter in a wager amount(in dollars): "); scanf("%lf", &wager); if (wager > 0) break; } return wager; } /* Checks to see if the wager is within the limits of the player's available balance. If the wager exceeds the player's balance, then 0 is returned; otherwise, 1 is returned. */ int check_wager_amount(double wager, double balance) { if (balance >= wager) return 1; return 0; } /* Rolls three die.This function should randomly generate a value between 1 and 6 inclusive */ void roll_die(int die) { int i; for (i = 0; i < 3; i++) die[i] = (rand() % 6) + 1; } /* Returns the rank of the combination for the dice values passed in. If the combination is 4-5-6, this function returns a 4; if the combination is Trips, this function returns a 3; if the combination is Point, this function returns a 2; if the combination is 1-2-3, this function returns a 1; if the combination is not one of the previous four (aka it is not a recognized combination), this function returns a 0. */ int get_rank(int die) { int i, j, temp; /* Sort the die in ascending order */ for (i = 0; i < 2; i++) { for (j = i + 1; j < 3; j++) { if (die[i] > die[j]) { temp = die[i]; die[i] = die[j]; die[j] = temp; } } } /* Check for a high straight */ if (die == 4 && die == 5 && die == 6) return 4; /* Check for trips */ if (die == die && die == die) return 3; /* Check for point */ if (has_pair(die)) return 2; /* Check for low straight */ if (die == 1 && die == 2 && die == 3) return 1; return 0; } /* Returns a 1 if the user has won, a 0 if the user has lost, and a -1 if there was a tie game. */ int user_won_lost_or_neither(int user_die, int cpu_die) { int user_rank, cpu_rank; user_rank = get_rank(user_die); cpu_rank = get_rank(cpu_die); if (user_rank > cpu_rank) return 1; if (user_rank < cpu_rank) return 0; /* Special case for trips */ if (user_rank == 3 && cpu_rank == 3) { if (user_die > cpu_die) return 1; if (user_die < user_die) return 0; return -1; } /* Special case for point */ if (user_rank == 2 && cpu_rank == 2) { if (has_pair(user_die) > has_pair(cpu_die)) return 1; if (has_pair(user_die) < has_pair(cpu_die)) return 0; return -1; } return -1; } /* If add_or_subtract is 1, then the wager is added to the balance and the sum is returned. If add_or_subtract is 0, then the wager is subtracted from the balance and the different is returned. Otherwise, the balance remains unchanged and is returned.*/ double adjust_balance(double balance, double wager, int add_or_subtract) { if (add_or_subtract == 1) balance += wager; else if (add_or_subtract == 0) balance -= wager; return balance; } /* Display the roll */ void print_roll(const char *label, int die) { printf("%s (%d, %d, %d)", label, die, die, die); } ```