5
\$\begingroup\$

Any idea to write this code (fixable part) smarter?

Note: Arrays, pointers, global value are not allowed to use.

The game is played with 6 rounds. At the beginning, each player rolls one dice, with the highest roll going first. On their turns, players roll three dice in order to earn points. During each round, players attempt to roll the same number as the number of the round (for example, rolling three 3's in Round 3 would earn the player points). For every number rolled that matches the round number, one point is awarded to that player. A player keeps rolling until they score no points. Then the dice are passed to other player.

Scoring:

Players score points when any of the dice they roll match the number of the round. Each matching number rolled scores 1 point. For example, if a player rolls two 2's in round 2, the player receives two points and rolls again.

The numbers on the dice are not added together, nor does the number on the dice indicate point value. A 1 rolled in round 1 is worth 1 point, a 3 rolled in round 3 is worth 1 point, and a 6 rolled in round 6 is also worth 1 point.

However, if a player's dice all show the same number, they will earn more points. If the three dice match the number of the round being played, it's called a Bunco and the player earns 21 points. The player must call out "Bunco!" in order to receive the points. (For example, if a player rolls three 4's in round 4, they would call out "Bunco!" and earn 21 points.)

If a player rolls three of another number that doesn't match the number of the current round (for example, rolling three 6's in round 4), the player earns 5 points instead.

In this project, your task is to write a simplified Bunco game for 2 players and 6 rounds. Your program should display the dice values for each round, accumulate and display the points won by each player and find the player that makes more points. Please note that, if a player's dice all show the same number, they will earn more points(BUNCO!).

Each time the dice are rolled, each die is read separately (they aren't added together).

In round 1, each 1 rolled is worth 1 point.

In round 2, each 2 rolled is worth 1 point.

In round 3, each 3 rolled is worth 1 point.

In round 4, each 4 rolled is worth 1 point.

In round 5, each 5 rolled is worth 1 point.

In round 6, each 6 rolled is worth 1 point.

Rolling three-of-a-kind(1-1-1, 2-2-2, 3-3-3, 4-4-4, 5-5-5,6-6-6) of the same number of the round you're on is a Bunco. The player must call out "Bunco!" to receive 21 points, and then must keep rolling

Rolling three-of-a-kind of any number other than the round you're on is worth five points For example, rolling three 5's in Round 3 is worth five points.

Programming Requirements: In order to implement this game you will need to write at least the following functions, but if you need more functions you can add them.

 menu – This function asks the user the following: (1) Start the game by selecting who will start first (2) Exit

 roll_a_dice – This function will roll a dice and return the result. The rolling action should be done randomly.

 display_dice_values – This function will mainly be responsible from displaying the dice values at the end of each round.

 compute_points – This function will compute the points won by each player at the end of each roll.

 display_points – This function will display the points won by each player at the end of each round.

 display_final_points – This function will display the final points won by each player at the end of each game.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int roll_a_dice()
{
    return 1+rand()%6;
}

void display_dice_values(int rollNumber, int dice1, int dice2, int dice3)
{
    printf("Roll %d \nDice are rolled:\nDice 1: %d \t Dice 2: %d \t Dice 3: %d", rollNumber, dice1, dice2, dice3 );
}

void display_points(int points_player, int total_points_player)
{
    printf("\nPoints: %d \nTotal points: %d\n\n", points_player, total_points_player);
}

void display_final_points(int total_points_player1, int total_points_player2)
{
    printf("\n\n\n\nFINAL RESULT \n------------\n------------\nPLAYER 1: %d \nPLAYER 2: %d", total_points_player1, total_points_player2 );
    if(total_points_player1>total_points_player2)        printf("\n\nPLAYER 1 IS WINNER! CONGRATULATIONS...");
    else if(total_points_player1==total_points_player2) printf("\n\nDRAW...");
    else                                                printf("\n\nPLAYER 2 IS WINNER! CONGRATULATIONS...");
}

int compute_points(int dice1, int dice2, int dice3, int round)
{
    int point;
    if     ( (dice1 == dice2) && (dice1 == dice3) && (dice1 == round) )     return 21;      //in case each dice equal to both round number and each other
    else if( (dice1 == dice2) && (dice1 == dice3) && (dice1 != round) )     return 5;       //in case each dice equal each other but not equal to round number
    else if( (dice1 != round) && (dice2 != round) && (dice3 != round) )     return 0;       //in case no score
    else        //in case at least one dice is different than others            
    {
        if(dice1==round) point++;
        if(dice2==round) point++;
        if(dice3==round) point++;
        return point;
    }       
}

void menu()
{
    int option, player1, player2, turn, round=1, dice1, dice2, dice3, roll, points;     
    int points_player1=0, points_player2=0, total_points_player1=0, total_points_player2=0 ,rollNumber;

    printf("\n\n\n\n\nBUNCO GAME!\nChoose one from the followings:\n1. Start the game by selecting who will start first\n2. Exit\n");
    scanf("%d", &option);
    if(option==1)
        {
            printf("\n\nBUNCO STARTS\nDice are rolled by each player in order to select who will start first:");
            player1=roll_a_dice();
            player2=roll_a_dice();
            printf("\nDice 1: %d --- Dice 2: %d\n\n", player1, player2);
            while(player1==player2) //if dice are equal they are rolled again
            {
                player1=roll_a_dice();
                player2=roll_a_dice();
                printf("\nDice are equal. Roll again \nDice 1: %d --- Dice 2: %d\n", player1, player2);
            }
            //determines first player, appoint turn as "1" or "2" that indicate player 1 and player 2
            if(player1>player2)  
            {
                turn=1;
                printf("Player %d stars", turn);
            }    
            else 
            {
                turn=2;
                printf("Player %d stars", turn);
            }

            while(round<=6)      //turns 6 times for rounds
            {
                printf("\n\n\nROUND %d\n-------\n",round);
                rollNumber=1;    //it makes rollNumber "1" for each round
                points=1;    // makes "points" non-zero to enter while loop in every round 
                printf("\nPLAYER %d'S TURN\n\n", turn);

                while(points!=0)
                {               
                    display_dice_values(rollNumber, dice1=roll_a_dice(), dice2=roll_a_dice(), dice3=roll_a_dice());     //both rolls dice and display
                    if(turn==1)     //if turn is for player 1, function computes points for player1
                    {
                        if( (points_player1=compute_points(dice1, dice2, dice3, round))==21 ) printf("\n\nBUNCO!\n");       //if point equals to 21, prints the message
                        total_points_player1+=points_player1;
                        display_points(points_player1, total_points_player1);
                        points=points_player1; // provides to keep re-roll in case point won in the round is non-zero
                    }
                    else        //if turn is for player 2, function computes points for player2
                    {
                        if( (points_player2=compute_points(dice1, dice2, dice3, round))==21 ) printf("\n\nBUNCO!\n");
                        total_points_player2+=points_player2;
                        display_points(points_player2, total_points_player2);
                        points=points_player2;
                    }
                    rollNumber++; // increas rollNumber for each roll
                }
                //to pass next player's turn
                if(turn==1) turn++;
                else        turn--;
                round++;    //passes next round
            }   
        }

    else
    {
        printf("\nGoodbye!");
        exit(1);
    }   
    display_final_points(total_points_player1, total_points_player2);
}

int main()
{
    srand(time(NULL));
    while(1)
        menu();     //to keep open new game 
    return 0;
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Bug

In compute_points(), you never initialized the variable point, which means the function could end up returning the wrong value. You should initialize it to 0 like this:

int point = 0;

Simplifications for compute_points()

There are a few things that I would change in the compute_points() function.

  1. You check whether the dice are equal twice, when you only need to do it once.
  2. You make a special case for no dice matching the round, which is unnecessary.
  3. You put the return statements on the same line as the if statements.

Here is how I would have written the function:

int compute_points(int dice1, int dice2, int dice3, int round)
{
    // If all 3 dice match, it's either a 21 point BUNCO or a 5 point BUNCO,
    // depending on whether the dice match the round or not.
    if (dice1 == dice2 && dice1 == dice3) {
        if (dice1 == round)
            return 21;
        else
            return 5;
    }

    // Otherwise, you get one point for each die that matches the round.
    return (dice1 == round) + (dice2 == round) + (dice3 == round);
}

Notes:

  1. I took advantage of the fact that (dice1 == round) evaluates to 1 if true and 0 if false.
  2. There is a practical reason for putting return statements on separate lines from if statements (not just for stylistic purposes). When you start using a debugger on your programs, you will often find that you will need to set a breakpoint on a return line to catch when your function returns a particular value. If you put the if statement on the same line as the return, your breakpoint will stop the program at the if instead of the return.

Other things

  • A few of your while loops could be better off by being do loops instead, but I'm not sure you have learned about do loops yet.
  • You tend to put a lot of things on the same line, such as an if statement, the code following the if, and a comment. I would advise putting each of these on a separate line. Again, this has a practical purpose for debugging.
  • For printing out multiple lines using printf(), I use a trick with string concatenation so that I can visualize what I'm printing better. For example, your code is this:

     printf("Roll %d \nDice are rolled:\nDice 1: %d \t Dice 2: %d \t Dice 3: %d", rollNumber, dice1, dice2, dice3 );     
    

    I would do this:

    printf("Roll %d \n"
           "Dice are rolled:\n"
           "Dice 1: %d \t Dice 2: %d \t Dice 3: %d",
           rollNumber, dice1, dice2, dice3);
    

    When you have two strings back to back such as "string1" "string2", the C compiler will automatically concatenate those two strings into one string, even if they are on different lines. So my version is equivalent to yours.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.