C and C++ realize dice game

  • 2020-11-25 07:27:27
  • OfStack

We are going to simulate a very popular game called dice.

Dice come in many forms, the most common being two six-sided dice. In some adventure games, five kinds of dice are used: four, six, eight, twelve, and twenty. The wise ancient Greeks proved that there are only five regular polyhedra, all of whose faces are of the same shape and size. The various types of dice developed from these regular polyhedra. You can have other faces, but they won't all be equal, so the probability of each face going up is different.
Computer calculations do not take into account the constraints of geometry, so you can design an electronic die with any number of faces. Let's start with six sides.
We want to get random Numbers between 1 and 6. However, rand() generates random Numbers between 0 and RAND_MAX. RAND_MAX is defined in stdlib.h and its value is usually INT_MAX. Therefore, some adjustments need to be made as follows.

1. Modulus 6 of the random number, and the integer obtained is between 0 and 5.
2. Add 1 to the result, and the new value is between 1 and 6.
3. To facilitate future expansion, replace the number 6 in Step 1 with the number of sides of the die.

The following code implements these three steps:


#include <stdlib.h> /*  provide rand() The prototype of the  */
int rollem(int sides)
{
int roll;
roll = rand() % sides + 1;
return roll;

}

We also want to use a function to prompt the user to choose a die with any number of faces and return the sum of the Numbers.


/* diceroll.c --  Dice simulation program  */
/*  with  mandydice.c 1 The compiler  */
#include "diceroll.h"
#include <stdio.h>
#include <stdlib.h>      /*  Provide library functions  rand() The prototype of the  */
int roll_count = 0;      /*  External links  */
static int rollem(int sides)  /*  This function is private to the file  */
{
int roll;
roll = rand() % sides + 1;
++roll_count;       /*  Count the number of function calls  */
return roll;
}
int roll_n_dice(int dice, int sides)
{
int d;
int total = 0;
if (sides < 2)
{
printf("Need at least 2 sides.\n");
return -2;
}
if (dice < 1)
{
printf("Need at least 1 die.\n");
return -1;
}
for (d = 0; d < dice; d++)
total += rollem(sides);
return total;
}

New elements are added to the file. 1, the rollem() function, which is private to the file, is a helper function of roll_n_dice(). Second, to demonstrate the nature of external links, the file declares an external variable, roll_count. This variable counts the number of calls to the rollem() function. This design is a bit lame, just to demonstrate the nature of external variables. Third, the file contains the following pre-processing instructions:


#include "diceroll.h"

If you use standard library functions, such as rand(), include the standard header file in the current file (for rand(), stdlib.h), rather than declaring the function. Because the correct function prototype is already included in the header file. Following this example, we put the prototype of the roll_n_dice() function in the ES45en.h header file. Place the file name in double quotation marks instead of Angle brackets, indicating that the compiler looks for the file locally, rather than where the compiler stores standard header files. What "local lookup" means depends on the implementation. Some common implementation header files are in the same directory or folder as source code files or project files (if the compiler USES them).


//diceroll.h
extern int roll_count;
int roll_n_dice(int dice, int sides);

This header file contains 1 function prototype and 1 extern declaration. Since the direroll.c file contains this file, direroll.c actually contains two declarations of roll_count:


extern int roll_count;   //  Declarations in header files (referential declarations) 
int roll_count = 0;     //  Declarations in source code files (defined declarations) 

It's ok to do that. A variable can only have one definition declaration, but a declaration with extern is a referential declaration and can have multiple referential declarations.
Programs that use the roll_n_dice() function must contain the diceroll.c header file. Once the header file is included, the program can use the roll_n_dice() function and the roll_count variable.


/* manydice.c --  A simulation program of rolling dice many times  */
/*  with  diceroll.c 1 The compiler */
#include <stdio.h>
#include <stdlib.h>    /*  For the library function  srand()  Provide a prototype */
#include <time.h>     /*  for  time()  Provide a prototype */
#include "diceroll.h"   /*  for roll_n_dice() Provide a prototype for roll_count variable   Provide a statement  */
int main(void)
{
int dice, roll;
int sides;
int status;
srand((unsigned int) time(0)); /*  A random seed  */
printf("Enter the number of sides per die, 0 to stop.\n");
while (scanf("%d", &sides) == 1 && sides > 0)
{
printf("How many dice?\n");
if ((status = scanf("%d", &dice)) != 1)
{
905
if (status == EOF)
break;       /*  Exit the loop  */
else
{
printf("You should have entered an integer.");
printf(" Let's begin again.\n");
while (getchar() != '\n')
continue;   /*  Handle incorrect input  */
printf("How many sides? Enter 0 to stop.\n");
continue;       /*  So let's go to the bottom of the loop 1 iteration  */
}
}
roll = roll_n_dice(dice, sides);
printf("You have rolled a %d using %d %d-sided dice.\n",
roll, dice, sides);
printf("How many sides? Enter 0 to stop.\n");
}
printf("The rollem() function was called %d times.\n",
roll_count);     /*  Using external variables  */
906
printf("GOOD FORTUNE TO YOU!\n");
return 0;
}

Compile this file with file 1 that contains program Listing 12.11. You can put program listings 12.11, 12.12, and 12.13 in the same folder or directory. To run the program, here is a sample output:


Enter the number of sides per die, 0 to stop.
6
How many dice?
2
You have rolled a 12 using 2 6-sided dice.
How many sides? Enter 0 to stop.
6
How many dice?
2
You have rolled a 4 using 2 6-sided dice.
How many sides? Enter 0 to stop.
6
How many dice?
2
907
You have rolled a 5 using 2 6-sided dice.
How many sides? Enter 0 to stop.
0
The rollem() function was called 6 times.
GOOD FORTUNE TO YOU!

Because the program USES srand() to randomly generate random number seeds, in most cases it is difficult to get the same output even if the input is the same. Note that main() in ES79en.c accesses the roll_count variable defined in ES82en.c.

There are three situations that can cause the outer while loop to end: side is less than 1, the input type does not match (in which case scanf() returns 0), and the end of the file is encountered (the return value is EOF). To read the number of dice, the program handles the end of the file in a different way (exiting the while loop) than it handles the type mismatch (entering the next iteration of the loop).

roll_n_dice() can be used in a number of ways. When sides is equal to 2, the program mimics tossing a hard coin with a "heads up" value of 2 and a "tails up" value of 1 (or vice versa). It is easy to modify the program to display the results of points individually, or to build a 1 die simulator. If you roll the dice many times (as in some role-playing games), you can easily modify the program to produce similar results:


Enter the number of sets; enter q to stop.
18
How many sides and how many dice?
6 3
Here are 18 sets of 3 6-sided throws.
908
12 10 6 9 8 14 8 15 9 14 12 17 11 7 10
13 8 14
How many sets? Enter q to stop.
q

rand1() or rand() (not rollem()) can also be used to create a number guessing program that lets the computer select a number that you guess. Readers can write this program themselves if they are interested.


Related articles: