c 语言文字游戏,C 猜猜猜😀文字小游戏,

C 猜猜猜😀文字小游戏,

前言 - 随机性

随机数生成 - https://zh.wikipedia.org/wiki/%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90

没啥事情, 写了个猜猜猜(猜数字)小游戏. 遇到猜的部分, 那肯定会用到随机函数. 我们为了多平台行为一致, 就统一

整合一个伪随机函数实现方案, 让随机更随机. 一开始看下接口设计 rand.h

1 #ifndef _RAND_H2 #define _RAND_H

3

4 #include

5 #include

6

7 //

8 //传承(抄袭)不灭(创新) rand 库9 //大体思路10 //{ r | r[n+1] = (a*r[n] + c) mod m11 //, n >= 012 //, m = 0xFFFFFFFFFFFF = 2 ^ 4813 //, a = 0x0005DEECE66D = 0x5DEECE66D,14 //, c = 0x000B = 0xB15 //}16 //17 structrand {18 uint32_t x0, x1, x2;19 uint32_t a0, a1, a2;20 uint32_t c;21 };22

23 typedef struct rand rand_t[1];24

25 //

26 //rand_init - 随机函数对象初始化种子27 //r : 随机函数对象28 //seed : 种子数29 //return : void30 //31 extern voidrand_init(rand_t r, int64_t seed);32

33 //

34 //rand_rand - 获取一个随机值35 //r : 随机函数对象36 //return : 返回 [0, INT32_MAX] 随机数37 //38 externint32_t rand_rand(rand_t r);39

40 //

41 //r_rand - 得到 [0, INT32_MAX] 随机数42 //r_ranb - 得到 [0, INT64_MAX] (int64 = big int32) 随机数43 //r_rang - 得到 range [min, max] 随机数44 //45 extern int32_t r_rand(void);46

47 extern int64_t r_ranb(void);48

49 inline int32_t r_rang(int32_t min, int32_t max) {50 assert(max >=min);51 return r_rand() % (max - min + 1) +min;52 }53

54 #endif//_RAND_H

rand.c

1 #include "rand.h"

2

3 #define X0 (0x330E)

4 #define X1 (0xABCD)

5 #define X2 (0x1234)

6 #define A0 (0xE66D)

7 #define A1 (0xDEEC)

8 #define A2 (0x0005)

9 #define C (0x000B)

10

11 #define N (16)

12 #define MASK ((1 << N) - 1)

13 #define LOW(x) ((uint32_t)(x) & MASK)

14 #define HIGH(x) LOW((x) >> N)

15

16 //

17 //rand_init - 随机函数对象初始化种子18 //r : 随机函数对象19 //seed : 种子数20 //return : void21 //22 inline void

23 rand_init(rand_t r, int64_t seed) {24 r->x0 = X0; r->x1 = LOW(seed); r->x2 =HIGH(seed);25 r->a0 = A0; r->a1 = A1; r->a2 =A2;26 r->c =C;27 }28

29 #define CARRY(x, y) ((x + y) > MASK) //基于 16 位判断二者和是否进位

30 #define ADDRQ(x, y, z) z = CARRY(x, y); x = LOW(x + y)

31 #define MUL(m, x, y, z) m = (x) * (y); z##0 = LOW(m); z##1 = HIGH(m)

32

33 inline voidrand_next(rand_t r) {34 uint32_t m, p0, p1, q0, q1, s0, s1, c0, c1;35

36 MUL(m, r->a0, r->x0, p);37 ADDRQ(p0, r->c, c0);38 ADDRQ(p1, c0, c1);39 MUL(m, r->a0, r->x1, q);40 ADDRQ(p1, q0, c0);41 MUL(m, r->a1, r->x0, s);42

43 m = c0 + c1 + CARRY(p1, s0) + q1 +s144 + r->a0 * r->x2 + r->a1 * r->x1 + r->a2 * r->x0;45 r->x2 =LOW(m);46 r->x1 = LOW(p1 +s0);47 r->x0 =LOW(p0);48 }49

50 //

51 //rand_rand - 获取一个随机值52 //r : 随机函数对象53 //return : 返回 [0, INT32_MAX] 随机数54 //55 inline int32_t56 rand_rand(rand_t r) {57 rand_next(r);58 return (r->x2 << (N - 1)) + (r->x1 >> 1);59 }60

61 //

62 //想过 - 朵朵浪花, 也不曾看见云彩飘过 :063 //64 static rand_t r_r ={ { X0, X1, X2 , A0, A1, A2 , C } };65

66 //EXTERN_RUN(r_init) 启动初始化

67 extern inline voidr_init(int64_t seed) {68 rand_init(r_r, seed);69 }70

71 inline int32_t72 r_rand(void) {73 returnrand_rand(r_r);74 }75

76 inline int64_t77 r_ranb(void) {78 uint64_t x = ((r_rand() << N) ^ r_rand()) &INT32_MAX;79 uint64_t y = ((r_rand() << N) ^ r_rand()) &INT32_MAX;80 return ((x << 2 * N) | y) &INT64_MAX;81 }

算法层面网上资料很够(redis rand48 原理) . 我这里只聊聊工程实现方面, 可以看出来多线程并发发起 r_rand()

请求是不可控的(非线程安全, 你也不知道内部运行状态是啥). 但如果存在特殊业务需要可窥探随机序列时候,

rand_init  就可以运用上了, 来构建多线程情况下可控的随机函数对象.

对于 r_init 多数使用 time(NULL) 时间量初始化种子, 有没有人觉得不太可靠, 毕竟服务器时间也可以改. 有

没有想过让其更加混乱一点. 这里有个小想法, 提出来可供大家一块参略讨论讨论.

1 //

2 //EXTERN_RUN - 函数包装宏, 声明并立即使用3 //frun : 需要执行的函数名称4 //... : 可变参数, 保留5 //6 #define EXTERN_RUN(frun, ...) \

7 do{ \8 extern voidfrun(); \9 frun (__VA_ARGS__); \10 } while(0)11

12 //此后 :) 随机与你无关 ~

13 EXTERN_RUN(rand_restrict);

17 //rand_nationalism - 民族主义, 国家是人民所共有, 各族平等, 团结一致

18 static void rand_nationalism(void) {19 structtimespec s;20 (void)timespec_get(&s, TIME_UTC);21 EXTERN_RUN(r_init, s.tv_nsec +s.tv_sec);22 for (int32_t i = BUFSIZ; i > 0 ; --i) {23 (void)timespec_get(&s, TIME_UTC);24 EXTERN_RUN(r_init, s.tv_nsec +i);25 }26 }27

28 //rand_democracy - 民权主义, 政治是人民所共管, 选举权、罢免权、创制权和复决权

29 static void rand_democracy(void) {30 int32_t x, y, z, w;31 do{32 x =r_rand();33 y =r_rand();34 z =r_rand();35 w =r_rand();36 } while (!(x > y && y > z && z > w && w >INT16_MAX));37 }38

39 //rand_livelihood - 民生主义, 利益是人民所共享, 让人像个人

40 static void rand_livelihood(void) {41 for (int32_t i = r_rand(); i >= 0; --i)42 r_rand();43 }44

45 //rand_restrict - 三权制衡在随机函数初中运用

46 void rand_restrict(void) {47 thread_async(rand_nationalism);48 thread_async(rand_democracy);49 thread_async(rand_livelihood);50 }

传送门 核心是引入多线程互相竞争制约, 让随机函数你我不知, 模糊不清, 捉摸不透.  这里只是瞎弄一个思路.

大家有更好的想法可以在评论区和我一块交流.

正文 - 猜猜猜

是不是要开始扯闲篇. 那就用上面随机库写个猜猜猜游戏吧 ~

main.c

#include "rand.h"#include#include#include#include

//

//EXTERN_RUN - 函数包装宏, 声明并立即使用//frun : 需要执行的函数名称//... : 可变参数, 保留//#define EXTERN_RUN(frun, ...) \

do{ \extern voidfrun(); \

frun (__VA_ARGS__); \

}while(0)//

//GUESS_THRESHOLD_INT - 猜数最多次数//GUESS_TEMPER_INT - 遇到小脾气不再触发提示//GUESS_MAX_INT - 最大值区间//#define GUESS_THRESHOLD_INT (8)

#define GUESS_TEMPER_INT (3)

#define GUESS_MAX_INT (8964)

//guess 猜数字游戏对象

structguess {

int32_t max;//数字区间上限

int32_t correct; //正确数值

int32_t use; //已经猜数次数

int32_t numbers[GUESS_THRESHOLD_INT]; //用户猜数数组

int32_t now; //用户当前输入值

};//guess_run 猜数字游戏开始

void guess_run(struct guess *restrict g);//guess_guess 猜数字开启猜猜猜

bool guess_guess(struct guess *restrict g);//guess_end 猜数字游戏结束总结

void guess_end(struct guess *restrict g);//threshold_input - 获取猜数字的范围

static int32_t threshold_input(int argc, char *argv[]) {

int32_t max=GUESS_MAX_INT;if (argc > 1) {int num = atoi(argv[1]);if (num <= 0) {

printf("亲, 别

http://www.dengb.com/Cyy/1361818.htmlwww.dengb.comtruehttp://www.dengb.com/Cyy/1361818.htmlTechArticleC 猜猜猜文字小游戏, 前言 - 随机性 随机数生成 -https://zh.wikipedia.org/wiki/%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90 没啥事情, 写了个猜猜猜(猜数字...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值