作者waynesan.bbs@csc241.twbbs.org (ln -s /dev/null hea 看板: itoc
標題[更新] bet.c 賭盤主程式仿 xover 介面
時間迷幻國度 (2008/03/21 Fri 01:34:37)
這陣子很多站都在玩押大選,
但是還在用舊版code的站沒有內建投票可兼賭盤的功能,
因此就照精華區加了bet.c系列的code下去.....
或許是這code已經有一段時間沒人更新了...所以介面感覺有點陽春......
這兩天花了時間將整個bet.c幾乎重寫,做成仿xover的介面.....
而資料結構方面都沒做改變與原本的相容........
如果有其他站之前也有加這個功能的話可以更新一下這個新介面....^^"
-----------------------------------------------------------------------------
: ~bbs/src/game/bet.c
/*-------------------------------------------------------*/
/* game/bet.c ( NTHU CS MapleBBS Ver 3.00 ) */
/*-------------------------------------------------------*/
/* target : 瘋狂賭盤 (原名:下注遊戲) */
/* create : 04/08/23 */
/* update : 08/03/20 */
/* author : dsyan.bbs@Forever.twbbs.org */
/* modify : weiren@weiren.net */
/* modify : waynesan.bbs@csc241.twbbs.org */
/*-------------------------------------------------------*/
#if 0
原構想及程式由 dsyan 提供及撰寫..
後經 weiren 改寫部分架構得雛型程式..
再經 waynesan 改寫整體架構而成本程式..
有任何問題或建議歡迎與這三位連絡.. :)
dsyan 是天長地久(Forever.twbbs.org) 的站長
=>dsyan.bbs@Forever.twbbs.org
weiren 是荒謬化境 (weird.twbbs.org.tw) 的站長
=>weiren@weiren.net
waynesan 是迷幻國度 (csc241.twbbs.org) 的站長
=>waynesan.bbs@csc241.twbbs.org
#endif
#include "bbs.h"
#define MAX_BET 40
#define NEW_GAME 5 /* 最後開的幾局要變色 */
#define LOCK_FILE "etc/game/bet/bet.lock"
#define NECKER_BET "[←]離開 [↑↓]選擇 [→,b]下注/開局/開盤 [h]說明 \n" \
COLOR3 "編號 單 價 項 目 敘 述%*s [ 開 局 者 ] [剩餘時間]\033[m"
#define FEETER_BET \
COLOR1 " 賭盤列表 " COLOR2 " (↑/↓)上下 (PgUp/PgDn)上下頁 (Home/End)首尾 (←)(q)離開 "
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);
hdr.xmode = POST_MARKED;
rec_bot(folder, &hdr, sizeof(HDR));
btime_update(brd_bno(brdname));
}
typedef struct
{
int money;
time_t close_time;
char userid[IDLEN + 1];
char title[TTLEN + 1];
} BET;
static int
open_bet(num, bet) /* 自己來開局 */
int num;
BET *bet;
{
int i, khour, kd, chn, newbet[NEW_GAME];
char buf[60], fpath[64], cho[9][51];
FILE *fs, *fss;
more("etc/game/bet/bet.anno", NULL);
if (vans("確定要開局(Y/N)?[N] ") != 'y')
return 0;
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
vmsg("請按任一鍵開始編輯此次 [開局宗旨]");
sprintf(fpath, "tmp/%s_bet.scr", cuser.userid);
if (vedit(fpath, 0) < 0)
return 0;
// move(1,0);
// clrtobot();
vs_bar("瘋狂賭盤");
vget(2, 0, "請填停注時間幾小時後(十位數要補0,0請輸入00,1請輸入01,以此類推):", buf, 3, DOECHO);
khour = (buf[0] - '0') * 10 + (buf[1] - '0');
vget(3, 0, "請填停注時間天後(十位數要補0,0請輸入00,1請輸入01,以此類推):", buf, 3, DOECHO);
kd = (buf[0] - '0') * 10 + (buf[1] - '0');
if (khour < 10 && kd == 0)
{
vmsg("時間過短(最短 10 小時)");
return 0;
}
if (kd > 14)
{
vmsg("時間過長(最長 14 天)");
return 0;
}
if (khour > 24)
{
vmsg("時間不可超過24小時");
return 0;
}
if (kd < 0 || khour < 0)
{
vmsg("十位數記得補0");
return 0;
}
bet->close_time = time(0) + khour * 3600 + kd * 24 * 3600;
if (!vget(4, 0, "請簡短敘述此局:", bet->title, 41, DOECHO))
return 0;
move(5, 0);
outs("\033[1;31m設定選項,請注意和局、比賽取消等狀況,絕不可沒有答案,設定後不可更改。\033[m");
vget(6, 0, "共有幾個選項?(2~9)", buf, 2, DOECHO);
chn = buf[0] - '0';
if (chn < 2 || chn > 9)
{
vmsg("選項數目錯誤!!");
return 0;
}
vget(7, 0, "彩券一張多少錢?(100~10000)", buf, 6, DOECHO);
bet->money = atoi(buf);
if (bet->money < 100 || bet->money > 10000)
{
vmsg("輸入金額錯誤!!");
return 0;
}
if (cuser.money < bet->money * (10 * chn + 5))
{
sprintf(buf, "你的錢不足 %d 元喔!!", bet->money * (10 * chn + 5));
vmsg(buf);
return 0;
}
for (i = 0; i < chn; ++i)
{
move(8 + i, 0);
prints("選項%d:", i + 1);
do
{
vget(8 + i, 7, "", cho[i], 50, DOECHO);
} while (!cho[i][0]);
}
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
sprintf(fpath, "etc/game/bet/bet.cho%d", num);
if (dashf(fpath))
{
fclose(fs);
vmsg("有人比你快一步了");
return 1;
}
if (vans("確定開局(Y/N)?[N] ") != 'y')
{
sprintf(fpath, "etc/game/bet/bet.scr%d", num);
unlink(fpath);
sprintf(fpath, "tmp/%s_bet.*", cuser.userid);
unlink(fpath);
vmsg("開局取消!");
return 0;
}
fs = fopen(fpath, "w");
fprintf(fs, "%d\n%d\n", chn, chn * 10);
for (i = 0; i < chn; ++i)
{
fprintf(fs, "%s\n10\n", cho[i]);
sprintf(fpath, "etc/game/bet/bet.cho%d.%d", num, i + 1);
fss = fopen(fpath, "a+");
fprintf(fss, "%s %d\n", cuser.userid, 10);
fclose(fss);
}
fclose(fs);
if (fss = fopen("etc/game/bet/bet.new", "r"))
{
for (i = 0; i < NEW_GAME; ++i)
fscanf(fss, "%d\n", &newbet[i]);
fclose(fss);
}
if (fss = fopen("etc/game/bet/bet.new", "w"))
{
fprintf(fss, "%d\n", num);
for (i = 0; i < NEW_GAME - 1; ++i)
fprintf(fss, "%d\n", newbet[i]);
fclose(fss);
}
cuser.money -= (bet->money * (10 * chn + 5));
fs = fopen("etc/game/bet/bet.list", "r");
fss = fopen("etc/game/bet/bet.list.w", "w");
for (i = 0; i < MAXBOARD; ++i)
{
if (i + 1 == num)
{
fgets(buf, 60, fs); /* 借用 fpath */
fgets(buf, 60, fs); /* 借用 fpath */
fprintf(fss, "%d %ld %s\n", bet->money, bet->close_time, cuser.userid);
fprintf(fss, "%s\n", bet->title);
}
else
{
fgets(buf, 60, fs);
fprintf(fss, buf);
fgets(buf, 60, fs);
fprintf(fss, buf);
}
}
fclose(fs);
fclose(fss);
f_mv("etc/game/bet/bet.list.w", "etc/game/bet/bet.list");
sprintf(buf, "tmp/%s_bet.scr", cuser.userid);
sprintf(fpath, "etc/game/bet/bet.scr%d", num);
f_mv(buf, fpath);
sprintf(fpath, "tmp/%s_bet.*", cuser.userid);
unlink(fpath);
vmsg("開局完成!");
return 1;
}
static int
end_bet(num, bet) /* 公佈開盤結果 */
int num;
BET *bet;
{
char fpath[64];
sprintf(fpath, "etc/game/bet/bet.ans%d", num);
if (dashf(fpath))
{
vmsg("結果已公佈,獎金將於明天 6:30am 發放...:)");
return 0;
}
if (strcmp(bet->userid, cuser.userid))
{
sprintf(fpath, "下注期限已到,等待 %s 開盤...", bet->userid); /* 借用 fpath */
vmsg(fpath);
return 0;
}
while(1)
{
int i, ch[9], ans, chn, all = 0;
char cc[10], cho[9][51];
FILE *fs;
vmsg("下注期限已到,請輸入開盤的結果!");
move(1,0);
clrtobot();
vs_bar("瘋狂賭盤");
prints("\n\n\033[44;1m 賭券數 倍率 敘 述 \033[m\n\n");
sprintf(fpath, "etc/game/bet/bet.cho%d", num);
fs = fopen(fpath, "r");
fscanf(fs, "%d\n%d\n", &chn, &all);
for (i = 0; i < chn; ++i)
{
long xx;
fgets(cho[i], 60, fs);
fscanf(fs, "%d\n", &ch[i]);
xx = all * 100 / ch[i];
prints("%d)%6d %3d.%-2d %s", i + 1, ch[i], xx / 100, xx % 100, cho[i]);
}
fclose(fs);
vmsg("注意:亂開盤者,將處以停權與金錢歸零的處分!");
move(b_lines - 1, 0);
prints("\033[1;31m注意:亂開盤者,將處以停權與金錢歸零的處分!\033[m");
sprintf(fpath, "請輸入最後的結果(1~%d)或按 q 離開:", chn); /* 借用 fpath */
vget(b_lines, 0, fpath, cc, 2, DOECHO);
if (cc[0] == 'q')
return 0;
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
ans = cc[0] - '0';
if (ans < 1 || ans > chn )
{
vmsg("輸入範圍有誤!!請重新輸入..");
continue;
}
if (vans(msg_sure_ny) == 'y')
{
char title[TTLEN + 1], fname[64];
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
sprintf(fpath, "etc/game/bet/bet.ans%d", num);
fs = fopen(fpath, "w");
fprintf(fs, "%d", ans);
fclose(fs);
sprintf(fpath, "tmp/addpost.tmp%d", num);
if (fs = fopen(fpath, "w"))
{
sprintf(title, "[公告] 瘋狂賭盤 盤號[%d] 封盤結果", num);
fprintf(fs, "%s %s (%s) %s %s\n", STR_AUTHOR1, STR_SYSOP, SYSOPNICK, STR_POST2, BN_BET);
fprintf(fs, "標題: %s\n時間: %s\n\n", title, Now());
fprintf(fs, "\n[開盤結果]:\033[1;3%dm%d號\033[m\n", ans % 8, ans);
fprintf(fs, "\n[開 盤 者]:\033[1m%s\033[m\n", cuser.userid);
fprintf(fs, "\n[開局宗旨]\n\n");
sprintf(fname, "etc/game/bet/bet.scr%d", num);
f_suck(fs, fname);
fprintf(fs, "\n[開局選項]\n\n");
sprintf(fname, "etc/game/bet/bet.cho%d", num);
f_suck(fs, fname);
fprintf(fs, "\n--\n※ 以下為此次下注狀況,明天早上6:30將發放獎金\n\n");
sprintf(fname, "etc/game/bet/bet.betlog%d", num);
f_suck(fs, fname);
fclose(fs);
add_post(BN_BET, fpath, title);
unlink(fpath);
unlink(fname);
}
return 1;
}
}
}
static int
buy_bet(num, bet) /* 下注買賭券 */
int num;
BET *bet;
{
char buf[100], fpath[64];
sprintf(fpath, "etc/game/bet/bet.scr%d", num);
more(fpath, NULL);
while (1)
{
int i, ch[9], ans, chn, all = 0, pall = 0;
char cc[10], cho[9][51];
FILE *fs, *fss;
// move(1,0);
// clrtobot();
vs_bar("瘋狂賭盤");
prints("\n\n\033[44;1m 賭券數 倍率 敘 述 \033[m\n\n");
sprintf(fpath, "etc/game/bet/bet.cho%d", num);
fs = fopen(fpath, "r");
fscanf(fs, "%d\n%d\n", &chn, &all);
for (i = 0; i < chn; ++i)
{
int phh = 0;
long xx; /* 倍率 */
fgets(cho[i], 60, fs); /* 取描述 */
fscanf(fs, "%d\n", &ch[i]); /* 取票數 */
sprintf(fpath, "etc/game/bet/bet.cho%d.%d", num, i + 1);
if (fss = fopen(fpath, "r"))
{
int hh = 0;
char id[IDLEN + 1];
while (fscanf(fss, "%s %d\n", id, &hh) != EOF)
{
if (!strcmp(id, cuser.userid))
{
phh += hh;
pall += hh;
}
}
fclose(fss);
}
xx = all * 100 / ch[i];
prints("%2d)%4d/%4d %3d.%-2d %s", i + 1, phh, ch[i], xx / 100, xx % 100, cho[i]);
}
fclose(fs);
prints("\n全>%4d/%4d\n", pall, all);
prints("\n本局總賭金: \033[1;36m%d\033[m 單張賭券價格: \033[1m%d\033[m", all * bet->money, bet->money);
sprintf(buf, "請輸入你的選擇(1~%d)或按 q 跳出:", chn);
vget(b_lines, 0, buf, cc, 2, DOECHO);
if (cc[0] == 'q')
return 0;
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
ans = cc[0] - '0';
if (ans < 1 || ans > chn )
{
vmsg("輸入範圍有誤!!請重新輸入..");
continue;
}
sprintf(buf, "一張賭券銀幣%d元,你目前有銀幣%d元,要買幾張?(0-%d)",
bet->money, cuser.money, cuser.money / bet->money);
vget(b_lines, 0, buf, cc, 6, DOECHO);
if (atoi(cc) > cuser.money / bet->money || !atoi(cc) ||(atoi(cc) < 1))
{
vmsg("輸入範圍有誤!!取消..");
continue;
}
if (vans(msg_sure_ny) != 'y')
continue;
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
if (bet->close_time < time(0))
{
vmsg("超過時間了!");
return 1;
}
sprintf(fpath, "etc/game/bet/bet.cho%d", num);
fs = fopen(fpath, "r");
fscanf(fs, "%d\n%d\n", &chn, &all);
for (i = 0; i < chn; ++i)
{
fgets(cho[i], 250, fs);
fscanf(fs, "%d\n", &ch[i]);
}
fclose(fs);
cuser.money -= (atoi(cc) * bet->money);
ch[ans - 1] += atoi(cc);
all += atoi(cc);
fs = fopen(fpath, "w");
fprintf(fs, "%d\n%d\n", chn, all);
for (i = 0; i < chn; ++i)
{
char g = strlen(cho[i]) - 1;
cho[i][g] = 0;
fprintf(fs, "%s\n%d\n", cho[i], ch[i]);
}
fclose(fs);
sprintf(fpath, "etc/game/bet/bet.cho%d.%d", num, ans);
fs = fopen(fpath, "a");
fprintf(fs, "%s %d\n", cuser.userid, atoi(cc));
fclose(fs);
sprintf(fpath, "etc/game/bet/bet.betlog%d", num);
sprintf(buf, "使用者 \033[1m%s\033[m 買了 \033[1m%d張\033[m 的 \033[1;3%dm%d號\033[m 賭券 (%s)\n",
cuser.userid, atoi(cc), ans % 8, ans, Now());
f_cat(fpath, buf);
vmsg("購買完成!");
}
}
static int /* 0:redraw 1:reload -1:return */
do_bet(num, bet)
int num;
BET *bet;
{
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
if (bet->money > 0) /* 已有人開局 */
if (bet->close_time < time(0)) /* 下注時間到 */
return end_bet(num, bet); /* 公佈開盤結果 */
else
return buy_bet(num, bet); /* 下注買賭券 */
else /* 自己來開局 */
return open_bet(num, bet);
}
static void
show_bet(num, bet, newbet)
int num;
BET *bet;
int *newbet;
{
if (bet->money > 0) /* 已有人開局 */
{
int i, color;
char buf[60];
for (i = 0; i < NEW_GAME; ++i)
{
if (newbet[i] == num)
{
color = 1;
break;
}
color = 0;
}
sprintf(buf, "etc/game/bet/bet.ans%d", num);
if (fopen(buf, "r")) /* bet.ans 檔案存在 */
{
prints(" \033[35;1m %2d %5d %-*.*s %-12s [等待發錢]\033[m\n",
num, bet->money, d_cols + 40, d_cols + 40, bet->title, bet->userid);
}
else if (bet->close_time - time(0) > 0) /* 時間未到 */
{
int day = (bet->close_time - time(0)) / 3600 / 24;
int hour = (bet->close_time - time(0)) / 3600 % 24;
prints(" \033[%d;37m %2d %5d %-*.*s %-12s \033[1;%dm%2d天%2d小時\033[m\n",
color, num, bet->money, d_cols + 40, d_cols + 40,
bet->title, bet->userid, day < 1 ? (hour < 10 ? 31 : 33) : 37, day, hour);
}
else
prints(" \033[32;1m %2d %5d %-*.*s %-12s [ 封 盤 ]\033[m\n",
num, bet->money, d_cols + 40, d_cols + 40, bet->title, bet->userid);
}
else
prints(" \033[1;30m %2d ----- ======== 尚未有人開局 ======== \033[m\n", num);
}
int
main_bet() /* waynesan.080317:賭盤主程式,仿 xover 的介面 */
{
int pageno, pagemax, redraw, reload;
int ch, cur, pos, newbet[NEW_GAME];
BET bet[MAX_BET];
if (HAS_STATUS(STATUS_COINLOCK))
{
vmsg(msg_coinlock);
return XEASY;
}
more("etc/game/bet/bet.welcome", NULL);
if (dashf(LOCK_FILE))
{
vmsg("發錢時間停止下注");
return -1;
}
reload = 1;
pageno = 0;
cur = 0;
do
{
if (reload)
{
int i;
FILE *fs;
if (fs = fopen("etc/game/bet/bet.new", "r"))
{
for (i = 0; i < NEW_GAME; ++i)
fscanf(fs, "%d\n", &newbet[i]);
fclose(fs);
}
fs = fopen("etc/game/bet/bet.list", "r");
for (i = 0; i < MAX_BET; ++i)
{
fscanf(fs, "%d %ld %s\n", &bet[i].money, &bet[i].close_time, bet[i].userid);
fgets(bet[i].title, TTLEN - 1, fs);
ch = strlen(bet[i].title) - 1; /* 借用 ch */
bet[i].title[ch] = 0;
}
fclose(fs);
pagemax = (MAX_BET - 1) / XO_TALL;
reload = 0;
redraw = 1;
}
if (redraw)
{
char buf[60];
sprintf(buf, "《 擁有銀幣:%d 》", cuser.money);
vs_head("瘋狂賭盤", buf);
prints(NECKER_BET "\n", d_cols, "");
pos = pageno * XO_TALL;
ch = BMIN(MAX_BET - 1, pos + b_lines - 4);
move(3, 0);
do
{
show_bet(pos + 1, &bet[pos], newbet);
} while (++pos <= ch);
outf(FEETER_BET);
move(3 + cur, 0);
outc('>');
redraw = 0;
}
ch = vkey();
switch (ch)
{
case KEY_RIGHT:
case '\n':
case 'b':
pos = cur + pageno * XO_TALL;
if ((reload = do_bet(pos + 1, &bet[pos])) == -1)
return 0;
redraw = 1;
break;
case 'h':
more("etc/game/bet/bet.welcome", NULL);
redraw = 1;
break;
default:
ch = xo_cursor(ch, pagemax, MAX_BET - 1, &pageno, &cur, &redraw);
break;
}
} while (ch != 'q');
}
--
╴╴
/ /▔▔\ 迷幻國度 Charming Shadow Country
▕ / /\ ▏入境位址 csc241.twbbs.org
▕ \/ / ▏位址代碼 203.71.212.241
\╴╴/ / 來源母國 218-163-192-227.dynamic.hinet.net
/ ▔▔\ 發表時間 2008/03/21 Fri 01:32:50