从C语言开始,模拟掷骰子

前言

沃尔特·萨维奇的书 《Problem Solving with C++ 》中第四章 首先提到:

逐步求精分而治之 实际上是一个思想,都是软件工程中学到的 自顶向下设计,简单说就是:把任务分解成子任务,对子任务再次分解,直到分解得到的任务足够简单、可以实现。这些“子任务”,通常以“函数”的方式存在。

随后在 Chap.4.2 预定义函数 中介绍了:在包含了编译库中的 <cstdlib> 头文件之后,函数中可以调用产生随机数(random number)的预定义函数 rand()

rand()函数有一个辅助函数srand(),它为rand()函数提供“种子值”(理论上,这个值经过复杂计算后得到rand()的返回值)。srand()不返回值,而获取一个无符号整数作为种子值。如果想要每次运行时都改变随机数的种子,可以把time(0)的返回值当作整数传给srand()。time函数需要 <ctime> 库文件。

正文

为了得到一个电子骰子,就是从 1 到 6 产生一个随机数。在stdlib.h函数库中,有一个产生 [0, INT_MAX] 范围内的随机数的函数 rand()。

基于提供的函数,可以写一个 diceroll.c 文件,这里为了后续拓展,引入了一个变量sides, 函数产生的点数在 [1,sides] 内。


// diceroll. C -- dice simulation program

#include <stdio.h>
#include <stdlib.h> /* provides the prototype of rand() */

int roll_count = 0;  /* this var is an external */

static int rollem(int sides)  /* the function belongs to the private */
{
    int roll;
    
    roll = rand() % sides + 1;
    ++roll_count;
    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;
}

// manydice.c

#include <time.h>  /* provide prototype for time() */

int main()
{
    int dice, roll;
    int sides;
    
    srand((unsigned int)time(0));  /* prototype in <stdlib. H> */
    
    // Do you want a 6-sided dice?
    printf("输入每个骰子有多少面? 输入0退出。\n  \n");  
    
    // You have rolled a %d using %d %d-sided dice.
    // How many dices? Enter 0 to stop.
    while (scanf("%d", &sides) == 1 && sides > 0)
    {
        printf("你要扔多少个骰子?\n");
        scanf("%d",&dice);
        roll = roll_n_dice(dice, sides);
        printf("你掷出的总和为 %d, 用了共 %d 个 %d面的 骰子.\n", roll, dice, sides);
        printf("你要玩的骰子有多少面? Enter 0 to stop.\n");
    }
    printf("The rollem() function was called %d times. \n", roll_count);
    printf("Good Fortune!\n");
    return 0;
    
}


大致如此,运行结果:



PS:
实际上C语言中的“头文件”,里面写的也只是“函数声明(函数原型)”,函数头和函数身子(函数体)可能并不在头文件里。具体在哪只有编译器知道。
但只要编辑器知道,那么在一份源代码的开头引入了库函数的“头文件”之后,代码内就可以随意地进行“函数调用”了。

posted @ 2025-04-25 17:29  吴萝卜  阅读(62)  评论(0)    收藏  举报