作者simple.bbs@bbs.wfc.edu.tw (養兵千日 用在一時) 看板: plan
標題[功能]樂透彩-大樂透(修改版)
時間卡布奇諾 (2004/10/27 Wed 00:39:26) Updated: 2006/01/24
: crontab -e 加入二行
# 每星期樂透開獎一次
50 4 * * 6 bin/lottery-open > /dev/null 2>&1
: src/util/Makefile
EXE = ... lottery-open
: util/lottery-open.c 新增此程式
/*-------------------------------------------------------*/
/* util/lottery-open.c ( YZU WindTopBBS Ver 3.00 ) */
/*-------------------------------------------------------*/
/* target : 彩券遊戲 -- 開獎程式 */
/* create : 02/01/12 */
/* update : 03/05/26 */
/* author : verit.bbs@bbs.yzu.edu.tw */
/* modify : itoc.bbs@bbs.tnfsh.tn.edu.tw */
/* modify : simple.bbs@bbs.wfc.edu.tw */
/*-------------------------------------------------------*/
#include "bbs.h"
#define OUTFILE_LOTTERY "run/lottery.result"
/* lottery_num[0~5] 是一般號碼;lottery_num[6] 是特別號 */
static int lottery_num[6];
/* lottery_win[0~6] 依序是中各獎項的注數
0:普獎 1:陸獎 2:伍獎 3:肆獎 4:參獎 5:貳獎 6:頭獎 */
static int lottery_win[7];
static double totalmoney; /* 總押金 */
/* eachmoney[0~6] 依序是各獎項的獎金
0:普獎 1:陸獎 2:伍獎 3:肆獎 4:參獎 5:貳獎 6:頭獎 */
static int eachmoney[7];
static FILE *flog;
/*-------------------------------------------------------*/
/* 發獎金 */
/*-------------------------------------------------------*/
static void
add_money(log)
BUY_LOTTERY *log;
{
char fpath[64];
PAYCHECK paycheck;
static char name[7][3] = {"普", "陸", "伍", "肆", "參", "貳", "頭"};
memset(&paycheck, 0, sizeof(PAYCHECK));
time(&paycheck.tissue);
paycheck.money = eachmoney[log->prize];
sprintf(paycheck.reason, "大樂透%s獎獎金", name[log->prize]);
usr_fpath(fpath, log->userid, FN_PAYCHECK);
rec_add(fpath, &paycheck, sizeof(PAYCHECK));
fprintf(flog, " %-13s彩券號碼為 %02d %02d %02d %02d %02d %02d,"
"中了%s獎 %d 元\n",
log->userid, log->num[0], log->num[1], log->num[2],
log->num[3], log->num[4], log->num[5], name[log->prize], paycheck.money);
}
static void
mail_lottery(log) /* itoc.011115: 寄檔案給 userid */
BUY_LOTTERY *log;
{
int i;
char folder[64];
HDR hdr;
static char userid[IDLEN + 1];
static char fpath[64];
static FILE *fp;
/* log[] 要依 log->userid 來排序 */
/* 同一位使用者可能有多張彩券中獎,在同一封信裡面會把所有明細都寫出來 */
if (strcmp(userid, log->userid)) /* 新的 userid */
{
/* 將前一中獎人的信寄出 */
if (fp)
{
fclose(fp);
usr_fpath(folder, userid, FN_DIR);
hdr_stamp(folder, HDR_LINK, &hdr, fpath);
strcpy(hdr.owner, STR_SYSOP);
strcpy(hdr.nick, SYSOPNICK);
strcpy(hdr.title, "彩券發錢");
rec_add(folder, &hdr, sizeof(HDR));
unlink(fpath);
}
if (!log->userid[0]) /* 已寄出最後一位中獎人通知信 */
return;
/* 開始準備新中獎人的信 */
strcpy(userid, log->userid);
sprintf(fpath, "tmp/lottery.%d", userid);
if (fp = fopen(fpath, "w"))
{
/* 文章檔頭 */
fprintf(fp, "%s %s (%s)\n", STR_AUTHOR1, STR_SYSOP, SYSOPNICK);
fprintf(fp, "標題: 彩券發錢\n時間: %s\n\n", Now());
/* 文章內容 */
fprintf(fp, " 本期樂透中獎號碼為:\n\n ");
for (i = 0; i < 6; i++)
fprintf(fp, "%02d ", lottery_num[i]);
fprintf(fp, "\n\n 本期樂透特別號碼為:%\n\n ");
fprintf(fp, "%02d\n\n", lottery_num[6]);
}
}
fprintf(fp, " 您所購買的號碼為:\n\n ");
for (i = 0; i < 6; i++)
fprintf(fp, "%02d ", log->num[i]);
fprintf(fp, "恭喜您贏得 %d 元,詳細中獎記錄請參考 %s 板\n",
eachmoney[log->prize], BN_RECORD);
}
/*-------------------------------------------------------*/
/* 開獎記錄 */
/*-------------------------------------------------------*/
static void
add_post(brdname, fpath, title) /* 發文到看板 */
char *brdname; /* 欲 post 的看板 */
char *fpath; /* 檔案路徑 */
char *title; /* 文章標題 */
{
HDR hdr;
char folder[64];
brd_fpath(folder, brdname, FN_DIR);
hdr_stamp(folder, HDR_LINK | 'A', &hdr, fpath);
strcpy(hdr.owner, STR_SYSOP);
strcpy(hdr.nick, SYSOPNICK);
strcpy(hdr.title, title);
rec_add(folder, &hdr, sizeof(HDR));
}
/*-------------------------------------------------------*/
/* 對獎主程式 */
/*-------------------------------------------------------*/
static void
generate_number() /* 產生中獎結果 */
{
int i, j, num;
srand(time(NULL));
for (i = 0; i < 7; i++)
{
rand_num: /* random 出一個和之前都不同的數字 */
num = rand() % 49 + 1;
for (j = 0; j < i; j++)
{
if (num == lottery_num[j])/* 這個數字以前 random 過了 */
goto rand_num;
}
lottery_num[i] = num;
}
fprintf(flog, " 本期樂透中獎號碼為:\n\n ");
for (i = 0; i < 6; i++)
fprintf(flog, "%02d ", lottery_num[i]);
fprintf(flog, "\n\n 本期樂透特別號碼為:%\n\n ");
fprintf(flog, "%02d\n\n", lottery_num[6]);
/* 中獎注數歸零 */
for (i = 0; i < 7; i++)
lottery_win[i] = 0;
}
static int /* -1:摃龜 0:普獎 1:陸獎 2:伍獎 3:肆獎 4:參獎 5:貳獎 6:頭獎 */
check_prize(log)
BUY_LOTTERY *log;
{
int i, j;
int guessed; /* 中了幾個號碼 */
int spec; /* 1: 中了特別號碼 */
int prize;
guessed = 0;
for (i = 0; i < 6; i++)
{
for (j = 0; j < 6; j++)
{
if (log->num[i] == lottery_num[j])
{
guessed++;
break;
}
}
}
spec = 0;
for (i = 0; i < 6; i++)
{
if (log->num[i] == lottery_num[6])
{
spec = 1;
break;
}
}
/* 頭獎 與當期六個中獎號碼完全相同者〈順序不限〉
貳獎 對中當期中獎號碼之其中任五碼+特別號
參獎 對中當期中獎號碼之其中任五碼
肆獎 對中當期中獎號碼之其中任四碼+特別號
伍獎 對中當期中獎號碼之其中任四碼
陸獎 對中當期中獎號碼之其中任三碼+特別號
普獎 對中當期中獎號碼之其中任三碼
*/
if (guessed <= 2)
{
prize = -1;
}
else if (guessed == 3)
{
prize = (!spec) ? 0 : 1;
}
else if (guessed == 4)
{
prize = (!spec) ? 2 : 3;
}
else if (guessed == 5)
{
prize = (!spec) ? 4 : 5;
}
else if (guessed == 6)
{
prize = 6;
}
if (prize >= 0)
lottery_win[prize]++;
return prize;
}
static void
check_money() /* 計算各獎項獎金 */
{
int i;
double keepmoney;
int rate[7] = {0, 0, 20, 5, 10, 9, 56};
/* 頭獎 共 lottery_win[6] 注,佔剩餘獎金56%
貳獎 共 lottery_win[5] 注,佔剩餘獎金9%
參獎 共 lottery_win[4] 注,佔剩餘獎金10%
肆獎 共 lottery_win[3] 注,佔剩餘獎金5%
伍獎 共 lottery_win[2] 注,佔剩餘獎金20%
陸獎 共 lottery_win[1] 注,每注獎金為20000銀幣
普獎 共 lottery_win[0] 注,每注獎金為8000銀幣
*/
/* 取出上期未發出的獎金 */
keepmoney = 0;
rec_get(LAST_KEEP_MONEY, &keepmoney, sizeof(keepmoney), 0);
totalmoney += keepmoney;
/* 先扣除普獎、陸獎的獎金 */
totalmoney -= lottery_win[0] * 8000 + lottery_win[1] * 20000;
if (totalmoney < 0)
totalmoney = 0;
for (i = 2; i < 7; i++) /* 除普獎、陸獎以外 */
{
if (lottery_win[i])
eachmoney[i] = totalmoney / 100 / lottery_win[i] * rate[i];
else
keepmoney += totalmoney / 100 * rate[i];
}
eachmoney[1] = 20000;
eachmoney[0] = 8000;
/* 將未發出的獎金保留至下期 */
rec_put(LAST_KEEP_MONEY, &keepmoney, sizeof(keepmoney), 0, NULL);
fprintf(flog, "各獎項的獎金依序是:");
for (i = 0; i < 7; i++)
fprintf(flog, "%d ", eachmoney[i]);
fprintf(flog, "\n\n");
}
static int
lottery_cmp(a, b)
BUY_LOTTERY *a, *b;
{
int ap, bp;
ap = a->prize;
bp = b->prize;
if (ap * bp < 0) /* 一人有中獎,另一人沒中獎 */
return ap - bp; /* 沒中獎的放前面 */
/* 二人都有中獎或都沒中獎,依 id 排序 */
return strcmp(a->userid, b->userid);
}
static void
lottery_open()
{
int fsize;
BUY_LOTTERY *data, *head, *tail;
if (data = (BUY_LOTTERY *) f_img(FN_RUN_LOTTERY, &fsize))
{
unlink(FN_RUN_LOTTERY);
fsize /= sizeof(BUY_LOTTERY);
totalmoney = fsize * 1000;
/* 第一圈對獎 */
head = data;
tail = data + fsize;
do
{
/* 開始對獎,統計中獎注數 */
head->prize = check_prize(head);
} while (++head < tail);
/* 計算各獎項獎金 */
check_money();
/* 將 data 依 userid 排序 */
qsort(data, fsize * sizeof(BUY_LOTTERY), sizeof(BUY_LOTTERY), lottery_cmp);
/* 第二圈發獎金 */
head = data;
do
{
if (head->prize >= 0)
{
add_money(head);
mail_lottery(head);
}
} while (++head < tail);
/* 寄出最後一個中獎人通知信 */
data->userid[0] = '\0';
mail_lottery(data);
free(data);
}
}
int
main()
{
chdir(BBSHOME);
if (flog = fopen(OUTFILE_LOTTERY, "w"))
{
generate_number();
lottery_open();
fclose(flog);
add_post(BN_RECORD, OUTFILE_LOTTERY, "大樂透開獎記錄");
}
exit(0);
}
--
※ Origin: 吳鳳技術學院電算中心 卡布奇諾 <bbs.wfc.edu.tw>
◆ From: bbs.wfc.edu.tw精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻