学习不止!
问答不止!
一、粉丝问题
二、相关函数说明
1. 函数说明
产生随机数的方法很多,常用的是rand()、srand(),来看一下这2个函数的定义:
SYNOPSIS
#include <stdlib.h>
int rand(void);
int rand_r(unsigned int *seedp);
void srand(unsigned int seed);
DESCRIPTION
The rand() function returns a pseudo-random integer in the range 0 to
RAND_MAX inclusive (i.e., the mathematical range [0, RAND_MAX]).
The srand() function sets its argument as the seed for a new sequence
of pseudo-random integers to be returned by rand(). These sequences
are repeatable by calling srand() with the same seed value.
If no seed value is provided, the rand() function is automatically
seeded with a value of 1.
RETURN VALUE
The rand() and rand_r() functions return a value between 0 and RAND_MAX
(inclusive). The srand() function returns no value.
ubuntu的man手册都是英文的,建议各位同学把自己的英文水平好好提升一下,熟练的阅读英文技术文档一名合格的码农必备技能。
总结一下功能点:
- rand()回产生1个随机的整型数,介于[0~RAND_MAX]之间
- srand设置产生一系列伪随机数发生器的起始点,要想把发生器重新初始化,可用1作seed值。任何其它的值都把发生器匿成一个随机的起始点。rand检索生成的伪随机数。在任何调用srand之前调用rand与以1作为seed调用srand产生相同的序列。
- srand仅用于设置伪随机数发生器的起始点,并不产生随机数
2. 函数实例
为了说明这几个函数的使用特性,我们举下面几个例子。
1) rand
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc, char **argv)
5 {
6 int i;
7
8 for(i=0;i<10;i++)
9 {
10 printf("%d ",rand()%100);
11 }
12 putchar(‘\n‘);
13 return 0;
14 }
代码很简单,产生一个随机数,然后对100取余,
编译运行
从结果可以看出,从单次来看,每次产生的随机数是随机的,但是每次运行,随机队列是一致的,
所以此时还达不到我们真正的产生随机数的要求。
2) srand
修改代码如下:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4
5 int main(int argc, char **argv)
6 {
7 int i;
8
9
10 srand((unsigned)time(NULL));
11 for(i=0;i<10;i++)
12 {
13 printf("%d ",rand()%100);
14 }
15 putchar(‘\n‘);
16 return 0;
17 }
从结果来看,每次产生的数列基本保持随机,但是如果输入速度太快,1秒之内,仍会产生相同的序列。
这个一定要注意
三、最终实现
我们把问题相对优化一下:
随机产生0-99之间的数,统计出出现次数最多的那个数。
/*
*公众号:一口Linux
*2021.6.21
*version: 1.0.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define _MAX_ARRAY 100
int main(int argc, char **argv)
{
int i;
int num,max,index;
int count[_MAX_ARRAY];
memset(count,0,sizeof(count));
srand((unsigned)time(NULL));
for(i=0;i<10000;i++)
{
num = rand()%100;
count[num]++;
}
//find max
max = count[0];
index = 0;
for(i=1;i<_MAX_ARRAY;i++)
{
if(max < count[i])
{
max = count[i];
index = i;
}
}
printf("max is count[%d],appear %d times\n",index,count[index]);
return 0;
}
运行结果如下:
四、如何实现自动发牌的游戏?
一副扑克有52张牌,打桥牌时应将牌分给4个人。请设计一个程序完成自动发牌的工作。要求:黑桃用S (Spaces)表示,红桃用H (Hearts)表示,方块用D (Diamonds)表示,梅花用C (Clubs)表示。
1. 分析:
要设置数组表现扑克牌
要设置数组表现玩家
要给扑克牌做特定标识,得到结果后玩家要知道自己手中黑桃有哪些、方块有哪些
2. 设计思路:
设置4个字符数组保存4种梅花牌,设置4个字符数组表示4名玩家分配到的牌
每张牌随机发给4名玩家,当玩家的持牌数达到13,不再分配给该名玩家牌
3. 源码
/*
*公众号:一口Linux
*2021.6.21
*version: 1.0.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
void poke_13()
{
/*全部牌*/
char S[13] = { ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘T‘, ‘J‘, ‘Q‘, ‘K‘, ‘A‘ };
char H[13] = { ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘T‘, ‘J‘, ‘Q‘, ‘K‘, ‘A‘ };
char D[13] = { ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘T‘, ‘J‘, ‘Q‘, ‘K‘, ‘A‘ };
char C[13] = { ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘T‘, ‘J‘, ‘Q‘, ‘K‘, ‘A‘ };
/*4个玩家*/
char player1[13], player2[13], player3[13], player4[13];
int p1 = 0, p2 = 0, p3 = 0, p4 = 0;
srand((unsigned)(time(NULL)));
distribution(S, player1, player2, player3, player4, &p1, &p2, &p3, &p4);
distribution(H, player1, player2, player3, player4, &p1, &p2, &p3, &p4);
distribution(D, player1, player2, player3, player4, &p1, &p2, &p3, &p4);
distribution(C, player1, player2, player3, player4, &p1, &p2, &p3, &p4);
puts("发牌结果");
puts("play1:");
for (int i = 0; i < 13; i++)
printf("%c ", player1[i]);
putchar(‘\n‘);
puts("play2:");
for (int i = 0; i < 13; i++)
printf("%c ", player2[i]);
putchar(‘\n‘);
puts("play3:");
for (int i = 0; i < 13; i++)
printf("%c ", player3[i]);
putchar(‘\n‘);
puts("play4:");
for (int i = 0; i < 13; i++)
printf("%c ", player4[i]);
putchar(‘\n‘);
}
void distribution(char * S_H_D_C, char * player1, char * player2, char * player3, char * player4, int *p1, int *p2, int *p3, int *p4)
{
static int h = 1;
int r;
int a = *p1, b = *p2, c = *p3, d = *p4;
for (int i = 0; i < 13; i++)
{
r = (rand() % 4) + 1;
//保证了当某个人得到13张牌后不在得牌
while ((r == 1 && (*p1) == 13) || (r == 2 && (*p2) == 13) || (r == 3 && (*p3) == 13) || (r == 4 && (*p4) == 13))
r = (rand() % 4) + 1;
switch (r)
{
case 1:
player1[(*p1)++] = S_H_D_C[i];
break;
case 2:
player2[(*p2)++] = S_H_D_C[i];
break;
case 3:
player3[(*p3)++] = S_H_D_C[i];
break;
case 4:
player4[(*p4)++] = S_H_D_C[i];
break;
default:
break;
}
}
switch (h++)
{
case 1:
printf("黑桃:\n");
break;
case 2:
printf("红桃:\n");
break;
case 3:
printf("方块:\n");
break;
case 4:
printf("梅花:\n");
break;
}
printf("Player1:");
for (int i = a; i < (*p1); i++)
printf("%c ", player1[i]);
putchar(‘\n‘);
printf("Player2:");
for (int i = b; i < (*p2); i++)
printf("%c ", player2[i]);
putchar(‘\n‘);
printf("Player3:");
for (int i = c; i < (*p3); i++)
printf("%c ", player3[i]);
putchar(‘\n‘);
printf("Player4:");
for (int i = d; i < (*p4); i++)
printf("%c ", player4[i]);
putchar(‘\n‘);
}
int main(int argc, char **argv)
{
poke_13();
return 0;
}
运行结果如下:
这真是一个demo,实际上我们手机上很多的纸牌游戏,发牌算法要复杂的多,但是万变不离其宗,思想都是一样的。
还等什么呢?快来试试吧!
代码来源于网络,侵权删。