回精華區
作者itoc, 信區: itoc
標題[遊戲] bet.c 賭盤 (遊戲主程式)
時間05/06/08
作者: chwaian (無言) 看板: itoc
標題: Re: 想請問有做賭盤的站長
時間: 2004/08/23 Mon 20:20:27                           Updated: 2005/06/08

: src/game/Makefile

SO =    .... bet.so

: src/game/ 底下增加這隻程式

/*-------------------------------------------------------*/
/* so/bet.c         ( NTHU CS MapleBBS Ver 3.00 )        */
/*-------------------------------------------------------*/
/* target : 瘋狂賭盤 (原名:下注遊戲)                     */
/* create :   /  /                                       */
/* update :   /  /                                       */
/* author : dsyan.bbs@Forever.twbbs.org                  */
/*          weiren@weiren.net                            */
/*-------------------------------------------------------*/

#if 0
   原構想及程式由 dsyan 提供及撰寫..
   後經 weiren 改寫部分架構得此程式..
   有任何問題或建議歡迎與這兩位連絡.. :)

   dsyan 是天長地久(Forever.twbbs.org) 的站長
   =>dsyan.bbs@Forever.twbbs.org
   weiren 是荒謬化境 (weird.twbbs.org.tw) 的站長
   =>http://www.weiren.net/
   =>weiren@weiren.net
#endif


#include "bbs.h"

#define maxboard    40
#define newgame     5           /* 最後開的幾盤要變色 */
#define LOCK_FILE   "etc/game/bet/bet.lock"


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));
}


int
main_bet()
{
  char i, j, k, num, cc[51], userid[IDLEN + 1];
  char buf[80], fpath[64], cho[9][51];
  int t[maxboard], money, tmp, phh, a, b, newbet[newgame];
  int turn = 0, ch_color;
  char ch;
  time_t set_time, close_time;
  FILE *fs, *fss;

  if (HAS_STATUS(STATUS_COINLOCK))
  {
    vmsg(msg_coinlock);
    return XEASY;
  }

  more("etc/game/bet/bet.welcome", NULL);
  if (fss = fopen("etc/game/bet/bet.new", "r"))
  {
    for (j = 0; j < newgame; j++)
      fscanf(fss, "%d\n", &newbet[j]);
    fclose(fss);
  }

  while (-1)
  {
    vs_bar("瘋狂賭盤");

    if (dashf(LOCK_FILE))
    {
      vmsg("發錢時間停止下注");
      return 0;
    }

    do
    {
      move(1, 0);
      outs("\033[44;1m編號  單  價           項    目    敘    述 開 局 者"
        "   尚有幾小時  \033[m\n");
      fs = fopen("etc/game/bet/bet.list", "r");
      if (turn == 0)
        tmp = 0;
      else
      {
        tmp = 20;
        for (k = 0; k < 20; k++)
        {
          fscanf(fs, "%d %ld %s\n", &t[i], &close_time, userid);
          fgets(buf, 60, fs);
        }
      }
      for (i = tmp; i < 20 + tmp; i++)
      {
        fscanf(fs, "%d %ld %s\n", &t[i], &close_time, userid);
        fgets(buf, 60, fs);
        j = strlen(buf) - 1;
        buf[j] = 0;
        a = (close_time - time(0)) / 3600 / 24;
        b = (close_time - time(0)) / 3600 % 24;

        ch_color = 0;
        for (j = 0; j < newgame; j++)
        {
          if (newbet[j] == i + 1)
            ch_color = 1;
        }

        if (t[i])
        {
          sprintf(fpath, "etc/game/bet/bet.ans%d", i + 1);
          if (fss = fopen(fpath, "r"))
          {
            fclose(fss);
            prints("\033[35;1m %2d    %5d  %-40s %-12s [等待發錢]\033[m\n",
              i + 1, t[i], buf, userid);
          }
          else if (close_time - time(0) > 0)
            prints("\033[%d;1m %2d    %5d  %-40s %-12s %2d天%2d小時\033[m\n",
              ch_color ? 37 : 32, i + 1, t[i], buf, userid, a, b);
          else
            prints("\033[32;1m %2d    %5d  %-40s %-12s     [封盤]\033[m\n",
              i + 1, t[i], buf, userid);
        }
        else
          prints("\033[31;1m %2d    -----      尚未有人開局\033[m\n", i + 1);
      }
      fclose(fs);
      move(22, 0);
      clrtoeol();
      prints("\033[1;44;37m按鍵說明: [n]下一頁 [p]上一頁 [b]下注/開桌/開盤 "
        "[q]離開  金幣: %10d     \033[m", cuser.gold);
      do
      {
        ch = igetch();
      } while (ch != 'q' && ch != 'n' && ch != 'p' && ch != 'b');
      if (ch == 'q')
        return 0;
      if (ch == 'n')
        turn = 1;
      if (ch == 'p')
        turn = 0;
      j = 0;
      if (ch == 'b')
      {
        vget(22, 0, "請輸入 1-40 或直接按 Enter 離開:", cc, 3, DOECHO);
        j = atoi(cc);
      }
    } while (!j || j > maxboard || j < 1);


    if (dashf(LOCK_FILE))
    {
      vmsg("發錢時間停止下注");
      return 0;
    }

    if (t[j - 1])                /* 已有人開局 */
    {
      fs = fopen("etc/game/bet/bet.list", "r");
      for (i = 0; i < j; i++)
      {
        fscanf(fs, "%d %ld %s\n", &t[i], &close_time, userid);
        fgets(buf, 60, fs);
      }
      fclose(fs);
      if (close_time < time(0))        /* 時間到 */
      {
        sprintf(fpath, "etc/game/bet/bet.ans%d", j);
        if (dashf(fpath))
        {
          vmsg("結果已公佈..獎金將於明天 6:30am 發放..:)");
        }
        else if (strcmp(userid, cuser.userid))
        {
          sprintf(buf, "下注期限已到..等待 %s 開局..", userid);
          vmsg(buf);
        }
        else
        {
          int ch[9], all = 0;

          vs_bar("瘋狂賭盤");
          prints("\n\n\033[44;1m  彩票數    倍率      敘  述"
            "           \033[m\n\n");
          sprintf(fpath, "etc/game/bet/bet.cho%d", j);
          fs = fopen(fpath, "r");
          fscanf(fs, "%d\n%d\n", &tmp, &all);
          for (i = 0; i < tmp; i++)
          {
            long xx;
            fgets(cho[i], 250, 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);
          sprintf(buf, "請輸入最後的結果(1-%d)或直接按 Enter離開:", tmp);
          move(20, 0);
          prints("\033[1;31m注意:亂開盤者,將處以停權與金錢歸零的處分\033[m");
          vget(22, 0, buf, cc, 3, DOECHO);
          num = atoi(cc);

          if (dashf(LOCK_FILE))
          {
            vmsg("發錢時間停止下注");
            return 0;
          }
          if (num <= tmp && num >= 1)
          {
            if (vans(msg_sure_ny) == 'y')
            {
              char fpath[64], title[30], fname[60];

              if (dashf(LOCK_FILE))
              {
                vmsg("發錢時間停止下注");
                return 0;
              }

              sprintf(fpath, "etc/game/bet/bet.ans%d", j);
              fss = fopen(fpath, "w");
              fprintf(fss, "%d", num);
              fclose(fss);

              sprintf(fpath, "tmp/addpost.tmp%d", j);
              sprintf(fname, "etc/game/bet/bet.betlog%d", j);

              if (fss = fopen(fpath, "w"))
              {
                sprintf(title, "盤號[%d] 封盤結果", j);

                fprintf(fss, "%s %s (%s) %s %s\n", STR_AUTHOR1, STR_SYSOP,
                  SYSOPNICK, STR_POST2, BN_BET);
                fprintf(fss, "標題: %s\n時間: %s\n\n", title, Now());

                fprintf(fss, "\n[開獎結果]:%d\n", num);
                fprintf(fss, "\n--\n※ 底下為此次下注狀況,"
                  "明天早上6:30將發放獎金\n\n\n");

                f_suck(fss, fname);

                fclose(fss);
                add_post(BN_BET, fpath, title);
                unlink(fpath);
                unlink(fname);
              }
            }
          }
        }
      }
      else
      {
        sprintf(fpath, "etc/game/bet/bet.scr%d", j);
        more(fpath, NULL);

        while (1)
        {
          int ch[9], all = 0, hhall = 0;

          vs_bar("瘋狂賭盤");
          prints("\n\n\033[44;1m  彩票數       倍率      敘  述"
            "           \033[m\n\n");
          sprintf(fpath, "etc/game/bet/bet.cho%d", j);
          fs = fopen(fpath, "r");
          fscanf(fs, "%d\n%d\n", &tmp, &all);
          for (i = 0; i < tmp; i++)
          {
            int hh = 0;
            long xx;
            fgets(cho[i], 250, fs);
            fscanf(fs, "%d\n", &ch[i]);
            sprintf(fpath, "etc/game/bet/bet.cho%d.%d", j, i + 1);
            if (fss = fopen(fpath, "r"))
            {
              char id[13];
              phh = 0;
              while (fscanf(fss, "%s %d\n", id, &hh) != EOF)
              {
                if (!strcmp(id, cuser.userid))
                {
                  phh += hh;
                  hhall += hh;
                }
              }
              fclose(fss);
            }
            else
              hh = 0;
            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", hhall, all);
          prints("\n本局總賭金: \033[1;36m%d\033[m 單張賭票價格: %d",
            all * t[j - 1], t[j - 1]);

          sprintf(buf, "請輸入你的選擇(1-%d)或按 q 跳出:", tmp);
          vget(20, 0, buf, cc, 2, DOECHO);
          if (dashf(LOCK_FILE))
          {
            vmsg("發錢時間停止下注");
            return 0;
          }
          if (cc[0] == 'q')
            break;
          num = cc[0] - 48;
          if (num > tmp || num < 1)
            vmsg("輸入範圍有誤!!請重新輸入..");
          else
          {
            sprintf(buf, "一張彩券金幣%d元,你目前有金幣%d元,"
              "要買幾張?(0-%d)",
              t[j - 1], cuser.gold, cuser.gold / t[j - 1]);
            vget(21, 0, buf, cc, 6, DOECHO);
            if (dashf(LOCK_FILE))
            {
              vmsg("發錢時間停止下注");
              return 0;
            }
            if (atoi(cc) > cuser.gold / t[j - 1] || !atoi(cc) ||(atoi(cc) < 1))
              vmsg("輸入範圍有誤!!取消..");
            else
            {
              int hh = 0;
              if (close_time < time(0))
              {
                vmsg("超過時間了!");
                return 0;
              }
              cuser.gold -= (atoi(cc) * t[j - 1]);
              sprintf(fpath, "etc/game/bet/bet.cho%d", j);
              fs = fopen(fpath, "r");
              fscanf(fs, "%d\n%d\n", &tmp, &all);
              for (i = 0; i < tmp; i++)
              {
                fgets(cho[i], 250, fs);
                fscanf(fs, "%d\n", &ch[i]);
              }
              fclose(fs);
              ch[num - 1] += atoi(cc);
              all += atoi(cc);
              fs = fopen(fpath, "w");
              fprintf(fs, "%d\n%d\n", tmp, all);
              for (i = 0; i < tmp; 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", j, num);
              fs = fopen(fpath, "a");
              fprintf(fs, "%s %d\n", cuser.userid, atoi(cc));
              fclose(fs);

              sprintf(fpath, "etc/game/bet/bet.betlog%d", j);
              sprintf(buf, "使用者%s買了%d張%d號選項(%s)\n",
                cuser.userid, atoi(cc), num, Now());
              f_cat(fpath, buf);
            }
          }
        }
      }
    }
    else    /* 自己開局 */
    {
      int khour, kd;

      more("etc/game/bet/bet.anno", NULL);

      if (vans("確定要開局(Y/N)?[N] ") != 'y')
        continue;

      if (dashf(LOCK_FILE))
      {
        vmsg("發錢時間停止下注");
        return 0;
      }

      sprintf(cc, "tmp/%s_bet.scr", cuser.userid);
      vmsg("請按任一鍵開始編輯此次 [開局宗旨]");
      if (vedit(cc, 0) < 0)
        continue;

      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 小時)");
        continue;
      }
      if (kd > 14)
      {
        vmsg("時間過長(最長 14 天)");
        continue;
      }
      if (khour > 24)
      {
        vmsg("時間不可超過24小時");
        continue;
      }
      if (kd < 0 || khour < 0)
      {
        vmsg("十位數記得補0");
        continue;
      }
      set_time = time(0) + khour * 3600 + kd * 24 * 3600;

      if (!vget(4, 0, "請簡短敘述此局:", cc, 41, DOECHO))
        continue;

      move(5, 0);
      outs("\033[1;31m設定選項,請注意和局、比賽取消等狀況,"
        "絕不可沒有答案,設定後不可更改。\033[m");

      vget(6, 0, "共有幾個選項?(2-9)", buf, 2, DOECHO);
      tmp = atoi(buf);
      if (tmp < 1 || tmp > 9)
      {
        vmsg("選項數目錯誤!!");
        continue;
      }

      vget(7, 0, "彩券一張多少錢?(100-10000)", buf, 6, DOECHO);
      money = atoi(buf);
      if (money < 100 || money > 10000)
      {
        vmsg("輸入金額錯誤!!");
        continue;
      }
      if (cuser.gold < money * (10 * tmp + 5))
      {
        sprintf(buf, "你的錢不足 %d 元喔!!", money * (10 * tmp + 5));
        vmsg(buf);
        continue;
      }

      for (i = 0; i < tmp; i++)
      {
        move(8 + i, 0);
        prints("選項%d:", i + 1);
        do
        {
          vget(8 + i, 7, "", cho[i], 50, DOECHO);
        } while (!cho[i][0]);
      }
      sprintf(buf, "etc/game/bet/bet.cho%d", j);
      if (dashf(LOCK_FILE))
      {
        vmsg("發錢時間停止下注");
        return 0;
      }
      if (dashf(buf))
      {
        fclose(fs);
        vmsg("有人比你快一步了");
        return 0;
      }

      if (vans("確定開盤(Y/N)?[N] ") != 'y')
      {
        sprintf(cc, "etc/game/bet/bet.scr%d", j);
        unlink(cc);
        sprintf(cc, "tmp/%s_bet.*", cuser.userid);
        unlink(cc);
        vmsg("開桌取消!!");
        return 0;
      }

      fs = fopen(buf, "w");
      fprintf(fs, "%d\n%d\n", tmp, tmp * 10);
      for (i = 0; i < tmp; i++)
      {
        fprintf(fs, "%s\n10\n", cho[i]);
        sprintf(buf, "etc/game/bet/bet.cho%d.%d", j, i + 1);
        fss = fopen(buf, "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 < newgame; i++)
          fscanf(fss, "%d\n", &newbet[i]);
        fclose(fss);
      }
      if (fss = fopen("etc/game/bet/bet.new", "w"))
      {
        fprintf(fss, "%d\n", j);
        for (i = 0; i < newgame - 1; i++)
          fprintf(fss, "%d\n", newbet[i]);
        fclose(fss);
      }

      cuser.gold -= (money * (10 * tmp + 5));
      close_time = set_time;
      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 == j)
        {
          fgets(buf, 60, fs);
          fgets(buf, 60, fs);
          fprintf(fss, "%d %ld %s\n", money, close_time, cuser.userid);
          fprintf(fss, "%s\n", cc);
        }
        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", j);
      f_mv(buf, fpath);
      sprintf(fpath, "tmp/%s_bet.*", cuser.userid);
      unlink(fpath);
      vmsg("開桌完成!!");
    }
  }
}

--
  Origin:  Maple-itoc˙動力核心  processor.tfcis.org 
  Author: chwaian 218-171-119-168.dynamic.hinet.net 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻