回精華區
作者simple.bbs@bbs.wfc.edu.tw (養兵千日 用在一時) 看板: plan
標題[功能]樂透彩-大樂透(修改版)
時間卡布奇諾 (2004/10/27 Wed 00:39:26) Updated: 2006/01/24
: src/so/Makefile

SO =    ... lottery.so

: so/lottery.c 新增此程式

/*-------------------------------------------------------*/
/* lottery.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"


static int choose_num[6];       /* 所選的六個號碼 */
static int choose_count;        /* 已經選了幾個號碼 */


/*-------------------------------------------------------*/
/* 畫面重繪                                              */
/*-------------------------------------------------------*/


static void
lottery_screen(fpath)
  char *fpath;
{
  FILE *fp;
  char buf[ANSILINELEN];

  vs_bar("樂透彩券遊戲");

  if (fp = fopen(fpath, "r"))
  {
    while (fgets(buf, ANSILINELEN, fp))
      outs(buf);
    fclose(fp);
  }
}


/*-------------------------------------------------------*/
/* 將選擇的樂透號碼寄到自己信箱                          */
/*-------------------------------------------------------*/


static void
lottery_mail_one()
{
  int i;
  FILE *fp;
  char fpath[64];

  sprintf(fpath, "tmp/%s.lottery", cuser.userid);

  if (fp = fopen(fpath, "w"))
  {
    fprintf(fp, "%s\n", Now());
    fprintf(fp, "您所購買的樂透號碼為:");
    for (i = 0; i < 6; i++)
      fprintf(fp, "%d ", choose_num[i]);
    fprintf(fp, "\n");
    fclose(fp);

    mail_self(fpath, cuser.userid, "[備 忘 錄] 彩券紀錄", MAIL_READ);
    unlink(fpath);
  }
}


/*-------------------------------------------------------*/
/* 樂透系統紀錄                                          */
/*-------------------------------------------------------*/


static int
int_cmp(a, b)
  int *a;
  int *b;
{
  return *a - *b;
}


static void
lottery_log()
{
  int i;
  BUY_LOTTERY log;

  qsort(choose_num, 6, sizeof(int), int_cmp);

  memset(&log, 0, sizeof(BUY_LOTTERY));
  strcpy(log.userid, cuser.userid);
  for (i = 0; i < 6; i++)
    log.num[i] = choose_num[i];

  rec_add(FN_RUN_LOTTERY, &log, sizeof(BUY_LOTTERY));
}


/*-------------------------------------------------------*/
/* 畫控制游標                                            */
/*-------------------------------------------------------*/


static void
draw_cursor(x, y, mode)
  int x, y;
  int mode;                     /* 1:選取 0:取消選取 */
{
  move(2 * x - 1, 4 + y * 8);
  outc(mode == 1 ? '[' : ' ');
  move(2 * x - 1, 7 + y * 8);
  outc(mode == 1 ? ']' : ' ');
}


/*-------------------------------------------------------*/
/* 畫樂透彩券下注畫面                                    */
/*-------------------------------------------------------*/


static void
draw_numbers()
{
  int i, x, index;

  vs_bar("樂透彩券下注");

  x = 4;
  index = 1;

  move(x++, 1);
  outs("╭───┬───┬───┬───┬───┬───┬───╮"
    "   ╭───╮ ");
  for (i = 0; i < 7; i++, index += 7)
  {
    move(x++, 1);
    prints("│  %02d  │  %02d  │  %02d  │"
      "  %02d  │  %02d  │  %02d  │  %02d  │      │      │",
      index, index + 1, index + 2,
      index + 3, index + 4, index + 5, index + 6);
    move(x++, 1);
    if (i < 6)
      outs("├───┼───┼───┼───┼───┼───┼───┤"
        "   ├───┤");
  }
  outs("╰───┴───┴───┴───┴───┴───┴───╯"
    "   ╰───╯");
}


/*-------------------------------------------------------*/
/* 畫出使用者選擇的樂透號碼                              */
/*-------------------------------------------------------*/


static void
draw_choose()
{
  int x;

  for (x = 0; x < choose_count; x++)
  {
    move(2 * x + 5, 68);
    prints(" %02d", choose_num[x]);
  }
  for (; x < 6; x++)
  {
    move(2 * x + 5, 68);
    outs("   ");
  }
}


/*-------------------------------------------------------*/
/* 選取樂透號碼                                          */
/*-------------------------------------------------------*/


static int                      /* 1:已選完六個號碼 */
do_choose(num)
  int num;                      /* 所選取的號碼 */
{
  int i;
  int choose_flag;              /* -1:選取 >=0:取消選取 */

  choose_flag = -1;

  for (i = 0; i < choose_count; i++)
  {
    if (choose_num[i] == num)
    {
      choose_flag = i;
      break;
    }
  }

  if (choose_flag >= 0)         /* 取消 */
  {
    choose_count--;
    for (i = choose_flag; i < choose_count; i++)
      choose_num[i] = choose_num[i + 1];
    draw_choose();
  }
  else                          /* 選取 */
  {
    if (choose_count == 6)
    {
      vmsg("您已經選了六個號碼");
      return 1;
    }
    else
    {
      choose_num[choose_count] = num;
      choose_count++;
      draw_choose();
    }
  }
  return 0;
}


/*-------------------------------------------------------*/
/* 樂透下注號碼選擇                                      */
/*-------------------------------------------------------*/


static void
random_choose()
{
  int i, j;

  /* 造出六個不同的數字 */
  for (i = 0; i < 6; i++)
  {
    choose_num[i] = rnd(49) + 1;
    for (j = 0; j < i; j++)
    {
      if (choose_num[i] == choose_num[j])
      {
        i--;
        break;
      }
    }
  }
}


static void
lottery_buy_one()
{
  int cx, cy, ch;

  if (cuser.money < 1000)
  {
    vmsg("您的銀幣不夠購買彩券");
    return;
  }

  if (vans("每張彩券價格為 1000 銀幣,是否要購買呢(Y/N)?[Y] ") == 'n')
    return;

  draw_numbers();

  if (vans("是否要電腦選號(Y/N)?[N] ") == 'y')
  {
    random_choose();

#if 1  /* 純粹只是為了秀出選號結果,要不然不需要這段 */
    choose_count = 0;
    for (ch = 0; ch < 6; ch++)
      do_choose(choose_num[ch]);
    vmsg("電腦選號結果");
#endif
  }
  else     /* 手動選號 */
  {
    choose_count = 0;
    memset(choose_num, 0, sizeof(choose_num));
    cx = 3;
    cy = 0;

    while (1)
    {
      outz("★ 操作說明 (方向)移動 (Enter)選取/取消 (q)離開");

      for (;;)
      {
        draw_cursor(cx, cy, 1);
        ch = vkey();
        draw_cursor(cx, cy, 0);

        switch (ch)
        {
        case '\n':
          if (do_choose((cx - 3) * 7 + cy + 1))
            goto end_choose;
          break;
        case KEY_DOWN:
          cx = (cx == 9) ? 3 : cx + 1;
          break;
        case KEY_UP:
          cx = (cx == 3) ? 9 : cx - 1;
          break;
        case KEY_LEFT:
          cy = (cy == 0) ? 6 : cy - 1;
          break;
        case KEY_RIGHT:
          cy = (cy == 6) ? 0 : cy + 1;
          break;
        case 'q':
          return;
        }
      }

  end_choose:

      if (vans("是否要確定這六個號碼(Y/N)?[N] ") == 'y')
        break;
    }
  }

  cuser.money -= 1000;
  lottery_log();

  if (vans("是否要保留彩券(Y/N)?[Y] ") != 'n')
    lottery_mail_one();
}


static void
lottery_buy_some()
{
  int i, j, num;
  char fpath[64];
  FILE *fp;

  if (cuser.money < 1000)
  {
    vmsg("您的銀幣不夠購買彩券");
    return;
  }

  vget(b_lines, 0, "請輸入欲買張數:", fpath, 5, DOECHO);
  if ((num = atoi(fpath)) <= 0)
    return;

  if (cuser.money < num * 1000)
  {
    vmsg("您的銀幣不夠購買彩券");
    return;
  }

  fp = NULL;
  if (vans("是否要保留彩券(Y/N)?[Y] ") != 'n')
  {
    sprintf(fpath, "tmp/%s.lottery", cuser.userid);
    if (fp  = fopen(fpath, "w"))
    {
      fprintf(fp, "%s\n", Now());
      fprintf(fp, "您所購買的樂透號碼為:");
    }
  }

  for (i = 0; i < num; i++)
  {
    random_choose();
    lottery_log();

    if (fp)
    {
      for (j = 0; j < 6; j++)
        fprintf(fp, "%d ", choose_num[j]);
      fprintf(fp, "\n");
    }
  }

  if (fp)
  {
    fclose(fp);
    mail_self(fpath, cuser.userid, "[備 忘 錄] 彩券紀錄", MAIL_READ);
    unlink(fpath);
  }

  cuser.money -= num * 1000;
}


/*-------------------------------------------------------*/
/* 主程式                                                */
/*-------------------------------------------------------*/


int
main_lottery()
{
  double money;

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

  srand(time(NULL) + cuser.userno);

  while (1)
  {
    lottery_screen("etc/game/lottery.main");

    /* 顯示累積獎金 */
    money = 0;
    rec_get(LAST_KEEP_MONEY, &money, sizeof(money), 0);
    money += rec_num(FN_RUN_LOTTERY, sizeof(BUY_LOTTERY)) * 1000;
    move(20, 10);
    prints("目前累積獎金有 %.0f 元", money);

    switch (vkey())
    {
    case 'b':
      lottery_buy_one();
      break;

    case 's':
      lottery_buy_some();
      break;

    case 'h':
      lottery_screen("etc/game/lottery.rule");
      vmsg(NULL);
      break;

    default:
      return 0;
    }
  }
}

--
※ Origin: 吳鳳技術學院電算中心 卡布奇諾 <bbs.wfc.edu.tw>
◆ From: bbs.wfc.edu.tw
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻