Board logo

标题: [特效代码] 批处理人机对战五子棋[新算法重写了核心代码,智能中等] [打印本页]

作者: caruko    时间: 2011-1-8 17:02     标题: 批处理人机对战五子棋[新算法重写了核心代码,智能中等]

一个能玩的BAT版人机对战五子棋游戏,智能大概接近net版主那个。

快过年了,闲的时间不过,“定式”跟“多层搜索”都只完成了一半,发现了很多问题,这里只是写只是修改完善了一下代码。

修改了禁手判断的错误。
增加了同样得分的棋,使用随机走棋。
目前重玩尚有点问题,有时需要关掉黑窗后再双击玩。

不必再去后面翻代码了,已经更新到这里了。
更新日期: 2011-1-29
  1. @echo off
  2. mode con: lines=17 cols=60
  3. :start
  4. setlocal enabledelayedexpansion
  5. ::初始变量
  6. set "tzk=11111_9999999 011110_300000 11110_2500 01111_2500 0011100_3000 11101_2700 10111_2700 11011_2600  11100_500 00111_500 010110_800 011010_800 10011_600 11001_600 10101_550 00011000_650 11000_150 00011_150 0010100_250 010010_200"
  7. set "p_tzk=22222_9999999 022220_300000 22220_2500 02222_2500 0022200_3000 22202_2700 20222_2700 22022_2600 22200_500 00222_500 020220_800 022020_800 20022_600 22002_600 20202_550 00022000_650 22000_250 00022_250 0020200_250 020020_200"
  8. set "C_禁手=0011100_三 011010_三 010110_三 011100_叁 001110_弎 01111_四 11110_四  10111_四 11011_四  11101_四 11111_五 111111_长连"
  9. set "P_禁手=0022200_三 022020_三 020220_三 022200_叁 002220_弎 02222_四 22220_四  20222_四 22022_四  22202_四 22222_五 222222_长连"
  10. set "error1=坐标应为“x,y”形式,并且1-x-15,0-y-15。"
  11. set "error2=x,y坐标越界。"
  12. set "error3=该坐标已有棋子,无法在指定坐标下子。"
  13. set /a 步=0
  14. ::初始化棋盘
  15. for /l %%i in (1 1 15) do (
  16.         set "Display_%%i=┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼"
  17. )
  18. for /l %%i in (1 1 15) do for /l %%j in (1 1 15) do set QP[%%i][%%j]=0
  19. call :显示棋盘
  20. ::设置先手
  21. :xs
  22. set /p 先手=请选择先手(玩家Player:P,电脑Computer:C)
  23. if "!先手!"=="C" (set "行动方=Computerr" & set /a k1=10,k2=7 & set "先手=C" & set "qizi1=○" & set "qizi2=●")
  24. if "!先手!"=="c" (set "行动方=Computer" & set /a k1=10,k2=7 & set "先手=C" & set "qizi1=○" & set "qizi2=●")
  25. if "!先手!"=="p" (set "行动方=Player" & set /a k1=7,k2=10 & set "先手=P" & set "qizi1=●" & set "qizi2=○")
  26. if "!先手!"=="P" (set "行动方=Player" & set /a k1=7,k2=10 & set "先手=P" & set "qizi1=●" & set "qizi2=○")
  27. if not defined 先手 goto :xs
  28. if "!先手!"=="C" (call :设置坐标 8 8 1) else (call :设置坐标 8 8 2 &goto :loop2)
  29. :loop
  30. call :显示棋盘
  31. call :玩家走 ||(echo,!error%ERRORLEVEL%!&goto :loop)
  32. :loop2
  33. call :显示棋盘
  34. call :电脑走
  35. goto :loop
  36. :玩家走
  37. set "行动方=Player"
  38. set /a zq=0
  39. set /p P_zb=请输入坐标{1-15,1-15}:
  40. for /f "tokens=1,2 delims=," %%a in ("!P_zb!") do (
  41.         if %%a GTR 0 if %%a LSS 16 set /a zq+=1
  42.         if %%b GTR 0 if %%b LSS 16 set /a zq+=1
  43.         if "!QP[%%a][%%b]!"=="0" set /a zq+=1
  44.         if "!zq!"=="3" call :设置坐标 %%a %%b 2
  45. )
  46. if "!P_zb!"=="exit" exit
  47. if !zq! EQU 0 exit /b 1
  48. if !zq! EQU 1 exit /b 2
  49. if !zq! EQU 2 exit /b 3
  50. exit /b 0
  51. :电脑走
  52. set "行动方=Computer"
  53. set /a 最高分=0,num=0
  54. for /l %%x in (1 1 15)  do (
  55.         for /l %%y in (1 1 15) do (
  56.                 if defined C_soce[%%x][%%y] (
  57.                         set "m=!C_soce[%%x][%%y]!"
  58.                         set "n=!P_soce[%%x][%%y]!"
  59.                         set /a m=!m!,n=!n!,mn=m*!k1!+n*!k2!
  60.                         if !最高分! EQU !mn! (
  61.                           set /a num+=1
  62.                           set "坐标集=!坐标集! [%%x][%%y]"
  63.                          )
  64.                         if !最高分! LSS !mn! (
  65.                                 set /a 最高分=!mn!,num=1
  66.                                 set "坐标集=[%%x][%%y]"
  67.                         )
  68.                 )
  69.         )
  70. )
  71. rem 坐标集可能含有多个坐标,以后应用在αβ剪枝算法中,现在只随机取一个。
  72. set /a get=%RANDOM%%%num+1,dd=0
  73. for %%i in (!坐标集!) do (
  74.         set /a dd+=1
  75.         if !dd! equ !num! (
  76.             for /f "tokens=1,2 delims=[]" %%x in ("%%i") do (
  77.                 call :设置坐标 %%x %%y 1
  78.              )
  79.          )
  80. )
  81. goto :eof
  82. :胜利
  83. call :显示棋盘
  84. if "%1"=="禁手" (
  85.   echo !行动方!范"!禁!"禁手,该局判负!
  86. ) else (
  87.   echo !行动方!五子连珠,赢得该局胜利!
  88. )
  89. set /p =按任意键重新开始游戏!<nul
  90. pause>nul
  91. endlocal
  92. goto :start
  93. goto :eof
  94. :显示棋盘
  95. for /l %%i in (15 -1 1) do (
  96.     echo %%i !Display_%%i!
  97. )
  98. echo,Y↑X→ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  99. goto :eof
  100. :设置坐标 [x] [y] [1,2]
  101. set /a QP[%1][%2]=%3,x=%1,y=%2,z=%3,cut1=x-1,cut2=x,最高分=0,fens=0,步+=1
  102. set "cr=!qizi%3!"
  103. set "Display_!y!=!Display_%y%:~0,%cut1%!!cr!!Display_%y%:~%cut2%!"
  104. set "第!步!步=%1,%2"
  105. ::判断禁手,“三四” “成五” 不算禁手,"弎""叁"看似不是活三,两个一起构不成活四,但是跟别的活三,四搭配仍然是活三。
  106. set "禁="
  107. set "j="
  108. if "!行动方:~0,1!"=="!先手!" (
  109.     for %%i in (!%先手%_str[%1][%2]!) do (
  110.       for %%D in (!%先手%_禁手!) do (
  111.         for /f "tokens=1,2 delims=_" %%E in ("%%D") do (
  112.           set "sstr=%%i"
  113.           if not "!sstr!"=="!sstr:%%E=@!" set "j=%%F"
  114.         )
  115.       )
  116.       set 禁=!禁!!j!
  117.       set "j="
  118.   )
  119. )
  120. if "!禁!"=="三四" set "禁="
  121. if not "!禁!"=="!禁:叁=!" if not "!禁!"=="!禁:弎=!" set "禁="
  122. if not "!禁!"=="!禁:五=!" if "!禁!"=="!禁:长连=!" set "禁="
  123. if "!禁:~1,1!"=="" set "禁="
  124. if defined 禁 call :胜利 禁手
  125. ::判断是否5连,断定胜负
  126. if !步! GTR 1 if "!行动方!"=="Computer" (set /a fens=!C_soce[%1][%2]!) else (set /a fens=!P_soce[%1][%2]!)
  127. if !fens! GEQ 9999999 call :胜利
  128. set "C_str[%1][%2]="
  129. set "C_soce[%1][%2]="
  130. set "P_soce[%1][%2]="
  131. set "P_str[%1][%2]="
  132. ::落子点估值
  133. for /l %%i in (1 1 4) do (
  134.         for %%j in (%%i_0 %%i_-%%i 0_-%%i -%%i_-%%i -%%i_+0 -%%i_+%%i 0_%%i %%i_%%i) do (
  135.                 for /f "tokens=1,2 delims=_" %%x in ("%%j") do (
  136.                         set /a xx=x+%%x,yy=y+%%y
  137.                         for /f "tokens=1,2" %%a in ("!xx! !yy!") do (
  138.                                 if defined QP[%%a][%%b] if !QP[%%a][%%b]! EQU 0 (
  139. rem 更新双方字串并评分,没有的则重新创建,只更新 x-4 => x+4 范围且在一条直线上的评分。
  140. set /a a=%%a,b=%%b,c=1
  141. if "!C_str[%%a][%%b]!"=="" (
  142.         set /a c_str1=c,c_str2=c,c_str3=c,c_str4=c,p_str1=2,p_str2=2,p_str3=2,p_str4=2
  143.         for /l %%I in (-1 -1 -4) do (
  144.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  145.                 if !xxx! LSS 1 (
  146.                         set /a lj1=1
  147.                         set "c_str1=x!c_str1!"
  148.                         set "p_str1=x!p_str1!"
  149.                 ) else (
  150.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  151.                                 set "c_str1=!QP[%%A][%%B]!!c_str1!"
  152.                                 set "p_str1=!QP[%%A][%%B]!!p_str1!"
  153.                         )
  154.                 )
  155.                 if !yyy! LSS 1 (
  156.                         set /a lj1=1
  157.                         set "c_str2=x!c_str2!"
  158.                         set "p_str2=x!p_str2!"
  159.                 ) else (
  160.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  161.                                 set "c_str2=!QP[%%A][%%B]!!c_str2!"
  162.                                 set "p_str2=!QP[%%A][%%B]!!p_str2!"
  163.                         )
  164.                 )
  165.                 if !lj1! EQU 1 (
  166.                         set "c_str3=x!c_str3!"
  167.                         set "p_str3=x!p_str3!"
  168.                 ) else (
  169.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  170.                                 set "c_str3=!QP[%%A][%%B]!!c_str3!"
  171.                                 set "p_str3=!QP[%%A][%%B]!!p_str3!"
  172.                         )
  173.                 )
  174.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  175.                 if !xxx! LSS 1 set /a lj1=1
  176.                 if !yyy! GTR 15 set /a lj1=1
  177.                 if !lj1! EQU 1 (
  178.                         set "c_str4=x!c_str4!"
  179.                         set "p_str4=x!p_str4!"
  180.                 ) else (
  181.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  182.                                 set "c_str4=!QP[%%A][%%B]!!c_str4!"
  183.                                 set "p_str4=!QP[%%A][%%B]!!p_str4!"
  184.                         )
  185.                 )
  186.         )
  187.         for /l %%I in (1 1 4) do (
  188.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  189.                 if !xxx! GTR 15 (
  190.                         set /a lj1=1
  191.                         set "c_str1=!c_str1!x"
  192.                         set "p_str1=!p_str1!x"
  193.                 ) else (
  194.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  195.                                 set "c_str1=!c_str1!!QP[%%A][%%B]!"
  196.                                 set "p_str1=!p_str1!!QP[%%A][%%B]!"
  197.                         )
  198.                 )
  199.                 if !yyy! GTR 15 (
  200.                         set /a lj1=1
  201.                         set "c_str2=!c_str2!x"
  202.                         set "p_str2=!p_str2!x"
  203.                 ) else (
  204.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  205.                                 set "c_str2=!c_str2!!QP[%%A][%%B]!"
  206.                                 set "p_str2=!p_str2!!QP[%%A][%%B]!"
  207.                         )
  208.                 )
  209.                 if !lj1! EQU 1 (
  210.                         set "c_str3=!c_str3!x"
  211.                         set "p_str3=!p_str3!x"
  212.                 ) else (
  213.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  214.                                 set "c_str3=!c_str3!!QP[%%A][%%B]!"
  215.                                 set "p_str3=!p_str3!!QP[%%A][%%B]!"
  216.                         )
  217.                 )
  218.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  219.                 if !xxx! GTR 15 set /a lj1=1
  220.                 if !yyy! LSS 1 set /a lj1=1
  221.                 if !lj1! EQU 1 (
  222.                         set "c_str4=!c_str4!x"
  223.                         set "p_str4=!p_str4!x"
  224.                 ) else (
  225.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  226.                                 set "c_str4=!c_str4!!QP[%%A][%%B]!"
  227.                                 set "p_str4=!p_str4!!QP[%%A][%%B]!"
  228.                         )
  229.                 )
  230.         )
  231.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  232.         for %%X in (!tzk!) do (
  233.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  234.                         for /l %%W in (1 1 4) do (
  235.                                 if not "!c_str%%W!"=="!c_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  236.                         )
  237.                 )
  238.         )
  239.         set "C_str[!a!][!b!]=!c_str1!,!c_str2!,!c_str3!,!c_str4!"
  240.         set "C_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  241.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  242.         for %%X in (!p_tzk!) do (
  243.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  244.                         for /l %%W in (1 1 4) do (
  245.                                 if not "!p_str%%W!"=="!p_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  246.                         )
  247.                 )
  248.         )
  249.         set "P_str[!a!][!b!]=!p_str1!,!p_str2!,!p_str3!,!p_str4!"
  250.         set "P_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  251. rem end 创建。
  252. ) else (
  253. rem 更新字串及评分,已存在的点会加快效率。
  254.         if %%x NEQ 0 (
  255.                 set /a cut1=5-%%x-1,cut2=5-%%x,tk=1,pd=%%x+%%y
  256.                 if !pd! EQU 0 (
  257.                         set /a cut1=cut1+30,cut2=cut2+30,tk=4
  258.                 )
  259.                 if %%x EQU %%y (
  260.                         set /a cut1=cut1+20,cut2=cut2+20,tk=3
  261.                 )
  262.         ) else (
  263.                 set /a cut1=15-%%y-1,cut2=15-%%y,tk=2
  264.         )
  265.         for /f "tokens=1,2" %%X in ("!cut1! !cut2!") do (
  266.                 set "C_str[%%a][%%b]=!C_str[%%a][%%b]:~0,%%X!!z!!C_str[%%a][%%b]:~%%Y!"
  267.                 set "P_str[%%a][%%b]=!P_str[%%a][%%b]:~0,%%X!!z!!P_str[%%a][%%b]:~%%Y!"
  268.         )
  269.         for /f "tokens=1-4 delims=+" %%A in ("!C_soce[%%a][%%b]!") do (
  270.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  271.         )
  272.         set /a soce=0,ttk=tk*10-10
  273.         for %%T in (!ttk!) do (
  274.                 set "t_str=!C_str[%%a][%%b]:~%%T,9!"
  275.         )
  276.         for %%Q in (!tzk!) do (
  277.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  278.                         if not "!t_str!"=="!t_str:%%A=@!" (
  279.                                 if !soce! LSS %%B set /a soce=%%B
  280.                         )
  281.                 )
  282.         )
  283.         set /a soce!tk!=!soce!
  284.         set "C_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  285. rem 更新player评分
  286.         for /f "tokens=1-4 delims=+" %%A in ("!P_soce[%%a][%%b]!") do (
  287.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  288.         )
  289.         set /a soce=0
  290.         for %%T in (!ttk!) do (
  291.                 set "t_str=!P_str[%%a][%%b]:~%%T,9!"
  292.         )
  293.         for %%Q in (!p_tzk!) do (
  294.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  295.                         if not "!t_str!"=="!t_str:%%A=@!" (
  296.                                 if !soce! LSS %%B set /a soce=%%B
  297.                         )
  298.                 )
  299.         )
  300.         set /a soce!tk!=!soce!
  301.         set "P_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  302. )
  303. rem end更新
  304.                                 )
  305.                         )
  306.                 )
  307.         )
  308. )
复制代码

[ 本帖最后由 caruko 于 2011-1-29 23:24 编辑 ]
作者: caruko    时间: 2011-1-8 17:12

写这个东西的时候有一个发现..
可以使用 endlocal&exit /b %var% 后来又发现 endlocal &set var=%var%的方式,将LOCAL内的变量带出来.
但是不支持需要扩展的变量!var!

setlocal  endlocal 以及这个小东西,帮我解决了很大的麻烦..
虚拟走棋变的方便多了..
作者: caruko    时间: 2011-1-8 19:50

尝试了一下,打开15个进程来计算评分,每个进程最多处理15个坐标,仍然花了4分钟,单进程也才5分多钟..

cmd的效率,看来是没办法了...
作者: netbenton    时间: 2011-1-8 20:12     标题: 回复 3楼 的帖子

终于又有人对人机对战五子棋感兴趣了,希望楼主搞出比我的更高智能的,呵呵
作者: caruko    时间: 2011-1-8 22:03

我是把棋盘上的数据用012来做成字符串,分为横15列15左斜21右斜21,一共72条字符串。
形式如: 001110220100

通过setlocal-endlocal的继承环境,但不改变变量的特性,做到假设在某个位置走了一步棋后,通过判断库中的特征字串,findstr 查出符合的,给予相应分数。包括 横列斜 多种方式匹配,分数相加,最后得出分数最高的坐标。


因此,只要判断库的“匹配字串”跟“分数”设置合理,完全可以做到很智能..
但是下一步棋可以泡几杯茶..

[ 本帖最后由 caruko 于 2011-1-8 22:05 编辑 ]
作者: hanyeguxing    时间: 2011-1-8 22:27

在这样的代码中,算法优化远比代码优化更重要
作者: caruko    时间: 2011-1-8 22:37

原本还想解决人机问题后,通过ipc$共享,使用at命令交换数据,做一个网络版五子棋的,还能支持聊天...
作者: 随风    时间: 2011-1-9 05:30

效率跟代码设计很有关系,先不说楼主的代码设计如何,单就语法上提几个建议
1、尽量不要反复使用 findstr 或 find 命令,这是狂耗效率的,最好不用。
2、call 命令最好也别使用,由其是在循环中
3、所有的 call set 。。。。 都改用for中转变量
作者: caruko    时间: 2011-1-9 12:05

听从楼上建议
嗯...主要资源都耗在特征字串匹配这上面..
我试试用字符串替换来检测匹配...
时间减少了一半 =.=,跑一步2-3分钟,72个循环的速度比一个findstr还快一倍..
IF里的CALL 使用跳过代码的办法减少了好几秒。。


在想是不是合并72个字符串到一个字符串上,然后使用按优先级顺序匹配的办法..
这样效率将大大提升,预计<30秒,但是智能大打折扣。

[ 本帖最后由 caruko 于 2011-1-9 15:28 编辑 ]
作者: netbenton    时间: 2011-1-10 10:54

楼主,针对比题,我再提点高效的方法:用if判断字符串经替换后与原来的是否相同,来代替finstr的查找,把要显示的内容全存到一个变量,一次echo,代替多个set /p,用for /f %%i中的%%i可实现endlocal把值回传,效率是call几倍

[ 本帖最后由 netbenton 于 2011-1-10 11:07 编辑 ]
作者: caruko    时间: 2011-1-10 19:05

字符替换已经这么做了,除了判断胜负的没改,其它地方已经没有findstr了..

上面那个特征库已经不适合了,必须重新制作大量精准的特征库..
现在这种模糊特征库,可能会导致棋盘原数据匹配到较低分值的特征,导致评分跟预想的差距很多..

嗯,一次echo棋盘确实可以加快.. 现在的棋盘也还没做好....
或许用替换的方式,将012替换为。".@#", ","替换为"&echo,"的办法来输出。

只是这个for /f %%i 怎么带出变量还是没明白,..
作者: netbenton    时间: 2011-1-18 19:27     标题: 楼主,你勾起了我修改五子棋的想法,就消失了

这是我在我原来的基上做的增强工作,


1,在处理禁手规则上,长连禁手、三三,及四四禁手都已经解决了,
2,现在的IQ对拼杀已经做得较全面了,
3,接下来要是有时间的话,再加入布局IQ,以及补杀IQ,就算是一个高智能的五棋游戏了


下面代码是可以玩的,请对五子棋感兴趣的朋友帮忙测试下,并提点意见~~
  1. @echo off&setlocal enabledelayedexpansion
  2. mode con: lines=43 cols=110
  3. set li39=    A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S
  4. set  li0=  ┌─────────────────────────────────────┐
  5. set  li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
  6. set var=1
  7. for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
  8. for /l %%a in (2,2,36) do (set li%%a=  ││  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  │  ││)
  9. set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
  10. set li38=  └─────────────────────────────────────┘
  11. set str=a b c d e f g h i j k l m n o p q r s
  12. for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)
  13. set li5=!li5!   五 棋 子 人 机 对 战
  14. set li7=!li7!        批 处 理
  15. set li10=!li10!      电 脑 水 平 中 等
  16. set li31=!li31!  由 netbenton 编写完成
  17. set li33=!li33!  棋盘设计参照了 batman
  18. title   批处理五子棋
  19. set str=###################
  20. set .=0
  21. for /l %%a in (1,1,19) do (
  22. set he%%a=!str!&set sh%%a=!str!
  23. for /l %%b in (1,1,19) do set [%%a.%%b=0
  24. )
  25. set .=37
  26. for /l %%a in (1,1,19) do (
  27. set pi%%a=!str:~,%%a!&set ni%%a=!str:~,%%a!
  28. set pi!.!=!str:~,%%a!&set ni!.!=!str:~,%%a!
  29. set/a .-=1
  30. )
  31. set ●=○&set ○=●
  32. set zhi=●
  33. set say=say
  34. ::读取电脑五子棋IQ
  35. for /f "usebackq tokens=*" %%a in ("%~dpnx0") do (
  36.   if defined idea (
  37. set idea=!idea! %%a
  38.   ) else (
  39. if "%%a" equ "五子棋IQ" set "idea= "
  40.   )
  41. )
  42. set jing=-100000
  43. :restart
  44. (
  45. setlocal enabledelayedexpansion
  46. for /l %%a in (0,1,39) do (echo    !li%%a!)
  47. set li39=!li39!   reboot重新开始,exit退出。
  48. set li37=!li37!       back 悔棋
  49. set /p var=选择谁先下[ W,玩家  D,电脑  Q,退出 ]:
  50. if /i "!var!" equ "Q" goto :quit
  51. if /i "!var!" equ "D" (set onez=○&set towz=●&set hou=☆) else (set onez=●&set towz=○&set hou=★)
  52. set a!onez!=电脑&set a!towz!=玩家
  53. )
  54. (
  55. set ttr=!idea:@=%onez%!&set ttr=!ttr:$=%towz%!
  56. set idea=
  57. for %%a in (!ttr!) do (
  58. for /f "tokens=1,2 delims=." %%b in ("%%a") do (set %%b=%%c&set idea=!idea! %%b)
  59. )
  60. set ttr=
  61. set li27=!li27!    !onez! !a%onez%!
  62. set li25=!li25!    !towz! !a%towz%!
  63. set/a pos=10,poh=10&goto :getok
  64. )
  65. :loop
  66. (if %zhi% equ %onez% goto :men
  67. set .=
  68. setlocal enabledelayedexpansion
  69. if "!onez!" equ "○" (set/a 本方jing=50000,对方jing=0) else (set/a 本方jing=0,对方jing=50000&call :禁手检查)
  70. for %%b in (he sh) do (
  71. set all%%b=!%%b1!!%%b2!!%%b3!!%%b4!!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!
  72. )
  73. for %%b in (pi ni) do (
  74. set all%%b=!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!!%%b20!!%%b21!!%%b22!!%%b23!!%%b24!!%%b25!!%%b26!!%%b27!!%%b28!!%%b29!!%%b30!!%%b31!!%%b32!!%%b33!
  75. )
  76. for %%a in (!idea!) do (
  77. set str=%%a
  78. if "!str:~,2!" neq "vs" (
  79. for %%b in (he sh) do (
  80.   if "!all%%b:%%a=!" neq "!all%%b!" (
  81.    for /l %%c in (1,1,19) do (
  82.     if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a
  83.    )
  84. ) )
  85. for %%b in (pi ni) do (
  86.   if "!all%%b:%%a=!" neq "!all%%b!" (
  87.    for /l %%c in (5,1,33) do (
  88.     if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a
  89.    )
  90. ) )
  91. ) else (
  92.   if %%a equ vs8 if defined . goto :get
  93.   if %%a equ vs9 if defined . goto :get
  94.    
  95. )
  96. ))
  97. if defined . (goto :get)
  98. echo. 已经和棋了
  99. pause
  100. endlocal&goto :restart
  101. :men
  102. (
  103. set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%hou%!%%b:~%%c!)
  104. set li38=!li38![%悔:~,24%]
  105. cls
  106. for /l %%a in (0,1,39) do (echo    !li%%a!)
  107. for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
  108. set li38=%li38%
  109. set /p user=!say:say=%error%! [列前,行后]:
  110. if "!user!" equ "reboot" endlocal&goto :restart
  111. if "!user!" equ "exit" goto :quit
  112. if "!user!" equ "back" call :悔&goto :men
  113. set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
  114. if not defined [!poh!.!pos! set error=输入点不存在&goto :men
  115. )
  116. if "!he%poh%:~%var%,1!" neq "#" set error=该点已经有子&goto men
  117. goto :getok
  118. :get
  119. rem set put&pause
  120. set `=
  121. ::取最佳的走法
  122. for /l %%z in (!.!,-1,1) do (
  123. for /f "tokens=1,2,3 delims=." %%1 in ("!put%%z!") do (
  124. for /f "tokens=1-4" %%a in ("%%1 %%2") do (
  125. set vara=!%%a%%b:*%%c=!srqponmlkjihgfedcba0
  126. for %%i in (!%%2:-^=;!) do (
  127.     for /f "tokens=1,2 delims=:" %%4 in ("%%i") do (
  128.   set/a var=!vara:~19,1!+%%4
  129.   if "%%a" equ "he" (set/a poh=%%b,pos=20-var)
  130.   if "%%a" equ "sh" (set/a poh=20-var,pos=%%b)
  131.   if %%b lss 19 (set/a var=%%b-var+1) else (set/a var=38-%%b-var+1)
  132.   if "%%a" equ "pi" (if %%b lss 19 (set/a pos=var,poh=%%b-var+1) else (set/a poh=20-var,pos=%%b-19+var))
  133.   if "%%a" equ "ni" (if %%b lss 19 (set/a pos=var,poh=19-%%b+var) else (set/a poh=var,pos=%%b-19+var))
  134.   if not defined R!pos!R!poh!R set /a `+=1&set ram!`!=R!pos!R!poh!R&set R!pos!R!poh!R=1000000000
  135.   set/a R!pos!R!poh!R+=%%5
  136.     )
  137. )
  138. )
  139. )
  140. )
  141. set test=
  142. set rmk=0
  143. for /l %%a in (1,1,!`!) do (
  144. for %%b in (!ram%%a!) do (
  145.      if "!%%b:~-4!" neq "0000" (
  146.   rem 四,三,识别
  147. set test=!test! "!%%b!
  148. set /a xd=!%%b:~-1!,xc=!%%b:~-2,-1!,xb=!%%b:~-3,-2!,xa=!%%b:~-4,-3!
  149. set /a "%%b=%%b/10000+(xd+xc)/2*(xd*500+xc*1000) - (xd/2+xc/2) * 本方jing + (xb+xa)/2*(xb*500+xa*1000) - (xb/2+xa/2) * 对方jing"
  150.   rem 四,三,识别
  151. set test=!test! %%b:    !%%b!"
  152.             ) else (
  153.   set %%b=!%%b:~,-4!
  154.      )
  155.   for %%c in (!%%b!) do (
  156.    if %%c gtr !rmk! set/a rmk=%%c,.=0
  157.    if %%c equ !rmk! set rmz!.!=%%b&set/a .+=1
  158.   )
  159. ) )
  160. rem if defined test start for %%a in (!test!) do @echo;%%a
  161. set jing=%.%
  162. set/a .=!random!%%.
  163. for /f "tokens=1,2 delims=R" %%a in ("!rmz%.%!") do (set/a pos=%%a,poh=%%b)
  164. rem start set r^&echo !.!^&pause^&exit
  165. endlocal&set/a pos=%pos%,poh=%poh%&   set jing=%rmk%{%jing%}&set 禁手=%禁手%
  166. set say=say !z%pos%!!z%poh%!(%poh%)&set error=电脑最后下在:[!jing!]
  167. :getok
  168. set 下之前=
  169. set 下之后=
  170. set zhi=!%zhi%!&set win=!zhi!!zhi!!zhi!!zhi!!zhi!
  171. (set/a piph=poh+pos-1,lips=pos*2+1,niph=19+pos-poh,liph=poh*2-1
  172. if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)
  173. if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)
  174. for %%a in ("li!liph! !lips!" "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do (
  175. for /f "tokens=1,2" %%b in (%%a) do (
  176.   set/a .=%%c-1
  177.   set 下之前=!下之前!!%%b!
  178.   for %%d in (!.!) do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
  179.   set 下之后=!下之后!!%%b!
  180. )
  181. ))
  182. if "!下之后:%win%=!" neq "!下之后!" set win=y
  183. if defined 禁手 set win=y&set 禁手=玩家%禁手%  
  184. set 下之前=!下之前:* =!
  185. set 下之后=!下之后:* =!
  186. (set/a asc%zhi%+=1
  187. set 悔= !z%pos%!!z%poh%!!悔!
  188. if !win! neq y goto :loop)
  189. for /l %%a in (0,1,39) do (echo    !li%%a!)
  190. set/p=   %禁手%!a%zhi%! %zhi%子 第!asc%zhi%!手 !z%pos%!!z%poh%!(%poh%)  胜出   <nul
  191. pause
  192. endlocal&goto :restart
  193. :悔
  194. if not defined 悔 goto :eof
  195. if "!悔:~6,1!" equ "" goto :eof
  196. for %%a in (!悔:~^,6!) do (set str=%%a
  197. set/a poh=!str:~-1!,pos=!str:~,1!
  198. set/a piph=poh+pos-1,niph=19+pos-poh,liph=poh*2-1,lips=pos*2+1
  199. if !piph! lss 19 (set/a pips=pos) else (set/a pips=20-poh)
  200. if !niph! lss 19 (set/a nips=pos) else (set/a nips=poh)
  201. for %%a in ( "he!poh! !pos!" "sh!pos! !poh!" "pi!piph! !pips!" "ni!niph! !nips!") do (
  202. for /f "tokens=1,2" %%b in (%%a) do (
  203.    set/a .=%%c-1
  204.    for %%d in (!.!) do (set %%b=!%%b:~0,%%d!#!%%b:~%%c!)
  205. )
  206. )
  207. for /f "tokens=1,2" %%b in ("li!liph! !lips!") do (
  208. set/a .=%%c-1
  209. for %%d in (!.!) do (set %%b=!%%b:~0,%%d!┼!%%b:~%%c!)
  210. ))
  211. set/a asc%zhi%-=1
  212. set 悔=!悔:~6!
  213. set error=你悔棋,耍赖皮!
  214. if not defined 悔 goto :eof
  215. set/a poh=!悔:~2,1!,pos=!悔:~1,1!,liph=poh*2-1,lips=pos*2+1
  216. set say=say !z%pos%!!z%poh%!(%poh%)
  217. goto :eof
  218. :quit
  219. taskkill /fi "WINDOWTITLE eq 批处理五子棋*" /im cmd.exe
  220. exit/b
  221. :禁手检查
  222. setlocal enabledelayedexpansion
  223. set 禁手=
  224. if "!下之后:○○○○○○=!" neq "!下之后!" set 禁手=长连禁手
  225. (
  226. for %%a in (#○○○## ##○○○# #○○#○# #○#○○#) do (
  227.     set 下之后=!下之后:%%a=" " !
  228.     set 下之前=!下之前:%%a=" " !
  229. )
  230. for %%a in (!下之后!) do (set /a 三后+=1)
  231. for %%a in (!下之前!) do (set /a 三前+=1)
  232. set/a 三=三后-三前
  233. set 下之前=%下之前%
  234. set 下之后=%下之后%
  235. for %%a in (#○○○○ ○#○○○ ○○#○○ ○○○#○ ○○○○#) do (
  236.     set 下之后=!下之后:%%a=" " !
  237.     set 下之前=!下之前:%%a=" " !
  238. )
  239. for %%a in ("!下之后!") do (set /a 四后+=1)
  240. for %%a in ("!下之前!") do (set /a 四前+=1)
  241. set/a 四=四后-四前
  242. )
  243. if !四! gtr 1 set 禁手=四四禁手
  244. if !三! gtr 1 set 禁手=三三禁手
  245. endlocal&set 禁手=%禁手%&exit/b
  246. :://2010-1-10 增加//
  247. :: 每种棋型串直接给出分值,甚至每个可下点给出分值,遇 vs 时如果有匹配,结束,
  248. :: 统计的内容:
  249. ::    一:必走棋;
  250. ::    二:分值相加:攻攻(4-3 3-3 4-4),攻防(不分),防防(4-3 3-3 4-4),同线不加,
  251. ::    三:布局
  252. ::    四:如何利用单三冲四
  253. ::
  254. ::   怎么计算禁手点,及对方是否下了禁手点
  255. ::   眠三/活二 在什么时候该冲,或是测试冲后是否可以杀棋,当冲了眠三后,对手只能下拦截点一点,而冲了活二后对手可以下的点有二个以上(两头,或冲四点)
  256. ::
  257. :://2010-1-10 增加//
  258. 流程:
  259. 开始:根据难度初始化回调层次 cengc(3)
  260. #开始分析
  261. 0 首先找出本方禁手点,可冲四点,可冲活三点,敌方冲四点,冲活三点
  262. 1 必下棋 (过滤长连禁手),退出(返回下点及禁手点及利弊值0-9)
  263.   1.9 冲5及活三冲四利为9,被逼下禁手利为0,
  264. 2 选下棋,对眠三,活二 进行模拟下子,对有可能一直冲到死棋的进行冲,(过虑禁手规则),退出(返回最优点及禁手点)
  265.   2.0 首先过虑自已方禁手,不要下,留着送返回
  266.   2.1 眠三冲四后 转到对方下,调用 [#开始分析],如果返回1的下点,在禁手点内,则就选该点,
  267.       否则摸拟走子一回合,再调用[#开始分析],如果返回最终结果对本方有利则选该点,否则放弃走该点
  268.   2.2 活二冲活三后 转到对方下,调用 [#开始分析],如果返回的下点,在禁手点内,则就选该点
  269.   2.9
  270. 3 对敌方的眠三,活二进行摸拟下子,对如果有可能一直冲到死棋的提前截掉,(过虑禁手规则),退出(返回最优点及下后敌方禁手点)
  271.   3.9
  272. 4 取一个分值高的点,若有多个随机取一个,层计数减1,退出
  273.   4.9
  274. 1 全盘扫描,记下规则串+棋盘串号 a4 b4 a3 A3 b3 B3 A2 a2 B2 b2 A1 B1
  275. 2 根据规则串+棋盘串号,统计所有可下点的影响力(比如:组成一个活三,组成一个活四,组成2个活三,等)
  276. 1,防止反攻
  277. 2,眠三冲四,无效的不冲(冲后,不能增加(活二,眠三,或者阻止对方的活二及眠三),
  278. 在冲活二时,选点考滤活一在先,眠一在后
  279. 本方4 3 则乘以3
  280. 4 4 如果是黑方*0,否则*3
  281. 3 3 如果是黑方*0,否则+30
  282. 对方4 3 则乘以2
  283. 4 4 如果是黑方*0,否则*2
  284. 3 3 如果是黑方*0,否则+20
  285. 双方4 3 ,4 4, 3 3 则仅仅相加
  286. ┼┼┼┼┼┼┼┼
  287. ┼★●●●●★┼ 活四点★
  288. ┼┼┼┼┼┼┼┼
  289. 1000      1000
  290.   
  291. ┼┼┼┼┼┼┼┼
  292. ☆★●●●★☆┼ 活三冲 活四点★ 眠四点☆
  293. ┼┼┼┼┼┼┼┼
  294. 1599      9915
  295. ┼┼┼┼┼┼┼┼
  296. ┼☆●★●●☆┼ 活三冲 活四点★ 眠四点☆
  297. ┼┼┼┼┼┼┼┼
  298.   15  99    15
  299. ┼┼┼┼┼┼┼┼
  300. ┼○☆●●●★☆ 活三冲 活四点★ 眠四点☆
  301. ┼┼┼┼┼┼┼┼
  302.     15      9015
  303. ┼┼┼┼┼┼┼┼
  304. ┼┼●☆☆●●┼ 跨三冲 眠四点☆
  305. ┼┼┼┼┼┼┼┼
  306.       1515
  307. ┼┼┼┼┼┼┼┼
  308. ┼○●●●☆☆┼ 眠三冲 眠四点☆
  309. ┼┼┼┼┼┼┼┼
  310.           1515
  311. ┼┼┼┼┼┼┼┼
  312. ┼○●●☆●☆┼ 眠三冲 眠四点☆
  313. ┼┼┼┼┼┼┼┼
  314.         15  15
  315. ┼┼┼┼┼┼┼┼
  316. ┼○●☆●●☆┼ 眠三冲 眠四点☆
  317. ┼┼┼┼┼┼┼┼
  318.       15    15
  319. ┼┼┼┼┼┼┼┼
  320. ┼○●☆☆●●┼ 眠三冲 眠四点☆
  321. ┼┼┼┼┼┼┼┼
  322.       1515
  323. ┼┼┼┼┼┼┼┼
  324. ┼○●●☆☆●┼ 眠三冲 眠四点☆
  325. ┼┼┼┼┼┼┼┼
  326.         1515
  327. ┼┼┼┼┼┼┼┼
  328. ☆★★●●★★☆ 活二冲 活三点★ 眠三点☆
  329. ┼┼┼┼┼┼┼┼
  330. 122030    302012
  331. ┼┼┼┼┼┼┼┼
  332. ☆★●★●★☆┼ 跨二冲 活三点★ 眠三点☆
  333. ┼┼┼┼┼┼┼┼
  334. 1220  30  2012
  335. ┼┼┼┼┼┼┼┼
  336. ┼☆●★★●☆┼ 大跨二冲 活三点★ 眠三点☆
  337. ┼┼┼┼┼┼┼┼
  338.   12  2020  12
  339. ┼┼┼┼┼┼┼┼
  340. ┼○●●★★☆┼┼眠二冲 眠三点☆
  341. ┼┼┼┼┼┼┼┼
  342.         111110
  343. ┼┼┼┼┼┼┼┼
  344. ┼○●☆●☆☆┼ 眠二冲 眠三点☆
  345. ┼┼┼┼┼┼┼┼
  346.       10  1010
  347. ┼┼┼┼┼┼┼┼
  348. ┼○●☆☆●☆┼ 眠二冲 眠三点☆
  349. ┼┼┼┼┼┼┼┼
  350.       10 8  8
  351. ┼┼┼┼┼┼┼┼
  352. ┼○●☆☆☆●┼ 眠二冲 眠三点☆
  353. ┼┼┼┼┼┼┼┼
  354.       10 8 8
  355. ┼┼┼┼┼┼┼┼
  356. ┼○●●☆☆☆┼眠二冲 眠三点☆
  357. ┼┼┼┼┼┼┼┼
  358.         101112
  359. ┼┼┼┼┼┼┼┼┼┼
  360. ☆★★★●★★★☆┼ 活一 冲活二
  361. ┼┼┼┼┼┼┼┼┼┼
  362. 1 4 7 9   9 7 4  1   
  363. ┼┼┼┼┼┼┼┼
  364. ○☆●★★★┼┼ 活一 冲活二
  365. ┼┼┼┼┼┼┼┼
  366.   1   4 6 5 2
  367. ┼┼┼┼┼┼┼┼
  368. ○☆★●★★★☆ 活一 冲活二
  369. ┼┼┼┼┼┼┼┼
  370.   1  4  8 7 4 3
  371. ┼┼┼┼┼┼┼┼
  372. ┼○●☆★★★┼ 眠一
  373. ┼┼┼┼┼┼┼┼
  374.       1 2 2 1
  375. 本方活三为个位,如1 00 01
  376. 本方四  为十位,如1 00 10
  377. 对方活三为百位,如1 01 00
  378. 对方四  为千位,如1 10 00
  379. 本方三、三 若是黑子则 -1000  白子则 +1000
  380. 本方三、四 不管白黑都 +15000
  381. 本方四、四 若是黑子则 -2000  白子则 +2000
  382. (个位+十位)/2*(个位*500+十位*1000)-!(个位/2+十位/2)* 本方jing +
  383. (百位+千位)/2*(百位*500+千位*1000)-!(百位/2+千位/2)* 对方jing
  384. 黑子:jing=-50000
  385. 白子:jing=0
  386. (个位大于2 or 十位大于2),否则为1
  387. 五子棋IQ
  388. ;冲五
  389. @@@@#.1:150000000 #@@@@.5:150000000 @#@@@.4:150000000 @@@#@.2:150000000 @@#@@.3:150000000
  390. ;长连禁手
  391. @@@@#@.2:本方jing
  392. @@@#@@.3:本方jing
  393. @@#@@@.4:本方jing
  394. @#@@@@.5:本方jing
  395. @@@@#@.6:本方jing
  396. vs0
  397. $$$$#.1:50000000 #$$$$.5:50000000 $$#$$.3:50000000 $#$$$.4:50000000 $$$#$.2:50000000
  398. vs1
  399. #@#@@#.4:15000000+~9
  400. #@@#@#.3:15000000+~9
  401. #@@@##.1:2000000-2:15000000-6:2000000-2:~9
  402. ##@@@#.1:2000000-5:15000000-6:2000000-5:~9
  403. vs3
  404. ##@@@.4:1000010-5:1000010 @@@##.2:1000010-1:1000010
  405. @##@@.4:1000010-3:1000010 @@##@.2:1000010-3:1000010
  406. #@#@@.3:1000010-5:1000010 @@#@#.1:1000010-3:1000010
  407. @#@@#.1:1000010-4:1000010 #@@#@.2:1000010-5:1000010
  408. @#@#@.2:1000010-4:1000010
  409. #@@@#.1:10-5:10
  410. vs4
  411. #$$#$#.3:15000000-6:401000-1:401000
  412. #$#$$#.4:15000000-1:401000-6:401000
  413. ##$$$#.5:15000000-1:400000
  414. #$$$##.2:15000000-1:400000
  415. vs5
  416. ###@@###.2:100000-3:550000+~0-6:550000+~0-7:100000
  417. ###@@##.2:100001-5:520000
  418. ##@@###.3:520000-6:100001
  419. ###@@#.4:100001-5:30001
  420. #@@###.3:100001-2:30001
  421. #@#@##.1:100000-2:100001-4:200000-6:100000
  422. ##@#@#.1:100000-3:200000-5:100001-6:100000
  423. #@#@#.3:1
  424. #@##@#.3:100001-4:100001-6:20000-1:20000
  425. @###@.2:20000-3:20000-4:20000
  426. #$$$#.1:41000-5:41000
  427. ##$$$##.2:~999-6:~999
  428. ##$$$.4:251000-5:251000 $$$##.2:251000-1:251000 $$##$.2:251000-3:251000 $##$$.3:251000-4:251000
  429. $#$$#.4:251000-1:251000 #$#$$.3:251000-5:251000
  430. $$#$#.1:251000-3:251000 #$$#$.5:251000-2:251000
  431. $#$#$.4:251000-2:251000
  432. ###$$###.2:100000-3:150000+~99-6:150000+~99-7:100000
  433. ###$$##.2:100100-6:100000
  434. ##$$###.2:100000-6:100100
  435. ;同一行上的四与活三,不算附加分
  436. $##$$##.5:~14999999
  437. ##$$##$.3:~14999999
  438. $#$$###.3:~14999999
  439. ###$$#$.5:~14999999
  440. @##@@##.5:~14999999
  441. ##@@##@.3:~14999999
  442. @#@@###.3:~14999999
  443. ###@@#@.5:~14999999
  444. #$$#$$#.4:~999
  445. ##$$##$$##.5:~14999999-6:~14999999
  446. #@@#@@#.4:~9
  447. ##@@##@@##.5:~14999999-6:~14999999
  448. ###$$#.4:200100-5:100100
  449. #$$###.3:200100-2:100100
  450. #$#$##.1:100000-2:100100-4:100100-6:100000
  451. ##$#$#.1:100000-3:100100-5:100100-6:100000
  452. ##$#$##.4:10000+~99-2:10000-6:10000
  453. #$##$#.3:100100-4:100100-6:50000-1:50000
  454. $###$.2:20000-3:20000-4:20000
  455. vs7
  456. @@###.1:10000-2:10000-3:10000 ###@@.3:10000-4:10000-5:10000
  457. ###@###.3:20000-5:20000-2:10000-6:10000
  458. #@####.1:10000-2:10000-3:10000-4:10000-6:10000
  459. ####@#.1:10000-3:10000-4:10000-5:10000-6:10000
  460. ##@###.1:10000-2:10000-3:10000-5:10000-6:10000
  461. ###@##.1:10000-2:10000-4:10000-5:10000-6:10000
  462. @#####.2:10000-3:10000-4:10000-5:10000
  463. #####@.2:10000-3:10000-4:10000-5:10000
  464. ##$###.1:10000-2:10000-3:10000-5:10000-6:10000
  465. ###$##.1:10000-2:10000-4:10000-5:10000-6:10000
  466. vs8
  467. ###$###.3:20000-5:20000-2:10000-6:10000
  468. $#####.2:10000-3:10000-4:10000-5:10000
  469. #####$.2:10000-3:10000-4:10000-5:10000
  470. #$####.1:10000-2:10000-3:10000-4:10000-6:10000
  471. ####$#.1:10000-3:10000-4:10000-5:10000-6:10000
  472. vs9
  473. @####.4:10000 ####@.2:10000 #$###.3:10000 ###$#.3:10000
  474. ###@#.3:10000 #@###.3:10000 $####.3:10000 ####$.3:10000 $$###.3:10000 ###$$.3:10000 $#$##.2:10000 ##$#$.4:10000 #$##$.3:10000 $##$#.3:10000 $###$.3:10000
  475. vs10
复制代码

[ 本帖最后由 netbenton 于 2011-1-21 10:43 编辑 ]
作者: BillGates    时间: 2011-1-21 11:24

netbenton兄,怎么才能让主板不响呢?
作者: netbenton    时间: 2011-1-21 23:57

你主板会响吗?
怎么个响法呀?没听说过~~
作者: caruko    时间: 2011-1-23 19:51

=.= 快过年了,忙的一段时间没来了,也没继续改脚本了..
果然还是版主高明,虽然代码看的稀里糊涂..
作者: caruko    时间: 2011-1-25 13:26

仔细看了下netbenton的代码,对五子棋规则了解很深,大大节省了代码提升了效率。
而且很多地方的字符串设计的很巧妙,集判断处理多种结果于一身。

最近我重新改写了五子棋核心代码,使用了别的算法;
返回最高评分坐标集合,判断棋型禁手布局,计算时间大约0.5-1秒,只是如果要完成计算3步棋,时间花费可能达到10秒,当然保存几个计算的走子结果,在电脑“意料中”的走棋将直接读取或者从布局查找,估计电脑“思考”时间将1-10秒不等。

只是我写的代码都有点其它语言的遗留传统,在BAT本身特性的了解方面,还差很远啊。
作者: BillGates    时间: 2011-1-25 13:56     标题: 回复 14楼 的帖子

嘻嘻,准确的说是蜂鸣器啦,别让蜂鸣器发出滴滴滴的声音,你那个五子棋哦,下一个子,会滴一声,我觉得这个似乎没必要吧。嘎嘎。
作者: caruko    时间: 2011-1-25 19:20

最近改写的程序如下,并没有多少特征字串,完全使用算法思考。
已经用它执白跟netbenton兄的程序对弈过,走了3次,都是20-30多步后不小心下错坐标罢手了,但至少一直防守没有错漏。

当前只有核心代码,很粗糙,界面,悔棋等都没有做,很多都处在调试阶段,但是已经可以下棋了。

以后将会更新:
1,动态调整k1,k2值,使得电脑在判断当前局面后不至于一味防守或者进攻,只是判断标准目前还没确定,简单的以当前最高得分的落子点分值判断,还是以 “二,三,四”的数量综合评分来判断。
2,禁手,查找分值串,可以很容易判断 多行交叉的禁手,只是长连禁手还得考虑下是否放入特征串。
3,开局棋谱,目前没有加入,所以测试都是用电脑做后手。如果要电脑先手,调整为k1=10,k2=7。
4,走棋预判,以目前的计算速度看,每一步评分的时间为0.5秒,那么考虑3步需要大量时间。代码框架已经完备,以后试着添加这个功能。
5,胜负判断还没做=。=
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "tzk=11111_9999999 011110_300000 11110_2500 01111_2500 11101_3000 10111_3000 11011_2600 0011100_3000 11100_500 00111_500 010110_800 011010_800 10011_600 11001_600 10101_550 00011000_650 11000_150 00011_150 0010100_250 010010_200"
  4. set "p_tzk=22222_9999999 022220_300000 22220_2500 02222_2500 22202_3000 20222_3000 22022_2600 0022200_3000 22200_500 00222_500 020220_800 022020_800 20022_600 22002_600 20202_550 00022000_650 22000_250 00022_250 0020200_250 020020_200"
  5. rem 默认走白棋,k1<k2侧重防守(后手),k1>k2侧重进攻(先手)。k1,k2值可在判断双方局面评分后动态调整。
  6. set /a k1=7,k2=10
  7. set error1=坐标应为“x,y”形式,并且1-x-15,1-y-15。
  8. set error2=x,y坐标越界。
  9. set error3=该坐标已有棋子,无法在指定坐标下子。
  10. :初始化棋盘
  11. for /l %%i in (1 1 15) do (
  12.         set "Display_%%i=┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼"
  13. )
  14. for /l %%i in (1 1 15) do for /l %%j in (1 1 15) do set QP[%%i][%%j]=0
  15. :loop
  16. call :显示棋盘
  17. call :玩家走 ||(echo,!error%ERRORLEVEL%!&goto :loop)
  18. call :显示棋盘
  19. call :判断胜负
  20. call :电脑走
  21. call :显示棋盘
  22. call :判断胜负
  23. goto :loop
  24. :玩家走
  25. set /a zq=0
  26. set /p P_zb=请输入坐标{1-15,1-15}:
  27. for /f "tokens=1,2 delims=," %%a in ("!P_zb!") do (
  28.         if %%a GTR 0 if %%a LSS 16 set /a zq+=1
  29.         if %%b GTR 0 if %%b LSS 16 set /a zq+=1
  30.         if "!QP[%%a][%%b]!"=="0" set /a zq+=1
  31.         if "!zq!"=="3" call :设置坐标 %%a %%b 2
  32. )
  33. if "!P_zb!"=="exit" exit
  34. if !zq! EQU 0 exit /b 1
  35. if !zq! EQU 1 exit /b 2
  36. if !zq! EQU 2 exit /b 3
  37. exit /b 0
  38. goto :eof
  39. :电脑走
  40. set /a 最高分=0
  41. for /l %%x in (1 1 15)  do (
  42.         for /l %%y in (1 1 15) do (
  43.                 if defined C_soce[%%x][%%y] (
  44.                         set "m=!C_soce[%%x][%%y]!"
  45.                         set "n=!P_soce[%%x][%%y]!"
  46.                         set /a m=!m!,n=!n!,mn=m*!k1!+n*!k2!
  47.                         if !最高分! EQU !mn! set "坐标集=!坐标集! [%%x][%%y]"
  48.                         if !最高分! LSS !mn! (
  49.                                 set /a 最高分=!mn!
  50.                                 set "坐标集=[%%x][%%y]"
  51.                         )
  52.                 )
  53.         )
  54. )
  55. rem 坐标集可能含有多个坐标,以后应用在αβ剪枝算法中,现在只取第一个。
  56. for /f "tokens=1,2 delims=[]" %%i in ("!坐标集!") do (
  57.         call :设置坐标 %%i %%j 1
  58. )        
  59. goto :eof
  60. :判断胜负
  61. rem 还没做。
  62. goto :eof
  63. :显示棋盘
  64. for /l %%i in (15 -1 1) do (
  65.         echo,%%i !Display_%%i!
  66. )
  67. echo,Y↑X→ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  68. goto :eof
  69. :设置坐标 [X为90°,Y为0°,Y-X为45°,Y+X为135°]
  70. set /a QP[%1][%2]=%3,x=%1,y=%2,z=%3,cut1=x-1,cut2=x,最高分=0
  71. if !z! equ 1 (set "cr=●") else (set "cr=○")
  72. set "str1=!Display_%y%:~0,%cut1%!"
  73. set "str2=!Display_%y%:~%cut2%!"
  74. set "Display_!y!=!str1!!cr!!str2!"
  75. set "C_str[%1][%2]="
  76. set "C_soce[%1][%2]="
  77. set "P_soce[%1][%2]="
  78. set "P_str[%1][%2]="
  79. ::落子点估值
  80. for /l %%i in (1 1 4) do (
  81.         for %%j in (%%i_0 %%i_-%%i 0_-%%i -%%i_-%%i -%%i_+0 -%%i_+%%i 0_%%i %%i_%%i) do (
  82.                 for /f "tokens=1,2 delims=_" %%x in ("%%j") do (
  83.                         set /a xx=x+%%x,yy=y+%%y
  84.                         for /f "tokens=1,2" %%a in ("!xx! !yy!") do (
  85.                                 if defined QP[%%a][%%b] if !QP[%%a][%%b]! EQU 0 (
  86. rem 更新双方字串并评分,没有的则重新创建,只更新 x-4 => x+4 范围且在一条直线上的评分。
  87. set /a a=%%a,b=%%b,c=1
  88. if "!C_str[%%a][%%b]!"=="" (
  89.         set /a c_str1=c,c_str2=c,c_str3=c,c_str4=c,p_str1=2,p_str2=2,p_str3=2,p_str4=2
  90.         for /l %%I in (-1 -1 -4) do (
  91.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  92.                 if !xxx! LSS 1 (
  93.                         set /a lj1=1
  94.                         set "c_str1=x!c_str1!"
  95.                         set "p_str1=x!p_str1!"
  96.                 ) else (
  97.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  98.                                 set "c_str1=!QP[%%A][%%B]!!c_str1!"
  99.                                 set "p_str1=!QP[%%A][%%B]!!p_str1!"
  100.                         )
  101.                 )
  102.                 if !yyy! LSS 1 (
  103.                         set /a lj1=1
  104.                         set "c_str2=x!c_str2!"
  105.                         set "p_str2=x!p_str2!"
  106.                 ) else (
  107.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  108.                                 set "c_str2=!QP[%%A][%%B]!!c_str2!"
  109.                                 set "p_str2=!QP[%%A][%%B]!!p_str2!"
  110.                         )
  111.                 )
  112.                 if !lj1! EQU 1 (
  113.                         set "c_str3=x!c_str3!"
  114.                         set "p_str3=x!p_str3!"
  115.                 ) else (
  116.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  117.                                 set "c_str3=!QP[%%A][%%B]!!c_str3!"
  118.                                 set "p_str3=!QP[%%A][%%B]!!p_str3!"
  119.                         )
  120.                 )
  121.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  122.                 if !xxx! LSS 1 set /a lj1=1
  123.                 if !yyy! GTR 15 set /a lj1=1
  124.                 if !lj1! EQU 1 (
  125.                         set "c_str4=x!c_str4!"
  126.                         set "p_str4=x!p_str4!"
  127.                 ) else (
  128.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  129.                                 set "c_str4=!QP[%%A][%%B]!!c_str4!"
  130.                                 set "p_str4=!QP[%%A][%%B]!!p_str4!"
  131.                         )
  132.                 )
  133.         )
  134.         for /l %%I in (1 1 4) do (
  135.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  136.                 if !xxx! GTR 15 (
  137.                         set /a lj1=1
  138.                         set "c_str1=!c_str1!x"
  139.                         set "p_str1=!p_str1!x"
  140.                 ) else (
  141.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  142.                                 set "c_str1=!c_str1!!QP[%%A][%%B]!"
  143.                                 set "p_str1=!p_str1!!QP[%%A][%%B]!"
  144.                         )
  145.                 )
  146.                 if !yyy! GTR 15 (
  147.                         set /a lj1=1
  148.                         set "c_str2=!c_str2!x"
  149.                         set "p_str2=!p_str2!x"
  150.                 ) else (
  151.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  152.                                 set "c_str2=!c_str2!!QP[%%A][%%B]!"
  153.                                 set "p_str2=!p_str2!!QP[%%A][%%B]!"
  154.                         )
  155.                 )
  156.                 if !lj1! EQU 1 (
  157.                         set "c_str3=!c_str3!x"
  158.                         set "p_str3=!p_str3!x"
  159.                 ) else (
  160.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  161.                                 set "c_str3=!c_str3!!QP[%%A][%%B]!"
  162.                                 set "p_str3=!p_str3!!QP[%%A][%%B]!"
  163.                         )
  164.                 )
  165.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  166.                 if !xxx! GTR 15 set /a lj1=1
  167.                 if !yyy! LSS 1 set /a lj1=1
  168.                 if !lj1! EQU 1 (
  169.                         set "c_str4=!c_str4!x"
  170.                         set "p_str4=!p_str4!x"
  171.                 ) else (
  172.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  173.                                 set "c_str4=!c_str4!!QP[%%A][%%B]!"
  174.                                 set "p_str4=!p_str4!!QP[%%A][%%B]!"
  175.                         )
  176.                 )
  177.         )
  178.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  179.         for %%X in (!tzk!) do (
  180.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  181.                         for /l %%W in (1 1 4) do (
  182.                                 if not "!c_str%%W!"=="!c_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  183.                         )
  184.                 )
  185.         )
  186.         set "C_str[!a!][!b!]=!c_str1!,!c_str2!,!c_str3!,!c_str4!"
  187.         set "C_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  188.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  189.         for %%X in (!p_tzk!) do (
  190.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  191.                         for /l %%W in (1 1 4) do (
  192.                                 if not "!p_str%%W!"=="!p_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  193.                         )
  194.                 )
  195.         )
  196.         set "P_str[!a!][!b!]=!p_str1!,!p_str2!,!p_str3!,!p_str4!"
  197.         set "P_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  198. rem end 创建。
  199. ) else (
  200. rem 更新字串及评分,已存在的点会加快效率。
  201.         if %%x NEQ 0 (
  202.                 set /a cut1=5-%%x-1,cut2=5-%%x,tk=1,pd=%%x+%%y
  203.                 if !pd! EQU 0 (
  204.                         set /a cut1=cut1+30,cut2=cut2+30,tk=4
  205.                 )
  206.                 if %%x EQU %%y (
  207.                         set /a cut1=cut1+20,cut2=cut2+20,tk=3
  208.                 )
  209.         ) else (
  210.                 set /a cut1=15-%%y-1,cut2=15-%%y,tk=2
  211.         )
  212.         for /f "tokens=1,2" %%X in ("!cut1! !cut2!") do (
  213.                 set "C_str[%%a][%%b]=!C_str[%%a][%%b]:~0,%%X!!z!!C_str[%%a][%%b]:~%%Y!"
  214.                 set "P_str[%%a][%%b]=!P_str[%%a][%%b]:~0,%%X!!z!!P_str[%%a][%%b]:~%%Y!"
  215.         )
  216.         for /f "tokens=1-4 delims=+" %%A in ("!C_soce[%%a][%%b]!") do (
  217.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  218.         )
  219.         set /a soce=0,ttk=tk*10-10
  220.         for %%T in (!ttk!) do (
  221.                 set "t_str=!C_str[%%a][%%b]:~%%T,9!"
  222.         )
  223.         for %%Q in (!tzk!) do (
  224.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  225.                         if not "!t_str!"=="!t_str:%%A=@!" (
  226.                                 if !soce! LSS %%B set /a soce=%%B
  227.                         )
  228.                 )
  229.         )
  230.         set /a soce!tk!=!soce!
  231.         set "C_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  232. rem 更新player评分
  233.         for /f "tokens=1-4 delims=+" %%A in ("!P_soce[%%a][%%b]!") do (
  234.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  235.         )
  236.         set /a soce=0
  237.         for %%T in (!ttk!) do (
  238.                 set "t_str=!P_str[%%a][%%b]:~%%T,9!"
  239.         )
  240.         for %%Q in (!p_tzk!) do (
  241.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  242.                         if not "!t_str!"=="!t_str:%%A=@!" (
  243.                                 if !soce! LSS %%B set /a soce=%%B
  244.                         )
  245.                 )
  246.         )
  247.         set /a soce!tk!=!soce!
  248.         set "P_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  249. )
  250. rem end更新
  251.                                 )
  252.                         )
  253.                 )
  254.         )
  255. )
复制代码

[ 本帖最后由 caruko 于 2011-1-26 15:17 编辑 ]
作者: caruko    时间: 2011-1-25 21:55

=。= 做了测试,发现防守还可以,进攻却缺少章法,不够犀利。

只有想办法加入“定式”,完善预判来提高智能了。
作者: caruko    时间: 2011-1-26 20:37

重复了。。看楼下。

[ 本帖最后由 caruko 于 2011-1-26 21:11 编辑 ]
作者: caruko    时间: 2011-1-26 20:59

已经完善了禁手判断,胜负判断,增加选择先后手。
对于匹配“定式”,走棋预判,已经有了思路。
有空完善后参上。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. ::初始变量
  4. set "tzk=11111_9999999 011110_300000 11110_2500 01111_2500 0011100_3000 11101_3000 10111_3000 11011_2600  11100_500 00111_500 010110_800 011010_800 10011_600 11001_600 10101_550 00011000_650 11000_150 00011_150 0010100_250 010010_200"
  5. set "p_tzk=22222_9999999 022220_300000 22220_2500 02222_2500 0022200_3000 22202_3000 20222_3000 22022_2600 22200_500 00222_500 020220_800 022020_800 20022_600 22002_600 20202_550 00022000_650 22000_250 00022_250 0020200_250 020020_200"
  6. set "禁手=0011100_三 011010_三 010110_三 011100_#三 001110_@三 01111_四 11110_四 10111_四 11011_四  11101_四 11111_五 111111_长连 "
  7. set "error1=坐标应为“x,y”形式,并且1-x-15,0-y-15。"
  8. set "error2=x,y坐标越界。"
  9. set "error3=该坐标已有棋子,无法在指定坐标下子。"
  10. set /a 步=0
  11. ::初始化棋盘
  12. for /l %%i in (1 1 15) do (
  13.         set "Display_%%i=┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼"
  14. )
  15. for /l %%i in (1 1 15) do for /l %%j in (1 1 15) do set QP[%%i][%%j]=0
  16. call :显示棋盘
  17. ::设置先手
  18. :xs
  19. set /p 先手=请选择先手(玩家Player:P,电脑Computer:C)
  20. if "!先手!"=="C" (set "行动方=Computerr" & set /a k1=10,k2=7 & set "先手=C" & set "qizi1=○" & set "qizi2=●")
  21. if "!先手!"=="c" (set "行动方=Computer" & set /a k1=10,k2=7 & set "先手=C" & set "qizi1=○" & set "qizi2=●")
  22. if "!先手!"=="p" (set "行动方=Player" & set /a k1=7,k2=10 & set "先手=P" & set "qizi1=●" & set "qizi2=○")
  23. if "!先手!"=="P" (set "行动方=Player" & set /a k1=7,k2=10 & set "先手=P" & set "qizi1=●" & set "qizi2=○")
  24. if not defined 先手 goto :xs
  25. if "!先手!"=="C" (call :设置坐标 8 8 1) else (call :设置坐标 8 8 2 &goto :loop2)
  26. :loop
  27. call :显示棋盘
  28. call :玩家走 ||(echo,!error%ERRORLEVEL%!&goto :loop)
  29. :loop2
  30. call :显示棋盘
  31. call :电脑走
  32. goto :loop
  33. :玩家走
  34. set "行动方=Player"
  35. set /a zq=0
  36. set /p P_zb=请输入坐标{1-15,1-15}:
  37. for /f "tokens=1,2 delims=," %%a in ("!P_zb!") do (
  38.         if %%a GTR 0 if %%a LSS 16 set /a zq+=1
  39.         if %%b GTR 0 if %%b LSS 16 set /a zq+=1
  40.         if "!QP[%%a][%%b]!"=="0" set /a zq+=1
  41.         if "!zq!"=="3" call :设置坐标 %%a %%b 2
  42. )
  43. if "!P_zb!"=="exit" exit
  44. if !zq! EQU 0 exit /b 1
  45. if !zq! EQU 1 exit /b 2
  46. if !zq! EQU 2 exit /b 3
  47. exit /b 0
  48. :电脑走
  49. set "行动方=Computer"
  50. set /a 最高分=0
  51. for /l %%x in (1 1 15)  do (
  52.         for /l %%y in (1 1 15) do (
  53.                 if defined C_soce[%%x][%%y] (
  54.                         set "m=!C_soce[%%x][%%y]!"
  55.                         set "n=!P_soce[%%x][%%y]!"
  56.                         set /a m=!m!,n=!n!,mn=m*!k1!+n*!k2!
  57.                         if !最高分! EQU !mn! set "坐标集=!坐标集! [%%x][%%y]"
  58.                         if !最高分! LSS !mn! (
  59.                                 set /a 最高分=!mn!
  60.                                 set "坐标集=[%%x][%%y]"
  61.                         )
  62.                 )
  63.         )
  64. )
  65. rem 坐标集可能含有多个坐标,以后应用在αβ剪枝算法中,现在只取第一个。
  66. for /f "tokens=1,2 delims=[]" %%i in ("!坐标集!") do (
  67.         call :设置坐标 %%i %%j 1
  68. )
  69. goto :eof
  70. :胜利
  71. call :显示棋盘
  72. if "%1"=="禁手" (
  73.   echo !行动方!范"!禁!"禁手,该局判负!
  74. ) else (
  75.   echo !行动方!五子连珠,赢得该局胜利!
  76. )
  77. set /p =按任意键结束游戏!<nul
  78. pause>nul
  79. exit
  80. goto :eof
  81. :显示棋盘
  82. for /l %%i in (15 -1 1) do (
  83.     echo %%i !Display_%%i!
  84. )
  85. echo,Y↑X→ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  86. goto :eof
  87. :设置坐标 [x] [y] [1,2]
  88. set /a QP[%1][%2]=%3,x=%1,y=%2,z=%3,cut1=x-1,cut2=x,最高分=0,fens=0,步+=1
  89. set "cr=!qizi%3!"
  90. set "Display_!y!=!Display_%y%:~0,%cut1%!!cr!!Display_%y%:~%cut2%!"
  91. set "第!步!步=%1,%2"
  92. ::判断禁手,“三四” “成五” 不算禁手,@三#三看似不是活三,两个一起构不成活四,但是跟别的活三,四搭配仍然是活三。
  93. set "禁="
  94. if "!行动方:~0,1!"=="!先手!" (
  95.    for %%D in (!禁手!) do (
  96.       for /f "tokens=1,2 delims=_" %%E in ("%%D") do (
  97.         if not "!%先手%_str[%1][%2]!"=="!%先手%_str[%1][%2]:%%E=@!" set "禁=!禁!%%F"
  98.       )
  99.    )
  100. )
  101. if "!禁!"=="三四" set "禁="
  102. if not "!禁!"=="!禁:#=!" if not "!禁!"=="!禁:@=!" set "禁="
  103. if not "!禁!"=="!禁:五=!" if "!禁!"=="!禁:长连=!" set "禁="
  104. if "!禁:~1,1!"=="" set "禁="
  105. if defined 禁 call :胜利 禁手
  106. ::判断是否5连,断定胜负
  107. if !步! GTR 1 if "!行动方!"=="Computer" (set /a fens=!C_soce[%1][%2]!) else (set /a fens=!P_soce[%1][%2]!)
  108. if !fens! GEQ 9999999 call :胜利
  109. set "C_str[%1][%2]="
  110. set "C_soce[%1][%2]="
  111. set "P_soce[%1][%2]="
  112. set "P_str[%1][%2]="
  113. ::落子点估值
  114. for /l %%i in (1 1 4) do (
  115.         for %%j in (%%i_0 %%i_-%%i 0_-%%i -%%i_-%%i -%%i_+0 -%%i_+%%i 0_%%i %%i_%%i) do (
  116.                 for /f "tokens=1,2 delims=_" %%x in ("%%j") do (
  117.                         set /a xx=x+%%x,yy=y+%%y
  118.                         for /f "tokens=1,2" %%a in ("!xx! !yy!") do (
  119.                                 if defined QP[%%a][%%b] if !QP[%%a][%%b]! EQU 0 (
  120. rem 更新双方字串并评分,没有的则重新创建,只更新 x-4 => x+4 范围且在一条直线上的评分。
  121. set /a a=%%a,b=%%b,c=1
  122. if "!C_str[%%a][%%b]!"=="" (
  123.         set /a c_str1=c,c_str2=c,c_str3=c,c_str4=c,p_str1=2,p_str2=2,p_str3=2,p_str4=2
  124.         for /l %%I in (-1 -1 -4) do (
  125.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  126.                 if !xxx! LSS 1 (
  127.                         set /a lj1=1
  128.                         set "c_str1=x!c_str1!"
  129.                         set "p_str1=x!p_str1!"
  130.                 ) else (
  131.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  132.                                 set "c_str1=!QP[%%A][%%B]!!c_str1!"
  133.                                 set "p_str1=!QP[%%A][%%B]!!p_str1!"
  134.                         )
  135.                 )
  136.                 if !yyy! LSS 1 (
  137.                         set /a lj1=1
  138.                         set "c_str2=x!c_str2!"
  139.                         set "p_str2=x!p_str2!"
  140.                 ) else (
  141.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  142.                                 set "c_str2=!QP[%%A][%%B]!!c_str2!"
  143.                                 set "p_str2=!QP[%%A][%%B]!!p_str2!"
  144.                         )
  145.                 )
  146.                 if !lj1! EQU 1 (
  147.                         set "c_str3=x!c_str3!"
  148.                         set "p_str3=x!p_str3!"
  149.                 ) else (
  150.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  151.                                 set "c_str3=!QP[%%A][%%B]!!c_str3!"
  152.                                 set "p_str3=!QP[%%A][%%B]!!p_str3!"
  153.                         )
  154.                 )
  155.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  156.                 if !xxx! LSS 1 set /a lj1=1
  157.                 if !yyy! GTR 15 set /a lj1=1
  158.                 if !lj1! EQU 1 (
  159.                         set "c_str4=x!c_str4!"
  160.                         set "p_str4=x!p_str4!"
  161.                 ) else (
  162.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  163.                                 set "c_str4=!QP[%%A][%%B]!!c_str4!"
  164.                                 set "p_str4=!QP[%%A][%%B]!!p_str4!"
  165.                         )
  166.                 )
  167.         )
  168.         for /l %%I in (1 1 4) do (
  169.                 set /a xxx=a+%%I,yyy=b+%%I,lj1=0
  170.                 if !xxx! GTR 15 (
  171.                         set /a lj1=1
  172.                         set "c_str1=!c_str1!x"
  173.                         set "p_str1=!p_str1!x"
  174.                 ) else (
  175.                         for /f "tokens=1,2" %%A in ("!xxx! !b!") do (
  176.                                 set "c_str1=!c_str1!!QP[%%A][%%B]!"
  177.                                 set "p_str1=!p_str1!!QP[%%A][%%B]!"
  178.                         )
  179.                 )
  180.                 if !yyy! GTR 15 (
  181.                         set /a lj1=1
  182.                         set "c_str2=!c_str2!x"
  183.                         set "p_str2=!p_str2!x"
  184.                 ) else (
  185.                         for /f "tokens=1,2" %%A in ("!a! !yyy!") do (
  186.                                 set "c_str2=!c_str2!!QP[%%A][%%B]!"
  187.                                 set "p_str2=!p_str2!!QP[%%A][%%B]!"
  188.                         )
  189.                 )
  190.                 if !lj1! EQU 1 (
  191.                         set "c_str3=!c_str3!x"
  192.                         set "p_str3=!p_str3!x"
  193.                 ) else (
  194.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  195.                                 set "c_str3=!c_str3!!QP[%%A][%%B]!"
  196.                                 set "p_str3=!p_str3!!QP[%%A][%%B]!"
  197.                         )
  198.                 )
  199.                 set /a xxx=a+%%I,yyy=b-%%I,lj1=0
  200.                 if !xxx! GTR 15 set /a lj1=1
  201.                 if !yyy! LSS 1 set /a lj1=1
  202.                 if !lj1! EQU 1 (
  203.                         set "c_str4=!c_str4!x"
  204.                         set "p_str4=!p_str4!x"
  205.                 ) else (
  206.                         for /f "tokens=1,2" %%A in ("!xxx! !yyy!") do (
  207.                                 set "c_str4=!c_str4!!QP[%%A][%%B]!"
  208.                                 set "p_str4=!p_str4!!QP[%%A][%%B]!"
  209.                         )
  210.                 )
  211.         )
  212.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  213.         for %%X in (!tzk!) do (
  214.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  215.                         for /l %%W in (1 1 4) do (
  216.                                 if not "!c_str%%W!"=="!c_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  217.                         )
  218.                 )
  219.         )
  220.         set "C_str[!a!][!b!]=!c_str1!,!c_str2!,!c_str3!,!c_str4!"
  221.         set "C_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  222.         set /a soce1=0,soce2=0,soce3=0,soce4=0
  223.         for %%X in (!p_tzk!) do (
  224.                 for /f "tokens=1,2 delims=_" %%A in ("%%X") do (
  225.                         for /l %%W in (1 1 4) do (
  226.                                 if not "!p_str%%W!"=="!p_str%%W:%%A=@!" if !soce%%W! LSS %%B set /a soce%%W=%%B
  227.                         )
  228.                 )
  229.         )
  230.         set "P_str[!a!][!b!]=!p_str1!,!p_str2!,!p_str3!,!p_str4!"
  231.         set "P_soce[!a!][!b!]=!soce1!+!soce2!+!soce3!+!soce4!"
  232. rem end 创建。
  233. ) else (
  234. rem 更新字串及评分,已存在的点会加快效率。
  235.         if %%x NEQ 0 (
  236.                 set /a cut1=5-%%x-1,cut2=5-%%x,tk=1,pd=%%x+%%y
  237.                 if !pd! EQU 0 (
  238.                         set /a cut1=cut1+30,cut2=cut2+30,tk=4
  239.                 )
  240.                 if %%x EQU %%y (
  241.                         set /a cut1=cut1+20,cut2=cut2+20,tk=3
  242.                 )
  243.         ) else (
  244.                 set /a cut1=15-%%y-1,cut2=15-%%y,tk=2
  245.         )
  246.         for /f "tokens=1,2" %%X in ("!cut1! !cut2!") do (
  247.                 set "C_str[%%a][%%b]=!C_str[%%a][%%b]:~0,%%X!!z!!C_str[%%a][%%b]:~%%Y!"
  248.                 set "P_str[%%a][%%b]=!P_str[%%a][%%b]:~0,%%X!!z!!P_str[%%a][%%b]:~%%Y!"
  249.         )
  250.         for /f "tokens=1-4 delims=+" %%A in ("!C_soce[%%a][%%b]!") do (
  251.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  252.         )
  253.         set /a soce=0,ttk=tk*10-10
  254.         for %%T in (!ttk!) do (
  255.                 set "t_str=!C_str[%%a][%%b]:~%%T,9!"
  256.         )
  257.         for %%Q in (!tzk!) do (
  258.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  259.                         if not "!t_str!"=="!t_str:%%A=@!" (
  260.                                 if !soce! LSS %%B set /a soce=%%B
  261.                         )
  262.                 )
  263.         )
  264.         set /a soce!tk!=!soce!
  265.         set "C_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  266. rem 更新player评分
  267.         for /f "tokens=1-4 delims=+" %%A in ("!P_soce[%%a][%%b]!") do (
  268.                 set /a soce1=%%A,soce2=%%B,soce3=%%C,soce4=%%D
  269.         )
  270.         set /a soce=0
  271.         for %%T in (!ttk!) do (
  272.                 set "t_str=!P_str[%%a][%%b]:~%%T,9!"
  273.         )
  274.         for %%Q in (!p_tzk!) do (
  275.                 for /f "tokens=1,2 delims=_" %%A in ("%%Q") do (
  276.                         if not "!t_str!"=="!t_str:%%A=@!" (
  277.                                 if !soce! LSS %%B set /a soce=%%B
  278.                         )
  279.                 )
  280.         )
  281.         set /a soce!tk!=!soce!
  282.         set "P_soce[%%a][%%b]=!soce1!+!soce2!+!soce3!+!soce4!"
  283. )
  284. rem end更新
  285.                                 )
  286.                         )
  287.                 )
  288.         )
  289. )
复制代码

[ 本帖最后由 caruko 于 2011-1-27 20:53 编辑 ]
作者: netbenton    时间: 2011-1-27 19:01

21楼,一开始就提示,找不到操作数,

下子无法对齐,请检查下看

才一个四,就提示四四禁手

就这样了
作者: caruko    时间: 2011-1-27 20:49

=.= 检查了一下, 操作数那个错误是下面这句
if "!行动方!"=="Computer" (set /a fens=!C_soce[%1][%2]!) else (set /a fens=!P_soce[%1][%2]!)
胜负判断放在估值前,导致第一次运行调用的变量没有。

至于禁手那个错误,我只惦记 2-4个符合的情况,竟然忘记了只有一个时不是禁手。
代码修改过了。。

至于对齐没发现问题啊。。

另外电脑也可能自己走出禁手,因为考虑禁手的多层的搜索算法还没写好。
主要是在 :设置坐标 函数基础上做部分修改,预判走棋的搜索范围进一步减小,因为在循环中不使用call,判断条件比较多,只能使用重复代码来写。

"定式"的算法想好了,只是定式字串还没找到资料参考,如下
set "定式=_[8][8][7][9][7][7][9][9]..._[8][8][7][9][9][7][7][7]..._....."
然后记录连续下子的坐标set jilu=!jilu![!x!][!y!],
比如第一步下[8][8],第2步下的[7][9],求第3步;
那么set !定式:%记录%=@! ,如果替换成功,表示有符合该棋路的定式
然后用替换后的字符串 "_@[7][7][9][9]_@[9][7][7][7]_.."
for /f "tokens=2,3 delims=@[]" 得到坐标值,如果替换后是@_,或者没有替换成功,那就表示以后都不需要检查定式了。

[ 本帖最后由 caruko 于 2011-1-27 21:23 编辑 ]
作者: caruko    时间: 2011-1-27 21:43

还考虑过用相对坐标设计定式 =。= 如 set "定式=[-1][1][-2][-1][-2][-2]"
具体还要测试了。。
作者: ShenMian    时间: 2017-11-12 11:22

回复 12# netbenton


    我觉得这所谓的智能好像还有点问题,三子一线都不理,自己在一边乱下。不管各种技巧,这应该是基本吧。




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