【C语言】随机滚动抽奖程序,可控制概率!(附源代码及解析)
1. 简介:
这是一个简单的抽奖程序,允许用户通过设定参与者名单和中奖概率来进行抽奖。程序支持自定义参与者名单、设定各自的中奖概率,并通过滚动显示和抽奖结果展示获奖者。
2. 主要功能:
- 加载参与者名单:可以自定义名单,支持最多 100 位参与者。
- 设定中奖概率:可以设定每个参与者的中奖概率,默认每个参与者概率为 2%。
- 抽奖过程:通过概率抽取中奖者,支持显示多个中奖者。
- 自定义输入:用户可以通过输入指定的中奖人数来进行抽奖。
3. 如何自定义使用:
修改名单:
在 loadParticipants
函数中修改 names
数组,加入或删除参与者的名字。
示例:
代码语言:javascript代码运行次数:0运行复制const char *names[] = {
"John Doe", "Jane Smith", "Alice Johnson" // 添加/修改名字
};
修改中奖概率:
使用 setProbability
函数设置每个参与者的中奖概率。
示例:
代码语言:javascript代码运行次数:0运行复制setProbability(0, 50); // 将第一个参与者的中奖概率设置为 50%
setProbability(1, 30); // 将第二个参与者的中奖概率设置为 30%
编译与运行:
在命令行中使用以下命令编译和运行程序:
代码语言:javascript代码运行次数:0运行复制gcc lottery.c -o lottery # 编译程序
./lottery # 运行程序
输入与显示:
- 运行程序后,输入抽奖人数(如:
5
)来决定本次抽取的中奖人数。 - 程序会先滚动显示所有参与者的名字,然后根据概率随机抽取获奖者。
- 中奖结果将会显示在屏幕上。
4. 流程:
- 启动程序后,程序会询问你抽取多少个中奖者。
- 输入中奖者人数后,程序开始滚动显示参与者名单。
- 在滚动结束后,程序按概率开始抽取中奖者,并显示每次抽奖的结果。
- 最终显示所有中奖者。
5. 示例运行:
代码语言:javascript代码运行次数:0运行复制Enter the number of winners for this lottery: 3
Starting the lottery...
John Doe
Jane Smith
Alice Johnson
...
Winner 1: John Doe
Winner 2: Jane Smith
Winner 3: Alice Johnson
Would you like to continue the lottery? (y/n): n
6. 小贴士:
- 每次修改名单或中奖概率后,请重新编译程序。
- 如果要增加更多的参与者,只需在
names
数组中添加名字,程序会自动处理。
7. 源代码:
"lottery.c"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h> // For usleep function to create a delay
#define MAX_PEOPLE 100 // Number of participants
#define MAX_NAME_LEN 50 // Maximum length of name
#define WINNER_DELAY 1000000 // Time between each winner selection in microseconds (1 second)
#define SCROLL_DELAY 100000 // Delay for scrolling each name (100ms)
typedef struct {
char name[MAX_NAME_LEN]; // Participant's name
int probability; // Probability of winning (0-100%)
} Person;
// Global array to store all participants
Person participants[MAX_PEOPLE];
int totalParticipants = 0; // Current total number of participants
int totalProbability = 0; // Total probability, used to balance probabilities
// Function declarations
void loadParticipants();
void setProbability(int index, int probability); // Set probability for a specific person
void drawLottery(int drawCount);
void clearScreen(); // Function to clear the screen
void scrollNames(); // Display names one by one in a loop
void displayWinners(int winners[], int winnerCount); // Function to display the winners
// Main function
int main() {
srand(time(NULL)); // Set the random seed
// Load participant information
loadParticipants();
// Set special participants' probabilities (can be customized)
//setProbability(0, 100); // Set 100% probability for participant 0 (e.g., John Doe)
//setProbability(1, 100); // Set 100% probability for participant 1 (e.g., Jane Smith)
//setProbability(2, 50); // Set 50% probability for participant 2 (e.g., Alice Johnson)
// Main loop for lottery drawing
while (1) {
int drawCount;
printf("\nEnter the number of winners for this lottery: ");
scanf("%d", &drawCount);
// Conduct the lottery
drawLottery(drawCount);
// Ask if the user wants to conduct another lottery
char choice;
printf("\nWould you like to continue the lottery? (y/n): ");
getchar(); // Clear the buffer
choice = getchar();
if (choice != 'y' && choice != 'Y') {
break;
}
}
return 0;
}
// Load participant information (example names)
void loadParticipants() {
// Example names for participants (can be modified to any number of participants)
const char *names[] = {
"John Doe", "Jane Smith", "Alice Johnson", "Bob Brown", "Charlie Davis",
"David Miller", "Eve Wilson", "Frank Moore", "Grace Taylor", "Hank Anderson",
"Ivy Thomas", "Jack Jackson", "Kathy White", "Leo Harris", "Mona Clark",
"Nina Lewis", "Oscar Walker", "Paul Young", "Quincy King", "Rachel Scott",
"Steve Adams", "Tina Baker", "Ursula Nelson", "Victor Carter", "Wendy Mitchell",
"Xander Roberts", "Yara Perez", "Zachary Cooper", "Abigail Green", "Benjamin Hill",
"Chloe Hall", "Daniel Lopez", "Ella Scott", "Freddie Allen", "Georgia King",
"Holly Wright", "Isaac Lee", "Jasmine Walker", "Kurt Martinez", "Lily Evans",
"Mark White", "Nora Baker", "Oliver Harris", "Penelope Carter", "Quinn Young",
"Rachel Smith", "Sophie Brown", "Tom Nelson", "Ursula Davis", "Vince Clark"
};
// Calculate the number of participants from the names array length
int numParticipants = sizeof(names) / sizeof(names[0]);
// Copy these names into the participants array and initialize their probabilities
for (int i = 0; i < numParticipants; i++) {
snprintf(participants[i].name, MAX_NAME_LEN, "%s", names[i]);
participants[i].probability = 2; // Default probability is 2% for everyone
totalProbability += participants[i].probability; // Update the total probability
}
totalParticipants = numParticipants; // Set the total number of participants
}
// Set the probability for a specific participant (0-100%)
void setProbability(int index, int probability) {
if (index >= 0 && index < totalParticipants) {
totalProbability -= participants[index].probability; // Subtract the old probability
participants[index].probability = probability; // Set the new probability
totalProbability += probability; // Add the new probability to the total
}
}
// Function to clear the screen (use "cls" for Windows, "clear" for Linux/Mac)
void clearScreen() {
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
// Function to display all names scrolling one by one in order
void scrollNames() {
// Scroll through all participants' names in order
for (int i = 0; i < totalParticipants; i++) {
clearScreen(); // Clear the screen before displaying the next name
printf("%s\n", participants[i].name); // Display one name at a time
usleep(SCROLL_DELAY); // Delay in microseconds (controlled by SCROLL_DELAY macro)
}
}
// Function to display the winners list
void displayWinners(int winners[], int winnerCount) {
printf("\nThe winners of this lottery are:\n");
for (int i = 0; i < winnerCount; i++) {
printf("Winner %d: %s\n", i + 1, participants[winners[i]].name);
}
}
// Lottery drawing function
void drawLottery(int drawCount) {
printf("\nStarting the lottery...\n");
int winners[drawCount]; // Array to store indices of winners
int winnerCount = 0;
// Initialize winners array to -1 (no winners initially)
for (int i = 0; i < drawCount; i++) {
winners[i] = -1;
}
// First, scroll through all participant names (No winners displayed during this)
scrollNames();
// Start the drawing process after the scrolling is done
printf("\nDrawing the winners...\n");
while (winnerCount < drawCount) {
// Randomly select a winner considering probabilities
int winnerIndex = rand() % totalProbability; // Randomly select a number between 0 and totalProbability
// Find the winner by checking the probability ranges
int cumulativeProbability = 0;
for (int i = 0; i < totalParticipants; i++) {
cumulativeProbability += participants[i].probability;
if (winnerIndex < cumulativeProbability) {
// Check if the person has already won
int alreadyWon = 0;
for (int j = 0; j < winnerCount; j++) {
if (winners[j] == i) {
alreadyWon = 1;
break;
}
}
if (!alreadyWon) {
winners[winnerCount] = i;
winnerCount++;
clearScreen(); // Clear screen before displaying the next winner
displayWinners(winners, winnerCount); // Display the current winners
usleep(WINNER_DELAY); // Delay between each winner selection
}
break;
}
}
}
// After all winners are selected, display the final list
clearScreen();
printf("Lottery Ended\n");
displayWinners(winners, winnerCount); // Display the final list of winners
}
8. 代码逻辑:
这个抽奖程序的原理可以分为几个主要部分。下面是对程序原理的详细讲解:
8.1 参与者加载与初始化
在程序开始时,会调用 loadParticipants
函数来加载参与者名单。
名单数组 names[]
存储了所有参与者的名字。这个数组可以根据实际需要进行修改或扩展。
参与者结构体
:每个参与者由
代码语言:javascript代码运行次数:0运行复制Person
结构体表示,结构体中包含:
name[MAX_NAME_LEN]
:存储参与者名字。probability
:存储该参与者的中奖概率,默认值为 2%。
总概率:totalProbability
记录了所有参与者的累计中奖概率,初始化时,每个参与者的概率为 2%,因此总概率就是参与者数量乘以 2。
核心原理:通过修改 names
数组,你可以控制参与者的名单,通过修改每个参与者的概率,来控制每个人的中奖机会。
8.2 设置参与者概率
- 通过
setProbability
函数,可以为每个参与者设置中奖概率。 - 该函数接收两个参数:
index
:参与者在participants
数组中的索引。probability
:参与者的中奖概率(0-100%)。
- 函数的工作方式是:
- 减去旧的概率:首先从
totalProbability
中减去原先的概率(participants[index].probability
)。 - 设置新的概率:将新的概率赋给参与者。
- 增加新的概率:将新的概率加入到
totalProbability
中。
- 减去旧的概率:首先从
核心原理:通过 setProbability
可以动态调整每个参与者的中奖机会,并自动调整 totalProbability
,保证整体概率的平衡。
8.3 抽奖过程
抽奖过程由
代码语言:javascript代码运行次数:0运行复制drawLottery
函数负责:
- 滚动显示:通过
scrollNames
函数,所有参与者的名字会逐个显示出来,模拟一个滚动效果,增强用户体验。 - 选择中奖者:使用一个
rand()
函数生成一个在[0, totalProbability)
范围内的随机数。根据这个随机数和每个参与者的概率,决定谁将中奖。 - 累计概率:在抽奖时,程序从第一个参与者开始,累计每个参与者的概率,直到累积的概率范围包含随机数。这个参与者就被选为中奖者。
- 去重处理:为了避免重复中奖,每次抽奖后,会检查该参与者是否已被选为中奖者,只有尚未中奖的人才会被选中。
- 显示结果:每选中一个中奖者,都会展示当前中奖者的名单,直到选满指定的中奖人数。
核心原理:通过累积每个参与者的概率范围来模拟中奖概率,并利用随机数选取中奖者,确保每个参与者的中奖概率与设置值一致。
8.4 滚动显示
-
scrollNames
函数 :用于模拟滚动显示参与者名字的效果:- 清屏:通过
clearScreen
函数清空当前屏幕(system("clear")
,适用于 Linux/macOS 系统,Windows 可用system("cls")
)。 - 显示名字:每个参与者的名字会逐个显示,并在显示后暂停
SCROLL_DELAY
时间,以便用户可以看到滚动效果。
- 清屏:通过
核心原理:此功能主要是为了增强用户体验,展示所有参与者的名字,增加一些抽奖的紧张氛围。
8.5 显示获奖者
displayWinners
函数:用于展示所有已中奖的参与者。- 在每次抽奖过程中,程序会实时显示当前的中奖者名单,直到抽取完指定数量的中奖者。
8.6 交互式输入
- 用户输入:通过
scanf
函数获取用户输入的中奖人数。用户可以通过输入不同的数字来指定要抽取的中奖者数量。 - 在抽奖结束后,程序会询问用户是否继续抽奖。如果用户输入
y
或Y
,程序会重新进入抽奖流程,否则退出程序。
8.7 程序执行流程
- 程序启动时,初始化参与者名单并设定初始概率。
- 用户输入需要抽取的中奖人数后,程序开始抽奖,滚动显示所有参与者名单,然后根据设定的概率选择中奖者。
- 每次抽奖后,程序会显示中奖者名单,并询问用户是否继续抽奖。
- 通过修改名单和概率,可以自定义每次抽奖的规则。
8.8 代码逻辑总结
- 名单与概率:使用结构体
Person
存储参与者信息,并通过setProbability
动态调整概率。 - 概率计算:通过累积概率区间来选择中奖者,并使用
rand()
生成随机数进行抽奖。 - 滚动显示与抽奖展示:增强用户体验,通过屏幕滚动展示参与者名单和抽奖结果。
- 交互输入:支持用户动态输入中奖人数,控制抽奖流程。
8.9 优势与可扩展性
- 动态设置:可以随时修改名单和概率,适应不同的抽奖场景。
- 简单易用:用户只需修改名单和概率,编译运行即可使用。
- 可扩展性:可以根据需要修改代码来支持更多参与者、不同的抽奖规则或其他功能(如时间控制、中奖限制等)。