Board logo

标题: [游戏娱乐] 一个用以抽奖的批处理 [打印本页]

作者: amwfjhh    时间: 2014-11-7 14:24     标题: 一个用以抽奖的批处理

思路:
以csv格式存储两个文档:成员名单及其愿望(中特等奖后使用),奖项设置
成员名单按“编号,姓名,愿望”的格式存储文本,奖项设置按“中奖等级,名额,等级名称”的格式存储文本
将成员名单的内容读入内存,然后分别按奖项设置中的等级与名额来进行名单的随机滚动,人为按下任意键后停止滚动并显示中奖人序号名及字,如为特等奖,显示其愿望,并将显示内容语音播报。代码及附件如下:
  1. @echo off
  2. if not %1#==# goto %1
  3. setlocal enabledelayedexpansion
  4. prompt $
  5. chcp 437>nul&graftabl 936>nul
  6. color 0f
  7. title 抽奖程序.::by 呼吸新世界::.
  8. set /a nMemCount=0
  9. set /a nChoiseCount=0
  10. set /a gDegree=0
  11. set "clr=123456789abcdef"
  12. set /p= <nul>%tmp%\$$
  13. :_Main
  14. (
  15.     call :_LoadList
  16.    
  17.     for /f "tokens=1,2,3 delims=, skip=1" %%i in (奖项设置.csv) do (
  18.         call :_MakeList %%i %%j %%k
  19.     )
  20.    
  21.     call :_ShowChoiseList
  22.    
  23.     goto :EOF
  24. )
  25. REM =============================================分割线======================================================
  26. REM 取得列表
  27. :_LoadList
  28. (
  29.     for /f "tokens=1,2,* delims=, skip=1" %%i in (名单.csv) do (
  30.         if not %%k#==# (
  31.             set /a nMemCount+=1
  32.             call :_AddMemList !nMemCount! %%i "%%j" %%k  
  33.         )
  34.     )
  35.     pause
  36.     goto :EOF
  37. )
  38. REM 抽奖主函数(%1 抽奖等级0为特等奖,%2 抽奖名额)
  39. :_MakeList
  40. (
  41.     echo.&echo.&echo.
  42.     if not %3#==# (
  43.         set "strShow=下面抽取%3..."
  44.     ) else (
  45.         set "strShow=下面抽取%1等奖..."
  46.     )
  47.     ECHO !strShow!
  48.     call :_SpeakContent "!strShow:.=!"
  49.     echo =========================================
  50.     for /l %%i in (1 1 %2) do (
  51.         call :_GetChoise %1
  52.     )
  53.     echo =========================================
  54.     if not %3#==# (
  55.         set "strShow=%3抽取完毕..."
  56.     ) else (
  57.         set "strShow=%1等奖抽取完毕..."
  58.     )
  59.     ECHO !strShow!
  60.     call :_SpeakContent "!strShow:.=!"
  61.     pause
  62.     goto :EOF
  63. )
  64. REM 添加参与人员名单(%1 载入队列序号,%2 抽奖编号,%3 人员名字,%4 愿望)
  65. :_AddMemList
  66. (
  67.     set /a nNum%1=%2
  68.     set strName%1=%3
  69.     set strName%1=!strName%1:"=!
  70.     set "strWish%1=%4"
  71.     set "strWish%1=!strWish%1:"=!"
  72.     set "strShowNum=  !nNum%1!"
  73.     set "strShowNum=!strShowNum:~-2!"
  74.     echo 编号:!strShowNum!    人名:!strName%1!    愿望:!strWish%1!
  75.     goto :EOF
  76. )
  77. REM 添加已抽中人员名单(%1 抽中队列序号,%2 抽奖编号,%3 人员名字)
  78. :_AddChoiseList
  79. (
  80.     set /a nChoiseNum%1=%2
  81.     set "strChoiseName%1=%3"
  82.     set "strChoiseName%1=!strChoiseName%1:"=!"
  83.     set "strNull=!strNull:"=!"
  84.     goto :EOF
  85. )
  86. REM 得到抽奖号码的名字,如为特殊奖项,报出其愿望(%1 载入队列序号,%2 抽奖等级)
  87. :_GetMem
  88. (
  89.     if not !nNum%1!#==# (
  90.         call :_ChkMem %1 %2
  91.         if !nContinue!#==1# (
  92.             set /a nChoiseCount+=1
  93.             call :_AddChoiseList !nChoiseCount! !nNum%1! "!strName%1!"
  94.             set "strNum=     !nNum%1!"
  95.             set "strNum=!strNum:~-3!"
  96.             echo.
  97.             echo 请编号为 !strNum! 的 【!strName%1!】 上台领奖...
  98.             call :_SpeakContent "请编号为 !strNum! 的 !strName%1! 上台领奖"
  99.             REM if %2#==1# (
  100.             REM     rem pause
  101.             REM     echo 恭喜 【!strName%1!】 抽中一等奖,其愿望为 【!strWish%1!】
  102.             REM     call :_SpeakContent "恭喜 !strName%1! 抽中一等奖,其愿望为 !strWish%1!"
  103.             REM )
  104.             if %2#==0# (
  105.                 REM pause
  106.                 echo 恭喜 【!strName%1!】 抽中特等奖,其愿望为 【!strWish%1!】
  107.                 call :_SpeakContent "恭喜 !strName%1! 抽中特等奖,其愿望为 !strWish%1!"
  108.             )
  109.         ) else (
  110.             echo 重复号码!nNum%1!, 重新抽取...
  111.             call :_SpeakContent "重复号码!nNum%1!, 重新抽取"
  112.             call :_GetChoise %2
  113.             GOTO :EOF
  114.         )  
  115.     ) else (
  116.         echo 对不起,当前列表中无此抽奖号码...
  117.         call :_SpeakContent "对不起,当前列表中无此抽奖号码"
  118.     )
  119.     goto :EOF
  120. )
  121. REM 得到并检测当前产生的抽奖号码(%1 抽奖等级)
  122. :_GetChoise
  123. (
  124.     REM set /a nTmp=!random!%%!nMemCount!+1
  125.     REM echo 当前产生随机号为:!nTmp!
  126.     REM call :_GetMem !nTmp! %1
  127.    
  128.     set /a gDegree=%1
  129.     call :_StartScroll
  130.     REM pause>nul
  131.     goto :EOF
  132. )
  133. set /a nHaveMem=0
  134. set /a nContinue=0
  135. REM 检测是否有重复被抽取的情况(%1 载入队列序号,%2 抽奖等级)
  136. :_ChkMem
  137. (
  138.     for /l %%i in (1 1 !nChoiseCount!) do (
  139.         call :_ChkList %1 %%i
  140.         if !nHaveMem!#==1# (
  141.             set /a nContinue=0
  142.             goto :EOF
  143.         )
  144.     )
  145.     set /a nContinue=1
  146.     goto :EOF
  147. )
  148. REM 检测已存储抽奖队列中是否有当前编号(%1 载入队列序号,%2 已抽中队列中的序号)
  149. :_ChkList
  150. (
  151.     if !nNum%1!#==!nChoiseNum%2!# (
  152.         set /a nHaveMem=1
  153.     ) else (
  154.         set /a nHaveMem=0
  155.     )
  156.     goto :EOF
  157. )
  158. REM 显示已抽中人员名单(%1 已抽中队列序号)
  159. :_ShowChoiseNum
  160. (
  161.     set "nTmp=   %1"
  162.     set "nTmp=!nTmp:~-3!"
  163.     set "nTmpNum=   !nChoiseNum%1!"
  164.     set "nTmpNum=!nTmpNum:~-3!"
  165.     set "strShow2=第 !nTmp! 个抽中人员编号为 !nTmpNum!     姓名为【!strChoiseName%1!】"
  166.     call :_ShowColorLine "!strShow2!"
  167.     echo.
  168.     goto :EOF
  169. )
  170. REM 语音播报内容(%1 播报文本内容)
  171. :_SpeakContent
  172. (
  173.     set "strTmp=%1"
  174.     set "strTmp=!strTmp: =!"
  175.     mshta "javascript:new ActiveXObject("sapi.spvoice").speak(!strTmp!);window.close();"
  176.     goto :EOF
  177. )
  178. REM 显示抽奖列表
  179. :_ShowChoiseList
  180. (
  181.     echo.&echo.&echo.
  182.     for /l %%i in (1 1 !nChoiseCount!) do (
  183.         call :_ShowChoiseNum %%i
  184.     )
  185.     pause
  186.     goto :EOF
  187. )
  188. REM 显示滚动名单(%1 序号)
  189. :_ShowScrollList
  190. (   
  191.     set "strTmp=   !nNum%1!"
  192.     set "strTmp=!strTmp:~-3!"
  193.    
  194.     if not !nNewLine!#==1# (
  195.         set /p=<nul
  196.     )
  197.     set "strShow=★编号『!strTmp!』            姓名『!strName%1!』★"
  198.     call :_ShowColorLine "!strShow!"
  199.    
  200.     set /a nNewLine=0
  201.     goto :EOF
  202. )
  203. REM 随机显示
  204. :_ShowRnd
  205. (
  206.     REM color 9e
  207.     set /a nTmp=!random!%%!nMemCount!+1
  208.     REM echo 当前产生随机号为:!nTmp!
  209.     call :_ShowScrollList !nTmp!
  210.     REM pause>nul
  211.     if exist $ (
  212.         REM pause>nul
  213.         del $
  214.         REM color
  215.         set /a nNewLine=0
  216.         call :_GetMem !nTmp! !gDegree!
  217.         goto :EOF
  218.     )
  219.    
  220.     goto :_ShowRnd
  221.     goto :EOF
  222. )
  223. REM 开始滚动
  224. :_StartScroll
  225. (
  226.     del $ 2>nul
  227.     start /b %~fs0 :_Thread
  228.    
  229.     call :_ShowRnd
  230.    
  231.     goto :EOF
  232. )
  233. set /a nNewLine=0
  234. REM 另开线程用以监听按键
  235. :_Thread
  236. (
  237.     set /a nNewLine=1
  238.     pause>nul
  239.     >$ echo.
  240.     exit
  241. )
  242. REM 彩色字体显示(%1 显示的语句)
  243. :_ShowColorLine
  244. (
  245.     set /a nRndB=!random!%%15
  246. :_ReTry
  247.     set /a nRndF=!random!%%15
  248.     if !nRndB!#==!nRndF!# goto :_ReTry
  249.     call set tmpClr=%%clr:~!nRndB!,1%%%%clr:~!nRndF!,1%%
  250.     REM echo !tmpClr!
  251.     set "strShow1=%1"
  252.     set "strShow1=!strShow1:"=!"
  253.     set "strNull=!strNull:"=!"
  254.     pushd %tmp%
  255.     (
  256.         set /p=<nul
  257.         ren $$ "!strShow1!" >nul 2>nul
  258.         findstr /a:!tmpClr! . "!strShow1!*"
  259.         ren "!strShow1!" $$ >nul 2>nul
  260.     )
  261.     popd
  262.    
  263.     goto :EOF
  264. )
  265. REM =============================================分割线======================================================
复制代码
链接: https://pan.baidu.com/s/1Mmii3SeZR-QuN5PV7nUz8Q?pwd=u7as
作者: DAIC    时间: 2014-11-7 14:43

两点建议:
1、重复中奖号码在后台处理掉就行了,没有必要显示出来,对于观众来说它没有什么意义。
2、需要考虑中奖人没到现场,需要补抽的问题,年会上经常有这事。比如10个五等奖,其中3个人没来,就要再抽3个五等奖。
作者: amwfjhh    时间: 2014-11-7 15:19

回复 2# DAIC

  好提议,重复抽奖当初在使用的时候也发现这个问题了,特别是随着中奖人员的增加,后期会有很多重复的情况出现,后台处理也会相对较慢,当时想了另一个方法,就是将未抽中的人员另存一个队列,后面的抽奖直接在这个队列里面进行挑选,这样就快得多了。至于说的未到人员,因为领取编号是到年会之后再领取的号牌,名字与愿望是事先输入的,在处理时,对于未编号的人员是直接跳过的,所以这个问题当时也就没有过多处理。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2