|
bat-zw
金牌会员
永远的学习者
积分 3105
发帖 1276
注册 2008-3-8
状态 离线
|
『楼 主』:
挑战代码极限效率(模拟围棋版五子棋)
在此,要非常感谢namejm的大力帮助,也请大家都来挑战一下这极限的效率(单
单大循环就是361*361次,其中还要涉及到call...)
----------------------------------------------------------------------------------------------------------
@echo off&color 1f&mode con cols=50 lines=25&setlocal enabledelayedexpansion
title 五子棋 by zw19750516 thanks for namejm
set "codes=A B C D E F G H I J K L M N O P Q R S"
set "code= %codes: =%"
for /l %%a in (1,1,19) do (
for /l %%i in (1,1,19) do (
set "a=!code:~%%i,1!"&set /a num+=1
set ".!num!=%%a!a!"
))
for /l %%i in (1,1,381) do (
set /a a=!random!%%381+1
call,set "b=%%.!a!%%"
set ".!a!=!.%%i!"
set ".%%i=!b!"
)
:begin
set /a n+=1,m+=1&if !m! equ 2 set m=0
if !m! equ 0 (set "zi=●"&set "vins=●●●●●") else (set "zi=○"&set "vins=○○○○○")
set "_!.%n%!=%zi%"
echo.>temp.txt
echo ┌───────────────────┐>>temp.txt
for /l %%a in (1,1,19) do (
for /l %%i in (1,1,19) do (
if %%a equ 1 (
if %%i equ 1 (
set "_p=│┌"
) else (
if %%i equ 19 (
set "_p=┐│"
) else (
set "_p=┬"
))) else (
if %%a equ 19 (
if %%i equ 1 (
set "_p=│└"
) else (
if %%i equ 19 (
set "_p=┘│"
) else (
set "_p=┴"
))) else (
if %%i equ 1 (
set "_p=│├"
) else (
if %%i equ 19 (
set "_p=┤│"
) else (
set "_p=┼"
))))
set str=!code:~%%i,1!
if defined _%%a!str! (
call :lop %%a %%i
) else (
if %%i equ 19 (
set /p=!_p!%%a<nul>>temp.txt
) else (
set /p=!_p!<nul>>temp.txt
)))
echo.>>temp.txt
)
echo └───────────────────┘>>temp.txt
echo %codes%>>temp.txt
cls&type temp.txt
if defined vin (
if %m% equ 0 (set /p=白子胜,<nul) else (set /p=黑子胜,<nul)
echo 最后落子为:%a%%b%。
del /q temp.txt&pause>nul&goto :eof
)
if %n% neq 361 (goto begin) else (echo 结果不分胜负!&pause>nul&goto :eof)
:lop
if %2 equ 1 (set "ll=set /p=│<nul>>temp.txt&") else (set "ll=")
if %2 equ 19 (set "rr=&set /p=│%1<nul>>temp.txt") else (set "rr=")
%ll%set /p=!_%1%str%!<nul>>temp.txt%rr%
if "%1%str%" equ "!.%n%!" (set "a=%1"&set "b=%str%"&goto judge) else (goto :eof)
:judge
rem 判断是否胜出
set "hang="&set "lie="&set "ls="&set "rs="&set "ss="&set "x=0"&set "y=0"&set "z=0"
set /a x1=%2-4,x2=%2+4,y1=%1+4,y2=%1-4
if %x1% lss 0 set "x1=0"
if %y2% lss 0 set "y2=0"
if %x2% gtr 19 set "x2=19"
if %y1% gtr 19 set "y1=19"
for /l %%i in (%x1%,1,%x2%) do set "ss=!ss! !code:~%%i,1!"
for %%i in (%ss%) do if defined _%1%%i (set "hang=!hang!!_%1%%i!") else (set "hang=!hang!#")
for /l %%i in (%y2%,1,%y1%) do if defined _%%i%str% (set "lie=!lie!!_%%i%str%!") else (set "lie=!lie!#")
for %%a in (%ss%) do (
set /a x+=1,y=0,z=0
for /l %%b in (%y1%,-1,%y2%) do (
set /a y+=1
if !x! equ !y! (
if defined _%%b%%a (
set "ls=!ls!!_%%b%%a!"
) else (
set "ls=!ls!#"
)))
for /l %%c in (%y2%,1,%y1%) do (
set /a z+=1
if !x! equ !z! (
if defined _%%c%%a (
set "rs=!rs!!_%%c%%a!"
) else (
set "rs=!rs!#"
))))
for %%i in (%hang% %lie% %ls% %rs%) do (
set var=%%i
if "!var:%vins%=!" neq "!var!" set vin=a&goto :eof
)
[ Last edited by zw19750516 on 2008-7-18 at 08:16 PM ]
|
批处理之家新域名:www.bathome.net |
|
2008-7-18 18:26 |
|
|
BC
中级用户
积分 338
发帖 175
注册 2007-10-21
状态 离线
|
『第
2 楼』:
看到一行行的for就头晕``
最近论坛好冷清``
|
C:\
C:\Del BC |
|
2008-7-18 20:01 |
|
|
BC
中级用户
积分 338
发帖 175
注册 2007-10-21
状态 离线
|
『第
3 楼』:
怎么是自己下的?
电脑自己打自己,但是好像速度慢了点哦
|
C:\
C:\Del BC |
|
2008-7-18 20:02 |
|
|
bat-zw
金牌会员
永远的学习者
积分 3105
发帖 1276
注册 2008-3-8
状态 离线
|
『第
4 楼』:
Quote: | Originally posted by BC at 2008-7-18 20:02:
怎么是自己下的?
电脑自己打自己,但是好像速度慢了点哦 |
|
要改为手动操作是很容易的,这也速度慢,估计这是最快的速度了!
|
批处理之家新域名:www.bathome.net |
|
2008-7-18 20:18 |
|
|
26933062
银牌会员
积分 2268
发帖 879
注册 2006-12-19
状态 离线
|
『第
5 楼』:
速度已经不错了,视觉效果也不错。美中不足是电脑走棋没有智能。
另外:提个建议,看是否行的通。
一、棋盘可扩大,不要边框 ,这样更美观。
二、是否可以将棋盘的落子处,不要显示十字架,而是直接显示坐标呢?否则走棋时寻找坐标很麻烦。但不知道这样是否会影响美观程度。
|
致精致简! |
|
2008-7-18 22:15 |
|
|
slore
铂金会员
积分 5212
发帖 2478
注册 2007-2-8
状态 离线
|
『第
6 楼』:
。。。。。
随机太厉害……快摆满了才有5个联的……
貌似名字不对哦~
|
S smile 微笑,L love 爱,O optimism 乐观,R relax 放松,E enthusiasm 热情...Slore |
|
2008-7-18 22:31 |
|
|
metoo
初级用户
积分 195
发帖 93
注册 2006-10-28
状态 离线
|
『第
7 楼』:
Quote: | Originally posted by BC at 2008-7-18 08:01 PM:
看到一行行的for就头晕``
最近论坛好冷清`` |
|
for没啥头晕的。。到处是goto最晕了。。自己写的看着都晕
|
|
2008-7-18 22:58 |
|
|
bat-zw
金牌会员
永远的学习者
积分 3105
发帖 1276
注册 2008-3-8
状态 离线
|
『第
8 楼』:
更新到双人下,并加入注释:
@echo off&setlocal enabledelayedexpansion
rem 设置窗口大小及色彩----------------------------------------------------------------------
color 1f&mode con cols=55 lines=27
title 五子棋 by zw19750516 thanks for namejm
echo.&echo.&echo.&echo.&echo 程序载入中...
set "codes=A B C D E F G H I J K L M N O P Q R S"
set "code= %codes: =%"&set /a n=-1,m=0
rem ----------------------------------------------------------------------------------------
rem 获取电脑随机步数并乱序------------------------------------------------------------------
for /l %%a in (1,1,19) do (
for /l %%i in (1,1,19) do (
set "a=!code:~%%i,1!"&set /a num+=1
set ".!num!=%%a!a!"
))
for /l %%i in (1,1,361) do (
set /a a=!random!%%361+1
call,set "b=%%.!a!%%"
set ".!a!=!.%%i!"
set ".%%i=!b!"
set "a="&set "b="
)
rem ----------------------------------------------------------------------------------------
rem 走子大循环(输出棋盘)--------------------------------------------------------------------
:begin
set "num=%m%"
set /a n+=1,m+=1&if !m! equ 2 set m=0
if %m% equ 0 (set "zi=●"&set "vins=●●●●●") else (set "zi=○"&set "vins=○○○○○")
if defined vin set "zi=胜"
if defined auto (set "_!.%n%!=%zi%") else (set "_%a%%b%=%zi%")
echo.>temp.txt
echo ┌───────────────────┐>>temp.txt
for /l %%a in (1,1,19) do (
for /l %%i in (1,1,19) do (
if %%a equ 1 (
if %%i equ 1 (
set "_p=│┌"
) else (
if %%i equ 19 (
set "_p=┐│"
) else (
set "_p=┬"
))) else (
if %%a equ 19 (
if %%i equ 1 (
set "_p=│└"
) else (
if %%i equ 19 (
set "_p=┘│"
) else (
set "_p=┴"
))) else (
if %%i equ 1 (
set "_p=│├"
) else (
if %%i equ 19 (
set "_p=┤│"
) else (
set "_p=┼"
))))
set str=!code:~%%i,1!
if defined _%%a!str! (
call :lop %%a %%i
) else (
if %%i equ 19 (
set /p=!_p!%%a<nul>>temp.txt
) else (
set /p=!_p!<nul>>temp.txt
)))
echo.>>temp.txt
)
echo └───────────────────┘>>temp.txt
echo %codes%>>temp.txt
cls&type temp.txt
rem ----------------------------------------------------------------------------------------
rem 选择走棋方式----------------------------------------------------------------------------
if defined hand goto step
if defined auto goto next
:choice
set /p select=请选择(1.人下 2.电脑下):
if %select% equ 2 set "auto=a"&goto begin
if %select% equ 1 set "hand=a"&set /a n-=1&goto begin
goto wrong
:step
if defined vin goto next
if defined step (
if %m% equ 0 (set /p=黑子下,<nul) else (set /p=白子下,<nul)
echo 对手上一步走的:%step%<nul
) else (
set /p=黑子先,<nul
)
set "ab="&set /p ab=请按纵、横顺序输入坐标(如:4h):
rem ----------------------------------------------------------------------------------------
rem 判断人工输入是否正确-------------------------------------------------------------------
if not defined ab goto wrong
if "%ab:~1%" equ "" goto wrong
if "%ab:~3%" neq "" goto wrong
if "%ab:~2%" equ "" (set "a=%ab:~,1%"&set "b=%ab:~1%") else (set "a=%ab:~,2%"&set "b=%ab:~2,1%")
if "%a:~,1%" equ "0" goto wrong
echo %a%|findstr "[^0-9]">nul&&goto wrong
echo %b%|findstr "[0-9]">nul&&goto wrong
if %a% lss 1 goto wrong
if %a% gtr 19 goto wrong
if "!codes:%b%=!" equ "%codes%" goto wrong
if defined _%a%%b% goto wrong
set "step=%ab%"
rem ----------------------------------------------------------------------------------------
rem 输出结果--------------------------------------------------------------------------------
:next
del /q temp.txt
if defined vin (
if %m% equ 0 (set /p=白子胜,<nul) else (set /p=黑子胜,<nul)
echo 最后落子为:%a%%b%。
pause>nul&exit
)
if %n% neq 361 (goto begin) else (echo 结果不分胜负!&pause>nul&exit)
rem ----------------------------------------------------------------------------------------
rem 判断是否胜出----------------------------------------------------------------------------
:lop
if %2 equ 1 (set "ll=set /p=│<nul>>temp.txt&") else (set "ll=")
if %2 equ 19 (set "rr=&set /p=│%1<nul>>temp.txt") else (set "rr=")
%ll%set /p=!_%1%str%!<nul>>temp.txt%rr%
if "%1%str%" equ "!.%n%!" set "a=%1"&set "b=%str%"&goto judge
if /i "%1%str%"=="%step%" goto judge
goto :eof
:judge
set "hang="&set "lie="&set "ls="&set "rs="&set "ss="&set "x=0"&set "y=0"&set "z=0"
set /a x1=%2-4,x2=%2+4,y1=%1+4,y2=%1-4
if %x1% lss 0 set "x1=0"
if %y2% lss 0 set "y2=0"
if %x2% gtr 19 set "x2=19"
if %y1% gtr 19 set "y1=19"
for /l %%i in (%x1%,1,%x2%) do set "ss=!ss! !code:~%%i,1!"
for %%i in (%ss%) do if defined _%1%%i (set "hang=!hang!!_%1%%i!") else (set "hang=!hang!#")
for /l %%i in (%y2%,1,%y1%) do if defined _%%i%str% (set "lie=!lie!!_%%i%str%!") else (set "lie=!lie!#")
for %%a in (%ss%) do (
set /a x+=1,y=0,z=0
for /l %%b in (%y1%,-1,%y2%) do (
set /a y+=1
if !x! equ !y! (
if defined _%%b%%a (
set "ls=!ls!!_%%b%%a!"
) else (
set "ls=!ls!#"
)))
for /l %%c in (%y2%,1,%y1%) do (
set /a z+=1
if !x! equ !z! (
if defined _%%c%%a (
set "rs=!rs!!_%%c%%a!"
) else (
set "rs=!rs!#"
))))
for %%i in (%hang% %lie% %ls% %rs%) do (
set var=%%i
if defined var if "!var:%vins%=!" neq "!var!" set /a n-=1&set "vin=a"&set "m=%num%"&goto begin
)
goto :eof
rem ----------------------------------------------------------------------------------------
rem 报错-----------------------------------------------------------------------------------
:wrong
set /p=错误,请正确输入。<nul&set "m=%num%"
ping /n 2 127.1>nul&set "a="&set "b="&set /a n-=1&goto begin
rem ----------------------------------------------------------------------------------------
[ Last edited by zw19750516 on 2008-7-19 at 01:35 PM ]
|
批处理之家新域名:www.bathome.net |
|
2008-7-18 23:39 |
|
|
HAT
版主
积分 9023
发帖 5017
注册 2007-5-31
状态 离线
|
『第
9 楼』:
要想电脑走棋有智能,可以到网上找个公开的算法,我看过很多C语言版本的,试着用批处理实现,不过估计会比较复杂。
|
|
|
2008-7-19 01:29 |
|
|
BC
中级用户
积分 338
发帖 175
注册 2007-10-21
状态 离线
|
『第
10 楼』:
支持下,总觉得批处理在这方面的能力很弱..
|
C:\
C:\Del BC |
|
2008-7-19 09:37 |
|
|
BC
中级用户
积分 338
发帖 175
注册 2007-10-21
状态 离线
|
『第
11 楼』:
@echo off
title 五子棋之兵临城下 作者:英雄 E-mail:bizhuang0917@126.com
setlocal enabledelayedexpansion
mode con cols=40 lines=5
color E0
echo.
set /p slt1= 您确定要向英雄家族挑战吗?(y/n)
cls
if /i not "%slt1%"=="y" goto def
:whofirst
echo.
echo 1、挑战者先手
echo 2、英雄家族先手
set /p slt2=
if not "%slt2%" equ "1" if not "%slt2%" equ "2" cls&echo 请正确输入!!&pause&cls&goto whofirst
cls
mode con cols=45 lines=10
:people
echo 请选择人物
echo.
echo 级别越高思考时间越长
echo.
echo 1、宠物 棋力--9级以下
echo 2、小师妹 宝宝 棋力--9~7级
echo 3、三师兄 猛虎 棋力--6~4级
echo 4、二师兄 飞龙 棋力--3~1级
echo 5、大师兄 英雄 棋力--9段
set /p slt3=
cls
if %slt3%==5 echo 对不起,英雄请产假回家照顾老婆了,请谅解~~。&pause&cls&goto people
if not "%slt3%" equ "1" if not "%slt3%" equ "2" if not "%slt3%" equ "3" if not "%slt3%" equ "4" (
cls
echo 请输入正确的人物代号!
pause
cls
goto people
)
::::::::::::::::::::::::::::::::::::::::::::::::
::以下定义一些变量,包括图形界面中的元素
::::::::::::::::::::::::::::::::::::::::::::::::
:def
set 纵轴=B C D E F G H I J K L M N
for %%i in (a %纵轴% o) do (
set /a bridge+=1
set ctoi%%i=!bridge!
)
set bridge=
for %%i in (a %纵轴% o) do (
set /a bridge+=1
set itoc!bridge!=%%i
)
:start
for %%i in (a %纵轴% o) do (
for /l %%j in (1,1,15) do (
set my%%i%%j=*
)
)
set A1=┏
set A15=┓
set O1=┗
set O15=┛
for /l %%i in (2,1,14) do set a%%i=┳
for /l %%i in (2,1,14) do set o%%i=┻
for %%i in (%纵轴%) do set %%i1=┣&set %%i15=┫
for %%i in (%纵轴%) do (
for /l %%j in (2,1,14) do (
set %%i%%j=╋
)
)
set round=1
set preinput=
mode con cols=61 lines=40
:::::::::::::::::::::::::::::::::::::::::::::::
::以下为交替落子模块
:::::::::::::::::::::::::::::::::::::::::::::::
call:graph
:play
:blackinput
if %round% geq 100 goto nowin
if /i "%slt1%"=="y" if "%slt2%"=="2" call:ai ● b&goto whiteinput
set /p input=第%round%手,请黑方输入
if /i "%input%"=="restart" goto start
if "!my%input%!"=="*" (
set %input%=●
set my%input%=b
set /a round+=1
) else (
echo 输入有误,请重新输入!
goto blackinput)
call:graph
call:judge %input%
:whiteinput
if %round% geq 100 goto nowin
if /i "%slt1%"=="y" if "%slt2%"=="1" call:ai ○ w&goto play
set /p input=第%round%手,请白方输入
if /i "%input%"=="restart" goto start
if "!my%input%!"=="*" (
set %input%=○
set my%input%=w
set /a round+=1
) else (
echo 输入有误,请重新输入!
goto whiteinput)
call:graph
call:judge %input%
goto play
:::::::::::::::::::::::::::::::::::::::::::::::
::以下为判断胜负模块
:::::::::::::::::::::::::::::::::::::::::::::::
:judge
set tmp=%1
set var1=!tmp:~0,1!
set var2=!tmp:~1!
set /a flag1=ctoi%var1%-1+var2
set /a flag2=var2-ctoi%var1%+1
rem 下面定义四个判断要用到的指标,分别代表横纵斜四个方向的落子情况
set judgeheng=
set judgezong=
set judgeyszx=
set judgezsyx=
rem 下面定义上述变量的具体值
rem 横向
for /l %%j in (1,1,15) do (
set judgeheng=!judgeheng!!my%var1%%%j!
)
rem 纵向
for %%j in (a %纵轴% o) do (
set judgezong=!judgezong!!my%%j%var2%!
)
rem 从右上到左下
for %%i in (a %纵轴% o) do (
call set judgeyszx=!judgeyszx!%%my%%i!flag1!%%
set /a flag1-=1
)
rem 从左上到右下
for %%i in (a %纵轴% o) do (
call set judgezsyx=!judgezsyx!%%my%%i!flag2!%%
set /a flag2+=1
)
rem 将上述四个指标串起来并进行判断
set judge=!judgeheng!*!judgezong!*!judgeyszx!*!judgezsyx!
(echo !judge!|find "bbbbb">nul)&&goto blackwin
(echo !judge!|find "wwwww">nul)&&goto whitewin
set score=
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::
::以下胜负已分
:::::::::::::::::::::::::::::::::::::::::::::::
:blackwin
set %input%=★
call :graph
echo 黑第%round%手胜!
pause
goto start
:whitewin
set %input%=☆
call :graph
echo 白第%round%手胜!
pause
goto start
:nowin
echo 百手和棋!
pause
goto start
:::::::::::::::::::::::::::::::::::::::::::::::
::以下为绘图过程
:::::::::::::::::::::::::::::::::::::::::::::::
:graph
cls
echo 输入RESTART重新开局
set /p = <nul
for /l %%i in (1,1,8) do set /p=%%i <nul
for /l %%i in (9,1,15) do set /p=%%i <nul
::echo.
for %%i in (A %纵轴%) do (
set /p =%%i<nul
for /l %%j in (1,1,14) do (
set /p =!%%i%%j!━<nul
)
echo !%%i15!
for /l %%j in (1,1,15) do (
set /p = ┃ <nul
)
echo.
)
set /p =O<nul
for /l %%i in (1,1,14) do set /p =!O%%i!━<nul
echo !O15!
echo 输入时先字母后数字。如H8。
goto :eof
:::::::::::::::::::::::::::::::::::::::::::::::
::以下是电脑下棋思路
:::::::::::::::::::::::::::::::::::::::::::::::
:ai
if %round% equ 1 set input=h8&goto ainext
set aitmp=%input%
set aivar1=%aitmp:~0,1%
set aivar2=%aitmp:~1%
:loop
set /a aiflag1=ctoi%aivar1%+%random%%%3-%random%%%3
set aiflag2=!itoc%aiflag1%!
set /a aivar=aivar2+%random%%%3-%random%%%3
if "!my%aiflag2%%aivar%!"=="*" (
set input=%aiflag2%%aivar%
)else goto loop
set /a aic1=ctoi%aivar1%+1
set /a aic2=ctoi%aivar1%-1
set aic1=!itoc%aic1%!
set aic2=!itoc%aic2%!
set /a aii1=aivar2+1
set /a aii2=aivar2-1
set aistr=bw
set air=!aistr:%2=!
call :analyse %aivar1%%aii1% %air%
call :analyse %aivar1%%aii2% %air%
call :analyse %aic1%%aivar2% %air%
call :analyse %aic2%%aivar2% %air%
call :analyse %aic1%%aii1% %air%
call :analyse %aic1%%aii2% %air%
call :analyse %aic2%%aii1% %air%
call :analyse %aic2%%aii2% %air%
if not defined preinput goto ainext
set aitmp=%preinput%
set aivar1=!aitmp:~0,1!
set aivar2=!aitmp:~1!
set /a aic1=ctoi%aivar1%+1
set /a aic2=ctoi%aivar1%-1
set aic1=!itoc%aic1%!
set aic2=!itoc%aic2%!
set /a aii1=aivar2+1
set /a aii2=aivar2-1
call :analyse %aivar1%%aii1% %2
call :analyse %aivar1%%aii2% %2
call :analyse %aic1%%aivar2% %2
call :analyse %aic2%%aivar2% %2
call :analyse %aic1%%aii1% %2
call :analyse %aic1%%aii2% %2
call :analyse %aic2%%aii1% %2
call :analyse %aic2%%aii2% %2
:ainext
set %input%=%1
set my%input%=%2
set /a round+=1
set preinput=%input%
call:graph
call:judge %input%
goto :eof
:::::::::::::::::::::::::::::::::::::::::::
::分析评价模块
:::::::::::::::::::::::::::::::::::::::::::
:analyse
if not "!my%1!"=="*" goto :eof
set Atmp=%1
set Avar1=!Atmp:~0,1!
set Avar2=!Atmp:~1!
set /a Aflag1=ctoi%Avar1%-1+Avar2
set /a Aflag2=Avar2-ctoi%Avar1%+1
set judgeheng=
set judgezong=
set judgeyszx=
set judgezsyx=
for /l %%j in (1,1,15) do (
set judgeheng=!judgeheng!!my%Avar1%%%j!
)
for %%j in (a %纵轴% o) do (
set judgezong=!judgezong!!my%%j%Avar2%!
)
for %%i in (a %纵轴% o) do (
call set judgeyszx=!judgeyszx!%%my%%i!Aflag1!%%
set /a Aflag1-=1
)
for %%i in (a %纵轴% o) do (
call set judgezsyx=!judgezsyx!%%my%%i!Aflag2!%%
set /a Aflag2+=1
)
set judge=!judgeheng!*!judgezong!*!judgeyszx!*!judgezsyx!
set Astr=%2
(echo !judge!|find "%Astr%">nul)&&(if "%score%" leq "1" set score=1&set input=%1)
if "%slt3%" geq "2" (echo !judge!|find "%Astr%%Astr%">nul)&&(if "%score%" leq "2" set score=2&set input=%1)
if "%slt3%" geq "3" (echo !judge!|find "%Astr%%Astr%%Astr%">nul)&&(if "%score%" leq "3" set score=3&set input=%1)
if "%slt3%" equ "4" (echo !judge!|find "%Astr%%Astr%%Astr%%Astr%">nul)&&(if "%score%" leq "4" set score=4&set input=%1)
goto :eof
从verybat转过来的
|
C:\
C:\Del BC |
|
2008-7-19 09:41 |
|
|