Board logo

标题: 欢迎大家一起来开发【批处理版斗地主】 [打印本页]

作者: cjiabing    时间: 2011-5-30 10:53     标题: 欢迎大家一起来开发【批处理版斗地主】

本帖最后由 cjiabing 于 2011-9-2 20:13 编辑

      斗地主游戏玩多了,心痒痒的也想用批处理写一个。见有人写批处理版的斗地主游戏,但都没见完工的。自己整理了下思路,有兴趣的朋友一起来共同开放吧!~以下是思路:

说明、进度等在三楼,主程序代码在二楼。

成功一半:代码在二楼2011年6月26日

这两天有空瞎整了一下,终于完成了自家牌分析——看自己有什么牌(还需完善),以及吃牌分析——看对家出的是什么牌。现在可以发牌开始玩游戏,不过还是自己在玩。电脑要稍微改进一下才能人机对战,不过也只能是初级的,因为分析牌型很费劲。

下一步:初级人机对战好高兴!~

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


    一、我一楼二楼说得不够爽朗,我这里说一下电脑怎么出牌。

    首先要用到一个“接口”。什么是接口,就是几个玩家之间相互通信、相互理解、相互交流的一个变量。
    比如,我们把这个接口变量命名为“%JieKou%”。现在有三个玩家,上家出的牌是34567,这是一个顺子,那么,上家提供给另外两个玩家的接口是:JieKou=07顺子5
    下一家获得该接口变量,则分析这个牌是什么类型——顺子,最大的牌是什么——07,牌子有多少张——5张。
    下一家继续分析,自己有没有顺子牌——分析自己的牌型,看看自己有什么牌——这个我可以做出来——然后看看自己这副牌的接口是什么——我们假定为56789,接口是:MyJieKou=09顺子5
    然后比较下上家的接口和自家的接口,看自家的牌是否比上家大,如果大过继续判断时分是搭档(农民),如果不是,就可以出牌了,如果没有大过,则Pass。
    第三方同样获得第一家出牌的接口,并获得上一家牌的接口,如果上一家Pass了,就可以直接对比第一家,如果上一家出牌了,就分析自己的牌,并与上家的接口%MyJieKou% 比较大小。
    这样,三方通过接口变量,获得了比较的途径,也就获得了电脑出牌的途径。
    从以上看,需要做的主要有:1、分析上一家或下一家的牌,也就是分析其他人出的牌是什么牌;2、分析自己的牌,看自己的牌有什么类型的牌。
    其他需要考虑的功能:1、比较牌的大小;2、分析是否搭档(农民还是地主);3、如何中止吃牌,并决定谁可以出牌;如何获得分数……
    其实,以上我都基本上做完了,但由于一个小地方出错,心烦,找不到原因就此停下来了。回头检查,发现漏洞百出,想整合全部功能,都不好整合。我认为,还是要从以上提到的主要问题着手,解决了这两个问题,后面整合就容易了。

    二、顺便谈谈牌型分析——一个数学问题。

    主要的两个问题,第一个是知道对家出的是什么牌,第二个是知道自己有什么牌。这两个问题的关键就是进行牌型分析。斗地主的牌型很简单,他们之中包含着一定的数学关系,下面做简单分析。(注意,等差是指两个牌之间的差,即两个数相减的结果)

    牌  型          排除           张  数         等  差                 举例      
——————————————————————————————————————————————
    单张牌                          1                 0                     5
    一对牌        王炸弹          2                 0                     22
    三个牌                          3                 00                    333
    四个牌        三带一          4            001、100          9999、5551、4777
    五张牌      顺子、三代二   5            1111、0020       45678、99944
    六张牌      顺子、连对      6           11111、01010     346789、334455
    …………
    有可能计算各种牌型之间的等差关系、张数等等就可以区别去是那种牌了,甚至可以从一堆牌里面找出对牌、顺子、炸弹等,前提是这些牌必须排好顺序。
    我数学是最差的,但我偏偏遇到这种问题,希望各位数学学得好的,批处理也好的,能够解决以上这些问题。
    前面说到的牌型与接口的问题,就是这个接口变量的格式:决定牌大小的最大一张牌+牌型+张数
    好比飞机 46667778 ,它决定这副牌大小的最大的一张牌应该是7,它的牌型是飞机带单翅膀,牌的张数是8张,所以,它的接口变量应该是这样写的:JieKou=07飞单08
    07表示最大的一张牌,用两位数表示,因为J、Q、K可能超过10;飞单表示飞机带单翅膀,也可以用其他字母表示;张数最好也用两位数,因为有时候张数超过十张。

    分析牌型是个比较细致的工作,容易出错,可能一两天找不到原因都有。最近也忙点,这个工作暂时就停下来了,一旦有空会继续完成的。谢谢大家关注!~
作者: cjiabing    时间: 2011-5-30 10:53

本帖最后由 cjiabing 于 2011-6-27 01:28 编辑

初次整合,初见雏形

使用方法,进入游戏,输入代号出牌。比如,想出 三个6带一个K ,则输入“1116  1216  1416 1323”并回车。
代号可在游戏规则里查,暂时这样。
先把代码放这里,过段时间有空再处理。
现在的问题是,!pkvar!不懂出什么问题了,竟然不对了!~找不到原因!~可恶!~
下一步:确定两个电脑玩家如何自动出牌,利用!pkvar!作为接口~

  1. @echo off&setlocal enabledelayedexpansion
  2. ::mode con cols=86 lines=45
  3. title 批处理版斗地主扑克牌游戏
  4. ::本程序尝试整合发牌、叫地主、出牌、吃牌等功能。
  5. ::需要进一步优化各个子函数代码。
  6. ::优化接口:set var=path,!pkvar!
  7. ::优化标签。
  8. ::!pkvar!有误!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  9. ::---------------------------★代码分割线:主菜单和总台★---------------------------
  10. :ZongTai
  11. ::总台
  12. cls
  13. echo;
  14. echo;      批处理版斗地主-单机试验版
  15. echo;
  16. echo;
  17. echo;         1、开始游戏
  18. echo;         2、游戏规则展示
  19. echo;         3、退出
  20. echo;
  21. echo;
  22. echo;
  23. set input=
  24. set /p input=    请选择:
  25. if "%input%"=="" goto ZongTai
  26. if %input%==1 goto Play
  27. if %input%==2 call :YSStart
  28. if %input%==3 exit
  29. goto ZongTai
  30. :Play
  31. cls
  32. ::开始游戏
  33. call :Fapai
  34. ::呼叫发牌
  35. call :排序
  36. ::呼叫排序
  37. :Playing
  38. ::开始出牌。打牌的过程。
  39. :Play1
  40. echo;
  41. echo,--------------------------地主:%DiZhu%-----------------------------
  42. echo;
  43. set "MyPoker=%~dp0DDZTemp\%DiZhu%"
  44. set "PerPoker=%~dp0DDZTemp\%DiZhu%"
  45. call :Pkhuase "%MyPoker%"
  46. call :自家牌分析 %PerPoker%
  47. call :Chupai %MyPoker%
  48. :Play2
  49. echo;
  50. echo,--------------------------农民:%NongM1%-----------------------------
  51. echo;
  52. set "MyPoker=%~dp0DDZTemp\%NongM1%"
  53. set "PerPoker=%~dp0DDZTemp\%NongM1%"
  54. call :Pkhuase "%MyPoker%"
  55. call :自家牌分析 %PerPoker%
  56. call :Chupai %MyPoker%
  57. :Play3
  58. echo;
  59. echo,--------------------------农民:%NongM2%-----------------------------
  60. echo;
  61. set "MyPoker=%~dp0DDZTemp\%NongM2%"
  62. set "PerPoker=%~dp0DDZTemp\%NongM2%"
  63. call :Pkhuase "%MyPoker%"
  64. call :自家牌分析 %PerPoker%
  65. call :Chupai %MyPoker%
  66. goto Playing
  67. pause
  68. exit
  69. ::建立一个循环,假设玩家A\B\C,循环于三者,直至有一个玩家先出完牌。
  70. ::这个循环包括:地主出牌——下家分析桌面牌(上家牌)——分析自家牌(是否有可打的牌)——出牌——下家分析桌面牌……
  71. ::三家出牌,最大的区别是,玩家是通过输入控制过程,而电脑自动出牌。
  72. ::---------------------------★代码分割线:出牌机制★---------------------------
  73. ::改造该段代码,使之能通用,优化代码,减少临时文件。
  74. :Chupai
  75. ::出牌机制,首先对自家牌进行分析,找出有规律的牌。
  76. echo;
  77. echo;    轮到 【%1】 出牌。
  78. echo;    返回【Q】排序【P】不出【N】
  79. echo;    输入要出的牌的序号,回车出牌。多个牌用空格隔开。
  80. echo;
  81. set input=
  82. set /p input=    输入出牌:
  83. if "%input%"=="" goto Chupai
  84. if /i "%input%"=="Q" goto ZongTai
  85. if /i "%input%"=="N" goto :eof
  86. if /i "%input%"=="P" (
  87.     call :Pkhuase "%1"
  88.     goto Chupai
  89. )
  90. cd.>"%~dp0DDZTemp\DDZPlay0"
  91. cd.>"%1ed"
  92. cd.>"%1tmp"
  93. set a=0
  94. set b=0
  95. set c=
  96. ::判断输入的是否为自己手中的牌
  97. for %%i in (!input!) do (
  98.     set /a a+=1
  99.     for /f "usebackq tokens=*" %%a in ("%1") do (
  100.         if "%%a"=="" (echo;&echo Game over&echo;&pause&goto :eof)
  101.         if %%i==%%a (
  102.             echo;%%i>>"%1ed"
  103.             set /a b+=1
  104.         )
  105.     )&&set c=1
  106. )
  107. if "%c%"=="" (echo;&echo 游戏结束&echo;&pause&goto ZongTai)
  108. if not !a!==!b! (echo     !a!=/=!b!,数据有误,重新输入!&goto Chupai) else (echo;    !a!==!b!,数据重合,输入正确!)
  109. call :比较结果
  110. echo;上家的牌:!PkShangJia!
  111. ::上家的牌
  112. ::剩下的牌
  113. findstr /v  /g:"%1ed" "%1">>"%1tmp"
  114. cd.>"%1"
  115. type "%1tmp">>"%1"
  116. echo;
  117. echo;    【%1】打出的牌:
  118. ::type "%1ed">>"%~dp0DDZTemp\DDZPlay0"
  119. set PerPoker="%1ed"
  120. call :牌型分析 %PerPoker%&call :牌型分析结果
  121. echo;
  122. echo;    【%1】剩下的牌:
  123. call :Pkhuase "%1"
  124. echo;
  125. goto :eof
  126. ::---------------------------★代码分割线:机器出牌★---------------------------
  127. ::试图将处理地主的模式转换为电脑自动处理。只是在调用文件上和出牌上有所区别。
  128. :机器出牌
  129. goto :eof
  130. ::---------------------------★代码分割线:发牌机制★---------------------------
  131. ::发牌后,得到发到三个玩家手中的牌,并确定谁是地主、谁是农民。
  132. :Fapai
  133. ::准备工作
  134. echo;
  135. echo     正在发牌,请稍候……
  136. echo;
  137. if exist "%~dp0\DDZTemp" (del /q "%~dp0DDZTemp\*.*") else (md "%~dp0\DDZTemp")
  138. ::将54张扑克牌分成54行,每行一个数据输入到一个文本中,然后对该文本进行随机排序,并将牌按照顺序发到三个玩家手中。
  139. :Fapai1
  140. ::产生一副扑克牌
  141. echo 2899>"%~dp0DDZTemp\DDZFapai"
  142. for %%m in (2999 2130 2230 2330 2430) do echo;%%m>>"%~dp0DDZTemp\DDZFapai"
  143. for /l %%a in (3,1,14) do (
  144.     set pkp=%%a
  145.     set /a Pkfp=%%a+1110
  146.     set /a Pkmh=%%a+1210
  147.     set /a Pkhx=%%a+1310
  148.     set /a Pkht=%%a+1410
  149.     echo;!Pkfp!&echo;!Pkmh!&echo;!Pkhx!&echo;!Pkht!
  150. )>>"%~dp0DDZTemp\DDZFapai"
  151. call :Suijpx
  152. ::随机排序,"%~dp0DDZTemp\DDZFpsj"为随机牌。
  153. :Fapai2
  154. ::将牌发到三个玩家手中
  155. cd.>"%~dp0DDZTemp\DDZPlay1"&cd.>"%~dp0DDZTemp\DDZPlay2"&cd.>"%~dp0DDZTemp\DDZPlay3"
  156. set Pkfp=0
  157. for /f "usebackq tokens=*" %%a in ("%~dp0DDZTemp\DDZFpsj") do (
  158.     set /a Pkfp+=1
  159.     for /l %%i in (0,3,50) do (
  160.         set /a Pkff=!Pkfp!-%%i
  161.         if !Pkff!==1 echo;%%a>>"%~dp0DDZTemp\DDZPlay1"
  162.         if !Pkff!==2 echo;%%a>>"%~dp0DDZTemp\DDZPlay2"
  163.         if !Pkff!==3 echo;%%a>>"%~dp0DDZTemp\DDZPlay3"
  164.         if !Pkfp!==52 set pkdp1=%%a
  165.         if !Pkfp!==53 set pkdp2=%%a
  166.         if !Pkfp!==54 set pkdp3=%%a
  167.     )
  168. )
  169. :Fapai3
  170. ::发到每个玩家手中的牌
  171. ::此处进行重新排序。[`sort /+3 "%~dp0DDZTemp\DDZchupai"`]
  172. for /l %%i in (1,1,3) do (
  173.     echo,
  174.     echo,     玩家 %%i 的牌:
  175.     set pkp=
  176.     echo,
  177.     call :Pkhuase "%~dp0DDZTemp\DDZPlay%%i"
  178. )
  179. echo,
  180. :JiaoDiZhu
  181. ::此处增加叫地主与积分翻倍计算。
  182. ::采用随机地主形式。玩家DDZPlay1为操作者,其余两个为电脑。
  183. ::但在后面的操作中,玩家为随机的一个,剩下的两个为电脑。
  184. set tm=
  185. set DiZhu=
  186. set "tm=%time:~10,1%"
  187. if %tm% geq 0 if %tm% leq 3 set DiZhu=DDZPlay1&set NongM1=DDZPlay2&set NongM2=DDZPlay3
  188. if %tm% geq 4 if %tm% leq 6 set DiZhu=DDZPlay2&set NongM1=DDZPlay1&set NongM2=DDZPlay3
  189. if %tm% geq 7 if %tm% leq 9 set DiZhu=DDZPlay3&set NongM1=DDZPlay1&set NongM2=DDZPlay2
  190. :Fapai4
  191. ::底牌
  192. echo;!pkdp1!>>"%~dp0DDZTemp\%DiZhu%"
  193. echo;!pkdp2!>>"%~dp0DDZTemp\%DiZhu%"
  194. echo;!pkdp3!>>"%~dp0DDZTemp\%DiZhu%"
  195. echo,
  196. echo,    %DiZhu% 是地主
  197. echo,
  198. if /i not %DiZhu% ==  DDZPlay1 echo,    DDZPlay1 是农民
  199. if /i not %DiZhu% ==  DDZPlay2 echo,    DDZPlay2 是农民
  200. if /i not %DiZhu% ==  DDZPlay3 echo,    DDZPlay3 是农民
  201. echo,
  202. echo     底牌是:
  203. echo,
  204. for /l %%i in (1,1,3) do (
  205.     set pkp=!pkdp%%i!
  206.     call :HuaSe
  207.     if "!pkp:~2,1!"=="0" (echo     !Pkp1!  !Pkp2!  !pkp:~3,1!  !pkdp%%i!) else (echo     !Pkp1!  !Pkp2!  !pkp:~2,2!  !pkdp%%i!)
  208. )
  209. echo,
  210. ::处理临时文件
  211. cd.>"%~dp0DDZTemp\DDZFpsjx"&cd.>"%~dp0DDZTemp\DDZFpsj"&cd.>"%~dp0DDZTemp\DDZFapai"
  212. goto :eof
  213. ::---------------------------★代码分割线:排序★---------------------------
  214. :排序
  215. ::已设定为三个玩家排序,直接调用即可。
  216. ::对三个玩家的牌进行排序,排序是必须的。
  217. for /l %%i in (1,1,3) do (
  218.     cd.>"%~dp0DDZTemp\DDZPx"
  219.     sort /+3 "%~dp0DDZTemp\DDZPlay%%i">>"%~dp0DDZTemp\DDZPx"
  220.     cd.>"%~dp0DDZTemp\DDZPlay%%i"
  221.     type "%~dp0DDZTemp\DDZPx">>"%~dp0DDZTemp\DDZPlay%%i"
  222. )
  223.     cd.>"%~dp0DDZTemp\DDZPx"
  224. echo,
  225. goto :eof
  226. :Suijpx
  227. ::随机排序——或许要减少临时文件、提高速度,可优化以下项目:
  228. ::set ddd=for——去掉一个临时文件
  229. ::call :Suijipx——去掉外部处理
  230. ::优化为调用模式。
  231. set sjpx=
  232. cd.>"%~dp0DDZTemp\DDZFpsjx"&cd.>"%~dp0DDZTemp\DDZFpsj"
  233. for /f "tokens=1,* delims=:" %%a in ('findstr /n .* "%~dp0DDZTemp\DDZFapai"') do (
  234.     if not "%%a"=="" set sjxh=%%a
  235.     call :Suijipx
  236.     echo;!sjpx!:%%b>>"%~dp0DDZTemp\DDZFpsjx"
  237. )>nul 2>nul
  238. for /f "tokens=1,* delims=:" %%a in ('sort "%~dp0DDZTemp\DDZFpsjx"') do echo;%%b>>"%~dp0DDZTemp\DDZFpsj"
  239. goto :eof
  240. :Suijipx
  241. set /a sjpx=!sjxh!+%random:~-2,2%
  242. goto :eof
  243. ::---------------------------★代码分割线:自家牌分析★---------------------------
  244. ::分析自己的牌,看自己有什么牌
  245. ::牌的关系只有两种,要么相等——等差等于0,要么相差——等差等于1。
  246. ::调用:call :自家牌分析 "%~dp0DDZTemp\%DiZhu%"
  247. ::获得分析结果:!pkvar!
  248. :自家牌分析
  249. echo;
  250. echo     【%MyPoker%】自家牌分析
  251. echo;
  252. set pkvar=
  253. set pkvar1=
  254. set pkvar0=
  255. set pkvar2=
  256. set pkvar3=
  257. set pk1=
  258. set pk2=
  259. set pk3=
  260. set pk4=
  261. set pk5=
  262. set dc=0
  263. set nb=0
  264. set nb1=0
  265. set nb0=0
  266. for /f "usebackq" %%a in (%1) do if not "%%a"=="" (
  267.     set pk1=%%a
  268.     set /a dc=!pk1:~2,2!-!pk2:~2,2!
  269.     if !dc!==0 (
  270.         set /a nb0+=1
  271.         set pkvar0=!pk2! !pk1!
  272.         set pkvar2=!pk3! !pk2! !pk1!
  273.         set pkvar3=!pk4! !pk3! !pk2! !pk1!
  274.         if !nb0! == 1 if not "!pk2!"=="" set pkvar=!pk1:~2,2!一对子2&echo !pkvar!  一对  pkvar0=!pkvar0!
  275.         if !nb0! == 2 if not "!pk3!"=="" set pkvar=!pk1:~2,2!三张牌3&echo !pkvar!  三个  pkvar2=!pkvar2!
  276.         if !nb0! == 3 if not "!pk4!"=="" set pkvar=!pk1:~2,2!小炸弹4&echo !pkvar!  炸弹  pkvar3=!pkvar3!
  277.     )
  278.     if !dc!==1 (
  279.         set /a nb1+=1
  280.         set nb0=0
  281.         set pkvar1=!pk1! !pkvar1!
  282.         if !nb1! geq 5 set pkvar=!pk1:~2,2!长顺子!nb1!&echo !pkvar!  顺子  pkvar1=!pkvar1!
  283.     )
  284.     if not !dc!==0 if not !dc!==1 (set nb1=0&set nb0=0&set pkvar1=&set pkvar0=)
  285. rem echo %%a : !pk1! !pk2! !pk3! !pk4! !pk5!$$ pkvar=!pkvar! ##!nb0!=!nb1!##&pause
  286.     set pk5=!pk4!
  287.     set pk4=!pk3!
  288.     set pk3=!pk2!
  289.     set pk2=!pk1!
  290. )
  291. goto :eof
  292. ::---------------------------★代码分割线:牌面转换★---------------------------
  293. ::调用方法 set HuaSe="%~dp0DDZTemp\%DiZhu%"&call :Pkhuase
  294. ::`sort /+3 %HuaSe%`
  295. :Pkhuase
  296. for /f "usebackq tokens=*" %%a in (%1) do (
  297.     set pkp=%%a
  298.     call :HuaSe
  299.     if "!pkp:~2,1!"=="0" (echo     !Pkp1!  !Pkp2!  !pkp:~3,1!  %%a) else (echo     !Pkp1!  !Pkp2!  !pkp:~2,2!  %%a)
  300. )
  301. ::牌面转换。将代码转换为牌面花色,可以在处理完所有数据后再转换。
  302. goto :eof
  303. :HuaSe
  304. set Pkp2=
  305. set Pkp1=
  306. if "!pkp:~0,1!"=="1" set Pkp1=副牌
  307. if "!pkp:~0,1!"=="2" set Pkp1=主牌
  308. if "!pkp:~1,1!"=="1" set Pkp2=方片 
  309. if "!pkp:~1,1!"=="2" set Pkp2=草花 
  310. if "!pkp:~1,1!"=="3" set Pkp2=红桃 
  311. if "!pkp:~1,1!"=="4" set Pkp2=黑桃 
  312. if not "!pkp:~0,2!"=="28"  (
  313.     if not "!pkp:~0,2!"=="29" (set /a pkp=!pkp!-10) else (set pkp=大王大王)
  314. ) else (set pkp=小王小王)
  315. if "!pkp:~2,2!"=="11" set pkp=JJJ
  316. if "!pkp:~2,2!"=="12" set pkp=QQQ
  317. if "!pkp:~2,2!"=="13" set pkp=KKK
  318. if "!pkp:~2,2!"=="14" set pkp=AAA
  319. if "!pkp:~2,2!"=="20" set pkp=222
  320. goto :eof
  321. ::---------------------------★代码分割线:桌面牌分析★---------------------------
  322. ::分析上家打出的牌,分析自己打出的牌,看看两者哪个大,下家出牌是否合乎规则。稍微复杂了点,需要改进。
  323. ::可喜的是,最后找到了各种牌对比的接口“!pkvar!”。
  324. ::与自家牌分析有所差距,自家牌分析不受牌的张数影响,而桌面牌分析则考虑牌的张数。
  325. ::普通调用示例:
  326. :: set PerPoker="%~dp0DDZTemp\%DiZhu%ed"
  327. :: call :牌型分析&call :牌型分析结果
  328. :牌型分析
  329. ::用于分析桌面上的牌(包括自家和对家的)的牌型,需要确定牌的张数和顺序,区别于自家牌分析。
  330. set pk1=
  331. set pk2=
  332. set pk3=
  333. set pk4=
  334. set pk5=
  335. set zs=0
  336. set dc=
  337. set dc1=
  338. set dc2=
  339. set dc3=
  340. set dc4=
  341. set nb=0
  342. set nb0=0
  343. set nb1=0
  344. set tj=0
  345. set tj1=0
  346. set tj2=0
  347. set pkstr=
  348. set pkvar=
  349. for /f "usebackq" %%a in (%1) do if not "%%a"=="" set /a zs+=1
  350. if !zs!==1 for /f "usebackq" %%a in (%1) do set pkvar=%%a单张牌1&set pkvar=!pkvar:~2,8!&goto :eof
  351. if "!zs!" gtr "1" for /f "usebackq" %%a in (%1) do if not "%%a"=="" (
  352.     set pk1=%%a
  353.     if not "!pk2!"=="" if not "!pk1!"=="" set /a dc=!pk1:~2,2!-!pk2:~2,2!
  354.     if not "!pk3!"=="" if not "!pk2!"=="" set /a dc1=!pk2:~2,2!-!pk3:~2,2!
  355.     if not "!pk4!"=="" if not "!pk3!"=="" set /a dc2=!pk3:~2,2!-!pk4:~2,2!
  356.     if not "!pk5!"=="" if not "!pk4!"=="" set /a dc3=!pk4:~2,2!-!pk5:~2,2!
  357.     if not "!pk1!"=="" if not "!pk5!"=="" set /a dc4=!pk1:~2,2!-!pk5:~2,2!
  358.     set pk5=!pk4!
  359.     set pk4=!pk3!
  360.     set pk3=!pk2!
  361.     set pk2=!pk1!
  362.     if "!dc!"=="0" if "!zs!"=="2" (if "!pk1:~2,2!"=="99" (set pkvar=99王炸弹2) else (set pkvar=!pk1:~2,2!一对子2)&goto :eof) else (set tj1=!pk1:~2,2!)
  363.     if "!dc!"=="0" if "!dc1!"=="0" (if "!zs!"=="3" (set pkvar=!pk1:~2,2!三张牌!zs!&goto :eof) else (set /a tj+=1&set tj2=!pk1:~2,2!))
  364.     if "!zs!"=="4" if "!dc!"=="0" if "!dc1!"=="0" if "!dc2!"=="0" set pkvar=!pk1:~2,2!小炸弹4
  365.     if "!zs!"=="4" if "!dc!"=="0" if "!dc1!"=="0" if not "!dc2!"=="0" set pkvar=!pk2:~2,2!三带一4
  366.     if "!zs!"=="4" if not "!dc!"=="0" if "!dc1!"=="0" if "!dc2!"=="0" set pkvar=!pk2:~2,2!三带一4
  367.     if "!zs!"=="5" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if "!dc3!"=="0" set pkvar=!pk4:~2,2!三带对5
  368.     if "!zs!"=="5" if "!dc!"=="0" if "!dc1!"=="0" if not "!dc2!"=="0" if "!dc3!"=="0" set pkvar=!pk4:~2,2!三带对5
  369.     if "!zs!"=="5" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带一5
  370.     if "!zs!"=="5" if "!dc!"=="0" if "!dc1!"=="0" if "!dc2!"=="0" if not !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带一5
  371.     if "!zs!"=="6" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带对6
  372.     if "!zs!"=="6" if "!dc!"=="0" if  "!dc1!"=="0" if "!dc2!"=="0" if not !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带对6
  373.     if !zs! gtr 7  if !dc!==0 if !dc1!==0 if !dc2!==1 if !dc3!==0  if !dc4!==1 set pkvar=!pk1:~2,2!飞机带!zs!
  374.     if !zs! gtr 7  if !dc!==0 if !dc1!==1 if !dc2!==0 if !dc3!==0  if !dc4!==1 set pkvar=!pk1:~2,2!飞机带!zs!
  375.     if !zs! geq 5 if !dc!==1  if !dc1!==1  if !dc2!==1  if !dc3!==1  if !dc4!==4 set pkvar=!pk1:~2,2!长顺子!zs!
  376.     if !zs! gtr 5 if "!dc!"=="0" if "!dc1!"=="1" if "!dc2!"=="0" if "!dc3!"=="1" if !dc4!==2 set pkvar=!pk1:~2,2!连对顺!zs!
  377.     if not "!dc!"=="" if not !dc!==0 if not !dc!==1 set /a nb+=1
  378.     if not "!dc!"=="" if !dc!==1 set /a nb1+=1
  379.     if not "!dc!"=="" if !dc!==0 set /a nb0+=1
  380. )
  381. )>nul 2>nul
  382. echo,
  383. if "!pkvar!"=="长顺子" if !nb1! == 11 if !nb! == 0 (if !nb0! == 0 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=)
  384. if "!pkvar!"=="连对顺" (
  385.     set /a jd=!nb0!*2
  386.     if !jd!==!zs! (if !nb! == 0 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=)
  387. )
  388. set dd=
  389. ::此处有冲突,会覆盖上面的结果。
  390. if !tj! gtr 0 for /l %%a in (2,1,20) do if !tj!==%%a (
  391.     set /a dd=%%a*3
  392.     if !dd!==!zs! set pkvar=!pk2:~2,2!三顺子!zs!
  393. )
  394. if "!pkvar!"=="四带一" (
  395.     if !nb0! == 4 (set pkvar=!pkvar!!zs!) else (set pkvar=)
  396. )
  397. if "!pkvar!"=="四带对" (
  398.     if !nb0! == 5 (set pkvar=!pkvar!!zs!) else (set pkvar=)
  399. )
  400. rem if !zs! gtr 7  (
  401.     if "!zs!"=="8"  if !tj!==2 (if !nb0! equ 2 (if !nb1! equ 1 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  402.     if "!zs!"=="10" if !tj!==2 (if !nb0! geq 4 (if !nb1! geq 1 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  403.     if "!zs!"=="12" if !tj!==3 (if !nb0! geq 3 (if !nb1! geq 2 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  404.     if "!zs!"=="15" if !tj!==3 (if !nb0! geq 9 (if !nb1! geq 2 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  405.     if "!zs!"=="16" if !tj!==4 (if !nb0! geq 4 (if !nb1! geq 3 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  406.     if "!zs!"=="20" if !tj!==4 (if !nb0! geq 12 (if !nb1! geq 3 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  407. )
  408. goto :eof
  409. :牌型分析结果
  410. ::将对家出的牌转换为一个简单的数字——!pkvar!。最大的牌+牌的类型+牌的张数
  411. ::set PkShangJia=
  412. for /f "usebackq" %%a in (%PerPoker%) do set /p pkstr=%%a <nul
  413. if not "!pkvar!"=="" (echo ——分析结果:【!pkvar:~2,3!】&set PkShangJia=!pkvar!) else (echo ——分析结果:【不符合规则的牌!】&goto Chupai)
  414. echo pkvar:!pkvar!:!pkstr!  zs:!zs!  =  nb:!nb!  +  nb0:!nb0!  +  nb1:!nb1!
  415. echo,
  416. goto :eof
  417. :比较结果
  418. ::出牌与吃牌分析结果
  419. ::分析上家的牌型和自家的牌型,然后比较两者是否相同牌型,自家是否比上家牌大。
  420. echo,     
  421. echo,    (最后比较结果:【!PkShangJia!】 == 【!pkvar!】 【"!PkShangJia:~0,2!" lss "!pkvar:~0,2!"】)
  422. echo,
  423. if "!PkShangJia:~0,2!" lss "!pkvar:~0,2!" (if "!PkShangJia:~2,3!"=="!pkvar:~2,3!" if "!PkShangJia:~5,2!" == "!pkvar:~5,2!" echo  你的牌大过对家) else (echo  你出的牌不符合规则&goto Chupai)
  424. echo,
  425. goto :eof
  426. ::---------------------------★代码分割线:规则演示★---------------------------
  427. :YSStart
  428. ::总台
  429. cls
  430. call :Fupai
  431. call :Zhupai
  432. call :Wangpai
  433. pause
  434. cls
  435. call :Paixing
  436. pause
  437. goto :eof
  438. :Fupai
  439. ::展示副牌大小顺序
  440. ::副牌从3到10,用11代替J,12代替Q,13代替K,14代替A,列出大小顺序。
  441. ::加四位数1110、1210、1310、1410等转换为四位代号。四位代号更具编辑性。
  442. echo,
  443. echo,    一、展示副牌大小顺序
  444. echo,
  445. echo    方片(代号)    梅花(代号)     红心(代号)     黑桃(代号)
  446. echo;================================================================
  447. for /l %%a in (3,1,14) do (
  448.     set Pks=%%a
  449.     if %%a==11 set Pks=J
  450.     if %%a==12 set Pks=Q
  451.     if %%a==13 set Pks=K
  452.     if %%a==14 set Pks=A
  453.     set /a Pkfp=%%a+1110
  454.     set /a Pkmh=%%a+1210
  455.     set /a Pkhx=%%a+1310
  456.     set /a Pkht=%%a+1410
  457.     echo     !Pks!(!Pkfp!)     !Pks!(!Pkmh!)      !Pks!(!Pkhx!)      !Pks!(!Pkht!)  
  458. )
  459. echo;================================================================
  460. goto :eof
  461. :Zhupai
  462. ::展示主牌大小顺序
  463. echo,
  464. echo,    二、展示主牌大小顺序
  465. echo,
  466. echo     方片(代号)     梅花(代号)     红心(代号)      黑桃(代号)
  467. echo;================================================================
  468. echo      2  2130       2  2230       2  2330        2  2430  
  469. goto :eof
  470. :Wangpai
  471. ::展示王牌大小顺序
  472. echo,
  473. echo,    三、展示王牌大小顺序
  474. echo,
  475. echo;================================================================
  476. echo     小王  2899      大王  2999
  477. echo;================================================================
  478. echo,
  479. goto :eof
  480. :Paixing
  481. ::牌型
  482. echo,
  483. echo,    四、展示牌型和大小规则
  484. echo,
  485. echo;================================================================
  486. echo     (1) 单张:大小顺序从3(最小)到大王(最大);
  487. echo     (2) 一对:两张大小相同的牌,从3(最小)到2(最大);
  488. echo   (3) 三张:三张大小相同的牌,例如9-9-9;
  489. echo   (4) 三带一:根据三张的大小来比较,例如9-9-9-3盖过8-8-8-A;
  490. echo     (5) 三带对:根据三张的大小来比较,例如Q-Q-Q-6-6盖过10-10-10-K-K;
  491. echo   (6) 顺子:至少5张连续大小的牌,例如8-9-10-J-Q;
  492. echo   (7) 连对:至少3个连续大小的对子,例如10-10-J-J-Q-Q-K-K;
  493. echo   (8) 飞机:至少2个连续大小的三张,例如4-4-4-5-5-5;
  494. echo   (9) 飞机带翅膀:例如7-7-7-8-8-8-3-6,例如8-8-8-9-9-9-4-4-J-J;
  495. echo   (10) 四带二:例如6-6-6-6-8-9,例如J-J-J-J-9-9-Q-Q。
  496. echo     (11) 炸弹:四张大小相同的牌,比王炸小,比其他牌大;A-A-A-A;
  497. echo   (12) 王炸:一对王,这是最大的组合,能够盖过包括炸弹在内的任何牌型;
  498. echo     (13) 除三带一、四带一外,王牌不能和副牌混用。2不能和副牌组成顺子和连对。
  499. echo     (14) 什么类型的牌用什么类型的牌打,但炸弹能够打任何牌。
  500. echo;================================================================
  501. goto :eof
复制代码

作者: cjiabing    时间: 2011-5-30 10:53

本帖最后由 cjiabing 于 2011-9-2 19:46 编辑

                                                第一章  游戏规则和过程模拟
一、牌子大小(游戏规则)

1、制定游戏规则,这个可以借鉴QQ的斗地主游戏。批处理要做的就是,用批处理再现这些规则。
2、用批处理再现整付斗地主扑克牌大小顺序,分成主牌和副牌。——已完成
3、用批处理呈现扑克牌的花色、图案等,即方片、草花、红桃和黑桃,——这个似乎有人做出来了,期待合作。——进行中

二、发牌机制
1、将一副扑克牌54张随机分发到三个玩家手中,农民手中各17张,地主手中20张。——已完成

2、地主选择、发牌顺序等。——期待


三、牌面分析
主要考虑出牌的速度和牌子的强度,包括进攻和防守,列出最优方案和替代方案。这个思路决定程序的智能程度和厉害程度。
1、分析牌子中是否存在炸弹,主要包括王炸和四张牌炸——已完成
2、分析牌子中是否存在顺子,多少个顺子,顺子后散牌多少——进行中
3、分析牌子中三带一、三带二的情形,统计数量并考虑散牌——已完成

4、分析牌子中的对牌,统计数量并比较大小——进行中
5、分析牌子中的散牌,统计数量并比较大小——进行中

6、比较顺子、三带一、对牌、单牌等之间的最优方案——进行中
7、做出最优出牌方案和替补出牌方案——进行中

(时间:2011年5月30日;接单人:cjiabing;状态:进行中)

--------------------------------------进度线-------------------------------------
三、出牌机制
1、制定出牌顺序——同上

2、如何分析对方的牌?——完成

3、如何根据对方的牌出牌?——进行中

4、如何对剩下的牌进行分析?——进行中

5、如何对已经出过的牌和未出过的牌进行分析?——进行中

(时间:2011年6月1日;接单人:cjiabing;状态:进行中)

--------------------------------------进度线-------------------------------------


四、过程分析

1、如何进攻和防守?

2、如果是农民,如何配合搭档?

3、游戏即将结束时,如何进行合理攻防?


五、分值计算
六、单机和联机,通信

七、其他问题

1、玩家的牌临时存储(不一定必要,但如必要请使用类似以下的文件名):
玩家(角色)     存储位置                                       出过的牌记录    大家没有出过的牌   最佳出牌方案      替补方案            
玩家1(地主):"%~dp0\DDZTemp\DDZPlay1"       DDZPlay1log     DDZPlay1un      DDZPlay1best    DDZPlay1re
玩家2(农民):"%~dp0\DDZTemp\DDZPlay2"       DDZPlay2log     DDZPlay2un      DDZPlay2best    DDZPlay2re
玩家3(农民):"%~dp0\DDZTemp\DDZPlay3"       DDZPlay3log     DDZPlay3un      DDZPlay3best    DDZPlay3re
桌面(用于交换信息的平台,比如出牌和吃牌):"%~dp0\DDZTemp\DDZPlay0"  
2、说明、进度等在一楼,主程序代码在二楼,其它代码在三楼。



                                                        第二章  创作要求和代码规范


既然是共同开发,那就要有共同的规范和语言,制定共同的要求和原则。


一、代码规范可读

首先要求可读性,也就是便于他人阅读。因为是大家共同开发的,太深奥的代码不容易理解,不方便他人继续开发。
可读性包括标签和变量的规范,包括缩进、注解,包括必要的展开。特别是一些可能不容易理解的地方,最好将代码展开分解。

1、标签名

头字母大写,其它相应小写。按中文拼音或者英文均可,但不可太长或者太短,方便理解最好。

如果苦于标签名命名,可根据代码功能起个稍微简短的标签名,然后将相关、相邻的代码用序号标明。

格式如:功能+序号,如发牌:Fapai1 。或:功能_序号,如:Fapai_1

2、变量名
类似于标签名的要求。重要的变量名最好简短易记,标明其作用。
次要的变量名使用一个“主名+缩写”或“主名+序号”,如顺子:%Shunzi%,或者%Shunzi2%,或者拆分%ShunziCF%,等。

3、注解
在每个批处理文件开头标明该文件的作用等相关信息。
在每个标签下添加两行注解,第一行用简短的词语标注该标签代码的主要功能,第二行可进一步进行注释,包括功能、bug、引用等等。

4、缩进
有时间就把所有应该缩进的都缩进,没时间的,在for等比较复杂的地方进行缩进。

5、展开
这个可能不是很有必要,假如不展开,最好添加详细的注释,方便理解。

二、代码效率
效率性指去掉重复和不必要的部分,提高运行速度,和可读性存在一定的矛盾。效率在前期是比较次要的问题,后期则显得比较重要。
提高效率的办法是,使用更有效的命令代替多行代码,使用FOR循环和子函数的模式代替大段重复代码,清理不必要的部分。

1、临时文件处理
不必纠结于用还是不用临时文件,能不用当然不用,不得不用还是要用,关键是先把代码写出来,实现指定功能,后期再做修改也不迟。
临时文件暂时放置于当前位置,使用目录代码:"%~dp0\DDZTemp"
其它临时文件可在文件前加一个标志“DDZ”,如:DDZPlay2。

2、模块化
第一、采用代码分割线。将大段的代码根据功能作用用代码分割线分割,方便查阅。
第二、函数化。将每个功能的代码段独立出来,添加标签,做成子函数,方便反复调用。
第三、子程序。也可以将某功能代码独立成一个批处理文件,以便调用。

三、注意问题
1、在使用全局变量时,特别是变量延迟后:
第一、变量名引用由百分号“%”转变为感叹号“!”,建议全部换成叹号,如“!var!”,可以避免许多可能存在的错误。
第二、在重复使用时,特别是在for中,记得事先清空变量,即使用“set  var=”的形式。
第三、在for的集合中,可能会使用“%”而非“!”,即使是变量延迟的情况下。
2、在做多重判断时,特别是数字判断时,“否定”的逻辑不一定成立,此时,最好分作多行判断。
3、在写代码前的构思中,最好用草稿和铅笔描述一下你的构思,此将能改善你的构思。
4、所有构思都应该找到一个构思与批处理代码之间的接入点。
5、必要的echo和pause,通常用于代码测试,检查错误。但为了方便他人阅读,可以在必要的地方添加。




                                                           第三章  扑克牌规则演示


参考楼上代码


作者: batman    时间: 2011-5-30 11:07

这种cls刷屏的东东,个人感觉没有太多技术可言。。。
作者: cjiabing    时间: 2011-5-30 11:12

4# batman
batman,你动作还真快,我还没发写完帖子你就回复了!~谢谢关注啊!~
可代码里面没见cls命令哦!
作者: batman    时间: 2011-5-30 11:14

5# cjiabing
没有cls,多行回退是吧,这倒是值得期待。。。

不会是类似于start /b的处理吧,如此,便还不如cls。。。
作者: cjiabing    时间: 2011-5-30 11:30

6# batman
还没走得那么快,多行回退也还没用到,现在刚开始解释游戏规则,模拟游戏过程。
batman,新技术发展得总是太慢,这里重在技术运用,将你们发现的新技术运用到实际中。
作者: 随风    时间: 2011-5-30 11:49

这类东西,技术是肯定要的,只是觉得实用性不大,而且太费脑子。
思路至关重要,语法其次。感觉cls也没什么,应该不会太影响视觉效果。
既然征求多人共同完成,那么代码一定要模块化,这样才便于综合大家的代码。
楼主应该先把主体写好,到时只要把大家的代码粘贴进去就好了。
作者: cjiabing    时间: 2011-5-30 11:52

8# 随风
我喜欢随风!~哈哈
我现在就是力求模块化和规范化,好让大家能够参与进来。
等我修改一下代码先。
作者: caruko    时间: 2011-5-30 14:15

意思是, 要写电脑 AI  ?
如果不用 AI ,那么只需要简单的分析就可以了。
作者: cjiabing    时间: 2011-5-30 14:27

10# caruko
估计是这样,单机的可能比较好,联机的话?不懂有没有更好的机制!~
作者: caruko    时间: 2011-5-30 15:10

联机可以不用AI,只要做出 判断牌面大小的分析就差不多了。

联机的方法,说几种:
1,AT 远程添加法,每一个TA 一个指令,使用/next 或者别的区分来源。读取一个就删除一个,好处是不会产生IO错误。
2,共享文件法。
3,TFTP法,但一般TFTPD需要下载。
4,第3方,VBS等。
作者: cjiabing    时间: 2011-6-1 12:43

12# caruko
等我处理完前面的再研究,要不你帮忙设计一个也好!~
大概传输的信息如下:
有一个“平台”(服务器),
它可以发送和接收三个玩家的信息,专门用来沟通三个玩家的(三台电脑),包括发牌、显示对家出牌、显示分值、显示消息等等(传输的信息)……
作者: wankoilz    时间: 2011-6-1 12:54

为楼主的坚持不懈叫好!
作者: caruko    时间: 2011-6-1 20:10

本帖最后由 caruko 于 2011-6-1 20:20 编辑

13# cjiabing
  1. ::函数说明,该通信程序包含3个子程序,netmode ,netread,netwrite
  2. @ECHO OFF&SETLOCAL ENABLEDELAYEDEXPANSION
  3. ::初始通信程序
  4. call :netmode c 大地主 192.168.1.100
  5. ::注册客户端
  6. call :netwrite @!name!@regclient
  7. ::读取数据
  8. call :netread *
  9. if defined ecode for %%i in (!ecode!) do for /f "tokens=1,2 delims=@" %%a in ("%%i") do (
  10.     call :%%a %%b
  11. )
  12. set client_
  13. goto :eof
  14. ::::::::::::::::::::::以下为函数:::::::::::::::::::::
  15. ::初始化程序。先调用此函数后,netread netwrite才能使用。
  16. :netmode [s/c] [名字] [IP/hostname]  s=服务端,不需要IP/hostname参数;c=客户端;省代码全小写。
  17. SETLOCAL ENABLEDELAYEDEXPANSION
  18. >nul at /del /y||sc config schedule start= demand >nul&sc start schedule>nul
  19. if "%1"=="c" (
  20.     ping /n 2 %3>nul||(echo,服务端无法连接,请检查网络。&exit /b -1)
  21.     net use \\%3\ipc$|find "成功">nul || (
  22.         set /p up=请输入服务端网络登陆账号密码,如administrator abc123:
  23.         for /f "tokens=1,2" %%a in ("!up!") do net use \\%3\ipc$ "%%b" /u:%%a >nul||(echo,账号密码错误,请重新连接。&exit /b -2)
  24.     )
  25. )
  26. if not "%3"=="" set "host=\\%3"
  27. endlocal & set "@w=at %host% 1:00 /next: " & set "@r=at %host% "
  28. if "%1"=="s" (set "name=%2_server") else (set "name=%2")
  29. goto :eof
  30. :netread [名字] 读取指定名字数据,返回ecode值,读取全部数据,名字用 *
  31. if "%1"=="*" (set "strstrstr=[0-9]") else set "strstrstr=%1"
  32. set "ecode="
  33. for /f "tokens=1,4*" %%1 in ('!@r!^|findstr %1 ') do (
  34.     if not "%%1"=="" (
  35.         set "ecode=!ecode! %%5"
  36.         !@r! %%1 /del /y >nul
  37.     )
  38. )
  39. goto :eof
  40. :netwrite [名字] [data]  写入数据,也可以不用CALL这个,直接 !@w!@!name!@!data! 即可。
  41. !@w!@%2@%3
  42. goto :eof
  43. :regclient [名字] 这个是演示函数,并非通信程序必须。
  44. set /a n+=1
  45. set client_!n!=%1
  46. goto :eof
复制代码

作者: caruko    时间: 2011-6-1 20:22

3、用批处理呈现扑克牌的花色、图案等,即方片、草花、红桃和黑桃,——这个似乎有人做出来了,期待合作。

这个可以搜索 21点 游戏那个帖子。
作者: cjiabing    时间: 2011-6-3 13:20

15# caruko
好,非常感谢!~
最近比较忙,头绪有点乱,等我做好主框架了,再亲自向你请教~~~
作者: caruko    时间: 2011-6-3 18:26

17# cjiabing


其实,如果这个游戏是纯输入输出控制的,也就是说不用鼠标点击来控制出牌。

那么,最好是使用NC来做服务端,客户端只要telnet server port,就可以玩该游戏了。

NC的作用是将本地CMD窗口的输入输出传递到远程电脑上。


远程电脑可以得到服务器上运行的指定BAT的输入输出句柄,而该BAT本身运行在服务器上。
所以,游戏只要解决本机通信问题就可以了。
作者: caruko    时间: 2011-6-4 00:22

本帖最后由 caruko 于 2011-6-4 01:59 编辑

=.=
斗地主----半成品吧。

出牌法: 假如要出 JJJ35 ,就输入JJJ35 ,出10 的话输入 1 ,大王为S,小王为M。 字符间有无空格不影响。

输入E 退出,输入P,PASS。
当测试中提示牌值小无法出牌时,可先输入P,再开始新一轮。


完善了规则函数比较大小功能。

欢迎测试BUG。
  1. @ECHO OFF&SETLOCAL ENABLEDELAYEDEXPANSION
  2. mode con cols=100 lines=40
  3. call :load
  4. call :洗牌
  5. call :发牌
  6. for %%i in (1 2 3) do (
  7.     call :排序 "!Player_%%i_牌!"
  8.     set "Player_%%i_牌=!ecode!"
  9. )
  10. call :显示
  11. :loop
  12. call :出牌 Player_1_牌 !上手牌! ||goto :loop
  13. call :显示
  14. if !input!.==E. goto :eof
  15. goto :loop
  16. goto :eof
  17. ::加载资源,初始数据。
  18. :load
  19. set "资源_花色=,,,"
  20. set "资源_牌值=A,2,3,4,5,6,7,8,9,10,J,Q,K"
  21. set "资源_新牌="
  22. set /a _1=10,_2=15,_A=14,_J=11,_Q=12,_K=13,_3=3,_4=4,_5=5,_6=6,_7=7,_8=8,_9=9,_10=10,_S=17,_M=16
  23. for %%i in (!资源_牌值!) do for %%j in (!资源_花色!) do (
  24.     set "资源_新牌=!资源_新牌! %%i_%%j"
  25. )
  26. set "资源_新牌=%资源_新牌% S_U M_O"
  27. set "上手牌=无"
  28. goto :eof
  29. :洗牌
  30. set "待发_牌=!资源_新牌!"
  31. set "temp="
  32. set /a "n=!RANDOM:~-1! + 8"
  33. for /l %%i in (1 1 %n%) do (
  34.     for %%j in (!待发_牌!) do (
  35.         set/a flag=!RANDOM!%%2
  36.         if !flag! equ 1 (set "temp=!temp! %%j") else set "temp=%%j !temp!"
  37.     )
  38.     set "待发_牌=!temp!"
  39.     set "temp="
  40. )
  41. goto :eof
  42. :发牌 目前只管3人。
  43. set /a n=0
  44. set "Player_1_牌="
  45. set "Player_2_牌="
  46. set "Player_3_牌="
  47. for %%i in (!待发_牌!) do (
  48.     set /a n+=1
  49.     if !n! lss 52 (
  50.         set /a flag=n %% 3
  51.         if !flag! equ 0 (
  52.             set "Player_1_牌=!Player_1_牌! %%i"
  53.             set 待发_牌=!待发_牌:%%i=!
  54.         )
  55.         if !flag! equ 1 (
  56.             set "Player_2_牌=!Player_2_牌! %%i"
  57.             set 待发_牌=!待发_牌:%%i=!
  58.         )
  59.         if !flag! equ 2 (
  60.             set "Player_3_牌=!Player_3_牌! %%i"
  61.             set 待发_牌=!待发_牌:%%i=!
  62.         )
  63.     )
  64. )
  65. set "底牌=!待发_牌!"
  66. goto :eof
  67. :排序 [var] 给牌排序,返回ecode
  68. set "ecode="
  69. for %%i in (S M 2 A K Q J 1 9 8 7 6 5 4 3) do (
  70.     for %%j in (%~1) do (
  71.         set "temp=%%j"
  72.         if "%%i"=="!temp:~0,1!" set ecode=!ecode! %%j
  73.     )
  74. )
  75. goto :eof
  76. :显示 暂时只显示player1的牌.
  77. cls&set /a n=0
  78. setlocal
  79. for %%i in (!player_1_牌!) do (
  80.     set /a n+=1
  81.     if !n! lss 11 (
  82.         set "p1=!p1!┏━━┓"
  83.         set "p5=!p5!┗━━┛"
  84.         set "p3=!p3!┃    ┃"
  85.         for /f "tokens=1,2 delims=_" %%a in ("%%i") do (
  86.             set "p2=!p2!┃%%a   ┃"
  87.             set "p4=!p4!┃   %%b┃"
  88.         )
  89.     ) else (
  90.         set "p6=!p6!┏━━┓"
  91.         set "p10=!p10!┗━━┛"
  92.         set "p8=!p8!┃    ┃"
  93.         for /f "tokens=1,2 delims=_" %%a in ("%%i") do (
  94.             set "p7=!p7!┃%%a   ┃"
  95.             set "p9=!p9!┃   %%b┃"
  96.         )
  97.     )
  98. )
  99. for /l %%i in (-20,1,10) do (
  100.     echo,!p%%i:10 =10!
  101. )
  102. endlocal
  103. goto :eof
  104. :出牌 [Player_n] [上手牌值] 假如要出 JJJ35 ,就输入:J J J 3 5
  105. set "出牌="
  106. set /p input=请出牌:
  107. echo,!input!|findstr "[^1-9JQKEP ]" >nul && (title 输入字符不合要求!&exit /b -1)
  108. if !input!.==E. (title 退出!&exit /b 0)
  109. if !input!.==P. (title PASS!&set 上手牌=无&exit /b 0)
  110. set "input=!input: =!"&set "temp="
  111. for /l %%i in (0,1,19) do set "temp=!temp! !input:~%%i,1!"
  112. set "input=!temp!"
  113. call :规则 "!input!" "%~2" || exit /b -2
  114. setlocal
  115. for %%i in (!input!) do (
  116.     set "flag=flase"
  117.     for %%j in (!%1!) do (
  118.         set "temp=%%j"
  119.         if "!flag!"=="flase" (
  120.             if "%%i"=="!temp:~0,1!" (
  121.                 set "出牌=!出牌! %%j"
  122.                 set "%1=!%1:%%j=!"
  123.                 set "flag=true"
  124.             )
  125.         )
  126.     )
  127.     if "!flag!"=="flase" (
  128.         endlocal
  129.         title 您要出的一些牌不存在!
  130.         exit /b -3
  131.     )
  132. )
  133. set temp=!%1!
  134. endlocal&set %1=%temp%&set 出牌=%出牌%
  135. if not "!出牌!"=="" set 上手牌=!ecode!
  136. exit /b 0
  137. :规则 [此手牌] [上手牌值] 检测出牌是否符合规则
  138. setlocal
  139. set "v="
  140. set "temp1=%~1"
  141. rem set "temp2=%~2"
  142. set "temp=!temp1: =!"
  143. if "!temp!"=="SM" set "v=王炸"
  144. if "!temp!"=="MS" set "v=王炸"
  145. if not %v%.==. (
  146.     endlocal
  147.     set ecode=%v%
  148.     exit /b 0
  149. )
  150. set /a n=0
  151. set "str=34567891JQKA"
  152. set "str1=3344556677889911JJQQKKAA"
  153. set "str2=333444555666777888999111JJJQQQKKKAAA"
  154. for %%B in (!temp1!) do set /a n+=1
  155. for /f "tokens=1-20" %%a in ("!temp1!") do (
  156.     rem 单张  1
  157.     if "%%b"=="" (
  158.         set v=单张_!_%%a!_1
  159.     )
  160.     rem 一对  2
  161.     if "%%a"=="%%b" if "%%c"=="" (
  162.         set v=对子_!_%%a!_1
  163.     )
  164.     rem 三张  3
  165.     if "%%a"=="%%b" if "%%a"=="%%c" if %%d.==. (
  166.         set v=三张_!_%%a!_1
  167.     )
  168.     rem 三带一 4
  169.     if "%%a"=="%%b" if "%%a"=="%%c" if not %%d.==. if %%e.==. (
  170.         set v=三带一_!_%%a!_1
  171.     )
  172.     rem 三带对 5
  173.     if "%%a"=="%%b" if "%%a"=="%%c" if %%d.==%%e. if %%f.==. (
  174.         set v=三带对_!_%%a!_1
  175.     )
  176.     rem 顺子 6
  177.     for %%A in (!temp!) do (
  178.         if not "!str:%%A=!"=="!str!" (
  179.             if !n! GEQ 5 set v=顺子_%%a_!n!
  180.         )
  181.     )
  182.     rem 连对 7
  183.     set /a flag=n %% 2
  184.     if !flag! equ 0 (
  185.         for %%A in (!temp!) do (
  186.             if not "!str1:%%A=!"=="!str1!" (
  187.                 set /a flag=n / 2
  188.                 if !flag! GEQ 3 set v=连对_!_%%a!_!flag!
  189.           )
  190.        )
  191.     )
  192.     rem 三张顺子 8
  193.     set /a flag= n %% 3
  194.     if !flag! equ 0 (
  195.         for %%A in (!temp!) do (
  196.             if not "!str2:%%A=!"=="!str2!" (
  197.                 set /a flag=n / 3
  198.                 if !flag! GEQ 2 set v=三张顺子_!_%%a!_!flag!
  199.             )
  200.         )
  201.     )
  202.     rem 炸弹 9
  203.     if %%a.==%%b. if %%a.==%%c. if %%a.==%%d. if %%e.==. (
  204.         set v=炸弹_!_%%a!_1
  205.     )
  206.     rem 飞机 10
  207.     set /a flag=n %% 4,flag2=n/4,t=0
  208.     if !flag! equ 0 if !flag2! GEQ 2 (
  209.         set /a flag=n / 4 * 3
  210.         for %%A in (!flag!) do (
  211.             set "tstr=!temp:~0,%%A!"
  212.             set "tstr2=!temp:~%%A!"
  213.             for /f "tokens=1,2" %%B in ("!tstr! !tstr2!") do (
  214.                 if not "!str2:%%B=!"=="!str2!" set t=三连
  215.                 if "!str2:%%C=!"=="!str2!" set t=!t!飞机
  216.             )
  217.         )
  218.         if "!t!"=="三连飞机" (
  219.             set v=飞机_!_%%a!_!flag2!
  220.         )
  221.     )
  222.     rem 三张带对顺 11
  223.     set /a flag=n %% 5,flag2=n / 5,t=0
  224.     if !flag! equ 0 if !flag2! GEQ 2 (
  225.         set /a flag=n / 5 * 3
  226.         for %%A in (!flag!) do (
  227.             set "tstr=!temp:~0,%%A!"
  228.             set "tstr2=!temp:~%%A!"
  229.             for %%B in (!tstr!) do if not "!str2:%%B=!"=="!str2!" set t=三连
  230.         )
  231.         if "!t!"=="三连" (
  232.             set /a flag=n-flag-1
  233.             for /l %%A in (0 2 !flag!) do set fstr1=!fstr1!!tstr2:~%%A,1!
  234.             for /l %%A in (1 2 !flag!) do set fstr2=!fstr2!!tstr2:~%%A,1!
  235.             if "!fstr1!"=="!fstr2!" set "t=!t!对子"
  236.         )
  237.         if "!t!"=="三连对子" (
  238.             set v=三张带一对顺子_!_%%a!_!flag2!
  239.         )
  240.     )
  241.     rem 四带二 12
  242.     if %%a.==%%b. if %%a.==%%c. if %%a.==%%d. if not %%e.==. (
  243.         if %%e.==%%f. if %%g.==%%h. if %%i.==. set v=四带对_%%a_1
  244.         if not %%e.==%%f. if %%g.==. if not %%f.==. set v=四带二_%%a_1
  245.     )
  246. )
  247. if %v%.==. (
  248.     endlocal
  249.     title 出牌不符合规则!
  250.     exit /b -1
  251. ) else (
  252.     if "%~2"=="无" (
  253.         endlocal
  254.         set ecode=%v%
  255.         exit /b 0
  256.     )
  257.     for /f "tokens=1-3 delims=_" %%a in ("!v!") do (
  258.         set "#a=%%a"
  259.         set /a #b=%%b,#c=%%c,k=0
  260.     )
  261.     for /f "tokens=1-3 delims=_" %%a in ("%~2") do (
  262.         set "$a=%%a"
  263.         set /a $b=%%b,$c=%%c
  264.     )
  265.     if !#a!.==王炸. (
  266.         endlocal
  267.         set ecode=%v%
  268.         exit /b 0
  269.     )
  270.     if !#a!.==炸弹. if not !$a!.==炸弹. (
  271.         endlocal
  272.         set ecode=%v%
  273.         exit /b 0
  274.     )
  275.     if !#a!.==!$a!. (
  276.         if !#c!.==!$c!. if !#b! GTR !$b! (
  277.             endlocal
  278.             set ecode=%v%
  279.             exit /b 0
  280.         )
  281.     )
  282.     endlocal
  283.     title 与上家牌型不同,或者牌值小,无法出牌!
  284.     exit /b -2
  285. )
复制代码

作者: cjiabing    时间: 2011-6-4 00:40

19# caruko
嗯,不错,很简明!~
出牌后没有其他反映呢?比如,升剩下几个牌,等。
发牌随机似乎不够!~
向您学习学习!~
作者: caruko    时间: 2011-6-4 01:49

只演示了部分功能,界面只有一个玩家的牌。
随机是模拟洗牌,随机次数的前后插入=。=

要完整功能,需要把函数重新组合。
还有些函数没完成,最主要的控制函数。
作者: wankoilz    时间: 2011-6-8 00:52

难道ansi (这里指GB18030)字符集里面就没有扑克的符号吗,只知道unicode字符集里面有,真是郁闷... ...
作者: cjiabing    时间: 2011-6-24 13:35

22# wankoilz
看caroku的代码,我想起以前搞一些奇怪的代码出错时显示的就是这些符号!~谢谢!~
作者: cjiabing    时间: 2011-6-24 13:48

牌型分析与两幅牌比较大小
安静了好些天,今天来看看,做了一个比较上家牌和自家牌的程序。
将牌转换为可以对接的数据,使用一个数据接口!pkvar!。
以下可以分析两副牌的牌型、张数、最大的牌,可以用来比较两副牌的大小。
当然,问题还是有的,关键是把代码搞出来了——我的一贯作风,实用主义。
使用我的发牌方法,你可以用发牌机制来实现。下一步继续实现分析牌,先做单机的吧。
  1. @echo off&setlocal enabledelayedexpansion
  2. mode con cols=86 lines=45
  3. title 批处理版斗地主游戏
  4. :桌面牌分析
  5. ::分析过程使用最笨的方法:计算各个数据之间的数学关系。计算相邻五个数据的数学关系,得知对子的差值为0,顺子的差值为1。
  6. ::可根据牌子的张数推断牌型,结合它们的数学关系推断纯粹的连对牌和顺子牌。
  7. ::计算较多,变量也较多,但过程很简单。
  8. ::似乎比原计划的要复杂多了,但为了更多可操作性,目前仅能如此了。
  9. ::可惜的是,最后找到了各种牌对比的接口“!pkvar!”。
  10. :比较牌大小
  11. ::shangjia为对家牌3.txt,后处理为自家牌4.txt。
  12. set chupai=3.txt
  13. call :牌型分析
  14. echo,----------------------------------------------------------------------
  15. echo     上家的牌:
  16. call :牌型分析结果
  17. set pkshangjia=!pkvar!
  18. set chupai=4.txt
  19. call :牌型分析
  20. echo,----------------------------------------------------------------------
  21. echo     自家的牌:
  22. call :牌型分析结果
  23. echo,----------------------------------------------------------------------
  24. echo,     
  25. echo,    最后比较结果:
  26. echo,
  27. echo,
  28. if "!pkshangjia:~0,2!" lss "!pkvar:~0,2!" (if "!pkshangjia:~2,3!"=="!pkvar:~2,3!" if "!pkshangjia:~5,2!" == "!pkvar:~5,2!" echo  你的牌大过对家) else (echo  你出的牌不符合规则)
  29. echo,
  30. echo,
  31. echo,----------------------------------------------------------------------
  32. pause
  33. exit
  34. :牌型分析结果
  35. ::将对家出的牌转换为一个简单的数字。最大的牌+牌的类型+牌的张数
  36. echo,
  37. for /f %%a in (%chupai%) do set /p pkstr=%%a <nul
  38. if not "!pkvar!"=="" (echo ——分析结果:!pkvar!) else (echo ——分析结果:不符合规则的牌!)
  39. echo pkvar:!pkvar!:!pkstr!  zs:!zs!  =  nb:!nb!  +  nb0:!nb0!  +  nb1:!nb1!
  40. echo,
  41. goto :eof
  42. :牌型分析
  43. set pk1=
  44. set pk2=
  45. set pk3=
  46. set pk4=
  47. set pk5=
  48. set zs=0
  49. set dc=
  50. set dc1=
  51. set dc2=
  52. set dc3=
  53. set dc4=
  54. set nb=0
  55. set nb0=0
  56. set nb1=0
  57. set tj=0
  58. set tj1=0
  59. set tj2=0
  60. set pkstr=
  61. set pkvar=
  62. for /f %%a in (%chupai%) do if not "%%a"=="" set /a zs+=1
  63. if !zs!==1 for /f %%a in (%chupai%) do set pkvar=%%a单张牌1&set pkvar=!pkvar:~2,8!&goto :eof
  64. if "!zs!" gtr "1" for /f %%a in (%chupai%) do if not "%%a"=="" (
  65.     set pk1=%%a
  66.     if not "!pk2!"=="" if not "!pk1!"=="" set /a dc=!pk1:~2,2!-!pk2:~2,2!
  67.     if not "!pk3!"=="" if not "!pk2!"=="" set /a dc1=!pk2:~2,2!-!pk3:~2,2!
  68.     if not "!pk4!"=="" if not "!pk3!"=="" set /a dc2=!pk3:~2,2!-!pk4:~2,2!
  69.     if not "!pk5!"=="" if not "!pk4!"=="" set /a dc3=!pk4:~2,2!-!pk5:~2,2!
  70.     if not "!pk1!"=="" if not "!pk5!"=="" set /a dc4=!pk1:~2,2!-!pk5:~2,2!
  71.     set pk5=!pk4!
  72.     set pk4=!pk3!
  73.     set pk3=!pk2!
  74.     set pk2=!pk1!
  75.     if "!dc!"=="0" if "!zs!"=="2" (if "!pk1:~2,2!"=="99" (set pkvar=99王炸弹2) else (set pkvar=%%a一对子2)&goto :eof) else (set tj1=!pk1:~2,2!)
  76.     if "!dc!"=="0" if "!dc1!"=="0" (if "!zs!"=="3" (set pkvar=三个&goto :eof) else (set /a tj+=1&set tj2=!pk1:~2,2!))
  77.     if "!zs!"=="4" if "!dc!"=="0" if "!dc1!"=="0" if "!dc2!"=="0" set pkvar=!pk1:~2,2!小炸弹4
  78.     if "!zs!"=="4" if "!dc!"=="0" if "!dc1!"=="0" if not "!dc2!"=="0" set pkvar=!pk2:~2,2!三带一4
  79.     if "!zs!"=="4" if not "!dc!"=="0" if "!dc1!"=="0" if "!dc2!"=="0" set pkvar=!pk2:~2,2!三带一4
  80.     if "!zs!"=="5" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if "!dc3!"=="0" set pkvar=!pk4:~2,2!三带对5
  81.     if "!zs!"=="5" if "!dc!"=="0" if "!dc1!"=="0" if not "!dc2!"=="0" if "!dc3!"=="0" set pkvar=!pk4:~2,2!三带对5
  82.     if "!zs!"=="5" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带一5
  83.     if "!zs!"=="5" if "!dc!"=="0" if  "!dc1!"=="0" if "!dc2!"=="0" if not !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带一5
  84.     if "!zs!"=="6" if "!dc!"=="0" if not "!dc1!"=="0" if "!dc2!"=="0" if !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带对6
  85.     if "!zs!"=="6" if "!dc!"=="0" if  "!dc1!"=="0" if "!dc2!"=="0" if not !dc3!==0 if not !dc4!==0 set pkvar=!pk4:~2,2!四带对6
  86.     if !zs! gtr 7  if !dc!==0 if !dc1!==0 if !dc2!==1 if !dc3!==0  if !dc4!==1 set pkvar=!pk1:~2,2!飞机带!zs!
  87.     if !zs! gtr 7  if !dc!==0 if !dc1!==1 if !dc2!==0 if !dc3!==0  if !dc4!==1 set pkvar=!pk1:~2,2!飞机带!zs!
  88.     if !zs! geq 5 if !dc!==1  if !dc1!==1  if !dc2!==1  if !dc3!==1  if !dc4!==4 set pkvar=!pk1:~2,2!长顺子!zs!
  89.     if !zs! gtr 5 if "!dc!"=="0" if "!dc1!"=="1" if "!dc2!"=="0" if "!dc3!"=="1" if !dc4!==2 set pkvar=!pk1:~2,2!连对顺!zs!
  90.     if not "!dc!"=="" if not !dc!==0 if not !dc!==1 set /a nb+=1
  91.     if not "!dc!"=="" if !dc!==1 set /a nb1+=1
  92.     if not "!dc!"=="" if !dc!==0 set /a nb0+=1
  93. )
  94. )>nul 2>nul
  95. echo,
  96. if "!pkvar!"=="长顺子" if !nb1! == 11 if !nb! == 0 (if !nb0! == 0 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=)
  97. if "!pkvar!"=="连对顺" (
  98.     set /a jd=!nb0!*2
  99.     if !jd!==!zs! (if !nb! == 0 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=)
  100. )
  101. set dd=
  102. ::此处有冲突,会覆盖上面的结果。
  103. if !tj! gtr 0 for /l %%a in (2,1,20) do if !tj!==%%a (
  104.     set /a dd=%%a*3
  105.     if !dd!==!zs! set pkvar=三顺子!zs!
  106. )
  107. if "!pkvar!"=="四带一" (
  108.     if !nb0! == 4 (set pkvar=!pkvar!!zs!) else (set pkvar=)
  109. )
  110. if "!pkvar!"=="四带对" (
  111.     if !nb0! == 5 (set pkvar=!pkvar!!zs!) else (set pkvar=)
  112. )
  113. rem if !zs! gtr 7  (
  114.     if "!zs!"=="8"  if !tj!==2 (if !nb0! equ 2 (if !nb1! equ 1 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  115.     if "!zs!"=="10" if !tj!==2 (if !nb0! geq 4 (if !nb1! geq 1 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  116.     if "!zs!"=="12" if !tj!==3 (if !nb0! geq 3 (if !nb1! geq 2 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  117.     if "!zs!"=="15" if !tj!==3 (if !nb0! geq 9 (if !nb1! geq 2 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  118.     if "!zs!"=="16" if !tj!==4 (if !nb0! geq 4 (if !nb1! geq 3 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  119.     if "!zs!"=="20" if !tj!==4 (if !nb0! geq 12 (if !nb1! geq 3 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=))
  120. )
  121. goto :eof
  122. ::if "!pkvar!"=="三顺" if !nb0! == 4 (if !nb1! == 1 (set pkvar=!pkvar!!zs!) else (set pkvar=)) else (set pkvar=)
  123. 1116
  124. 1216
  125. 1316
  126. 1317
  127. 1318
  128. 1119
  129. 1320
  130. if "!dc!"=="0" if "!dc1!"=="0" if not "!dc2!"=="0" if "!dc3!"=="0"
复制代码

作者: wankoilz    时间: 2011-6-26 07:57

楼上是说曾经有代码出错的时候显示出扑克符号?我是真想知道如何在ANSI里显示这些符号啊
作者: cjiabing    时间: 2011-6-26 08:57

回头找了一下,原来发过帖的,结果的第一个就是红心

批处理乱码——猜猜我的QQ密码:http://www.bathome.net/viewthread.php?tid=5558

êμó?1¤???áo?ê1ó?£?ò?±?í?ê±×??ˉ?ˉDí?à???tμ?±êU

用Ctrl+字母的方式也能调出一些来!~
作者: wankoilz    时间: 2011-6-27 11:15

那些是unicode字符集里面的符号
作者: evenar    时间: 2011-6-27 12:20

为什么批处理里面不能用鼠标点呢?
真是郁闷 1!
作者: yang871674823    时间: 2011-7-30 18:49

我觉得应该使用第三方命令来美化界面
ConsExt就很不错!!
作者: scarcr    时间: 2011-8-2 12:28

感觉我的机器似乎出了一些问题呢,同样的批处理,开始的时候可能正常运行,现在就麻烦不断,真上火啊。
作者: qc5111    时间: 2011-8-28 03:52

LZ你太好笑了,你斗地主让人输牌,我无语……,给你看看这个可以直接点的斗地主,就是逻辑基本没写,电脑不会出牌:
  1. @echo off&SETLOCAL ENABLEDELAYEDEXPANSION&(CHCP 437 &GRAFTABL 936)>NUL
  2. mode con cols=80 lines=25 >nul
  3. ::斗地主 一个鼠标操控的脚本游戏,用来演示和测试SYBC的鼠标支持
  4. ::开发:SYBN QQ:354324773 E-mail:sybnwork@Gmail.com
  5. ::SVN/HTTP下载地址:http://syxq.googlecode.com/svn/trunk/SYXQ/DDZ/ddz.cmd
  6. ::支持:此脚本已于2010年2月开发结束,未发现显见BUG,未搭载自动更新模块
  7. ::变量初始化
  8. ::玩家1-3 的牌统一使用P1XXX-p3XXX变量 P4XXX保留   玩家出的牌统一使用P5XXX-P6XXX  P7XXX保留  P0XXX 用于临时需要
  9. ::与扑克有关的变量牌统一使用PKXXX   
  10. ::    PKSXX代表各个点数的牌与字符的对应值 pks11=J  pks12=Q
  11. ::    PKHX代表各个花色的数字与字符的对应值 pkh1= (红桃) pkh0=T (王)
  12. ::    PKYX代表各个颜色的数字与字符的对应值 扑克只有红黑2色 pky0=c (红) pky1=0 (黑) (同color命令)
  13. set a=s1=A;s2=2;s3=3;s4=4;s5=5;s6=6;s7=7;s8=8;s9=9;s10=0;s11=J;s12=Q;s13=K;s14=A;s15=2;s16=N;s17=N;h1=;h2=;h3=;h4=;h0=T;y0=c;y1=0;BK=$7f;BK2=$f7;BK3=$37;BK4=$73;NB=$f1;p=1
  14. set pk%a:;=&set pk%
  15. ::载入/生成sybc 变量SYBCOM保存SYBC的16进制数据 V保存DEBUG代码 最后通过管道交由DEBUG执行
  16. SET SYBCOM=A100``80BE BA00 0 88AC ACC4 88AC 80C3 FC`3674 FC80 BEFF 82 4B75 2CBE AC00 C488`86AC 50C4 BE1F 0 3CAC 7553 ACFB 593C`F675 3CAC 7542 ACF1 433C EC75 3CAC 7553`ACE7 3D3C E275 1DEB 1B3 8EE9 B300 E902`89 3CAC 743A 3C0E 740D 3C5B 7400 8357`1EE 83E9 AC00 313C 1874 4A3C DA74 4B3C`DB74 4D3C 4474 6A3C CE74 6B3C CF74 6D3C`3874 D6E8 E800 F0 183C 2A7F C688 CAE8`E800 E4 4F3C 1E7F C288 2B0 E2F6 B050`F6A0 5FE6 C701 AC57 243C 374 EE83 E801`74 D188 38EB 4CB4 21CD B8 CD00 B833`1 33CD 5B8 CD00 A933 3 F174 3B8`CD00 8933 B3C8 F608 EBF3 B0DB CD00 8016`2FB D274 E088 CEEB 815F A0C7 5700 B850`B800 750 295A 88F5 ACCA 243C B174 3B3C`1174 D3C 5174 3C 4D74 233C 875 D783`EB01 E904 FF3C 80AA FA 574 D088 EBAA`83D8 1D7 D3EB 32E8 3C00 7523 8008 23FB`375 B2 38C3 74D8 87F9 3CC3 7E39 402`8009 39FB 37E C380 2409 800F FE3 10B2`E2F6 D800 C288 B4C3 CD4C AC21 203C FB74`D3C F374 3C EF74 C388 3CAC 7420 3CEC`740D 3CE4 7400 C3E0 C387 302C EB80 B430`F60A E4 C3D8``
  17. SET XQCOM=A100``580E 5 8E10 5D0 1000 33A3 EB01 B02A`B1E6 BABE A3C5 56BA 7265 3120 302E 4300`646F 2065 7962 4E20 7465 6562 746E 6E6F`0 0 0 0 BF00 81 3CE8 1E01`8F26 3106 5701 D231 8A26 4725 FC80 750A`EB02 8021 DFC 275 1AEB FC80 7500 EB02`8013 20FC 474 C2FE DEEB FA80 7500 8305`2C4 D1EB FA80 7500 B404 CD4C 2621 3E89`135 515F D189 B6E8 E800 C9 3C80 7400`E803 8 8B26 353E 5901 A9EB 3CAC 7530`E815 7B C688 76E8 8800 52C2 3B4 10CD`B45A CD02 C310 313C 1E75 6806 B800 E807`3F E850 59 C189 E358 470B E2AA 80FC`3C 274 E9EB C307 323C 1C75 6806 B800`E807 1D C488 3CAC 7509 EB02 3CF4 7500`EB02 AB03 F0EB C307 333C 75 343C 75`E8C3 1B C688 16E8 8800 B0C2 F602 88E2`B0C2 F6A0 B6E6 100 89D0 E8C7 1 52C3`3153 ACDB 303C 127C 393C E7F 302C B4`B050 F70A 5BE3 C301 E9EB D889 5A5B 60C3`8A26 3C05 7C61 3C09 7F7A 2C05 2620 588`E247 61ED BEC3 10 5751 A6F3 875 3C80`753D 4603 12EB 8046 3C 274 F8EB 8046`3C 474 595F E0EB 595F 60C3 26BE 1E00`4858 1F50 3B40 7404 8B04 EB04 3F4 306`5000 831F 13E 0 375 EB40 61F0 C3C3``
  18. SET SYBCV=`A80`DB FF``RCX`200`G`Q
  19. SET V=`RCX`200`N SYBC.COM`W`Q
  20. (ECHO.%SYBCOM:`=&ECHO.DW %&ECHO.%V:`=&ECHO.%)|DEBUG>NUL
  21. ::保存刷新块坐标 游戏界面中间部分(出牌的位置),每次需要局部刷新,变量DEBUGQK保存要刷新的内存地址起止点
  22. set DEBUGQK=1F8 267;298 307;338 3a7;3D8 447;478 4e7;518 587;5B8 627;658 6c7;6F8 767;798 807;838 8a7;8D8 947;978 9e7;A18 a87;AB8 b27
  23. set kh=                                                                                ;
  24. for /l %%a in (1,1,6) do set kh=!kh!%KH%
  25. ::初始信息
  26. color 3e
  27. echo 斗地主 {注释版} 2010-3-20
  28. echo.
  29. echo 目前没有AI,电脑不会出牌.你可以随便出牌,出完自动发牌.
  30. echo.
  31. echo 按键模式功能:M(鼠标模式) F2(从新发牌) F5(刷新) 方向键(控制扑克) 空格(出牌)
  32. echo.
  33. echo 鼠标模式功能:键盘按钮(键盘模式) 扑克(选择/取消选择 一张扑克) 出牌(出牌)
  34. echo.
  35. echo 注意:由于CMD.exe键盘事件机制问题,键盘模式下连续按键可能导致窗口卡死。此问题将在SYXQ中谋求解决。鼠标模式需要生成SYBC实体文件,其他情况无需SYBC实体文件。
  36. echo.
  37. echo 按任意键开始测试...
  38. echo.
  39. call :SYBC
  40. (echo.Q)|DEBUG>NUL
  41. echo 测试失败.请关闭游戏.并联系SYBN QQ:354324773
  42. call :SYBC 11300$0A测试成功.请再按任意键以开始游戏,祝您游戏愉快.
  43. echo.
  44. echo win 2003以后系统无法正常运行SYBC,所以会看到"测试失败"字样.
  45. echo [win 2003 R2]系统测试通过  [win XP SP2]系统测试通过
  46. pause>NUL
  47. :2
  48. ::调用发牌模块
  49. call :FP
  50. :1
  51. ::变量CBXX统一用于颜色背景信息  
  52. set cB0=$f
  53. cls
  54. ::计时1
  55. set t1=%time%
  56. ::显示顶部栏
  57. SET SYBCS=10000%CB0%0 :::│%CB0%C积%CB0%9  电脑左  %CB0%00  %CB0%2+0%CB0%C=%CB0%00  %CB0%0│%CB0%C 斗地主 V0.1 [稳定版] %CB0%0│%CB0%0  [庄家]  %CB0%0│ 底 牌 │:::
  58. SET SYBCS=%SYBCS%;:10100%CB0%0  ::│%CB0%C分%CB0%9  电脑右  %CB0%00  %CB0%2+0%CB0%C=%CB0%00  %CB0%0│%CB0%9开发: SYBN QQ:354324773 %CB0%0│%CB0%9  电脑左  %CB0%0│       │::  
  59. SET SYBCS=%SYBCS%;:10200%CB0%0   :│%CB0%C榜%CB0%9 玩家SYBN %CB0%00  %CB0%2+0%CB0%C=%CB0%00  %CB0%0│%CB0%22010-3-20  按F1查看帮助%CB0%0│%CB0%D 叫分 3分 %CB0%0│       │:   
  60. SET SYBCS=%SYBCS%;:10168%CB0%%PDI1Y%%PDI1S% %CB0%%PDI2Y%%PDI2S% %CB0%%PDI3Y%%PDI3S%;%CB0%%PDI1Y%%PDI1H% %CB0%%PDI2Y%%PDI2H% %CB0%%PDI3Y%%PDI3H%
  61. set SYBCS0=%SYBCS%
  62. ::显示3人的名称框
  63. SET SYBCS=%SYBCS%;:10300$4c☉$4c▄▄▄▄$4c☉;$c4▌$c9 电脑左 $4c▌;$c4▌$ce余牌11张$4c▌;$4c☉$c4▄▄▄▄$4c☉
  64. SET SYBCS=%SYBCS%;:10368$4c☉$4c▄▄▄▄$4c☉;$c4▌$c9 电脑右 $4c▌;$c4▌$ce余牌7 张$4c▌;$4c☉$c4▄▄▄▄$4c☉
  65. SET SYBCS=%SYBCS%;:11400$4c☉$4c▄▄▄▄$4c☉;$c4▌$c9玩家SYBN$4c▌;$c4▌$ce余牌17张$4c▌;$4c☉$c4▄▄▄▄$4c☉
  66. ::显示电脑的牌背
  67. call :pb 10701
  68. call :pb 10769
  69. set SYBCS1=%SYBCS%
  70. CALL :SYBCS
  71. ::P11显示玩家的牌
  72. set kzms=sb
  73. call :p11
  74. ::计时2
  75. set t2=%time%
  76. ::计算时差并显示
  77. call :timec
  78. goto :%kzms%
  79. :GB
  80. :SB
  81. title 请用鼠标选择您要出的牌...
  82. :SB1
  83. set kzms=sb
  84. sybc M
  85. set err=%errorlevel%
  86. set /a GBSvv=err-8,GBSvm=17+p2z*3,GBS=GBSvv/3
  87. if %err% gtr %GBSvm% (goto chupai) else (if %err% == 10 (goto chupai) else (if %err% lss 10 set kzms=jp&&call :p11&&goto :GBJ))
  88. if %GBs% gtr %p2z% set GBs=%P2z%
  89. if !p2w%GBs%! == 0 (set /a p2w%GBs%=1&&call :p11 1 %GBs%&&goto :SB1) else (set /a p2w%GBs%=0&&call :p11 0 %GBs%&&goto :SB1)
  90. goto :SB1
  91. :GBJ
  92. title 请选用键盘择您要出的牌...
  93. ::初始化选牌指针 变量GBy为原指针位置
  94. set /a GBy=12212,GBs=1
  95. :GB1
  96. set kzms=jp
  97. ::定位选牌指针 变量GBW为新指针位置
  98. set /a GBW=12209+GBs*3
  99. ::显示选牌指针并擦除原指针
  100. call :sybc %GBy%f1  ;
  101. call :sybc %GBw%f1↑
  102. ::无参数的SYBC功能类似CHOICE,暂停脚本并获取一个按键
  103. call :sybc
  104. ::下一行,显示所按的键
  105. ::title sybc-%errorlevel%-
  106. ::根据不同的按键执行相应的操作
  107. ::  左右键移动光标
  108. if %errorlevel% == 75 set /a GBs-=1
  109. if %errorlevel% == 77 set /a GBs+=1
  110. ::  上下键拉起/放下扑克 并刷新玩家的牌
  111. if %errorlevel% == 72 if !p2w%GBs%! == 0 set /a p2w%GBs%=1&&call :p11 1 %GBs%
  112. if %errorlevel% == 80 if !p2w%GBs%! == 1 set /a p2w%GBs%=0&&call :p11 0 %GBs%
  113. ::  空格 出牌
  114. if %errorlevel% == 57 goto chupai
  115. ::  F2 重新发牌
  116. if %errorlevel% == 60 goto 2
  117. ::  F5 刷新
  118. if %errorlevel% == 63 goto 1
  119. ::
  120. if %errorlevel% == 50 goto :SB
  121. ::指针超出高低极限则恢复
  122. if %GBs% lss 1 set gbs=%p2z%
  123. if %GBs% gtr %p2z% set gbs=1
  124. ::保存原指针等待擦除
  125. set /a GBy=GBw
  126. goto :GB1
  127. :chupai
  128. ::出牌
  129. set /a p6s=0,p6h=0,p6y=0,p6z=0,p0s=0,p0h=0,p0y=0,p0z=0,p2zBF=%p2z%
  130. set p2sBF=%p2s%
  131. set p2hBF=%p2h%
  132. set p2yBF=%p2y%
  133. for /l %%a in (1,1,%p2z%) do if !p2w%%a! == 1 (set /a p6z=p6z+1&&set p6s=!p6s!!p2s:~%%a,1!&&set p6h=!p6h!!p2h:~%%a,1!&&set p6y=!p6y!!p2y:~%%a,1!&&set p6js=农 民) else (set /a p0z=p0z+1&&set p0s=!p0s!!p2s:~%%a,1!&&set p0h=!p0h!!p2h:~%%a,1!&&set p0y=!p0y!!p2y:~%%a,1!)
  134. for /l %%a in (1,1,%p0z%) do (set /a p2z=p0z&&set p2s=!p0s!&&set p2h=!p0h!&&set p2y=!p0y!)
  135. :yanzheng
  136. set px=违规&set pxs=0&set pxz={违规了!}&set ps=---34567890JQKA02N$
  137. ::初始化
  138. for /l %%a in (0,1,4) do set pss%%a=0
  139. for %%a in (3 4 5 6 7 8 9 0 J Q K A 2 N) do set ps%%a=0&set p6zs%%a=0
  140. ::计算各中点数的牌的数量
  141. for /l %%a in (1,1,20) do for /f %%b in ("!p6s:~%%a,1!") do set /a ps%%b+=1
  142. ::计算牌的数量
  143. set /a p6zs=%ps3%+%ps4%+%ps5%+%ps6%+%ps7%+%ps8%+%ps9%+%ps0%+%psj%+%psq%+%psk%+%psa%+%ps2%+%psn%
  144. ::获取标记字符串%p6ss%
  145. set p6ss=---%ps3%%ps4%%ps5%%ps6%%ps7%%ps8%%ps9%%ps0%%psj%%psq%%psk%%psa%0%ps2%%psn%$
  146. ::提取最大的单张,2张,3张,4张
  147. for /l %%a in (3,1,17) do set pss!p6ss:~%%a,1!=%%a
  148. ::提取最小的单张,2张,3张,4张
  149. for /l %%a in (17,-1,3) do set psx!p6ss:~%%a,1!=%%a
  150. ::单牌
  151. if %p6zs% == 1 set px=一张&set pxz=一张{!ps:~%pss1%,1!}&set pxs=%pss1%
  152. set p=%p6ss%&set q=%p6zs%
  153. ::3张和飞机
  154. ::解释:  %p:3=.% == %p%  表示%p%中没有3则if生效,加上not表示有3则if生效
  155. if %q% == 6 if not %p:33=.% == %p% set px=飞机
  156. if %q% == 8 if not %p:33=.% == %p% set px=飞机带单
  157. if %q% == 10 if not %p:33=.% == %p% if %p:1=.% == %p% set px=飞机带对
  158. if not %px:飞机=.% == %px% set pxs=%pss3%&set pxz=%px%
  159. if %q% == 9 if not %p:333=.% == %p% set px=三顺
  160. if %q% == 12 if not %p:333=.% == %p% set px=三顺带单
  161. if %q% == 15 if not %p:333=.% == %p% if %p:1=.% == %p% set px=三顺带对
  162. if %q% == 12 if not %p:3333=.% == %p% set px=三大顺
  163. if %q% == 16 if not %p:3333=.% == %p% set px=三大顺带单
  164. set p3=%p:3333=.%
  165. if %q% == 20 if not %p:3333=.% == %p% if %p:1=.% == %p% if %p3:3=.% == %p3% set px=三大顺带对
  166. if %q% == 15 if not %p:33333=.% == %p% set px=三巨顺
  167. if %q% == 20 if not %p:33333=.% == %p% set px=三巨顺带单
  168. if %q% == 18 if not %p:333333=.% == %p% set px=三神顺
  169. if not %px:三=.% == %px% set pxs=%pss3%&set pxz=%px%
  170. if %q% == 3 if not %p:3=.% == %p% set px=三张&set pxz=三张!ps:~%pss3%,1!
  171. if %q% == 4 if not %p:3=.% == %p% set px=三带一&set pxz=三张!ps:~%pss3%,1!带一张!ps:~%pss1%,1!
  172. if %q% == 5 if not %p:3=.% == %p% if not %p:2=.% == %p% set px=三带对&set pxz=三张!ps:~%pss3%,1!带一对!ps:~%pss2%,1!
  173. ::对子和兄弟
  174. if %q% == 2 if %p:1=.% == %p% set px=对子&set pxz=一对!ps:~%pss2%,1!&set pxs=%pss2%
  175. if %q% == 6 if not %p:222=.% == %p% set px=3兄弟
  176. if %q% == 8 if not %p:2222=.% == %p% set px=4兄弟
  177. if %q% == 10 if not %p:22222=.% == %p% set px=5兄弟
  178. if %q% == 12 if not %p:222222=.% == %p% set px=6兄弟
  179. if %q% == 14 if not %p:2222222=.% == %p% set px=7兄弟
  180. if %q% == 16 if not %p:22222222=.% == %p% set px=8兄弟
  181. if %q% == 18 if not %p:222222222=.% == %p% set px=9兄弟
  182. if %q% == 20 if not %p:2222222222=.% == %p% set px=10兄弟
  183. ::顺子
  184. if %q% == 5 if not %p:11111=.% == %p% set px=5张顺子
  185. if %q% == 6 if not %p:111111=.% == %p% set px=6张顺子
  186. if %q% == 7 if not %p:1111111=.% == %p% set px=7张顺子
  187. if %q% == 8 if not %p:11111111=.% == %p% set px=8张顺子
  188. if %q% == 9 if not %p:111111111=.% == %p% set px=9张顺子
  189. if %q% == 10 if not %p:1111111111=.% == %p% set px=10张顺子
  190. if %q% == 11 if not %p:11111111111=.% == %p% set px=11张顺子
  191. if %q% == 12 if not %p:111111111111=.% == %p% set px=12张顺子
  192. ::炸弹
  193. if %q% == 4 if not %p:4=.% == %p% set px=炸弹&set pxz=炸弹{四张!ps:~%pss4%,1!}&set pxs=%pss4%&set pxs=%pss4%
  194. if %q% == 2 if not %p:2$=.% == %p% set px=王炸&set pxz=王炸{无敌}&set pxs=%pss2%
  195. ::提取有效牌(顺子和兄弟里的最大一张,3张里的不含带牌的最大一张)
  196. if not %px:顺子=.% == %px% set pxs=%pss1%&set pxz=%px%!ps:~%psx1%,1!到!ps:~%pss1%,1!
  197. if not %px:兄弟=.% == %px% set pxs=%pss2%&set pxz=%px%!ps:~%psx2%,1!到!ps:~%pss2%,1!
  198. call :sybc 11468$30您出的牌:   ;            ;:11568$3C%pxz%
  199. if "%px%" == "违规" (set p2s=%p2sBF%&&set p2h=%p2hBF%&&set p2y=%p2yBF%&&set p2z=%p2zBF%
  200. for /l %%a in (1,1,20) do set p2w%%a=0
  201. call :p11
  202. call :sybc 11668$30不能这样出.;请重新出牌!
  203. goto :GB)
  204. (ECHO.fB800:%DEBUGQK:;= 20 3e&ECHO.fB800:% 20 3e&ECHO.q%)|DEBUG>NUL
  205. for /l %%a in (1,1,%P6z%) do set /a wz=11220+%%a*3&&call :pa !wz! !p6y:~%%a,1! !p6s:~%%a,1! !p6h:~%%a,1! %p6js%
  206. call :sybcs
  207. for /l %%a in (1,1,20) do set p2w%%a=0
  208. SET SYBCS=%SYBCS%;:10350$30  ▁▁▁▁▁▁  ;$03▉$30      ▏;$03▉$3e 俺懒得要!$30▏;$03▉$3e      $30╲;  $03▇▇▇▇▇▇▇
  209. call :sybcs
  210. SET SYBCS=%SYBCS%;:10713$30  ▁▁▁▁▁▁  ;$03▉$30      ▏;$03▉$3e 俺要不起!$30▏;╱$3e      $30▏;$03▇▇▇▇▇▇▇$30  
  211. call :sybcs
  212. if %p6z% == %p2zBF% goto :win
  213. call :p11
  214. call :sybc 11606$ce  ;:11606$ce%p2z%
  215. call :sybc 11668$30没人要得起.;请继续出牌!
  216. goto :GB
  217. :p1
  218. if "%2" == "" goto :P11
  219. :P11
  220. set SYBCS=11800$3e%KH%:12000$3E按M键切换;到鼠标模式;出牌更方便;建议用鼠标;:12070$3EF2重新发牌;F5刷新屏幕;方向键控制;空格键出牌
  221. if "%kzms%" == "sb" set SYBCS=11800$3e%KH%:11900$3E┌───┒;│键  盘┃;┕━━━┛;鼠标模式不;能用功能键;点击用键盘;:11970$3E┌───┒;│出  牌┃;┕━━━┛;鼠标模式下;单击选扑克;然后出牌.
  222. for /l %%a in (1,1,%p2z%) do set /a wz=11908+%%a*3,pz=%%a+1&(if !p2w%%a! == 1 set /a wz=!wz!-100)&call :pa !wz! !p2y:~%%a,1! !p2s:~%%a,1! !p2h:~%%a,1! 农 民
  223. CALL :SYBCS
  224. goto :eof
  225. :pl
  226. set pl=%2
  227. for %%a in (0,1,20) set /a pq1=%%a*7+5,pq2=%%a*7+6 &&call :pa %1
  228. goto :eof
  229. :pb
  230. SET SYBCS=%SYBCS%;:%1%pkBK3%▄▄▄▄▄;%pkbk% %pkNB% {\__/} %pkBK% ; %pkNB% / $fc@@%pkNB% \ %pkBK% ; %pkNB%( ($f0oo%pkNB%) )%pkBK% ; %pkNB% / ~~ \ %pkBK% ;%pkbk% $f2斗 地 主%pkbk% ;%pkBK4%▄▄▄▄▄%pkBK%
  231. goto :eof
  232. :pa
  233. if not "%4" == "" SET SYBCS=%SYBCS%;:%1%pkBK% ▄▄▄▄ ; $f%2%3%pkNB%     %pkBK% ; $f%2%4%pkNB%  %5   %pkBK% ; %pkNB%   %6  $f%2%4%pkBK% ; %pkNB%     $f%2%3%pkBK% ; %pkBK2%▄▄▄▄%pkBK%
  234. goto :eof
  235. :fp
  236. title 发牌中...
  237. for /l %%a in (1,1,20) do set p2w%%a=0
  238. set paid=&set paif=&set paiy=&set /a p1z=17,p2z=17,p3z=17
  239. :FP1
  240. set /a pran+=1,m=0,n=0,d=0
  241. ::随机排序54张牌(洗牌)
  242. for %%a in (3 4 5 6 7 8 9 0 J Q K A 2) do (for %%b in (!pkh1!-!pky0! !pkh2!-!pky0! !pkh3!-!pky1! !pkh4!-!pky1!) do (set p%pran%#!random!!random!.%%a-%%b=1))
  243. set P%pran%#300543001.N-!pkh0!-!pky1!=1&set P%pran%#543001000.N-!pkh0!-!pky0!=1
  244. ::发牌,并留三张底
  245. set he1=&set he2=&set he3=&set Di=
  246. for /f "tokens=2 delims==." %%a in ('set p%pran%#') do set /a m=m%%3+1,n+=1&&if !n! leq 51 (for %%c in (!m!) do set he%%c=!he%%c! %%a) else (set di=!di! %%a)
  247. set a=1s=%di:~1,1%;1h=%di:~3,1%;1y=%di:~5,1%;2s=%di:~7,1%;2h=%di:~9,1%;2y=%di:~11,1%;3s=%di:~13,1%;3h=%di:~15,1%;3y=%di:~17,1%
  248. set pdi%a:;=&set pdi%
  249. ::整理各家手上的牌
  250. for /l %%a in (1,1,3) do (for %%b in (!he%%a!) do (for /f "tokens=1,2,3 delims=-" %%c in ("%%b") do (
  251. set pd%pran%#%%c=!pd%pran%#%%c!%%c
  252. set pf%pran%#%%c=!pf%pran%#%%c!%%d
  253. set py%pran%#%%c=!py%pran%#%%c!%%e))
  254. for %%b in (3 4 5 6 7 8 9 0 J Q K A 2 N) do set paid%pran%#=!paid%pran%#!!pd%pran%#%%b!&set paif%pran%#=!paif%pran%#!!pf%pran%#%%b!&set paiy%pran%#=!paiy%pran%#!!py%pran%#%%b!
  255. for /f "tokens=1,2,3 delims=." %%b in ("!paid%pran%#!.!paif%pran%#!.!paiy%pran%#!") do set p%%as=0%%b&set p%%ah=0%%c&set p%%ay=0%%d
  256. )
  257. if "%pdi3s%" == "" goto FP
  258. goto :eof
  259. :win
  260. (echo.FB800:B40 FFF 20 3E&echo q)|DEBUG>NUL
  261. set sybcs=12030F1╔════════╗;║$FC恭喜你,获得胜利.$F1║;║$F8按任意键从新开局$F1║;╚════════╝
  262. call :SYBCS
  263. pause>nul
  264. goto :2
  265. :timec
  266. IF "%t1%" == "" EXIT /B 0
  267. FOR /F "DELIMS=:. TOKENS=1,2,3,4" %%N IN ("%t1%") DO SET O=1%%O&SET P=1%%P&SET Q=1%%Q&SET /A N=100+%%N
  268. IF "%t2%" == "" SET /A T=N*360000+O*6000+P*100+Q-36610100&&EXIT /B !T!
  269. FOR /F "DELIMS=:. TOKENS=1,2,3,4" %%M IN ("%t2%") DO SET I=1%%N&SET J=1%%O&SET K=1%%P&SET /A H=100+%%M
  270. IF "%t2%" GTR "A" (SET L=%t2%&SET /A T=N*360000+O*6000+P*100+Q-36610100,S=T/100,M=T/6000,H=T/360000) ELSE (SET L=%3&SET /A H=H-N,I=I-O,J=J-P,K=K-Q,T=H*360000+I*6000+J*100+K,S=T/100,M=T/6000,H=T/360000)
  271. IF "%L%" == "" SET L=T
  272. call :sybc 1176831耗时:   厘秒;:11773$3c!%L%!
  273. goto :eof
  274. :SYBCS
  275. echo %SYBCS% >>sybc.txt
  276. (ECHO.%SYBCOM:`=&ECHO.DW %&ECHO.%SYBCV:`=&ECHO.%)|DEBUG>NUL
  277. goto :EOF
  278. :SYBC
  279. IF "%1" == "" SET SYBCCD=00&GOTO SYBCC
  280. echo %1 >>sybc.txt
  281. SET SYBCCD=64
  282. set SYBCC=%*
  283. :SYBCC
  284. SET V=`A80`DB %SYBCCD% 00 "%SYBCC%" 0D``RCX`200`G`Q
  285. (ECHO.%SYBCOM:`=&ECHO.DW %&ECHO.%V:`=&ECHO.%)|DEBUG>NUL
  286. EXIT /B %ERRORLEVEL%
复制代码

作者: qc5111    时间: 2011-8-28 14:26

怎么没人,那么好的代码
作者: cjiabing    时间: 2011-8-28 14:46

看到SYBN我就知道是谁弄的了,不会是你吧@~
这个界面确实漂亮,不过cpu老高。
整体做得差不多了,就差电脑自己出牌,比我的好多了,希望sl543001继续完善!~
http://bbs.bathome.net/thread-7375-1-2.html
作者: caruko    时间: 2011-9-2 13:39

电脑出牌...
曾经写过一段算法,能比照牌面大小,但是要让电脑有全局观,就没那么容易了。
作者: cjiabing    时间: 2011-9-2 20:11

回复 34# caruko


    仍然是可以解决的,就是细节太多了,弄得心烦去,时间不多,暂停一段时间再说。

    我一楼二楼说得不够爽朗,我这里说一下电脑怎么出牌。

    首先要用到一个“接口”。什么是接口,就是几个玩家之间相互通信、相互理解、相互交流的一个变量。
    比如,我们把这个接口变量命名为“%JieKou%”。现在有三个玩家,上家出的牌是34567,这是一个顺子,那么,上家提供给另外两个玩家的接口是:JieKou=07顺子5
    下一家获得该接口变量,则分析这个牌是什么类型——顺子,最大的牌是什么——07,牌子有多少张——5张。
    下一家继续分析,自己有没有顺子牌——分析自己的牌型,看看自己有什么牌——这个我可以做出来——然后看看自己这副牌的接口是什么——我们假定为56789,接口是:MyJieKou=09顺子5
    然后比较下上家的接口和自家的接口,看自家的牌是否比上家大,如果大过继续判断时分是搭档(农民),如果不是,就可以出牌了,如果没有大过,则Pass。
    第三方同样获得第一家出牌的接口,并获得上一家牌的接口,如果上一家Pass了,就可以直接对比第一家,如果上一家出牌了,就分析自己的牌,并与上家的接口%MyJieKou% 比较大小。
    这样,三方通过接口变量,获得了比较的途径,也就获得了电脑出牌的途径。
    从以上看,需要做的主要有:1、分析上一家或下一家的牌,也就是分析其他人出的牌是什么牌;2、分析自己的牌,看自己的牌有什么类型的牌。
    其他需要考虑的功能:1、比较牌的大小;2、分析是否搭档(农民还是地主);3、如何中止吃牌,并决定谁可以出牌;如何获得分数……
作者: caruko    时间: 2011-9-5 13:21

那只是简单的判断,难点在于,出牌的时机把握,并不是牌面能比上家大,就一定出牌。

另外,牌面可能有多种组合,比如一个顺子,是不是拆掉了手上的炸弹,三条? 本来2手牌能出完的,是不是变成3手4手了?


玩家本身就有技巧高低之分,电脑能做到的有限。
作者: a20001017    时间: 2012-10-23 09:34

多人游戏服务器可以用百度开发人员中心(话说那是带有自由上传功能的)只是不知copy命令能不能把文件上传到网络
作者: 111    时间: 2013-4-12 20:53

回复 31# qc5111


    为什么不继续设计下去了,我还等有iq版的呢
作者: dengyuli    时间: 2013-6-11 10:37

  1. @echo off
  2. ::用于特效显示的数所初始化
  3. (set chu0=$
  4. set m1=1
  5. set m2=2
  6. set m3=3
  7. set m4=
  8. set a$#0= &rem 定义尾巴
  9. set b$#0=—=—=╮
  10. set c$#0=      │
  11. set d$#0=      │
  12. set e$#0=      │
  13. set f$#0=批  §│
  14. set g$#0=  处  │
  15. set h$#0=§  理│
  16. set i$#0=━=━=╯
  17. set a$@0=—=—=╮
  18. set b$@0=      │
  19. set c$@0=      │
  20. set d$@0=      │
  21. set e$@0=批  §│
  22. set f$@0=  处  │
  23. set g$@0=§  理│
  24. set h$@0=━=━=╯
  25. set i$@0=
  26. set a$#1=—=╮
  27. set b$#1=—=┷=╮
  28. set c$#1=      │
  29. set d$#1=      │
  30. set e$#1=      │
  31. set f$#1=批  §│
  32. set g$#1=  处  │
  33. set h$#1=§  理│
  34. set i$#1=━=━=╯
  35. set a$@1=—=—=╮
  36. set b$@1=      │
  37. set c$@1=      │
  38. set d$@1=      │
  39. set e$@1=批  §│
  40. set f$@1=  处  │
  41. set g$@1=§  理│
  42. set h$@1=━=┯=╯
  43. set i$@1=━=╯
  44. set a$#2=╮
  45. set b$#2=┷=—=╮
  46. set c$#2=      │
  47. set d$#2=      │
  48. set e$#2=      │
  49. set f$#2=批  §│
  50. set g$#2=  处  │
  51. set h$#2=§  理│
  52. set i$#2=━=━=╯
  53. set a$@2=—=—=╮
  54. set b$@2=      │
  55. set c$@2=      │
  56. set d$@2=      │
  57. set e$@2=批  §│
  58. set f$@2=  处  │
  59. set g$@2=§  理│
  60. set h$@2=┯=━=╯
  61. set i$@2=╯
  62. set a@00$=╭=
  63. set b@00$=│!ob!
  64. set c@00$=│!oc!
  65. set d@00$=│
  66. set e@00$=│
  67. set f@00$=│
  68. set g@00$=│
  69. set h@00$=╰=
  70. set i@00$=   &rem 突出第一个,第一位
  71. set a@10=╭=
  72. set b@10=┥!ob!
  73. set c@10=┊!oc!
  74. set d@10=┊
  75. set e@10=┊
  76. set f@10=┊
  77. set g@10=┊
  78. set h@10=╰-
  79. set i@10=━=&rem 突出第N个,第N位,变换
  80. set a@12=╭=
  81. set b@12=┥!ob!
  82. set c@12=┊!oc!
  83. set d@12=┊
  84. set e@12=┊
  85. set f@12=┊
  86. set g@12=┊
  87. set h@12=╰-
  88. set i@12=━=&rem 突出第N个,第1,2位,变换
  89. set a@13=╭=
  90. set b@13=┥!ob!
  91. set c@13=┊!oc!
  92. set d@13=┊
  93. set e@13=┊
  94. set f@13=┊
  95. set g@13=┊
  96. set h@13=╰-
  97. set i@13=━=&rem 突出第N个,第3位,变换
  98. set a@0=╭=
  99. set b@0=┊!ob!
  100. set c@0=┊!oc!
  101. set d@0=┊
  102. set e@0=┊
  103. set f@0=┊
  104. set g@0=┊
  105. set h@0=╰=
  106. set i@0=   &rem 突出第N个,第N位
  107. set a@2=╭=
  108. set b@2=┊!ob!
  109. set c@2=┊!oc!
  110. set d@2=┊
  111. set e@2=┊
  112. set f@2=┊
  113. set g@2=┊
  114. set h@2=╰-
  115. set i@2=━=&rem 突出第N个,第2位
  116. set a@3=╭=
  117. set b@3=┊!ob!
  118. set c@3=┊!oc!
  119. set d@3=┊
  120. set e@3=┊
  121. set f@3=┊
  122. set g@3=┊
  123. set h@3=╰-
  124. set i@3=╯ &rem 突出第N个,第3位
  125. set a#00$=   &rem 不突第一个
  126. set b#00$=╭=
  127. set c#00$=│!ob!
  128. set d#00$=│!oc!
  129. set e#00$=│
  130. set f#00$=│
  131. set g#00$=│
  132. set h#00$=│
  133. set i#00$=╰=
  134. set a#10=—=&rem 不突第N个,第N位,变换
  135. set b#10=╭=
  136. set c#10=┊!ob!
  137. set d#10=┊!oc!
  138. set e#10=┊
  139. set f#10=┊
  140. set g#10=┊
  141. set h#10=┤
  142. set i#10=╰=
  143. set a#12=—=&rem 不突第N个,第1,2位,变换
  144. set b#12=╭=
  145. set c#12=┊!ob!
  146. set d#12=┊!oc!
  147. set e#12=┊
  148. set f#12=┊
  149. set g#12=┊
  150. set h#12=┤
  151. set i#12=╰=
  152. set a#13=—=&rem 不突第N个,第3位,变换
  153. set b#13=╭=
  154. set c#13=┊!ob!
  155. set d#13=┊!oc!
  156. set e#13=┊
  157. set f#13=┊
  158. set g#13=┊
  159. set h#13=┤
  160. set i#13=╰=
  161. set a#0=   &rem 不突第N个,第1位
  162. set b#0=╭=
  163. set c#0=┊!ob!
  164. set d#0=┊!oc!
  165. set e#0=┊
  166. set f#0=┊
  167. set g#0=┊
  168. set h#0=┊
  169. set i#0=╰=
  170. set a#2=—=&rem 不突第N个,第2位
  171. set b#2=╭=
  172. set c#2=┊!ob!
  173. set d#2=┊!oc!
  174. set e#2=┊
  175. set f#2=┊
  176. set g#2=┊
  177. set h#2=┊
  178. set i#2=╰=
  179. set a#3=╮ &rem 不突第N个,第3位
  180. set b#3=╭=
  181. set c#3=┊!ob!
  182. set d#3=┊!oc!
  183. set e#3=┊
  184. set f#3=┊
  185. set g#3=┊
  186. set h#3=┊
  187. set i#3=╰=
  188. )
  189. (rem 牌型定义
  190. set #3-1.1=三带一
  191. set #3-1.2=三带二
  192. set #3-2.1.1=飞机
  193. set #3-2.2=飞机
  194. set #3-2.2.2=飞机
  195. set #3-3=三顺
  196. set #3-3.1.1.1=三顺拖
  197. set #3-3.2.2.2=三顺拖
  198. set #3-4=三顺
  199. set #3-4.1.1.1.1=三顺拖
  200. set #4-1.1.1=四带二
  201. set #4-1.2=四带二
  202. set #4-1.2.2=四带二
  203. set #2-3=连对
  204. set #2-4=连对
  205. set #2-5=连对
  206. set #2-6=连对
  207. set #2-7=连对
  208. set #2-8=连对
  209. set #2-9=连对
  210. set #2-10=连对
  211. set #1-5=顺子
  212. set #1-6=顺子
  213. set #1-7=顺子
  214. set #1-8=顺子
  215. set #1-9=顺子
  216. set #1-10=顺子
  217. set #1-11=顺子
  218. set #1-12=顺子
  219. set #1-1=n
  220. set #2-1=一对n
  221. set #3-1=三个n
  222. set #4-1=炸弹
  223. set v#1-1.1=王炸)
  224. ::定义显示缓存
  225. set num1=17
  226. set num2=17
  227. set num3=17
  228. set system=请各方叫地主
  229. set name1=玩家 “你”
  230. set name2=貂蝉
  231. set name3=西施
  232. set comm=出牌
  233. set comm=讲话
  234. set rsay1=牌真好呀!这次我赢定了。
  235. set rsay2=我有炸的,小心哦
  236. set rsay3=这么烂的牌!可怎么打呀?
  237. set rsay4=你是MM,还是GG?
  238. set rsay5=和你合作真是太愉快了
  239. set rsay6=我要是能抢到地主就好了。
  240. set rsay7=Hello! everyone.
  241. set rsay8=你们好呀!
  242. set rsay9=今天的天气不怎么样
  243. set rsay0=批处理也能“斗地主”,强吧!
  244. set paix=重新开始
  245. set paic=0
  246. set kkk=3456789pJQKA2vw#
  247. set "spac=                                                                                  "
  248. (set ec0=
  249. set ec1=     ┌──┐  !say2!
  250. set ec2=     │ !ain2:~-2! │
  251. set ec3=     │    │
  252. set ec4= !name2!│ 张 │
  253. set ec5=     │    │
  254. set ec6=     ╘≡≡╛
  255. set ec7=     !@dz2!!@bj2!
  256. set ec8= !say3!
  257. set ec9=!spac:~-80!┌──┐
  258. set ec10=!spac:~-80!│ !ain3:~-2! │
  259. set ec11=!sayp32!│    │
  260. set ec12=!sayp33!│ 张 │!name3!
  261. set ec13=!sayp34!│    │
  262. set ec14=!sayp35!╘≡≡╛
  263. set ec15=!spac:~-80!!@dz3!!@bj3!
  264. set ec16=玩家!pad1!
  265. set ec17=    !paf1!
  266. set ec19=西施!pai3d!
  267. set ec20=    !pai3f!   !system!
  268. set ec21=貂蝉!pai2d!
  269. set ec22=    !pai2f!
  270. set ec23=
  271. set ec24=
  272. set ec25=
  273. set ec26=
  274. set ec27= !@dz1!!@bj1!     !say1!
  275. set ec37=!key!
  276. set key=  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  w
  277. )
  278. ::为了显示方便,用p代替10
  279. ::定义花色数据
  280. set a1=&set a2=&set a3=&set a4=&set a5=&set a6=
  281. mode con: cols=100 lines=200&color 2f
  282. :begin 开始/重新开始
  283. setlocal enabledelayedexpansion
  284. set sayp32=!spac:~,80!
  285. set sayp33=!spac:~,80!
  286. set sayp34=!spac:~,80!
  287. set sayp35=!spac:~,80!
  288. set n=0
  289. for %%a in (!key!) do (set w%%a=!n!&set/a n=n+1&set nums=!nums!%%a)
  290. ::随机排序54张牌(洗牌)
  291. for %%a in (3 4 5 6 7 8 9 p J Q K A 2) do (for %%b in (!a3! !a5! !a4! !a6!) do (set #p!random!.%%a-%%b=1))
  292. set #P!random!.v-!a1!=1
  293. set #P!random!.W-!a2!=1
  294. ::发牌,并留三张底
  295. set/a m=0,n=0
  296. for /f "tokens=2 delims==." %%a in ('set #p') do (
  297. set /a m=m%%3+1,n+=1
  298. if !n! leq 51 (
  299. for %%c in (!m!) do (
  300. set he%%c=!he%%c! %%a
  301. )
  302. ) else (set di=!di! %%a)
  303. )
  304. set/a dizu=!random!%%3+1&rem 随机定谁先叫地主
  305. set sub=pc!dizu!
  306. set/a quan=0,beis=0
  307. set say2=!rsay%random:~-1%!
  308. set say3=!rsay%random:~-1%!
  309. :jdzend 叫地主结束
  310. ::整理各家手上的牌
  311. for /l %%a in (1,1,3) do (
  312. setlocal enabledelayedexpansion
  313. for %%b in (!he%%a!) do (
  314. for /f "tokens=1,2 delims=-" %%c in ("%%b") do (
  315. set pd.%%c=!pd.%%c!%%c
  316. set pf.%%c=!pf.%%c!%%d
  317. )
  318. )
  319. for %%b in (3 4 5 6 7 8 9 p J Q K A 2 v W) do (
  320. set paid=!paid!!pd.%%b!
  321. set paif=!paif!!pf.%%b!
  322. )
  323. for /f "tokens=1-2 delims=." %%b in ("!paid!.!paif!") do (
  324. endlocal
  325. set pai%%ad=%%b
  326. set pai%%af=%%c
  327. )
  328. )
  329. ::电脑诂计牌大小,设定叫分值
  330. if "!comm!" equ "讲话" (
  331. set #qW=7
  332. set #qv=6
  333. set #q2=4
  334. set #qa=2
  335. set #qk=1
  336. set #q3=-2
  337. set #q4=-2
  338. set #q5=-1
  339. set #q6=-1
  340. for %%a in (2 3) do (
  341. set/a var=0,quan%%a=0
  342. for %%b in (W v 2 a k 3 4 5 6) do (
  343. if "!pai%%ad:%%b=!" neq "!pai%%ad!" set/a var+=#q%%b
  344. )
  345. if !var! gtr 0 set quan%%a=1
  346. if !var! gtr 4 set quan%%a=2
  347. if !var! gtr 8 set quan%%a=3
  348. )
  349. )
  350. set pad1=!pai1d: =!
  351. set paf1=!pai1f: =!
  352. ::玩家选择的为:@,没选为:#
  353. set chu=######################
  354. set ain3= !num3!
  355. set ain2= !num2!
  356. :loop
  357. set c#=@
  358. set c@=#
  359. ::显示玩家牌面部分
  360. set a1=
  361. set/a @=4,#=4
  362. set is@=$
  363. set/a n=!num1!-1
  364. if !num1! lss 0 goto :控制中心
  365. setlocal enabledelayedexpansion
  366. for /l %%a in (0,1,!n!) do (
  367. for %%z in (!chu:~%%a^,1!) do (
  368. set hu=&set var=
  369. if %%z neq !is@! (
  370. set/a var=!is@!
  371. set/a hu=m!var!
  372. set is@=%%z&set %%z=1
  373. if %%a equ 0 set %%z=4
  374. ) else (set /a !is@!+=1)
  375. if !is@! equ @ (set/a n@#=m!@!) else (set/a n@#=m!#!)
  376. set var=!n@#!!hu!
  377. if !n@#!!hu! equ 11 set var=12
  378. for /f "tokens=1-4" %%b in ("!pad1:~%%a,1! !paf1:~%%a,1! !var! !chu%%a!") do (
  379. set oc=%%c&set ob=%%b
  380. rem 测试用变量显示:echo b%%z%%d%%e !@!-!#! !b%%z%%d%%e!  !var!
  381. for %%i in (a b c d e f g h i) do (
  382. for %%j in ("!%%i%%z%%d%%e!") do (
  383. set %%iN=!%%iN!%%~j
  384. ) )
  385. ))
  386. )
  387. if !n@#! equ 3 set n@#=0
  388. for %%i in (a b c d e f g h i) do (
  389. for %%j in ("%%i$!is@!!n@#!") do (
  390. set %%iN=!%%iN!!%%~j!
  391. ) )
  392. ::显示玩家牌面部分
  393. endlocal&(set ec28=%an%
  394. set ec29=%bn%
  395. set ec30=%cn%
  396. set ec31=%dn%
  397. set ec32=%en%
  398. set ec33=%fn%
  399. set ec34=%gn%
  400. set ec35=%hn%
  401. set ec36=%in%)
  402. ::把玩家的牌处理结果送到显示缓存
  403. ::转变量出牌方的显示
  404. if !sub! equ pc2 (
  405. cls
  406. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  407. set say1=
  408. ping -n 2 127.1>nul)
  409. :控制中心
  410. set/a "var=(%sub:~-1%+1)%%3+1"
  411. if !num%var%! leq 2  set @bj%var%=¤!num%var%!张
  412. if "!num%var%!" equ "0" (echo 游戏结束^^!&endlocal&pause&goto :begin)
  413. ::如果放弃记数等于2,转调用最后一个出牌者,重新出牌。
  414. if !ascc! geq 2 (
  415. set sub=!lasssub!
  416. set paix=重新开始
  417. )
  418. set system=轮到 !name%sub:~-1%! !comm!
  419. goto :%sub%
  420. ::AI1 动作 是叫地主,还是出牌,(状态只保持一家)
  421. :pc2
  422. if /i "!comm!" equ "讲话" (
  423. set say2=不叫
  424. if !beis! lss !quan2! set say2=叫地主&set @dz=%sub%&set/a beis+=1
  425. set/a quan+=1
  426. if !quan! gtr 3 goto :jdz
  427. cls
  428. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  429. ) else (
  430. set say2=!rsay%random:~-1%!
  431. call :IQ
  432. if defined bu1 (
  433. set ec3=!ec3:~,11!┍!bu1:~,-1!┑
  434. set ec4=!ec4:~,13!│!bu2:~,-1!│
  435. set ec5=!ec5:~,11!│!bu3:~,-1!│
  436. set ec6=!ec6:~,9!┕!bu4:~,-1!┙
  437. ) else (
  438. set ec3=!ec3:~,11!
  439. set ec4=!ec4:~,13! 不
  440. set ec5=!ec5:~,11! 要
  441. set ec6=!ec6:~,9!
  442. )
  443. cls
  444. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  445. set say2=
  446. ping -n 2 127.1>nul
  447. )
  448. set sub=pc3&goto :控制中心
  449. ::AI2 动作 是叫地主,还是出牌,
  450. :pc3
  451. if /i "!comm!" equ "讲话" (
  452. set say3=不叫
  453. if !beis! lss !quan3! set say3=叫地主&set @dz=%sub%&set/a beis+=1
  454. set/a quan+=1
  455. if !quan! gtr 3 goto :jdz
  456. cls
  457. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  458. ) else (
  459. set say3=!rsay%random:~-1%!
  460. call :IQ
  461. if defined bu1 (
  462. set/a var=80-5-chen*3
  463. for %%v in (!var!) do (
  464. set sayp32=!spac:~,%%v!┍!bu1:~,-1!┑
  465. set sayp33=!spac:~,%%v!│!bu2:~,-1!│
  466. set sayp34=!spac:~,%%v!│!bu3:~,-1!│
  467. set sayp35=!spac:~,%%v!┕!bu4:~,-1!┙
  468. )
  469. ) else (
  470. set sayp32=!spac:~,80!
  471. set sayp33=!spac:~,77!不
  472. set sayp34=!spac:~,77!出
  473. set sayp35=!spac:~,80!
  474. )
  475. cls
  476. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  477. set say3=
  478. ping -n 2 127.1>nul
  479. )
  480. set sub=pc1&goto :控制中心
  481. :error
  482. ::把显示缓存进行显示输出
  483. set say1=输入字串中含有不可识别字符
  484. :pc1
  485. set ec23=
  486. set ec24=
  487. set ec25=
  488. set ec26=
  489. if not defined say1 set say1=终于轮到我!comm!了
  490. cls
  491. for /l %%a in (0,1,37) do for %%b in ("!ec%%a!") do echo;     %%~b
  492. set a讲话=[J]叫地主  [A]加倍   [直接回车pass]
  493. set a出牌=[U]不出   [X]退出   [T]提示   [选好直接回车出牌]
  494. set input=
  495. echo.
  496. echo; !a%comm%!
  497. set "menu= u x t "
  498. set /p input= :^>
  499. ::玩家是否叫地主
  500. if /i "!comm!" equ "讲话" (
  501. if /i "!input!" equ "J" (set @dz=%sub%&set say1=叫地主&set/a beis+=1)
  502. set/a quan+=1
  503. if !quan! gtr 3 goto :jdz
  504. set sub=pc2
  505. goto :loop
  506. )
  507. set say1=
  508. if not defined input if "!chu:@=!" neq "!chu!" goto :chupai 如果已经选择,回车后出牌
  509. if "!menu: %input% =!" neq "!menu!" goto :menu%input% 跳到处理菜单项
  510. ::处理玩家对牌的选择,先把串打散,再一一处理。改变!chu!变量
  511. for %%a in (!key!) do (for %%b in (!w%%a!) do set input=!input:%%a= %%b !)
  512. for %%a in (!input!) do (
  513. if %%a gtr 20 set chu=%chu%&goto :error
  514. if %%a lss 0 set chu=%chu%&goto :error
  515. set/a var=1+%%a
  516. for /f "tokens=1,2" %%b in ("!chu:~%%a,1! !var!") do (
  517. set chu=!chu:~,%%a!!c%%b!!chu:~%%c!
  518. )
  519. )
  520. goto :loop
  521. :chupai
  522. setlocal enabledelayedexpansion
  523. set var1=
  524. set var2=
  525. set chp1=
  526. set chp2=
  527. set chpn=0
  528. for /l %%a in (0,1,!n!) do (
  529. if "!chu:~%%a,1!" equ "@" (
  530. set/a num1-=1,chpn+=1
  531. set chp1=!chp1!!pad1:~%%a,1!
  532. set chp2=!chp2!!paf1:~%%a,1!
  533. ) else (
  534. set var1=!var1!!pad1:~%%a,1!
  535. set var2=!var2!!paf1:~%%a,1!
  536. )
  537. )
  538. ::把选择的牌提取出来
  539. set /a var=chpn-1
  540. set pad=!chp1!
  541. set paf=!chp2!
  542. for /l %%a in (0,1,!var!) do (
  543. for %%b in ("!pad:~%%a,1!") do (
  544. set/a pd.%%~b+=1
  545. set pds.%%~b=!pds.%%~b!!pad:~%%a,1!
  546. set pfs.%%~b=!pfs.%%~b!!paf:~%%a,1!
  547. )
  548. )
  549. for %%a in (3 4 5 6 7 8 9 p J Q K A 2 v w) do (
  550. for %%b in (!pd.%%a!) do (
  551. set pd.#%%b=!pd.#%%b! %%a
  552. )
  553. )
  554. for /l %%a in (4,-1,1) do (
  555. set vkk=0!kkk:~,-4!
  556. set pstr=
  557. set n=1
  558. if defined pd.#%%a (
  559. for %%b in (!pd.#%%a!) do (
  560. if not defined ptop (
  561. if "!vkk:~,1!" equ "%%b" (set /a n+=1) else (set pstr=!pstr!.!n!&set n=1)
  562. set vkk=!vkk:*%%b=!
  563. ) else (set pstr=!pstr!.%%a)
  564. set chv1=!chv1!!pds.%%b!
  565. set chv2=!chv2!!pfs.%%b!
  566. )
  567. if not defined ptop (set ptop=#%%a-!n!!pstr:~2!) else (set pstr1=!pstr1!.%%a!pstr:~2!)
  568. )
  569. )
  570. set ppp=!ptop!!pstr1!
  571. rem 起牌检查规则 可以处理炸弹及王炸
  572. if not defined !ppp! (
  573. if "!chv1:~,1!!ppp!" equ "v#1-1.1" (set paix=v#1-2&set paic=v&goto :zhaid)
  574. endlocal&set say1=你选择的牌不符合规则!%chv1:~,1%%ppp%&goto :pc1
  575. )
  576. if "!paix!" equ "重新开始" (set paic=!kkk!) else (
  577. if "!ppp!" neq "!paix!" (
  578. if "!ppp!" equ "#4-1" (set paix=#4-1&set paic=!kkk!&goto :zhaid)
  579. endlocal&set say1=你选择的牌不符合规则!%chp1%&goto :pc1
  580. )
  581. )
  582. ::牌形不对不可以出,重新出牌任出。
  583. :zhaid 炸弹处理
  584. if "!paic:%chv1:~,1%=!" equ "!paic!" (endlocal&set say1=你选择的牌小了!%chv1%&goto :pc1)
  585. ::小于不可以出
  586. ( endlocal
  587. set chp1=%chv1%
  588. set chp2=%chv2%
  589. set chpn=%chpn%
  590. set pad1=%var1%
  591. set paf1=%var2%
  592. set chu=%chu:@=%
  593. set num1=%num1%
  594. rem 提取选好的牌到变量chp1(点) chp2(花)chpn(个数)paix(牌形)paic(关键点数)
  595. set paix=%ppp%
  596. set paic=!kkk:*%chv1:~,1%=!
  597. )
  598. set say1=!rsay%random:~-1%!
  599. call :putbuff 把要出的牌转换为显示变量
  600. ::再送显示缓存
  601. set ec23=┍!bu1:~,-1!┑
  602. set ec24=│!bu2:~,-1!│
  603. set ec25=│!bu3:~,-1!│
  604. set ec26=┕!bu4:~,-1!┙
  605. ::下一个人
  606. set sub=pc2&goto :loop
  607. ::系统选项处理 x u t
  608. :menuX
  609. start "" C:\BatMPlayer\BatMPlayer.bat G&&exit
  610. :menuU
  611. set ec24= Pass...
  612. set/a ascc+=1
  613. set chu=#########################
  614. set sub=pc2&goto :loop
  615. :menuT
  616. echo 暂时还不支持此功能!
  617. pause>nul
  618. goto :pc1
  619. :jdz 叫地主处理 三家均调用这里
  620. if not defined @dz goto :begin
  621. set var=%@dz:~-1%
  622. set sub=%@dz%
  623. set he%var%=!he%var%!!di!
  624. set num%var%=20
  625. set comm=出牌
  626. set @dz%var%=★地主★
  627. set lasssub=pc%var%
  628. set ascc=2
  629. goto :jdzend
  630. :IQ 电脑自动出牌
  631. setlocal enabledelayedexpansion
  632. set /a vn=%sub:~-1%
  633. set /a var=num!vn!-1
  634. set pad=!pai%vn%d!
  635. set paf=!pai%vn%f!
  636. ::玩家数据读入临时变量
  637. for /l %%a in (0,1,!var!) do (
  638. for %%b in ("!pad:~%%a,1!") do (
  639. set/a pd.%%~b+=1
  640. set pds.%%~b=!pds.%%~b!!pad:~%%a,1!
  641. set pfs.%%~b=!pfs.%%~b!!paf:~%%a,1!
  642. )
  643. )
  644. ::按点数整理
  645. ::pd.%%~b 同点个数
  646. ::pds.%%~b 同点串
  647. ::pds.%%~b 同花串
  648. for %%a in (3 4 5 6 7 8 9 p J Q K A 2 v w) do (
  649. for %%b in (!pd.%%a!) do (
  650. set pd.##%%b=!pd.##%%b!%%a
  651. for /l %%c in (%%b,-1,1) do (
  652. set pd.#%%c=!pd.#%%c!%%a
  653. )
  654. )
  655. )
  656. ::按个数统计
  657. ::pd##.n 分别为1到4个的点
  658. ::pd#.n 分别为1到4个的点,向下兼容,如有2个时,对1个也有效
  659. if "!paix!" equ "重新开始" (
  660. set paic=!kkk!
  661. for /l %%a in (0,1,4) do (
  662. for %%b in ("!pd.#1:~%%a,1!") do (
  663. if %%b equ "" goto :you
  664. set paix=#!pd.%%~b!-1&set chpn=!pd.%%~b!
  665. if "!pd.%%~b!" neq "4" goto :you
  666. )
  667. )
  668. )
  669. ::如果是发牌,则取最小的出
  670. :you
  671. set paid=&set paif=&set pad=&set paf=
  672. if defined pd.#%paix:~,2% (
  673. set str=!pd.#%paix:~,2%!$
  674. set nn=!pd.#%paix:~,2%!%nums%
  675. set /a nn=w!nn:~20,1!
  676. for /l %%a in (0,1,!nn!) do (
  677. for %%b in ("!str:~%%a,%paix:~3,1%!") do (
  678. set find=%%~b
  679. if "!paic:%%~b=!" neq "!paic!" (goto :ok)
  680. )
  681. )
  682. )
  683. ::nn 取同型串的长度
  684. ::paic 已经把比当前点小的丢弃,所以如果%%b不在串中则认为比当前点大,可以出牌
  685. ::否则清空find
  686. set find=
  687. :ok
  688. ::如果主牌型对且大,则存在find
  689. if defined find (
  690. for /l %%a in (%paix:~3,1%,-1,1) do (
  691. for %%b in ("!find:~-%%a,1!") do (
  692. set paid=!paid!!pds.%%~b:~,%paix:~1,1%!
  693. set paif=!paif!!pfs.%%~b:~,%paix:~1,1%!
  694. set pds.%%~b=!pds.%%~b:~%paix:~1,1%!
  695. set pfs.%%~b=!pfs.%%~b:~%paix:~1,1%!
  696. )
  697. )
  698. rem 根据牌型的连顺数把点及花串放到结果变量,并在原串减去
  699. set var=%paix:~5%
  700. if defined var (
  701. for %%a in ("!var:.=" "!") do (
  702. if defined pd.##%%~a (
  703. for %%b in ("!pd.##%%~a:~,1!") do (
  704. set paid=!paid!!pds.%%~b:~,%%~a!
  705. set paif=!paif!!pfs.%%~b:~,%%~a!
  706. set pds.%%~b=!pds.%%~b:~%%~a!
  707. set pfs.%%~b=!pfs.%%~b:~%%~a!
  708. )
  709. set pd.##%%~a=!pd.##%%~a:~1!
  710. ) else (
  711. if defined pd.#%%~a (
  712. for %%b in ("!pd.#%%~a:~,1!") do (
  713. set paid=!paid!!pds.%%~b:~,%%~a!
  714. set paif=!paif!!pfs.%%~b:~,%%~a!
  715. set pds.%%~b=!pds.%%~b:~%%~a!
  716. set pfs.%%~b=!pfs.%%~b:~%%~a!
  717. )
  718. set pd.#%%~a=!pd.#%%~a:~1!
  719. )
  720. if defined pd.##4 set paix=#4-1&set chpn=4&set paic=!kkk!&goto :you
  721. endlocal
  722. set bu1=
  723. set/a ascc+=1
  724. goto :eof
  725. )
  726. )
  727. )
  728. rem 处理牌型尾巴部分,没有也不能出牌
  729. for %%a in (3 4 5 6 7 8 9 p J Q K A 2 v W) do (
  730. set pad=!pad!!pds.%%a!
  731. set paf=!paf!!pfs.%%a!
  732. )
  733. ) else (
  734. if defined pd.##4 set paix=#4-1&set chpn=4&set paic=!kkk!&goto :you
  735. endlocal
  736. set bu1=
  737. rem 放弃记数加1
  738. set/a ascc+=1
  739. goto :eof
  740. )
  741. rem 可以出牌
  742. goto :skrem
  743. set pd
  744. set ch
  745. set pai
  746. echo !find!  !kkk!
  747. echo !str!
  748. pause
  749. :skrem
  750. ::判断是否有相同的类型,paix(#3-2.1.1),有的话,取一个比当前的大的出牌。
  751.                                           
  752. ::如果有符合的牌,则提取选好的牌到变量paig(点字符串) paif(花字符串)chpn(个数不变)paix(规则不变)最后点数(paic)
  753. ::按现出规则,如果有大的则出牌
  754. (endlocal
  755. set pai%vn%d=%pad%
  756. set pai%vn%f=%paf%
  757. set paic=!kkk:*%find:~,1%=!
  758. set chp1=%paid%
  759. set chp2=%paif%
  760. set/a num%vn%=num%vn%-%chpn%
  761. set chpn=%chpn%
  762. set paix=%paix%
  763. )
  764. set ain2= !num2!
  765. set ain3= !num3!
  766. ::出牌显示处理
  767. :putbuff
  768. set bu1=&set bu2=&set bu3=&set bu4=
  769. set/a chen=chpn-1
  770. if !num%sub:~-1%! equ 0 set system=这一盘 !name%sub:~-1%! 赢了!
  771. for /l %%a in (0,1,!chen!) do (
  772. set bu1=!bu1!=┯
  773. set bu2=!bu2!!chp1:~%%a,1!│
  774. set bu3=!bu3!!chp2:~%%a,1!│
  775. set bu4=!bu4!=┷
  776. )
  777. ::放弃记数清0,记录最后出牌者
  778. set ascc=0
  779. set lasssub=%sub%
  780. goto :eof
  781. :aizlp
  782. 需要解决的问题
  783. 3。电脑出牌,如何处理组合牌形,如:顺子,三带一(二),飞机,四带二,连对等。
复制代码
注:非原创
作者: cjiabing    时间: 2013-6-11 21:42

回复 39# dengyuli


    谢谢!这个游戏当初也是一时冲动去做的,然后断断续续的持续了一两年都没开发得,前面的问题搞清楚了,结果后面的问题又来了,现在卡在轮流出牌这里,但不想动了,因为太复杂了,单靠一个人的能力有限啊!如果能够成立一个开发小组,大家统一思路,分工合作,应该是可以很快实现的。
作者: yixinyichao    时间: 2014-8-2 11:51

有點雜亂,要是加個方框就好多了
作者: tcasdsss    时间: 2014-9-13 00:28

批处理有点意思
作者: xiaolijian916    时间: 2015-12-8 22:32

39L原著是作者是谁




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