因为最近抽卡非常的脸黑,就开始怀疑,抽卡概率真的这么低吗,一点几的概率真的很难中吗?
所以我我就自己用c语言搞了一个抽卡算法。
我们直接看代码,因为我是在vs写的代码,所以我用了头文件,和两个源文件。方便后续维护。
这是头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
//抽奖函数的声明
void draw(int x,int *nums,int*gold,int*silver,int*copper);
头文件主要用于接口函数。
然后我们看运行的源文件
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include"mian.h"
enum zgw
{
EXIT,
DRAW, //枚举变量从上到下为0,1,2提高代码可读性
NUMS
};
void menu()
{
printf("############################\n");//打印菜单
printf("###### 1. draw ######\n");//1为抽奖
printf("###### 2. drawnums ######\n");//2为打印抽奖次数,以及获得各种奖的个数
printf("###### 0. exit ######\n");//0退出
printf("############################\n");
}
void test()
{
int gold = 0; //记录抽到多少金将
int silver = 0; //记录抽到多少银奖
int copper = 0; //记录抽到多少铜奖
int numtimes = 0; //记录抽的次数
int nums = 0; //记录保底功能
int input = 10; //操作选择
do //dowhile至少运行一次
{
menu();
printf("请选择喵~\n");
scanf("%d", &input);
switch (input)
{
case DRAW: //抽奖选择
{
flag: int num = 0;
printf("1连or10连->");//抽几次
scanf("%d", & num);
if (num != 10&&num!=1) //如果没有选择10或1就回去重选
{
goto flag;
}
draw(num,&nums,&gold,&silver,&copper);//将所有参数传入
numtimes +=num;
break;
}
case NUMS: //打印抽奖信息
{
printf("您抽了%d次喵\n", numtimes);
printf("抽到金奖为%d个喵~\n", gold);
printf("抽到银奖为%d个喵~\n", silver);
printf("抽到铜奖为%d个喵~\n", copper);
break;
}
default: / /如果选择012其他数字就重新选择
{
printf("选择错误,请从新选择喵~\n");
break;
}
}
} while (input);
}
int main()
{
srand((unsigned int)time(NULL));//随机数更随机
test();
return 0;
}
最后看实现函数的源文件:
#define _CRT_SECURE_NO_WARNINGS 1
#include"mian.h"
//规定当金奖概率为%2,银奖的概率为%10,剩余为铜奖%82
enum draw
{
gold,
silver, //哈哈~查了一下单词
copper
};
const char* checkdraw(int x) //检测抽奖
{
if (x==1||x==2) //如果随机数为1或2为金
{
return "gold";
}
if (x >= 3 && x <= 12)//3-12为银
{
return "silver";
}
else
{
return "copper";//13-100为铜
}
}
void draw(int x,int*nums, int* gold, int* silver, int* copper)
{
int numgold = *nums; 用numgold来记录保底,方便后续修改
if (x == 1) //抽一次
{
numgold += 1; //每次进来保底数加一
int a = rand() % 100 + 1;//随机生成一个数(1-100)
const char* pa = NULL;
if (numgold == 20) //保底二十一个金奖,可修改
{
pa = "gold";
*gold += 1; //金奖数加一
numgold = 0; //保底金奖,将保底重置为0
}
else if (numgold % 10 == 0) //保底每十次必定一个银奖
{
pa = "silver"; //直接将pa为银奖
*silver += 1; //银奖数加一
}
else //如果都不是以上两种保底情况就随机抽奖
{
pa = checkdraw(a);//检测抽奖
if (strcmp(pa, "copper") == 0 || strcmp(pa, "silver") == 0)//如果为银奖或铜奖进
{
if (strcmp(pa, "copper") == 0)
{
*copper += 1; //为铜奖加1
}
else
{
*silver += 1; //否则银奖将加一
}
}
else if (strcmp("gold", pa) == 0)//如果为金
{
numgold = 0; //也会将保底数变为0
*gold += 1; //金奖加一
}
}
printf("您抽到了%s奖\n", pa); //打印抽到的将
}
else 如果为10连进入后续操作一样只是用一个j控制循环10次
{
int j = 10;
while (j)
{
numgold += 1;
int a = rand() % 100 + 1;
const char* pa = NULL;
if (numgold == 20)
{
pa = "gold";
*gold += 1;
numgold = 0;
}
else if (numgold % 10 == 0)
{
pa = "silver";
*silver += 1;
}
else
{
pa = checkdraw(a);
if (strcmp(pa, "copper") == 0 || strcmp(pa, "silver") == 0)
{
if (strcmp(pa, "copper") == 0)
{
*copper += 1;
}
else
{
*silver += 1;
}
}
else if (strcmp("gold", pa) == 0)
{
numgold = 0;
*gold += 1;
}
}
printf("您抽到了%s奖\n", pa);
j--;
}
}
printf("请按键确定\n");//按键确认,方便查看
*nums = numgold;
char c = getchar();
c = getchar();
}
用vs的兄弟们直接创建一个头文件和两个源文件就可以直接将代码对应粘贴上去。
其他编译器就根据所需粘贴,
后续我合并一下,补充一下