Board logo

标题: [原创]五子棋人机对战批处理游戏 [打印本页]

作者: netbenton     时间: 2009-5-5 12:41    标题: [原创]五子棋人机对战批处理游戏
这个批处理花了我两天时间,所以打上了原创。
我还在批处理之家发表有这个批处理,若还有与其它贴子雷同,纯属巧合。
欢迎大家指正,谢谢。


41楼
增加了背景音乐《春江花月夜》,如高山流水般的声音,听着下五棋子,太爽了,包含播放代码及音乐文件仅96K。


鼠标操作版
50楼
最新在60楼 2009.8.1





@echo off&setlocal enabledelayedexpansion
set li0=┌───────────────────┐
set li1=│┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐│1
for /l %%a in (2,1,18) do (set li%%a=│├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤│%%a)
set li19=│└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘│19
set li20=└───────────────────┘
set li21= A B C D E F G H I J K L M N O P Q R S
for %%a in (%li21%) do (set/a .+=1,%%a=.&set z!.!=%%a)
set z0= &set z20= &set "z21= "

set li5=!li5! 五 棋 子 人 机 对 战
set li7=!li7! 批 处 理
set li9=!li9! 电 脑 水 平 中 等
set li12=!li12! 由 netbenton 编写完成
set li14=!li14! 棋盘设计参照了 batman
title 批处理五子棋


set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set


























:
if /i "!var!" equ "Q" goto :eof
if /i "!var!" equ "W" (set zhi=●) else (set zhi=○)
echo.


:loop
if %zhi% equ ● goto :men
set .=&set put1=
for %%a in (!idea!) do (
for %%b in (he sh) do (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
) )
for %%b in (pi ni) do (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
) )
if defined put1 set put=%%a&goto :get
)

echo. 已经和棋了
pause
goto :restart

:men
for /l %%a in (0,1,21) do (echo !z%%a!!li%%a!)
set /p user=:
echo.
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" exit
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined











































Last edited by netbenton on 2009-8-3 at 06:06 ]

作者: sexfio     时间: 2009-5-5 12:47
太精彩了,要能写出vbs的就好了,因为批处理我看不大懂

提个建议,棋盘搞大点,棋子用红 黄色比较好,文字搞小点,还有列数数字和线没对齐
还有电脑第一步棋走的离谱,我下中间,他跑边上下了一个<img src="images/smilies/face-smile-big.png" align="absmiddle" border="0">

Last edited by sexfio on 2009-5-5 at 12:49 ]

作者: netbenton     时间: 2009-5-5 12:55
要做成红黄的话,得用到三方,将就一点吧!

如果是为了显示好看一点的话,正准备改进,如果还要增加行列的话,就不必了,19X19下完一盘(和棋)也要不少时间了。

五子棋吗,并非要走到一起的,只要能五个一串,就算赢了。才一个子,电脑没有必要马上就堵的。

看过了一些五子棋的资料,发现原来是我对五子棋子解得太少了,
这人批处理的棋术真的是太低了。

Last edited by netbenton on 2009-5-10 at 08:38 ]

作者: provem     时间: 2009-5-5 22:05
建议使用第三方工具 cmos 支持鼠标

作者: jmz573515     时间: 2009-5-6 08:54
太牛了!加分

作者: wishpopo     时间: 2009-5-6 10:02
很不错 ,没想到 可以这样设计电脑的智商 学习了

作者: netbenton     时间: 2009-5-6 10:23
应2楼的一点意见,已经把棋盘搞大一点了
同时增加了悔棋功能,增加了音效,
把系统提示放到了更合理的地方,
并增加了一点电脑方的棋艺,
增加了电脑方最后一步特别显示

5.10 修改:固定为黑子先手,第一手固定下在天元 JJ10 位置

5.17 修改:增强了电脑方的IQ
5.21 修改:完善了电脑方IQ,并在有多个等效位置下时,随机取位,可玩性提高了,也因为随机,所以玩家不一定能下赢电脑,电脑也不会必胜。
6.2 小修改。


@echo off&setlocal enabledelayedexpansion
mode con: lines=43 cols=110
set li39= A B C D E F G H I J K L M N O P Q R S
set li0= ┌─────────────────────────────────────┐
set li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
set var=1
for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
for /l %%a in (2,2,36) do (set li%%a= ││ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││)
set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
set li38= └─────────────────────────────────────┘
set str=a b c d e f g h i j k l m n o p q r s
for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)

set li5=!li5! 五 棋 子 人 机 对 战
set li7=!li7! 批 处 理
set li10=!li10! 电 脑 水 平 中 等
set li31=!li31! 由 netbenton 编写完成
set li33=!li33! 棋盘设计参照了 batman
title 批处理五子棋


set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set




























:
if /i "!var!" equ "Q" goto :quit

if /i "!var!" equ "D" (set onez=○&set towz=●&set hou=☆) else (set onez=●&set towz=○&set hou=★)
set a!onez!=电脑&set a!towz!=玩家
)
(
set ttr=!idea:@=%onez%!&set ttr=!ttr:$=%towz%!
set idea=
for %%a in (!ttr!) do (
for /f "tokens=1,2 delims=." %%b in ("%%a") do (set %%b=%%c&set idea=!idea! %%b)
)

set ttr=
set li27=!li27! !onez! !a%onez%!
set li25=!li25! !towz! !a%towz%!

set/a pos=10,poh=10&goto :getok
)
:loop

(if %zhi% equ %onez% goto :men
set .=
setlocal enabledelayedexpansion
for %%a in (!idea!) do (
set str=%%a
if "!str:~,2!" neq "vs" (

for %%b in (he sh) do (
set all=!%%b1!!%%b2!!%%b3!!%%b4!!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
for %%b in (pi ni) do (
set all=!%%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!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c.%%a.!iqam!
)
) )
) else (
set/a "iqam=(iqam+1)/8"
if %%a equ vs8 if defined . goto :get
if %%a equ vs9 if defined . goto :get


)

))
if defined . (goto :get)

echo. 已经和棋了
pause
endlocal&goto :restart

:men
(
set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%hou%!%%b:~%%c!)
set li38=!li38!
cls
for /l %%a in (0,1,39) do (echo !li%%a!)
for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
set li38=%li38%
set /p user=!say:say=%error%! :
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" goto :quit
if "!user!" equ "back" call :悔&goto :men
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined









































































































Last edited by netbenton on 2009-6-2 at 09:52 ]

作者: yishanju     时间: 2009-5-6 16:59
真的真的很漂亮,震撼了

作者: zh159     时间: 2009-5-7 13:53
建议把这算法转为VBS或JS,可以用在HTA里面,支持鼠标点击,界面也会更漂亮

作者: netbenton     时间: 2009-5-8 02:13
re 9楼
我对vbs 没有深入了解,哪位有兴趣的就写一下。

其实做五子棋游戏并不难,用其它语言,早就有相当漂亮的五子棋了,只是在纯批下做时要一点技巧。可是有一点,无论做得如何好,是比不上真正的图形界面的。


re 4楼

也想过用三方来支持鼠标操作,但这个游戏只有几K,如果为了鼠标操作而用到一个几百K的三方,我认为不划算。如果可以用vbs,js,或其它系统自带的脚本语言来做的话,那还差不多。

用键盘有用键盘的好,可以在玩的过程中,无意识的在练习盲打。

作者: everest79     时间: 2009-5-8 12:00
有空讲解下,我都看不懂

作者: zh159     时间: 2009-5-8 12:20
有空讲解下算法,看看如何转为VBS

作者: netbenton     时间: 2009-5-8 14:26
::算法是利用了批处理的变量名可变,
::在定义变量和使用时,变量名也是数据的一部分,不知vbs可不可以这样

::已经在主要的地方加了注释了。

@echo off&setlocal enabledelayedexpansion
mode con: lines=43 cols=110
set li39= A B C D E F G H I J K L M N O P Q R S
set li0= ┌─────────────────────────────────────┐
set li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
set var=1
for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
for /l %%a in (2,2,36) do (set li%%a= ││ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││)
set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
set li38= └─────────────────────────────────────┘`
rem 前面定义棋盘布局数组li0~li39,相当于显示缓存

set str=a b c d e f g h i j k l m n o p q r s
for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)
rem 定义字母与数值互换对等变量如:a=1 z1=a
rem 此处定义后面有多个地方用到

set li5=!li5! 五 棋 子 人 机 对 战
set li7=!li7! 批 处 理
set li10=!li10! 电 脑 水 平 中 等
set li31=!li31! 由 netbenton 编写完成
set li33=!li33! 棋盘设计参照了 batman
title 批处理五子棋


set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set












































:
if /i "!var!" equ "Q" goto :eof
if /i "!var!" equ "W" (set zhi=●) else (set zhi=○)
echo.

rem 完全由%zhi%这个变量来制轮到哪一方下子

:loop
(if %zhi% equ ● goto :men
set .=
for %%a in (!idea!) do (
for %%b in (he sh) do (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
) )
for %%b in (pi ni) do (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
) )
if defined . set put=%%a&goto :get
))

rem rem 根据前面定义的idea规则,搜索所有横竖撇倷串,取到最前的匹配后跳出,
rem rem 完全没有匹配的,说明已经和棋了

echo. 已经和棋了
pause
endlocal&goto :restart

:men
(
set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!★!%%b:~%%c!)
set li38=!li38:`=!
cls
for /l %%a in (0,1,39) do (echo !li%%a!)
rem rem 把缓存显示到屏幕

set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
set li38=%li38%
set /p user=!say:say=%error%! :
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" exit
if "!user!" equ "back" call :悔&goto :men
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined

















































































Last edited by netbenton on 2009-5-8 at 12:32 ]

作者: sady2009     时间: 2009-5-8 22:32
太复杂了。死了几万个脑细胞,还没看懂:D

作者: zh159     时间: 2009-5-9 13:27
还没空搞清算法,先弄个HTA的界面出来先

<html>
<title>五子棋界面 - zh159</title>
<hrad>

<HTA:APPLICATION
ID="MyhyliApp"
APPLICATIONNAME="五子棋界面 - zh159"
BORDER="thin"
BORDERSTYLE=""
VERSION="1.0"
SCROLL="no"
ICON="C:\WINDOWS\System32\wuauclt.exe"
INNERBORDER="no"
CONTEXTMENU="no"
CAPTION="yes"
MAXIMIZEBUTTON="no"
MINIMIZEBUTTON="yes"
SHOWINTASKBAR="yes"
SINGLEINSTANCE="yes"
SYSMENU="yes"
WINDOWSTATE="normal"
NAVIGABLE="yes"
/>
</hrad>

<script language="javascript"></script>
<script language="VBScript"></script>

<style>
.GUIwh {width:24;height:24;cursor:hand;}
</style>

<body background="bg.gif" scroll="no" style="background: SteelBlue ;color:#ffffff;">

<table align="center" width="630" border="1" cellspacing="0" cellpadding="10" borderColor="#ffffff" style="font: 13px 宋体;border-collapse:collapse;">
<tr align="center">
<td width="450" height="450">
<table border="0" cellspacing="0" cellpadding="0" borderColor="#ffffff" style="font: 21px 宋体;border:2px solid #ffffff;">
<script language="VBScript">
str = "ABCDEFGHIJKLMNOPQRS"
For i = 1 To Len(str)
with document
.write "<tr align='center'>"
For n = 1 To Len(str)
stri = MID(str,i,1)
strn = MID(str,n,1)
tdstr = "<td id='GUI_" & strn & stri & "' class='GUIwh'><span onclick='Test(this)' onMouseOver='innerText=""●"";style.color=""blue""' onMouseOut='innerText=""┼"";style.color=""""'>┼</span></td>"
s = "┼"

If (stri = "A" and strn = "A") Then .write Replace(tdstr,s,"┌")
If stri = "A" Then If not (strn = "A" or strn = "S") Then .write Replace(tdstr,s,"┬")
If (stri = "A" and strn = "S") Then .write Replace(tdstr,s,"┐")

If not (stri = "A" or stri = "S") Then If strn = "A" Then .write Replace(tdstr,s,"├")
If not (stri = "A" or stri = "S" or strn = "A" or strn = "S") Then .write tdstr
If not (stri = "A" or stri = "S") Then If strn = "S" Then .write Replace(tdstr,s,"┤")

If (stri = "S" and strn = "A") Then .write Replace(tdstr,s,"└")
If stri = "S" Then If not (strn = "A" or strn = "S") Then .write Replace(tdstr,s,"┴")
If (stri = "S" and strn = "S") Then .write Replace(tdstr,s,"┘")
Next
.write "</tr>"
end with
Next
</script>
</table>
</td>
<td>
<span id="PC"><button>电脑先下</button><br><br>直接点击为玩家先下</span>
</td>
</tr>
</table>
</body>

<script language="VBScript">

width = 660
height = 550
window.resizeTo width, height
ileft=(window.screen.width-width)/2
itop=(window.screen.height-height)/2
window.moveTo ileft,itop

Sub Test(this)
this.parentNode.style.cursor = "default"
this.parentNode.innerHtml = "●"
PC.style.display = "none"
End Sub


Sub Title
Document.title = "五子棋 - zh159 - " & FormatDateTime(Now, 1) & " " & WeekdayName(WeekDay(now)) & " " & FormatDateTime(Now, 3)
End Sub

Title:setInterval "Title()",500

</script>

</html>

作者: huchaolan     时间: 2009-5-9 20:29
这个牛哈
看不懂,但玩的有意思

作者: everest79     时间: 2009-5-10 07:24
我抄袭一下zh159



If Not (IsObject(Navigator)) Then
Dim Ie
Set Ie=WScript.CreateObject("InternetExplorer.Application","Event_")
'Msgbox "WSH"
MainF()
Else
'Msgbox "IEE"
End IF


Sub MainF()

Path="file://" & WScript.ScriptFullName


With Ie
.Navigate ("about:blank")
.Document.Write ("<Script Language=VBScript Src=""" & Path & """></Script><Script Langage=JavaScript></Script>") '需要写入的内容
.Document.Write ("<style>.GUIwh{width:24;height:24;cursor:hand;}</style><Body></Body>")


'窗口大小\位置
.Width = 660 '宽
.Height = 550 '高
.Resizable = 0 '不允许用户改变窗口大小'
.Left = Fix((.Document.ParentWindow.Screen.AvailWidth-.Width)/2) '水平居中
.Top = Fix((.Document.ParentWindow.Screen.AvailHeight-.Height)/2) '垂直居中


.Document.Title = " " '标题
.Document.Body.Scroll = "no" '关闭滚动条
.Document.Body.OnconTextMenu = GetRef("Disabled") '禁止右键
.Document.Body.OnSelectStart = GetRef("Disabled") '禁止选取
.Document.Body.Style.CssText = "background: SteelBlue ;color:#ffffff;"
.Document.Body.InnerHtml = "<table id=aT><tr><td><TABLE id=bT></TABLE></td><td id=sD></td></tr></table>"
.Document.ParentWindow.ExecScript "build(19)","VBScript"
With.Document.Body.All
.aT.Align = "Center"
.aT.Width = "630"
.aT.Border = "1"
.aT.BorderColor = "#ffffff"
.aT.CellSpacing = "0"
.aT.CellPadding = "10"
.aT.Style.CssText = "font: 13px 宋体;border-collapse:collapse;"

.aT.Rows(0).Align = "Center"
.aT.Rows(0).Cells(0).Width = "450"
.aT.Rows(0).Cells(0).Height = "450"

.bT.Align = "Center"
.bT.Border = "0"
.bT.BorderColor = "#ffffff"
.bT.CellSpacing = "0"
.bT.CellPadding = "0"
.bT.Style.CssText = "font: 21px 宋体;border:2px solid #ffffff;"
End With


'窗体
'.FullScreen=1
.MenuBar = 0 '取消菜单栏'
.AddressBar = 0 '取消地址栏'
.ToolBar = 0 '取消工具栏'
.StatusBar = 0 '取消状态栏'
.Visible = 1 '显示IE页面'
Set window=.Document.ParentWindow
End With
'.Document.OnClick = GetRef("Test1")
'window.ExecScript "fun()","VBScript"
'Ie.Document.ParentWindow.ExecScript "build(19)","VBScript"


Do
WScript.Sleep 200
Loop

End Sub


Function Test1()
'msgbox "event_boundElements"
End Function

Function Disabled()
Disabled=True
End Function

Function Event_OnQuit()
WScript.Quit
End Function


Function Build(N)
PS=N-1
While (S < N)
If S <= 1 Then charA=chr(43440):charB=chr(43472):charC=chr(43444)
If S >= 1 Then charA=chr(43456):charB=chr(43488):charC=chr(43464)
If S = PS Then charA=chr(43448):charB=chr(43480):charC=chr(43452)
Document.All.bT.insertrow(S)
For j = 0 To PS
If ((S*N+j) Mod PS) = (S Mod PS) Then
Char=charA:charA=charC
Else
Char=charB
End If

Document.All.bT.Rows(S).insertcell(j)
Document.All.bT.Rows(S).Cells(j).ID = S*N+j
Document.All.bT.Rows(S).Cells(j).CLASSName = "GUIwh"
Document.All.bT.Rows(S).Cells(j).InnerHtml = "<span onclick=Ts(this) onMouseOver='innerText=""" &chr(41457)& """;style.color=""blue""' onMouseOut='innerText=""" &chr(43488)& """;style.color=""""'>" &char& "</span>"
'Document.All.bT.Rows(S).Cells(j).InnerHtml = "<span id=mm onclick='Ts(this)' onMouseOver='innerText=X' onMouseOut='innerText=Y'>+</span>"
Next
S=S+1
Wend
End Function

Function Ts(this)

msgbox this.ParentNode.ID

this.parentNode.style.cursor = "default"
this.parentNode.innerHtml = chr(41457)
'PC.style.display = "none"

End Function


Function fun()
Msgbox "this is fun!"
End Function

哈哈

作者: zh159     时间: 2009-5-10 13:50
LS的代码只能用在IE浏览器为默认时,且有个bug:鼠标在边缘棋盘格移开后,并不是恢复边缘棋盘格的样子,而是变成中间棋盘格的样子

作者: netbenton     时间: 2009-5-10 13:56
re 17楼
存为什么扩展名呀?我运行不了呀,
.vbs .js .html .bat
都试了不行呢?

作者: HAT     时间: 2009-5-10 23:19    标题: Re 17楼
系统:XP SP2 EN
默认浏览器:IE 6
附件 1: 2009-05-11_100903.png (2009-5-10 23:19, 5.66 KiB)



作者: everest79     时间: 2009-5-11 02:21
Originally posted by zh159 at 2009-5-10 01:50 PM:
LS的代码只能用在IE浏览器为默认时,且有个bug:鼠标在边缘棋盘格移开后,并不是恢复边缘棋盘格的样子,而是变成中间棋盘格的样子



抄错了,哈哈
mouseout事件的文本应是char,我没看你后边替换的代码,直接填成+了
这个脚本我改了默认浏览器也是正常的呀

作者: everest79     时间: 2009-5-11 02:21
就是vbs,嘿嘿

作者: everest79     时间: 2009-5-11 02:23
这个错误我也碰到,原来是脚本中几个双字节符号造成的,我改成了cha(ascii)才解决掉,可能是你系统是英文版的原因吧

作者: HAT     时间: 2009-5-11 08:56    标题: Re 23楼
能否改改代码让它同时兼容中英文系统呢?

作者: everest79     时间: 2009-5-11 10:44
这些字符我也不熟,你可以换成英文字母先试试
只需要把chr(?????)换成chr(65)-chr(75)就可以了

作者: everest79     时间: 2009-5-11 11:38
弄了半天,写了下边这个代码,主要用来得到五子棋落子坐标的横竖撇捺行
我的思路是电脑不去对比整个棋盘,而是紧跟对手的落子判断落子四行是否有五子的风险
只写到提取四行数组
用的是一维数组,像棋盘要是二维的话可以使用 行数*总列(19)+列数 转成一维的
因为一维数组识别四行比较方便,横行步进1,竖行是19,撇是18,捺是20

有关坐标的关系可以使用以下代码观察
显示二维坐标

@echo off
setlocal enabledelayedexpansion
mode con: lines=100 cols=100
for /l %%i in (0,1,18) do (
for /l %%j in (0,1,18) do (
if %%i LSS 10 set x=0
if %%j LSS 10 set y=0
set/p=!x!%%i!y!%%j <nul
set x=&set y=
)
echo.
)

pause


显示一维坐标

@echo off
setlocal enabledelayedexpansion
for /l %%i in (0,1,18) do (
for /l %%j in (0,1,18) do (
set /a f=%%i*19+%%j
if !f! LSS 10 set f=0!f!
if !f! Lss 100 set f=0!f!
call set /p =%%f%% <nul
)
echo.
)

pause




Const N = 19
Const msg = 1
If Ucase(Right(WScript.FullName,11)) = "WSCRIPT.EXE" Then
CreateObject("WScript.Shell").Run "Cmd.exe /K Cscript """ & Wscript.ScriptFullName & """"
WScript.Quit
End If

ReDim arry(N*N-1)


For i =0 To N*N-1
arry(i)=i
Next

Function PriArry()
For i = 0 To 18
For j = 0 To 18
k="00"
If i*N+j > 9 Then k="0"
If i*N+j > 99 Then k=""
s=s & k & arry(i*N+j) & " "
Next
p s
s=""
Next
End Function


While True
PriArry
p xypn(gcon)
Wend

Function xypn(a)
M=N-1 '自定义坐标 标准x_ord*总列数+标准y_ord
x_ord = a\N '横向标准坐标 自定义坐标/总列数
y_ord = a Mod N '竖行标准坐标 自定义坐标/总列数的余数
x_base_value = x_ord*N '坐标所在行的 行首坐标值 (行数*总列数)
y_base_value = a-x_base_value '坐标所在列的 列首坐标值 (坐标值-行首坐标值)

For i = 0 To N-1
hen=hen & x_base_value+i & " " '横行=行首坐标值(x_base_value)以1递加至行尾
shu=shu & y_base_value+i*N & " " '竖行=列首坐标值(y_base_value)以N递加至列尾
Next
str = "横:" & hen & vbCrLf & "竖:" & shu & vcCrLf

px_ord = (Abs(x_ord+y_ord-M)+(x_ord+y_ord-M))\2 '撇行首标准坐标x ((标准x+y) > 18)?(px_ord=(x+y) mod 18):(0)
py_ord = x_ord+y_ord-px_ord '撇行首标准坐标y ((标准x+y) > 18)?(x+y-px_ord):(x+y)
p_base_value = px_ord*N+py_ord '撇行首自定义坐标值 标准x_ord*总列数+标准y_ord

For i = 0 To py_ord-px_ord '撇行长度为 py_ord-px_ord
pie=pie & p_base_value+i*(N-1) & " " '撇行自增量为 N-1
Next
str = str & vbCrLf & "撇:" & pie & vbCrLf

nx_ord = (Abs(x_ord-y_ord)+(x_ord-y_ord))\2 '捺行首标准坐标x nx_ord=((x_ord-y_ord) > 0)?(x_ord-y_ord):(0)
ny_ord = (x_ord-y_ord)*(Sgn(x_ord-y_ord)-1)\2 '捺行首标准坐标y ny_ord=((x_ord-y_ord) < 0)?(x_ord-y_ord):(0)
n_base_value = nx_ord*N+ny_ord '捺行首自定义坐标值 标准x_ord*总列数+标准y_ord

For i = 0 To 18-nx_ord-ny_ord '捺行长度为 18-(nx_ord+ny_ord)
na = na & n_base_value+i*(N+1) & " " '捺行自增量为 N+1
Next
str = str & "捺:" & na
xypn=str
End Function

Function p(str)
If msg Then WScript.Echo str Else InputBox "","",str
End Function

Function gcon()
gcon=WScript.StdIn.ReadLine
End Function



作者: netbenton     时间: 2009-5-11 12:17
不管是用二维坐标法,还是一维跨标法,最后还是要进行组串,然后才与规则串匹配
因为在进行规则串匹配时,是按串进行的。其实应该把:显示缓存、横、坚、撇、捺分别定义为数组串较好一点,不必要去进行多次组串操作。

电脑方是根据匹配到的最优规则串进行下子的,根据匹配到的是在哪个数组(横/坚/撇/捺)第几串的第几个字符,即可转换为实际坐标

因为定义了五个数组,所以只要下一个子,就要分别对这五个数组的相应位置进行替换,每个数组仅替换一行的一个字符即可

以行为单元显示肯定要比以字符为单元显示要快好多,因为用了显存串方式,所以可以直接以行为单元显示。

作者: HAT     时间: 2009-5-11 12:42    标题: Re 26楼
我的思路是电脑不去对比整个棋盘,而是紧跟对手的落子判断落子四行是否有五子的风险

这样的话电脑的棋力是否太弱了?通常的五子棋算法都是对下一步双方可能出现的情况(四三、双三等等)进行优先级排序,然后选择优先级最高的落点吧。

作者: rubble     时间: 2009-5-12 08:09    标题: 算法还没弄懂
太牛了,批处理也有这么强的功能!

作者: SNSB     时间: 2009-5-12 08:33
Originally posted by rubble at 2009-5-12 08:09:
太牛了,批处理也有这么强的功能!

真想不到能搞出这一个东西出来,不过代码我就很难懂了。

作者: everest79     时间: 2009-5-12 08:42
先写简单的把骨架支起来,慢慢再复杂化,嘿嘿

作者: netbenton     时间: 2009-5-12 13:57
增加了几行代码,却提速不少,

看来还是有可能进一步提高电脑的棋艺,
并引进五子棋的禁手及其它规则,


@echo off&setlocal enabledelayedexpansion
mode con: lines=43 cols=110
set li39= A B C D E F G H I J K L M N O P Q R S
set li0= ┌─────────────────────────────────────┐
set li1=A│┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐│A
set var=1
for %%a in (!li39:~5^,-1!) do (set/a var+=2&set li!var!=%%a│├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤│%%a)
for /l %%a in (2,2,36) do (set li%%a= ││ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ││)
set li37=S│└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘│S
set li38= └─────────────────────────────────────┘
set str=a b c d e f g h i j k l m n o p q r s
for %%a in (%str%) do (set/a .+=1,%%a=.&set z!.!=%%a)

set li5=!li5! 五 棋 子 人 机 对 战
set li7=!li7! 批 处 理
set li10=!li10! 电 脑 水 平 中 等
set li31=!li31! 由 netbenton 编写完成
set li33=!li33! 棋盘设计参照了 batman
title 批处理五子棋


set str=###################
set .=0
for /l %%a in (1,1,19) do (
set he%%a=!str!&set sh%%a=!str!
for /l %%b in (1,1,19) do set




























:
if /i "!var!" equ "Q" goto :eof

if /i "!var!" equ "D" (set onez=○&set towz=●&set hou=☆) else (set onez=●&set towz=○&set hou=★)
set a!onez!=电脑&set a!towz!=玩家
)
(
set ttr=!idea:@=%onez%!&set ttr=!ttr:$=%towz%!
set idea=
for %%a in (!ttr!) do (set var=%%a&set !var:~,-1!=!var:~-1!&set idea=!idea! !var:~,-1!)
set ttr=
set li27=!li27! !onez! !a%onez%!
set li25=!li25! !towz! !a%towz%!
set/a pos=10,poh=10&goto :getok
)

:loop
(if %zhi% equ %onez% goto :men
set .=
for %%a in (!idea!) do (
for %%b in (he sh) do (
set all=!%%b1!!%%b2!!%%b3!!%%b4!!%%b5!!%%b6!!%%b7!!%%b8!!%%b9!!%%b10!!%%b11!!%%b12!!%%b13!!%%b14!!%%b15!!%%b16!!%%b17!!%%b18!!%%b19!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (1,1,19) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
)
) )
for %%b in (pi ni) do (
set all=!%%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!
if "!all:%%a=!" neq "!all!" (
for /l %%c in (5,1,33) do (
if "!%%b%%c:%%a=!" neq "!%%b%%c!" set/a .+=1&set put!.!=%%b %%c
)
) )
if defined . set put=%%a&goto :get
))

echo. 已经和棋了
pause
endlocal&goto :restart

:men
(
set/a .=lips-1&for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%hou%!%%b:~%%c!)
set li38=!li38!
cls
for /l %%a in (0,1,39) do (echo !li%%a!)
for /f "tokens=1-3" %%b in ("li!liph! !lips! !.!") do (set %%b=!%%b:~0,%%d!%zhi%!%%b:~%%c!)
set li38=%li38%
set /p user=!say:say=%error%! :
if "!user!" equ "reboot" endlocal&goto :restart
if "!user!" equ "exit" exit
if "!user!" equ "back" call :悔&goto :men
set/a pos=!user:~0,1!,poh=!user:~1,2!,var=pos-1 2>nul
if not defined







































































Last edited by netbenton on 2009-5-14 at 00:31 ]

作者: netbenton     时间: 2009-5-17 11:44
增强电脑方的智能了!
已经在 7 楼更新。

作者: matlan     时间: 2009-5-17 14:22
太厉害了

作者: 516526966     时间: 2009-5-18 03:02
真的不可思议啊,很壮观,,崇拜你,你真是个好人。。。

Last edited by 516526966 on 2009-5-18 at 08:03 ]
附件 1: 2009-05-18_185017.png (2009-5-18 08:01, 25.14 KiB,下载次数: 1)



作者: zh159     时间: 2009-5-18 13:07
我已经晕了,除了界面,对预算法完全白痴,想改为VBS基本落空...

作者: 277854201     时间: 2009-5-19 04:20
太强了 ~

作者: netbenton     时间: 2009-5-21 09:09
又进行更新了,完善了电脑方的IQ,并在多个可下点等效时进行随机取位,增加了可玩性,因此,该批处理不再仅仅是一件艺术品,还是一个实实在在的五子棋游戏了,
欢迎大家使用,并把你认为电脑下得”笨“的地方发上来,以便再度完善。

最后更新,请看7楼

作者: zh159     时间: 2009-5-22 23:31
现在我想弄明白的两个算法:
1、电脑下位算法
2、5子结果的算法

作者: netbenton     时间: 2009-5-23 00:55    标题: 批处理五子棋算法
re 39L

数组定义:
1,显示缓存
2,横向(串长度为19)
3,竖向(串长度为19)
4,撇(斜向,串长度为5~19~5)
5,捺(斜向,串长度为5~19~5)

数组1,初始为空棋盘
数组2~5,初始全为#号的字符串

在有下子时,根据玩家输入或电脑取得的实际坐标,分别对5个数组中相应的位置进行替换为棋子(方法:!str:~,n!棋子!str:~n+1!)
替换后,马上匹配该串!str!是否含有五子相连,有即胜出了。

电脑怎样取位:
因为各个方向串是分别定义和替换更新的,所以只要拿各种规则串(即设置的IQ,如:#○○○#)同各个方向的数据串进行匹配,如果发现有则记录下来(在哪个数组,第几串),所有匹配完成后。则对记录下来的结果进行分析,转换为实际坐标。

(IQ规则串后的数字为该规则串的中可下点,算出规则串在方向串的位置,根据该点,即可算出方向串中的可下点,再根据是在哪个数组,即可算出在实际坐标中的可下点)

然后根据规则串给该坐标加权(初版时只求最先匹配到的可下点,没有的权计算),最后电脑取权值最大的坐标来下子。如果有权值相等的则随机取一个来下。

作者: netbenton     时间: 2009-5-25 11:39
五子棋批处理,带音乐播放和音乐文件,只有96K
一边听《春江花月夜》,一边下棋,享受啊!!

Last edited by netbenton on 2009-6-3 at 23:22 ]
附件 1: 五子棋(音乐版).rar (2009-6-4 01:22, 20.18 KiB,下载次数: 107)

作者: netbenton     时间: 2009-6-2 12:01
小更新:增强了一点点电脑棋艺。
(在7楼,41楼都已经更新)

看到网上有人贴出,玩家先下时,九手就赢了电脑,特此更改进。

作者: THENEWLIFE     时间: 2009-6-2 22:53
看了前辈的杰作,心里久久不能平静。我要学到什么时候才能达到前辈这样子的水平啊~
从今天起努力!努力!以前辈为目标

作者: tslnyys     时间: 2009-6-3 02:34
音乐不会停啊,批处理关了音乐还再继续。

作者: tslnyys     时间: 2009-6-3 02:36
哦,只有在游戏中打 Q退出时音乐才会停止,

直接点出关闭按纽的话游戏虽然退出了,但音乐还在响,

不知是不是只有我这里这样。

作者: tslnyys     时间: 2009-6-3 02:39
哎?桌面上的“春江花月夜”从哪来的?

是这个批处理从网上下来的吗?

作者: netbenton     时间: 2009-6-4 01:24
re 楼上
cjhyy.mid和playlist.vbs是程序自己生成的,现在可以自动关闭背景音乐了。
请重新下载.
谢谢使用。

作者: wssjzz     时间: 2009-6-4 04:36
首先说一下楼上的门太有才了!其他的没看就是41楼的那个带音乐的貌似设计的还是不到位,悔棋可以无限悔,可以一直悔到第一步,期待高手的完善

作者: tkaven     时间: 2009-6-4 11:08    标题: 楼主你好 你的那个5子棋文件大小可以 缩小到 50.7k
" ####### 代码 #########
'Any2Bat.vbs by zzzEVAzzz
on error resume next
set arg=wscript.arguments
if arg.count=0 then wscript.quit
with CreateObject("ADODB.Stream")
.type=1:.open:.loadfromfile arg(0):bs=.read:l=.size:.close
end with
if err.number<>0 then wscript.quit
set fso=CreateObject("Scripting.FileSystemObject")
with fso.opentextfile(arg(0)&".bat",2,true)
if err.number<>0 then wscript.quit
.writeline "@echo bs=_>xx.vbs"
for k=1 to l step 129
.write "@echo """
.write b64b(midb(bs,k,129))
.writeline """+_>>xx.vbs"
next
.writeline "@echo """":set rs=CreateObject(""ADODB.Recordset"")>>xx.vbs"
.writeline "@echo set ado=CreateObject(""ADODB.Stream"")>>xx.vbs"
.writeline "@echo l=len(bs):ss="""":for k=1 to l step 4096:ss=ss+ub64(mid(bs,k,4096)):next:l=len(ss)>>xx.vbs"
.writeline "@echo rs.fields.append ""b"",205,l/2:rs.open:rs.addnew:rs(""b"")=ss+chrb(0):rs.update>>xx.vbs"
.writeline "@echo ado.mode=3:ado.type=1:ado.open:ado.write rs(""b"").getchunk(l/2)>>xx.vbs"
.writeline "@echo ado.savetofile """+fso.getfilename(arg(0))+""",2:ado.close>>xx.vbs"
.writeline "@echo function ub64(s):dim t(4),b(3):ub64="""":n=len(s):r=2 >>xx.vbs"
.writeline "@echo if n mod 4^<^>0 then exit function:end if:for i=1 to n step 4:for j=0 to 3 >>xx.vbs"
.writeline "@echo a=asc(mid(s,i+j,1)):if a=43 then:a=62:else if a=47 then:a=63:else if a^>47 and a^<58 then:_>>xx.vbs"
.writeline "@echo a=a+4:else if a=61 then:a=0:if r=2 then r=j-2:end if:else if a^>64 and a^<91 then:_>>xx.vbs"
.writeline "@echo a=a-65:else if a^>96 and a^<123 then:a=a-71:else:exit function:_>>xx.vbs"
.writeline "@echo end if:end if:end if:end if:end if:end if:t(j)=a:next>>xx.vbs"
.writeline "@echo b(0)=t(0)+t(1)*64 mod 256:b(1)=t(1)\4+t(2)*16 mod 256:b(2)=t(2)\16+t(3)*4 >>xx.vbs"
.writeline "@echo for j=0 to r:if b(j)^<16 then ub64=ub64+""0"":end if:ub64=ub64+hex(b(j))>>xx.vbs"
.writeline "@echo next:next:end function>>xx.vbs&&cscript.exe //nologo xx.vbs&del xx.vbs"
end with
const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
function b64b(bin)
b64b=""
n=lenb(bin)
for i=1 to n step 3
a=ascb(midb(bin,i,1))
b64b=b64b+mid(b64,a mod 64+1,1)
if i<n then
b=ascb(midb(bin,i+1,1))
b64b=b64b+mid(b64,(a\64+b*4)mod 64+1,1)
if i+1<n then
c=ascb(midb(bin,i+2,1))
b64b=b64b+mid(b64,(b\16+c*16)mod 64+1,1)
b64b=b64b+mid(b64,c\4+1,1)
else
b64b=b64b+mid(b64,b\16+1,1)
b64b=b64b+"="
end if
else
b64b=b64b+mid(b64,a\64+1,1)
b64b=b64b+"=="
end if
next
end function

" ####### 代码 #########

请将 以上 保存 为 .vbs

然后 请将 CJHYY.MID 拖到 保存的 .vbs 文件上

之后 会 生成 一个 包涵 CJHYY.MID 的 .bat (只有41K)

将 包涵 CJHYY.MID 的 .bat 内容 做 适当修改 即可 加入到你的 五子棋.bat 当中了

作者: netbenton     时间: 2009-6-19 02:18
支持鼠标的人机对战五子棋批处理

Last edited by netbenton on 2009-6-19 at 06:55 ]
附件 1: 五子棋+鼠标.rar (2009-6-19 02:18, 31.16 KiB, 下载附件所需积分 1点 ,下载次数: 80)

作者: zh159     时间: 2009-6-20 01:28
这个爽,省了转换VBS了...

作者: chengbiner     时间: 2009-6-20 04:14
哈哈,这里是高手辈出的地方啊
从以前的通讯录到支持鼠标的五子棋

作者: whpluck     时间: 2009-7-3 03:30
这也太强了吧,真是要登峰造极!

作者: lsp19880301     时间: 2009-7-5 10:59
批处理还有这样的做法,..楼主太牛了...我绝对支持呀

作者: qinchun36     时间: 2009-7-6 07:25
真是太好了,不过哪个 cmos 能用批处理实现么 ??

作者: tomy000     时间: 2009-7-7 11:57
太历害了!看不懂了

作者: weasel     时间: 2009-7-7 12:51
这也太强了,
好好学习
  天天向上

作者: weiyepin     时间: 2009-7-7 14:58
向前辈们学习~~

作者: fengyl     时间: 2009-7-8 02:02
都好强啊

作者: netbenton     时间: 2009-7-31 11:59
对比了一下,一些flash做的五子棋游戏的智能还比不上这个批处理的,所以该的批处理五子棋游戏,可玩性还是有的,无聊时可以休闲玩一下。


2009.8.14修改
修正一些bug,并更新三方工具,并组合背景音乐。

Last edited by netbenton on 2009-8-14 at 08:10 ]
附件 1: 批处理五子棋.rar (2009-8-14 10:08, 29.05 KiB,下载次数: 97)

作者: kinfou     时间: 2009-8-1 06:10
都好强啊 ,好好看看

作者: wenqs27     时间: 2009-8-2 09:57
很钦佩。算法明晰,结构清楚,佳作!

作者: liuzikai     时间: 2009-11-30 17:43
good

作者: Taurus     时间: 2009-12-2 23:10
繁體系统運行不了

作者: xj787     时间: 2009-12-3 03:32
我还不会....还有很多要学习的...多多只教哟

作者: netbenton     时间: 2010-1-4 08:14
好久没回贴了,给自己灌一下水。汗一下。。。

作者: g21589     时间: 2010-1-19 21:09
這也太強了吧!!
玩玩看

作者: clamber     时间: 2010-1-19 22:33
厉害啊,厉害!

作者: acaigg     时间: 2010-12-28 15:58
太强大了。

作者: skyfreesky     时间: 2010-12-28 18:04
真没想到,批处理还能这么强..向楼主致敬

作者: acaigg     时间: 2010-12-30 09:55
能请教一下楼主,那个音乐文件是怎样转的。

作者: gudou     时间: 2011-1-5 18:38
可把文件都集中在1楼么……有点分不清哪个最新啊,呵呵

作者: sdlwsch     时间: 2011-1-7 17:23
很好很强大!!!楼上都是牛人!!!

作者: cechancao     时间: 2016-10-15 01:07
绝对 牛B 10年后还是经典