Skip to main content

Throwing The Dice

As an example of how to use functions, we conclude this section with a program that, while it isn't state of the art, does show that there are things you can already do with C. It also has to be said that some parts of the program can be written more neatly with just a little more C - but that's for later. All the program does is to generate a random number in the range 1 to 6 and displays a dice face with the appropriate pattern.

The main program isn't difficult to write because we are going to adopt the traditional programmer's trick of assuming that any function needed already exists. This approach is called stepwise refinement, and although its value as a programming method isn't clear cut, it still isn't a bad way of organising things:

main()

{

int r;

char ans;

ans = getans();

while(ans== 'y')

{

r = randn(6);

blines(25);

if (r==1) showone();

if (r==2) showtwo();

if (r==3) showthree();

if (r==4) showfour();

if (r==5) showfive();

if (r==6) showsix();

blines(21);

ans = getans();

}

blines(2);

}

If you look at main() you might be a bit mystified at first. It is clear that the list of if statements pick out one of the functions showone, showtwo etc. and so these must do the actual printing of the dot patterns - but what is blines, what is getans and why are we using randn()? The last time we used a random number generator it was called rand()!

The simple answers are that blines(n) will print n blank lines, getans() asks the user a question and waits for the single letter answer, and randn(n) is a new random number generator function that produces a random integer in the range 1 to n - but to know this you would have written the main program. We decided what functions would make our task easier and named them. The next step is to write the code to fill in the details of each of the functions. There is nothing to stop me assuming that other functions that would make my job easier already exist. This is the main principle of stepwise refinement - never write any code if you can possibly invent another function! Let's start with randn().

This is obviously an int function and it can make use of the existing rand() function in the standard library

int randn(int n)

{

return rand()%n + 1;

}

The single line of the body of the function just returns the remainder of the random number after dividing by n - % is the remainder operator - plus 1. An alternative would be to use a temporary variable to store the result and then return this value. You can also use functions within the body of other functions.

Next getans()

char getans()

{

int ans;

printf("Throw y/n ?");

ans = -1;

while (ans == -1)

{

ans=getchar();

}

return ans;

}

This uses the standard int function getchar() which reads the next character from the keyboard and returns its ASCII code or -1 if there isn't a key pressed. This function tends to vary in its behaviour according to the implementation you are using. Often it needs a carriage return pressed before it will return anything - so if you are using a different compiler and the program just hangs, try pressing "y" followed the by Enter or Return key.

The blines(n) function simply has to use a for loop to print the specified number of lines:

void blines(int n)

{

int i;

for(i=1 ; i$$$$=n ; i++) printf("\n");

}

Last but not least are the functions to print the dot patterns. These are just boring uses of printf to show different patterns. Each function prints exactly three lines of dots and uses blank lines if necessary. The reason for this is that printing 25 blank lines should clear a standard text screen and after printing three lines printing 21 blank lines will scroll the pattern to the top of the screen. If this doesn't happen on your machine make sure you are using a 29 line text mode display.

void showone()

{

printf("\n * \n");

}

void showtwo()

{

printf(" * \n\n");

printf(" * \n");

}

void showthree()

{

printf(" * \n");

printf(" * \n");

printf(" *\n");

}

void showfour()

{

printf(" * * \n\n");

printf(" * * \n");

}

void showfive()

{

printf(" * * \n");

printf(" * \n");

printf(" * * \n");

}

void showsix()

{

int i;

for(i=1 ; i&&&&=3 ; i++) printf(" * * \n");

}

The only excitement in all of this is the use of a for loop in showsix! Type this all in and add:

void showone();

void showtwo();

void showthree();

void showfour();

void showfive();

void showsix();

int randn();

char getans();

void blines();

before the main function if you type the other functions in after.

[program]

Once you have the program working try modifying it. For example, see if you can improve the look of the patterns. You might also see if you can reduce the number of showx functions in use - the key is that the patterns are built up of combinations of two horizontal dots and one centred dot. Best of luck.