回文章列表
作者brother21913.bbs@bbs.ntue.edu.tw (資料轉移中~~) 看板: itoc
標題[功能]即時樂
時間芝山情緣 (2008/07/30 Wed 16:42:49)
  跟坊間戳戳樂很像,當初是參考某站(年代久遠,忘記了!)做出來的,

  最近,有朋友跟我索取程式碼,想想乾脆公布出來分享給大家,

  讓有需要的站長們使用。

  因當初寫作程式較快,可能有不完善的地方,歡迎有興趣的人提出意見。

: global.h

+ #define FN_RTLOTTERY_LOG  "run/realtime-lottery.log"    /* 即時樂中獎 */
+ #define FN_RTLOTTERY_DECK "run/realtime-lottery.deck"   /* 即時樂彩券內容 */

: menu.c 適當地方加入選單

+ "bin/realtime-lottery.so:main_game", PERM_BASIC, -M_GAME,
+ "RTLottery    \033[1;33m【 即 時 樂 】\033[m",

: ~/src/so/Makefile

SO =     ..... realtime-lottery.so

: ~/src/so/realtime-lottery.c 新增這檔案

/*-------------------------------------------------------*/
/* realtime-lottery.c    ( Maple-itoc Ver 3.10 )         */
/*-------------------------------------------------------*/
/* target : 即時樂遊戲                                   */
/* create : 06/07/02                                     */
/* update :                                              */
/* author : brother21913.bbs@bbs.ntue.edu.tw             */
/*-------------------------------------------------------*/


#include "bbs.h"

#define PRICE 200

int ticket[9][18];        /* 彩券內容 */
int page;                /* = 1 第一頁 = 2 第二頁 */
int can_buy;                /* 目前還有幾張是可以買的 */

static void
do_paint(x, y, mode)
  int x;
  int y;
  int mode;
{
  move( y*2 +3,0);
  int c;
  prints("   \033[1m│");

  if(mode == 1)
  {
    for( c = 0 ; c < 9 ; c++ )
    {
      prints("\033[4%dm %3d  \033[40m│", ticket[c][page == 1 ? y : y + 9 ] == -
1 ? 7 : c == x ? 1 : 4, page == 1 ?
      (y*9) + c + 1 :  (y*9) + c + 1 + 81);
    }
  }
  else
  {
    for( c = 0 ; c < 9 ; c++ )
    {
      prints("\033[4%dm %3d  \033[40m│", ticket[c][page == 1 ? y : y + 9] == -1
 ? 7 : 4, page == 1 ? (y*9) + c + 1
      : (y*9) + c + 1 + 81 );
    }
  }
}

static void
move_cursor(x_pos, y_pos)
  int x_pos;
  int y_pos;
{
  move(y_pos*2 + 3,  8*(x_pos + 1));
}

void
do_pick(x_pos, y_pos)
  int x_pos;
  int y_pos;
{
  char msg[200];
  int i, j;
  rec_get(FN_RTLOTTERY_DECK, ticket, sizeof(ticket), 0);
  can_buy = 0;
  for( i = 0 ; i < 9 ; i++)
  {
    for( j = 0; j < 18 ; j++ )
    {
      if(ticket[i][j] >= 0)
        can_buy += 1;
    }
  }
  int money = ticket[x_pos][page == 1 ? y_pos : y_pos + 9];

  if( money == -1 )
    vmsg("對不起,這張彩券已經被購買走嘍!!!");
  else
  {
    if( cuser.money < PRICE )
    {
       vmsg("★您的銀幣不夠喔!!!");
       return;
    }

    sprintf(msg, "您確定要購買 編號:%d 的即時樂彩券(Y/N)?[Y] ",page == 1 ? (y_
pos * 9) + x_pos + 1 : (y_pos * 9) + x_pos + 1 + 81 );
    if( vans(msg) != 'n' )
    {
            --can_buy;
            ticket[x_pos][page == 1 ? y_pos : y_pos + 9 ] = -1;
      rec_put(FN_RTLOTTERY_DECK, ticket, sizeof(ticket), 0, NULL);

      move(b_lines,0);
      clrtobot();

      cuser.money = cuser.money + money - PRICE;
      vmsg("購買完畢後,您迫不及待的打開彩券...一見居然是...");

      if( money == 0) /* 沒有中獎 */
      {
        if( rand()%2 == 1 )
          vmsg("嗚嗚嗚!居然是銘謝惠顧,人家不要啦!");
        else
          vmsg("看到了一個0、、、和一行『銘謝惠顧』");
      }
      else if( money == 100 ) /* 中百元小獎 */
      {
        if( rand()%2 == 1 )
          vmsg("瞎米,才中一百元,反正有中總比沒中好。");
        else
          vmsg("中...中...中了一百元耶!!!");
      }

      else if( money > 100 && money <= 1000)
      {
        if( rand()%2 == 1 )
          sprintf(msg, "呵呵呵~看來這次是回本了,居然中了 %d 元。", money );
        else
          sprintf(msg, "哼哼哼~雖然沒有很滿意,不過,可以接收這個數目:%d。", m
oney );

        vmsg(msg);
      }
      else if( money > 1000 && money < 10000)
      {
        sprintf(msg,"紅鸞星動,做什麼都順,隨便摸一摸就抽到 %d 元的大獎。", mone
y);
        vmsg(msg);
      }
      else if( money == 10000  )
      {
        vmsg("喔呵呵!這不是傳說中的頭獎 10000 元嗎?,居然,給我抽中了");
      }

      if(money <= 0)
        sprintf(msg, "★結果:本次共獲得銘謝惠顧一張。");
      else
        sprintf(msg, "★結果:本次共獲得 %d 銀。", money);



      if(money >= 500)
      {
        sprintf(msg, "[\033[1;36m%s\033[m] \033[1;31m%s\033[m 抽中即時樂彩券 \03
3[1;33m%d\033[m 元。\n", Now(), cuser.userid, money);
        f_cat(FN_RTLOTTERY_LOG, msg);
      }

      return;
    }
    else
    {
      move(b_lines,0);
      clrtobot();
    }
  }

  return;
}

void draw_item();

void
do_move()
{
  int x_pos, y_pos;  // 3 5 7 9 11
  char ch;

  x_pos = y_pos = 0;

  do_paint(x_pos, y_pos, 1);
  move_cursor(x_pos, y_pos);

  for(;;)
  {
    ch = vkey();
    do_paint(x_pos, y_pos, 0);

    switch(ch )
    {
      case KEY_DOWN:

          if(y_pos == 8)
          {
            if(page == 1)
              page = 2;
            else
              page = 1;

            y_pos = 0;
            draw_item();
          }
          else
            ++y_pos;
          break;

      case KEY_UP:

          if(y_pos == 0)
          {
            if(page == 1)
              page = 2;
            else
              page = 1;

            y_pos = 8;
            draw_item();
          }
          else
            --y_pos;
          break;

      case KEY_RIGHT:

          if(x_pos == 8)
            x_pos = 0;
          else
            ++x_pos;
          break;

      case KEY_LEFT:

          if(x_pos == 0)
            x_pos = 8;
          else
            --x_pos;
          break;

      case 'n':
      case 'N':
          if(page == 1)
            page = 2;
          else
            page = 1;


          break;
      case '\n':
      case ' ' :
          do_paint(x_pos, y_pos, 1);
          do_pick( x_pos, y_pos );
          draw_item();
          break;

      case 'q':
      case 'Q': vmsg("★謝謝惠顧"); return;
    }

    do_paint(x_pos, y_pos, 1);
    move_cursor(x_pos, y_pos);
  }
}


void
draw_item()
{
  int i, x, y;


  move(2, 3);

  prints("\033[1m┌───┬───┬───┬───┬───┬───┬───┬──
─┬───┐\033[m\n");
  for( i = 1 ; i <= 17 ; i++ )
  {
    if( i % 2 == 1)
    {
      prints("   \033[1m│");
      for( x = 0 ; x < 9 ; x++ )
      {
        prints("\033[4%dm %3d  \033[40m│", ticket[x][page == 1 ? y : y + 9 ] ==
 -1 ? 7 : 4, page == 1 ? (y*9) + x + 1 :
        (y*9) + x + 1 + 81 );
      }
      prints("\033[m\n");
      ++y;
    }
    else
      prints("   \033[1m├───┼───┼───┼───┼───┼───┼───
┼───┼───┤\033[m\n");
  }
  prints("   \033[1m└───┴───┴───┴───┴───┴───┴───┴─
──┴───┘\033[m\n");
  move(b_lines - 2, 0);
  prints("\033[1m◎ 總共有 162 張彩券,已被買走 %d 張,剩下 %d 張。\033[m", 162
- can_buy, can_buy);
  move(b_lines - 1, 0);
  prints("\033[1m★ 您身上目前有:\033[1;33m%10d\033[37m 銀,每張即時樂 %d 元!\
033[m", cuser.money, PRICE);
  move(b_lines, 0);
  prints("\033[1;44;34m ▄▄▄▄▄▄\033[37m ↑↓←→ 移動 N/n 換頁 Q/q 離開 Ent
er/空白鍵 選取。 \033[44;34m▄▄▄▄▄▄ \033[m");
  return;
}

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

int
main_game()
{

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

  vs_bar("即時樂遊戲");
  move(0, 0);
  int i, j;
  prints("\033[1;33;44m【 即時樂遊戲 】\033[m  ╭ \033[1;44m 數字 \033[0;1m 代表
 尚未被買走的彩券\033m ╮ \033[0;31;41m█ \033[1;37;41m獎金最高一萬元,\033[0;31
;41m \033[40m◣\033[m");
  move(1, 18);
  prints("╰ \033[1;47m 數字 \033[0;1m 代表 已經被買走的彩券\033m ╯ \033[0;31m
◥\033[41m \033[1;37;41m買越多獎越多喔!"
  "\033[0;31;41m █\033[m");

  if(rec_get(FN_RTLOTTERY_DECK, ticket, sizeof(ticket), 0) == -1 )
    vmsg("即時樂彩券資料有誤,請報請站長修復。");
  else
  {
    can_buy = 0;
    for( i = 0 ; i < 9 ; i++)
    {
      for( j = 0; j < 18 ; j++ )
      {
        if(ticket[i][j] >= 0)
          can_buy += 1;
      }
    }
    page = 1;
    draw_item();
    do_move();
  }

  rec_put(FN_RTLOTTERY_DECK, ticket, sizeof(ticket), 0, NULL);

  return 0;
}

: ~/src/util/Makefile

EXE =     ..... rtlottery-check.c

: ~/src/util/rtlottery-check.c 新增這檔案

/*-------------------------------------------------------*/
/* util/rtlottery-check.c  ( Maple-itoc Ver 3.10 )       */
/*-------------------------------------------------------*/
/* target : 即時樂檢查程式                               */
/* create : 06/07/02                                     */
/* author : brother21913.bbs@bbs.ntue.edu.tw             */
/*-------------------------------------------------------*/


#include "bbs.h"

static void
put_newprize()
{
  int ticket[9][18] = {0};
  int award[5][2] = {
  {10000, 1},
  {5000,2},
  {1000,5},
  {500,5},
  {100,100}};
  int i, j, tmp, x ,y;
  tmp = 0;

  for( j = 0 ; j < 18 ; j++ )
  {
    if(award[tmp][0] == 100 && award[tmp][1] == 0)
        break;

    for( i = 0 ; i < 9 ; i++ )
    {
      if(award[tmp][1] == 0)
       tmp++;

      ticket[i][j] = award[tmp][0];
      --award[tmp][1];

      if(award[tmp][0] == 100 && award[tmp][1] == 0)
        break;
    }
  }

  srand(time(NULL) * 10);

  for( j = 0 ; j < 18 ; j++ )
  {
    for( i = 0 ; i < 9 ; i++ )
    {
      x = rand() % 9;
      y = rand() % 18;
      tmp = ticket[x][y];
      ticket[x][y] = ticket[i][j];
      ticket[i][j] = tmp;
    }
  }
}


static int
deck_check()
{
  int ticket[9][18], i, j, prizenum;

  if( rec_get(FN_RTLOTTERY_DECK, ticket, sizeof(ticket), 0) == -1) /* 檔案不存在
 */
    return -1;
  else
  {
    prizenum = 0;
    for(i = 0 ; i < 9 ; i++ )
    {
      for( j = 0 ; j < 18 ; j++ )
      {
        if(ticket[i][j] >= 0)
          prizenum += 1;
      }
    }

    if( prizenum <= 50 )
      return -1;
  }

  return 0;
}


int
main()
{
  chdir(BBSHOME);

  if(deck_check() == -1)
  {
    put_newprize();
  }

  exit(0);
}

: ~/src/util/account.c 適當地方加入

sprintf(title, "%s文章篇數統計", date);
keeplog(FN_RUN_POST_LOG, BN_SECURITY, title, 2);

+ sprintf(title, "%s及時樂中獎一覽", date);
+ keeplog(FN_RTLOTTERY_LOG, BN_SECURITY, title, 2);

: 最後要在 crontab 中加入

+ # 每小時做彩券即時樂審查
+ 45 2,5,10,15,20 * * * bin/rtlottery-check

------------------------------------------------------------------------

【以下是遊戲畫面】:

【 即時樂遊戲 】 數字  代表 尚未被買走的彩券 ╮ 獎金最高一萬元,  數字  代表 已經被買走的彩券 ╯  買越多獎越多喔!
   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
      1     2     3     4     5     6     7     8     9  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
     10    11    12    13    14    15    16    17    18  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
     19    20    21    22    23    24    25    26    27  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
     28    29    30    31    32    33    34    35    36  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
     37    38    39    40    41    42    43    44    45  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  46    47    48    49    50    51    52    53    54  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  55    56    57    58    59    60    61    62    63  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  64    65    66    67    68    69    70    71    72  
   ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  73    74    75    76    77    78    79    80    81  
   └───┴───┴───┴───┴───┴───┴───┴───┴───┘
◎ 總共有 162 張彩券,已被買走 0 張,剩下 162 張。
★ 您身上目前有:     48442 銀,每張即時樂 200 元!
 ▄▄▄▄▄▄ ↑↓←→ 移動 N/n 換頁 Q/q 離開 Enter/空白鍵 選取。 ▄▄▄▄▄▄ 


基本上 realtime-lottery.c 這支程式是主要的遊戲,常數 PRICE 就是一張即時樂
的價錢,而 rtlottery-check.c  是放在 crontab 中跑,每小時檢查一遍,如果彩
券少於 50 張,則重新至放新的彩券,獎金值與數量放在 award 這個陣列裡面。

記得,整個 make 完後,要先手動執行一次:

~/bin/rtlottery-check

這樣會在 ~/run/ 下面產生 realtime-lottery.deck 的檔案,這就是存放目前獎卷
資料的檔案,如果玩家抽中超過 500 元的點券時,在同一目錄下面還會產生
realtime-lottery.log 記錄玩家所得金額,不用擔心這個檔案會越來越大,因為,
每天晚上,這個檔案會隨著  log 版的紀錄,寫到 log 版文章中,之後就被刪掉了
。

後記:

當初是為了讓站上的人能賺點錢,所以,獎金比較優渥,如果,你不喜歡,可
以把 PRICE 改大一點,或是將獎金量放少一點。

其實,程式還有很多變數,沒有提出來,是因為當初寫程式時沒打算公布,所
以也沒這樣做,近來,也很少時間寫 BBS  程式了,若是有人感興趣願意花時
間把程式改的更彈性更簡潔,相當歡迎。

--

                                                                          
 ██◣ ██▊ ◢█▉ ██▉ █  ▉ █ˍ_ ██▊ █ ▉     ▉ ▉ ˍ_
 █▇▉ █▇▊ █  ▉   █      ▉ █ˍ_ █▇▊     ▌▉ █▇▉ ▉ ˍ_██
 █▇▉ █◥◣ ██▉   █       ▉ █    █◥◣    ▇ ▉ ▇▇▉ ▉    ██
▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅▅

--
  Origin:  國立臺北教育大學˙芝山情緣  bbs.ntue.edu.tw 
  Author: brother21913125-225-2-92.dynamic.hinet.net 發表
文章選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻