Board logo

标题: [游戏娱乐] 批处理井字棋(三子棋) [打印本页]

作者: wxcute    时间: 2009-1-7 12:31     标题: 批处理井字棋(三子棋)

又称三子棋。当然玩法可能有多种多样。
搜索了一下,发现小竹兄已经发过一个了。再发个纯当娱乐。

玩法:下子位置对应小键盘。
   子数不定,下满为止;
   三子连一线取先为胜,横竖斜均可;
   下满未有胜者为平局。

批处理简介:
   人机对弈,随机选择谁先下;
   下完自动进入新一局。
   电脑水平一般,因此你可以找到胜的方法;
   若选手下错位置电脑也可能赢。

刚发时系统自动把 “<nul” 截掉了,已修正。
  1. ::又叫井字棋
  2. ::当然玩法上可能会有差别
  3. ::CODE BY wxcute AT BBS.bathome.net
  4. @echo off
  5. mode con lines=12 cols=37
  6. setlocal enabledelayedexpansion
  7. for /l %%s in (1,1,7) do set SP= !sp!
  8. title .%SP%三子棋
  9. goto :start
  10. ::变量说明
  11. argument是否显示为提示棋盘的指针
  12. fate下子总计数
  13. special是否进行总计数
  14. Turn更换选手指针
  15. sub_flag选手指针
  16. input输入
  17. record下子记录
  18. remain剩下的位置
  19. winflag胜利标记
  20. ::标签说明
  21. start进入
  22. newGame新游戏
  23. begin循环开始
  24. Machine电脑下子
  25. T_flash下子棋盘更新
  26. :start
  27. ::设置棋盘棋子
  28. set chs1=●
  29. set chs0=×
  30. set L7=┏━┳━┳━┓
  31. set L6=┃7┃8┃9┃
  32. set L5=┣━╋━╋━┫
  33. set L4=┃4┃5┃6┃
  34. set L3=┣━╋━╋━┫
  35. set L2=┃1┃2┃3┃
  36. set L1=┗━┻━┻━┛
  37. ::============================================================
  38. ::开始
  39. :newGame
  40. color 72
  41. setlocal
  42. set argument=1
  43. set/a whoFirst=%random%%%2
  44. set "remain= 1 2 3 4 5 6 7 8 9"
  45. ::----------------------------------------
  46. :begin
  47. cls
  48. call :show
  49. ::调用胜负判断
  50. if "%fate%" geq "5" call :judgeVic
  51. if defined winflag goto :end
  52. if "%fate%" geq "9" goto :end
  53. ::计算下子数与判断下子方
  54. if not defined special (
  55.  set/a fate+=1,Turn="(whoFirst+fate+1)%%2"
  56. ) else set special=
  57. if %Turn% equ 0 goto :Machine
  58. ::下子
  59. set sub_flag=%Turn%
  60. set input=
  61. set/p input=%SP:~3%等待您的选择:
  62. if not defined input goto :judgeIn
  63. if %input% lss 1 goto :judgeIn
  64. if %input% gtr 9 goto :judgeIn
  65. if defined _%input% (
  66. :judgeIn
  67.  call :err
  68.  set special=1
  69.  goto :begin
  70. )
  71. goto :T_flash
  72. ::电脑下子
  73. :Machine
  74. set sub_flag=%Turn%
  75. if %fate% gtr 1 call :PCI
  76. ::电脑随机下子
  77. :PCR
  78. set Rc=
  79. if defined bN (set/a Rc=%random%%%bN) else set/a Rc="%random%%%(9-fate)"
  80. if not defined Best set Best=%remain: =%
  81. set input=!Best:~%Rc%,1!
  82. set/p=%SP:~3%电脑正在思考 <nul
  83. set "cir=/-\|"
  84. set CN=&set cirN=
  85. :lp
  86. if "%cirN%" geq "4" set/a cirN=0,CN+=1
  87. set/p=!cir:~%cirN%,1!<nul
  88. set/a cirN+=1
  89. ping -n 1 127.1>nul
  90. if "%CN%" leq "3" goto :lp
  91. ::下子后棋盘更新
  92. :T_flash
  93. set _%input%=%sub_flag%
  94. set record=%record%%input%
  95. set remain=!remain:%input%=!
  96. set/a m=(input-1)/3+1,n=(input-1)%%3+1
  97. set/a m2=m*2,n2=n*2,ln=n2-1
  98. set LL=!L%m2%!
  99. set/a pie="(sub_flag+whoFirst)%%2"
  100. set L%m2%=!LL:~,%ln%!!chs%pie%!!LL:~%n2%!
  101. goto :begin
  102. ::----------------------------------------
  103. ::结果显示
  104. :end
  105. set player1=你&set color1=color 3a
  106. set player0=电脑&set color0=color 7e
  107. if defined winflag (echo.%SP:~1%!player%sub_flag%!赢了。&!color%sub_flag%!) else echo.%SP%平局。
  108. set/p=%sp:~3%按任意键重来……<nul
  109. pause>nul
  110. endlocal
  111. goto :newGame
  112. ::============================================================
  113. ::调用标签
  114. ::显示棋盘
  115. :show
  116. echo+
  117. for /l %%i in (7 -1 1) do echo %SP:~2%!L%%i!
  118. if defined argument (
  119.  set argument=
  120.  set L=%L2:~,1%
  121.  set L2=!L! !L! !L! !L!
  122.  set L4=!L2!
  123.  set L6=!L2!
  124. )
  125. goto :eof
  126. ::错误
  127. :err
  128. echo 输入错误,或该位置上已有棋子。请重新输入……
  129. ping -n 2 127.1>nul
  130. goto :eof
  131. ::结束判断,胜负平
  132. ::最笨的列举法
  133. :judgeVic
  134. for %%i in (123 456 789 147 258 369 159 357) do (
  135.  set had=%%i
  136.  set had=!had:~,1! !had:~1,1! !had:~-1!
  137.  for /f "tokens=1-3" %%j in ("!had!") do (
  138.   if "!_%%j!!_%%k!!_%%l!"=="%sub_flag%%sub_flag%%sub_flag%" set winflag=%sub_flag%
  139.  )
  140. )
  141. goto :eof
  142. ::电脑智能下子
  143. :PCI
  144. ::echo Remain%remain%
  145. set/a _subFlag=(sub_flag+1)%%2
  146. set bN=
  147. set ept=&set Epx=
  148. set Best=
  149. set input=
  150. set d_3flag=
  151. for %%c in (%remain%) do (
  152.  set d1=&set d2=&set d3=
  153.  set d_1=&set d_2=&set d_3=
  154.  for %%i in ("1 2 3" "4 5 6" "7 8 9" "1 4 7" "2 5 8" "3 6 9" "1 5 9" "3 5 7") do (
  155.   set isFlag=
  156.   set noFlag=&set _noFlag=
  157.   set/a baseN=1,_baseN=1
  158.   for %%j in (%%~i) do (
  159.    if "%%j"=="%%c" set isFlag=1
  160.    if "!_%%j!"=="%_subFlag%" set/a noFlag=1,_baseN+=1
  161.    if "!_%%j!"=="%sub_flag%" set/a baseN+=1,_noFlag=1
  162.   )
  163.   if defined isFlag (
  164.    if not defined noFlag set/a d!baseN!+=1
  165.    if not defined _noFlag set/a d_!_baseN!+=1
  166.   )
  167.   if defined d3 set Best=%%c&set bN=1&goto :eof
  168.   if defined d_3 set d_3flag=%%c
  169.  )
  170.  set/a ept=baseN+d!baseN!+_baseN+d_!_baseN!
  171.  if "!Epx!" equ "!ept!" set Best=%%c!Best!&set/a bN+=1
  172.  if "!Epx!" lss "!ept!" set Epx=!ept!&set Best=%%c&set bN=1
  173. )
  174. if defined d_3flag set Best=%d_3flag%&set bN=1
  175. goto :eof
复制代码

作者: coolhui    时间: 2009-1-8 01:23

哇,代码好长啊,研究下,楼主辛苦了·~~
作者: 523066680    时间: 2009-1-14 08:22

我又上线了。。。

我的想法:
         也想过写这个东西,已开始想的是利用 九宫格 判断输赢
    因为九宫格是横竖斜 相加都=15 的 这个特性可以利用。剩下的就是细节部分

        定义a1-a9 , 被下的那个去掉定义,
   o第一步,用户下
   x1   随机下,给用户一个“走两条路” 的机会
   o2
      x2  假如15-o1-o2=一个定义的an   说明o再下一个就一线了,....
                若=一个没有意义的an 则x2走自己的路
   ......

暂时就是这些,我就不打算做了。我做了也没人看。倍感孤独,上网,仍感孤独。

建议这个跟def合作做一个 因为def做的五子棋不支持人机对战
这个虽然小型,但是也具有娱乐性,我很喜欢。

另外,我发现技术小组成员好像没搞过什么活动,是不是考虑什么时候找个主题
大家合力打造一个大大的batch? 觉得这个组织好像散散的。。。

另外,觉得def的鼠标.exe 可以做一个打地鼠的游戏。。。。。。
作者: Batcher    时间: 2009-1-14 11:43     标题: 回复 3楼 的帖子

等管理员出差回来以后,会指定一些措施,参考:
http://bbs.bathome.net/thread-2754-1-1.html
作者: wxcute    时间: 2009-1-14 12:13

代码智能下子部分故意留了个小漏洞
合作事宜困难重重。
作者: 523066680    时间: 2009-1-21 09:38

[管理员出差]  了?

真郁闷哟。。我可以上十几天网了。美好时光。。。。
作者: CrLf    时间: 2011-5-22 21:04

我从昨晚开始也在编写井字棋,前面都很简单,唯独到了ai部分没有了方向,若只是随机落子倒是简单,可是井字棋的特点是至少思考3层才不会忽略最优落子,但是我换了各种方法,可惜越写越乱,脑子已经成了浆糊
先把双人版的发上来,今天看到这个帖子才发现思路又和523066680兄撞车了(看来咱俩格外有缘...):
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a str=1492357816,xs=1,xs2=0
  3. set hh=^
  4. set $2=该位置已被使用!hh!
  5. set $3=输入的不是纯数字!hh!
  6. set .0=×
  7. set .1=●
  8. set other=1 2 3 4 5 6 7 8 9
  9. set b=1@2@3,4@5@6,7@8@9,1@4@7,2@5@8,3@6@9,1@5@9,3@5@7
  10. set all=┏━┳━┳━┓!hh!┃1 ┃2 ┃3 ┃!hh!┣━╋━╋━┫!hh!┃4 ┃5 ┃6 ┃!hh!┣━╋━╋━┫!hh!┃7 ┃8 ┃9 ┃!hh!┗━┻━┻━┛
  11. set th=  
  12. setlocal
  13. for /l %%a in (1 1 31) do (
  14. for /f "tokens=1,2" %%b in ("!xs! !xs2!") do (
  15. call :again !errorlevel! !.%%b! !.%%c!
  16. )
  17. set /a "xs=^!xs*^!!errorlevel!+xs*!errorlevel!","xs2=^!xs"
  18. if !errorlevel!==99 (
  19. cls&echo !all!
  20. echo Game Over,!winner!获胜
  21. endlocal&setlocal
  22. pause
  23. )
  24. )
  25. :again
  26. cls&echo !all!
  27. echo;!$%1!!choice!
  28. set winner=%2
  29. set /p n=请输入方格位置
  30. if defined %2%n% (exit /b 2) else (
  31. if "!all!"=="!all:%n% = !" (exit /b 3) else (
  32. set "all=!all:%n% =%2!"
  33. set choice=%choice% %n%
  34. )
  35. set %2%n%=!str:~%n%,1!
  36. )
  37. :test
  38. for %%a in (!b:@^=+%2!) do (
  39. set /a "test+=(%2%%~a)/15"
  40. )
  41. if %test% gtr 0 exit /b 99
  42. exit /b 0
复制代码

作者: CrLf    时间: 2011-5-22 21:07

ai部分没能解决多层剪枝的问题,一直没有成功对3层之内最优解的搜索,快疯了,实在不想继续写了...就这么算了吧,话说这若放在出题区可真是一个好题目




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