中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]根据返回正确数字位数与个数猜数字的游戏
作者:
标题: [原创]根据返回正确数字位数与个数猜数字的游戏 上一主题 | 下一主题
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『楼 主』:  [原创]根据返回正确数字位数与个数猜数字的游戏 使用 LLM 解释/回答一下

简单介绍以下这个游戏

有四位十进制数字,可猜8次
每次返回aAbB
A表示数字正确并且位置正确
B表示数字正确但位置不正确

如:假设要猜的数字是1234
如果游戏者猜0134即返回2A1B(3、4为A,1为B)
----------------------------------------------------------------------

关于这段代码
因为只是初步实现
所以免不了有些粗陋
现在感觉在JudgeNum上走了弯路
等有时间再改进吧

反向猜解才真正考验程序算法
各位有什么好注意
不妨提出来议一议


:: 猜数字游戏 : qzwqzw : 2007-07-29
:: 来自: http://www.cn-dos.net/forum/
@echo off & setlocal EnableDelayedExpansion
:Start - 游戏开始
set nCount=0
mode con cols=40 lines=25 & cls
echo.
echo 猜数字游戏现在开始,我出题你来猜
echo.
for /l %%i in (0,1,9) do set n%%i=%%i
set i=0

:GenLoop - 使用随机交换算法生成四个不重复的随机数组成目标数
setlocal
set r=%random:~-1,1%
call set tmp=%%n%i%%%
call set n%i%=%%n%r%%%
call set n%r%=%tmp%
set /a i+=1
if %i% neq 4 goto :GenLoop
endlocal & set nDest=%n0%%n1%%n2%%n3%

:Input - 等待用户输入猜测数
set nGuess=
set /p nGuess= 请输入猜测数(放弃请按 A):
if /i "%nGuess%"=="a" set "End=中止" & goto :End
set /a nGuess=1%nGuess% 2>nul || (echo ERR1: 数字无效,请重新输入 & goto :Input)
if %nGuess% lss 10123 echo ERR2: 数字无效,请重新输入 & goto :Input
if %nGuess% gtr 19876 echo ERR3: 数字无效,请重新输入 & goto :Input
set nGuess=%nGuess:~1,4%

:JudgeNum - 判断猜测数的准确性
setlocal EnableDelayedExpansion
set /a na=0,nb=0
for /l %%i in (0,1,3) do (
set bitDest=!nDest:~%%i,1!
set bitGuess=!nGuess:~%%i,1!
if !bitDest!==!bitGuess! (
set /a na+=1
) else (
set numt=!numt! !bitDest!
set gnumt=!gnumt! !bitGuess!
)
)
for %%i in (%numt%) do (
echo.%gnumt%|find "%%i">nul
if not errorlevel 1 (
set /a nb+=1
)
)
endlocal & set na=%na%&set nb=%nb%

set /a nCount+=1
echo 第 %nCount% 次判定结果: %na%A%nb%B
set strGuess=%strGuess% %nGuess%-%na%A%nb%B
if "%nCount%"=="9" set "End=失败" & goto :End
if not "%na%"=="4" goto :Input
set End=成功

:End
echo.
set /p choose= 猜测%End%,目标为%nDest%,继续吗(Y/N)
echo %End%:-: %strGuess% >> guess.log
set strGuess=
if "%choose%"=="y" goto :Start


Last edited by qzwqzw on 2007-9-25 at 11:19 AM ]

2007-7-30 07:48
查看资料  发短消息  网志   编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 2 楼』:   使用 LLM 解释/回答一下

曲高和寡。望尘莫及。



三人行,必有吾师焉。 学然后知不足,教然后知困,然后能自强也。
2007-7-30 10:20
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
hackerflysky
初级用户





积分 50
发帖 20
注册 2007-6-17
来自 湖南常宁
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

高手

2007-7-31 02:39
查看资料  发送邮件  发短消息  网志  OICQ (763900398)  编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

看来没有人提供意见
自己贴一个反向猜解的demo吧

对Judge做了修改
前提是比较的目标数各位互不重复
这个可以在非Demo中限定

Guess的算法比较弱
无法从速度还是猜解次数上
大概需要5到8次
在第2至4次可能会遇到猜解很慢的情形
因为那是在逐一判定

如果每次都进行逐一判定
那么猜解次数会有效减少
但是猜解时间会大幅提高
所以现有的算法是综合考虑以后得出来的


:: 猜数字游戏(演示版) : qzwqzw : 2007-07-30
:: 来自: http://www.cn-dos.net/forum/
@echo off & setlocal EnableDelayedExpansion

mode con cols=40 lines=25
:Start - 游戏开始
setlocal & cls
echo.
echo 猜数字游戏现在开始,你选数我来猜
echo.
call :Input iDest
if "%iDest%"=="" goto :eof
:: echo 猜测目标值:%iDest%

:GuessLoop - 游戏主循环
set /a iCount+=1
call :Guess iGuess %iGuess% %iNumA% %iNumB% %iCount%
if "%iGuess%"=="" set "End=失败" & goto :End
call :Judge iNumA iNumB %iGuess% %iDest%
echo.
echo. 第 %iCount% 次猜测:%iGuess%,判定值为:%iNumA%A %iNumB%B
set "strGuess=%strGuess% %iGuess%:%iNumA%A%iNumB%B"
if "%iCount%"=="9" set "End=失败" & goto :End
if "%iNumA%"=="4" set "End=成功" & goto :End
goto GuessLoop

:Input - 接受并保存用户输入的目标数
if "%1"=="" goto :eof
set _input=
set /p _input= 请输入猜测的数字(放弃请按 A):
if /i "%_input%"=="a" goto :eof
set /a _input=1%_input% 2>nul || (echo ERR1: 数字无效,请重新输入 & goto :Input)
if %_input% lss 10123 echo ERR2: 数字无效,请重新输入 & goto :Input
if %_input% gtr 19876 echo ERR3: 数字无效,请重新输入 & goto :Input
set "%1=%_input:~1,4%"
goto :eof

:Guess - 我来猜目标数
if not "%4"=="" goto :GuessNext
:GuessFirst - 首次猜测直接生成包含全部互不重复的四位数的数表
if exist guess.tbl (
copy guess.tbl _guess.tbl > nul
set _count=5040
goto :GuessSelect
)
if exist _guess.tbl del _guess.tbl
for /l %%i in (0,1,9) do (
for /l %%j in (0,1,9) do (
if not %%i==%%j for /l %%k in (0,1,9) do (
if not %%i==%%k if not %%j==%%k for /l %%l in (0,1,9) do (
if not %%i==%%l if not %%j==%%l if not %%k==%%l (
echo %%i%%j%%k%%l>>_guess.tbl
set /a _count+=1
)
)
)
)
)
copy _guess.tbl guess.tbl > nul
goto :GuessSelect

:GuessNext - 根据相似值使用 findstr 简单快速筛选数表
if not exist _guess.tbl goto :eof
set %1=
set _gss=%2
set /a _n=%3+%4
if "%_n%"=="0" set pattern="^*$"
if "%_n%"=="1" set pattern="^**$"
if "%_n%"=="2" set pattern="^***$"
if "%_n%"=="3" set pattern="^**$"
if "%_n%"=="4" set pattern="^*$"
findstr /r %pattern% _guess.tbl > _guess.tmp
for /f %%f in ('find /v /c "" ^<_guess.tmp') do set _count=%%f
if "%_count%"=="0" echo ERR4: 检索失败,请检查相似值 & goto :eof
copy _guess.tmp _guess.tbl > nul
for /f %%f in ('find /v /c "" ^<_guess.tbl') do set _count=%%f

set _isJudge=true
if 1%5 lss 13 set _isJudge=false
if 1%_n% equ 10 set _isJudge=false
if 1%3 equ 14 set _isJudge=true
if 1%_count% gtr 1500 set _isJudge=false
if 1%_count% lss 150 set _isJudge=true
if "%_isJudge%"=="false" goto :GuessSelect

:GuessJudge - 根据相似值对数表进行逐一判定,筛选出完全符合的数表
if exist _guess.tbl del _guess.tbl
set _nf=%2
for /f %%f in (_guess.tmp) do (
set _ng=%%f
set /a _numa=0, _numb=0
for /l %%i in (0,1,3) do (
set _nfb=!_nf:~%%i,1!
set _ngb=!_ng:~%%i,1!
if "!_nfb!"=="!_ngb!" (
set /a _numa+=1
) else (
echo.!_ng!|find "!_nfb!">nul && set /a _numb+=1
)
)
if 1%3==1!_numa! if 1%4==1!_numb! (
echo %%f>>_guess.tbl
)
)

:GuessSelect - 从筛选后的数表中随机选取一个作为新的猜测数
copy _guess.tbl _guess.sel > nul
for /f %%f in ('find /v /c "" ^<_guess.sel') do set _count=%%f
set /a rn=%random% %% _count + 1
for /f "tokens=2 delims=] " %%f in (
'find /v /n "" _guess.sel^|find ""'
) do (
set _guess=%%f
)
copy _guess.tbl guess_%5.txt > nul
endlocal & set %1=%_guess%
goto :eof

:Judge - 判断猜测数的准确性
setlocal EnableDelayedExpansion
set /a _numa=0,_numb=0
if not "%4"=="" set iGuess=%3&set iDest=%4
for /l %%i in (0,1,3) do (
set _dest=!iDest:~%%i,1!
set _guess=!iGuess:~%%i,1!
if !_dest!==!_guess! (
set /a _numa+=1
) else (
echo.%iGuess%|find "!_dest!">nul && set /a _numb+=1
)
)
endlocal & set %1=%_numa%&set %2=%_numb%
goto :eof

:End - 游戏单局结束后处理
echo.
set /p choose= 猜测%End%,目标为%iDest%,继续吗(Y/N)
echo %End%:-: %strGuess% >> guess.log
set strGuess=
endlocal & if /i "%choose%"=="y" goto :Start
del _guess*.*


Last edited by qzwqzw on 2007-8-1 at 10:19 AM ]

2007-7-31 08:08
查看资料  发短消息  网志   编辑帖子  回复  引用回复
Noname
新手上路





积分 18
发帖 9
注册 2007-7-25
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下

好游戏。。。。。

2007-7-31 18:04
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
tao0610
高级用户

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 6 楼』:   使用 LLM 解释/回答一下

很早以前写得猜数字.玩法差不多.
当时有写的点乱.也懒得改了.


@echo off&setlocal enabledelayedexpansion&color fc
:num
set/a a=%random%%%10
for %%a in (%num%) do if %a% equ %%a goto num
set num=%num% %a%
if "%num:~7%"=="" goto num
set z=%num: =%
set t=11

:start
echo\&echo/&echo=
set n=0&set a=0&set b=0&set aa=0&set aa1=
set/a t-=1
if %t%==0 goto fail
echo.你有%t%次机会.
set /p aa=请输入4位不同的数字:
if %aa%==%z% goto true
if %aa% leq 9999 if %aa% geq 0123 goto in
echo 输入错误,请输入4位不同的数字.&goto start

:in
set aa1=%aa1% %aa:~0,1%
set aa=%aa:~1%
if not defined aa goto next
for %%a in (%aa1%) do if %aa:~0,1% equ %%a echo.有重复数字,请重输入.&&goto start
goto in

:next
for %%a in (%aa1%) do (
call set str=%%z:~!n!,1%%
set/a n+=1
if %%a==!str! set/a a+=1
for %%b in (%num%) do (
if %%a==%%b set/a b+=1 ))
set/a b-=a
echo/数字位置都正确的有%a%个!
echo/数字对了位置不对的有%b%个!
goto :start

:fail
echo 你失败了
echo 答案是:%z%
echo.
pause>nul&goto :eof

:true
echo/&echo/&echo\
echo 你真厉害,猜对了!!!
echo.
pause>nul





认识自己,降伏自己,改变自己
,才能改变别人!
2007-7-31 18:52
查看资料  发短消息  网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 7 楼』:   使用 LLM 解释/回答一下

现在发布一个互动猜解版


:: 猜数字游戏(互动猜解版) : qzwqzw : 2007-07-31
:: 来自: http://www.cn-dos.net/forum/
@echo off & setlocal EnableDelayedExpansion

mode con cols=40 lines=20
:Start - 游戏开始
setlocal & cls
set iCount=0
echo.
echo 猜数字游戏现在开始,你出题我来猜
echo.

:GuessLoop - 游戏主循环
set /a iCount+=1
set /a iLimit=9-iCount
call :Guess iGuess %iGuess% %iNumA% %iNumB% %iCount%
if "%iGuess%"=="" set "End=失败" & goto :End
echo. 第 %iCount% 次(还有 %iLimit% 次)猜测数为:%iGuess%
set "iNumA=x" & set "iNumB=y"
call :UserJudge iNumA iNumB
set "strGuess=%strGuess% %iGuess%:%iNumA%A%iNumB%B"
if "%iNumB%"=="y" set "End=中止" & goto :End
if "%iNumA%"=="4" set "End=成功" & goto :End
if "%iCount%"=="9" set "End=失败" & goto :End
goto :GuessLoop

:Guess - 计算机猜解目标数
if not "%4"=="" goto :GuessFilter
:GuessFirst - 首次猜解直接生成包含全部互不重复的四位数的数表
setlocal
if exist guess.tbl (
copy guess.tbl _guess.tbl > nul
set _count=5040
goto :GuessSelect
)
if exist _guess.tbl del _guess.tbl
for /l %%i in (0,1,9) do (
for /l %%j in (0,1,9) do (
if not %%i==%%j for /l %%k in (0,1,9) do (
if not %%i==%%k if not %%j==%%k for /l %%l in (0,1,9) do (
if not %%i==%%l if not %%j==%%l if not %%k==%%l (
echo %%i%%j%%k%%l>>_guess.tbl
set /a _count+=1
)
)
)
)
)
copy _guess.tbl guess.tbl > nul
goto :GuessSelect

:GuessFilter - 根据相似值使用 findstr 简单快速筛选数表
set %1=
setlocal
set _gss=%2
set /a _n=%3+%4
if "%_n%"=="0" set pattern="^*$"
if "%_n%"=="1" set pattern="^**$"
if "%_n%"=="2" set pattern="^***$"
if "%_n%"=="3" set pattern="^**$"
if "%_n%"=="4" set pattern="^*$"
findstr /r %pattern% _guess.tbl > _guess.tmp
copy _guess.tmp _guess.tbl > nul
for /f %%f in ('find /v /c "" ^<_guess.tbl') do set _count=%%f
if "%_count%"=="0" echo ERR4: 检索失败,请检查指定的相似值 & goto :eof

set _isJudge=true
if 1%5 lss 13 set _isJudge=false
if 1%_n% equ 10 set _isJudge=false
if 1%3 equ 14 set _isJudge=true
if 1%_count% gtr 1500 set _isJudge=false
if 1%_count% lss 150 set _isJudge=true
if "%_isJudge%"=="false" goto :GuessSelect

:GuessJudge - 根据相似值对数表进行逐一判定,筛选出完全符合的数表
if exist _guess.tbl del _guess.tbl
set _nf=%2
for /f %%f in (_guess.tmp) do (
set _ng=%%f
set /a _numa=0, _numb=0
for /l %%i in (0,1,3) do (
set _nfb=!_nf:~%%i,1!
set _ngb=!_ng:~%%i,1!
if "!_nfb!"=="!_ngb!" (
set /a _numa+=1
) else (
echo.!_ng!|find "!_nfb!">nul && set /a _numb+=1
)
)
if 1%3==1!_numa! if 1%4==1!_numb! (
echo %%f>>_guess.tbl
)
)
if not exist _guess.tbl echo ERR5: 检索失败,请检查指定的相似值 & goto :eof

:GuessSelect - 从筛选的数列中随机选取
copy _guess.tbl _guess.sel > nul
for /f %%f in ('find /v /c "" ^<_guess.sel') do set _count=%%f
set /a rn=%random% %% _count + 1
for /f "tokens=2 delims=] " %%f in (
'find /v /n "" _guess.sel^|find ""'
) do (
set _guess=%%f
)
copy _guess.tbl guess_%5.txt > nul
endlocal & set %1=%_guess%
goto :eof

:UserJudge - 接受并保存用户输入的相似性值
if "%1"=="" goto :eof
set _judge=
set /p _judge= 请用两位数指定相似值(按 A放弃):
if /i "%_judge%"=="a" goto :eof
set /a _judge=1%_judge% 2>nul || (echo ERR6: 数字无效,请重新输入 & goto :UserJudge)
if %_judge% lss 100 echo ERR7: 数字无效,请重新输入 & goto :UserJudge
if %_judge% gtr 140 echo ERR8: 数字无效,请重新输入 & goto :UserJudge
set "%1=%_judge:~1,1%"
set "%2=%_judge:~2,1%"
goto :eof

:End - 游戏单局结束后处理
echo.
set /p choose= 猜测到%strGuess:~-9,4%%End%,重新开始吗(Y/N)
echo %End%于: %strGuess% >> guess.log
set strGuess=
endlocal & if /i "%choose%"=="y" goto :Start
del _guess*.*


2007-8-1 10:20
查看资料  发短消息  网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 8 楼』:   使用 LLM 解释/回答一下

tao0610
最好允许用户输入重复的数字
虽然目标数总是不重复的
但使用带有重复位的测试数
可能会方便确定目标数

2007-8-1 18:46
查看资料  发短消息  网志   编辑帖子  回复  引用回复
tao0610
高级用户

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 9 楼』:   使用 LLM 解释/回答一下

把判断重复输入那段去了就行.
其实10次之内.判断目标数.不是什么难事.




认识自己,降伏自己,改变自己
,才能改变别人!
2007-8-1 23:56
查看资料  发短消息  网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 10 楼』:   使用 LLM 解释/回答一下

现发布一个功能完整的Release 1版


:: 猜数字游戏 : 功能完整版 Release 1 : qzwqzw : 2007-08-02
:: 来源:http://www.cn-dos.net/forum/viewthread.php?tid=32554
@echo off & setlocal EnableDelayedExpansion
set iCount=0
set iLimit=9
set sGuess=-:----:----

:Start
mode con cols=40 lines=25 & cls
echo.
echo. 猜数字游戏介绍
echo.
echo. 由选数者随意选取一个四位数
echo. 四位数中的每位数均互不重复
echo.
echo. 由电脑者来猜测这个四位数
echo. 第一次可以随意猜测一个四位数
echo.
echo. 选数者根据电脑者的猜测数返回一个相似值
echo. 相似值由2 个数字组成,形似:xAyB
echo. xA表示猜测数中有 x个数字存在且位置正确
echo. yB则表示有 y个数字存在但位置不正确
echo.
echo. 比如:假设选数者所选取的数字是 1234
echo. 如果电脑者猜 1364 则选数者会返回 2A1B
echo. 其中的2A是指数字1、4,1B则是指数字 3
echo.
echo. 电脑者根据选数者返回的相似值继续猜测
echo. 选数者根据电脑者猜测的数字返回相似值
echo. 如此循环往复,直至电脑者猜出真正的数字
echo. 或者电脑者放弃电脑
echo.
pause

:ModeSelect
cls
echo.
echo. 本游戏提供以下游戏模式:
echo.
echo. U.我选数你来猜【用户】
echo. I.你选数我来猜【电脑】
echo.
echo. A.我选数我来猜【自动】
echo. M.你选数你来猜【手动】
echo.
echo. Q.退出游戏
echo.
echo.
set cMode=
set /p cMode= 请选择(U/I/A/M/Q):
if /i "%cMode%"=="U" goto :UGuess
if /i "%cMode%"=="I" goto :IGuess
if /i "%cMode%"=="A" goto :AGuess
if /i "%cMode%"=="M" goto :MGuess
if /i "%cMode%"=="Q" goto :eof
goto :ModeSelect

:UGuess - 用户模式开始
setlocal
set sMode=用户
call :Generate iDest
:UGLoop
cls
echo.
echo. 游戏现在开始,我选数你来猜【用户】
echo.
echo. 请在光标处直接输入你所猜测的4位数
echo. 我将在下方显示猜测数字的相似值
echo. 任意时刻按 Q 将中止本轮猜测游戏
echo.
echo. 次数 猜测数 相似值
for %%s in (%sGuess%) do (
for /f "tokens=1,2,3 delims=:" %%i in ("%%s") do (
echo. %%i %%j %%k
)
)
echo. - ---- ----
echo.
if "%iNumA%"=="4" set End=成功& goto :End
if "%iCount%"=="9" set End=失败& goto :End
set iGuess=
set /a iCount+=1
set /a iLimit-=1
call :UInput iGuess %iCount% %iLimit%
if "%iGuess%"=="" set End=中止& set /a iCount-=1 & goto :End
call :IJudge iNumA iNumB %iGuess% %iDest%
set sGuess=%sGuess% %iCount%:%iGuess%:%iNumA%A%iNumB%B
goto :UGLoop

:IGuess - 电脑模式开始
setlocal & cls
set sMode=电脑
echo.
echo.
set iDest=XXXX
:IGLoop
if "%iNumB%"=="y" set End=中止& goto :End
if "%iNumA%"=="4" set End=成功& goto :End
if "%iCount%"=="9" set End=失败& goto :End
cls
echo.
echo. 游戏现在开始,你选数我来猜【电脑】
echo.
echo. 首先我将在下方显示我所猜测的数字
echo. 请在光标处输入2位数确定它的相似值
echo. 任意时刻按 Q 将中止本轮猜测游戏
echo.
echo. 次数 猜测数 相似值
for %%s in (%sGuess%) do (
for /f "tokens=1,2,3 delims=:" %%i in ("%%s") do (
echo. %%i %%j %%k
)
)
echo. - ---- ----
echo.
call :IGuess iGuess %iGuess% %iNumA% %iNumB% %iCount%
if "%iGuess%"=="" set End=失败& goto :End
set /a iCount+=1
set /a iLimit=9-iCount
set "iNumA=x" & set "iNumB=y"
call :UJudge iNumA iNumB "第%iCount%次(还有%iLimit%次)猜测:%iGuess%"
set sGuess=%sGuess% %iCount%:%iGuess%:%iNumA%A%iNumB%B
goto :IGLoop

:AGuess - 自动模式开始
setlocal & cls
set sMode=自动
echo.
echo. 游戏现在开始,我选数我来猜【自动】
echo.
call :Generate iDest
echo. 我猜测的目标数字现在设定为 %iDest%
echo. 我将在下方分别显示猜测数和相似值
echo.
echo. 次数 猜测数 相似值
echo. - ---- ----
:AGLoop
if "%iNumA%"=="4" set End=成功& goto :End
if "%iCount%"=="9" set End=失败& goto :End
set /a iCount+=1
call :IGuess iGuess %iGuess% %iNumA% %iNumB% %iCount%
if "%iGuess%"=="" set End=失败& goto :End
call :IJudge iNumA iNumB %iGuess% %iDest%
echo. %iCount% %iGuess% %iNumA%A%iNumB%B
set sGuess=%sGuess% %iCount%:%iGuess%:%iNumA%A%iNumB%B
goto :AGLoop

:MGuess - 手动模式开始
setlocal & cls
set sMode=手动
cls
set iDest=
echo.
set /p iDest= 请设定要猜测的目标数字:
:MGLoop
cls
echo.
echo. 游戏现在开始,你选数你来猜【手动】
echo.
echo. 你所设定的目标数字为 %iDest%
echo. 请在光标处直接输入你所猜测的4位数
echo. 我将在下方显示出猜测数字与相似值
echo. 任意时刻按 Q 将中止本轮猜测游戏
echo.
echo. 次数 猜测数 相似值
for %%s in (%sGuess%) do (
for /f "tokens=1,2,3 delims=:" %%i in ("%%s") do (
echo. %%i %%j %%k
)
)
echo. - ---- ----
echo.
if "%iNumA%"=="4" set End=成功& goto :End
if "%iCount%"=="9" set End=失败& goto :End
set iGuess=
set /a iCount+=1
set /a iLimit-=1
call :UInput iGuess %iCount% %iLimit%
if "%iGuess%"=="" set End=中止& goto :End
call :IJudge iNumA iNumB %iGuess% %iDest%
set sGuess=%sGuess% %iCount%:%iGuess%:%iNumA%A%iNumB%B
goto MGLoop

:Generate - 使用随机交换算法生成四个不重复的随机数组成目标数
if "%1"=="" goto :eof
setlocal
for /l %%i in (0,1,9) do set n%%i=%%i
set i=0
:GenLoop
set r=%random:~-1,1%
call set tmp=%%n%i%%%
call set n%i%=%%n%r%%%
call set n%r%=%tmp%
set /a i+=1
if %i% neq 4 goto GenLoop
endlocal & set "%1=%n0%%n1%%n2%%n3%" & goto :eof

:UInput - 接受并保存用户输入的猜测数
if "%1"=="" goto :eof
set _input=
set /p _input= 第 %2 次 (还有 %3 次) 猜测:
if /i "%_input%"=="Q" goto :eof
set /a _input=1%_input% 2>nul
if errorlevel 9167 echo ERR1: 数字无效,请重新输入 & goto :UInput
if %_input% lss 10000 echo ERR2: 数字无效,请重新输入 & goto :UInput
if %_input% gtr 19999 echo ERR3: 数字无效,请重新输入 & goto :UInput
set "%1=%_input:~1,4%"
goto :eof

:IJudge - 判断猜测数的准确性
setlocal EnableDelayedExpansion
set /a _numa=0, _numb=0
if not "%4"=="" set iGuess=%3&set iDest=%4
for /l %%i in (0,1,3) do (
if "!iDest:~%%i,1!"=="!iGuess:~%%i,1!" (
set /a _numa+=1
) else (
echo.%iGuess%|find "!iDest:~%%i,1!">nul && set /a _numb+=1
)
)
endlocal & set %1=%_numa%&set %2=%_numb%
goto :eof

:IGuess - 我来猜目标数
if not "%4"=="" goto :IGFilter
:IGFirst - 首次猜测直接生成包含全部互不重复的四位数的数表
setlocal
if exist guess.tbl (
copy guess.tbl _guess.tbl > nul
set _count=5040
goto :IGSelect
)
if exist _guess.tbl del _guess.tbl
for /l %%i in (0,1,9) do (
for /l %%j in (0,1,9) do (
if not %%i==%%j for /l %%k in (0,1,9) do (
if not %%i==%%k if not %%j==%%k for /l %%l in (0,1,9) do (
if not %%i==%%l if not %%j==%%l if not %%k==%%l (
echo %%i%%j%%k%%l>>_guess.tbl
set /a _count+=1
)
)
)
)
)
copy _guess.tbl guess.tbl > nul
goto :IGSelect

:IGFilter - 根据相似值使用 findstr 简单快速筛选数表
set %1=
setlocal
set _gss=%2
set /a _ab=%3+%4
if "%_ab%"=="0" set pattern="^*$"
if "%_ab%"=="1" set pattern="^**$"
if "%_ab%"=="2" set pattern="^***$"
if "%_ab%"=="3" set pattern="^**$"
if "%_ab%"=="4" set pattern="^*$"
findstr /r %pattern% _guess.tbl > _guess.tmp
for /f %%f in ('find /v /c "" ^<_guess.tmp') do set _count=%%f
if "%_count%"=="0" echo ERR4: 猜测失败,输入的相似值互相矛盾 & goto :eof
if "%_ab%"=="2" (
findstr /r "^**$" _guess.tbl > _guess.tm2
for /f %%f in ('find /v /c "" ^<_guess.tm2') do set _count=%%f
if "!_count!"=="0" (
set _count=%_count%
del _guess.tm2
)
)
copy _guess.tmp _guess.tbl > nul

set _isJudge=true
:: if 1%3 equ 10 set _isJudge=false
if 1%5 lss 13 set "_isJudge=false" %- 前两次筛选不进行逐一判定 -%
if 1%_ab% equ 10 set "_isJudge=false" %- A+B等于0时不进行逐一判定 -%
if 1%3 equ 14 set "_isJudge=true" %- A等于4时进行逐一判定 -%
if 1%_count% gtr 1500 set "_isJudge=false" %- 表大于1500时不进行逐一判定 -%
if 1%_count% lss 150 set "_isJudge=true" %- 表小于150时进行逐一判定 -%
if "%_isJudge%"=="false" goto :IGSelect

:IGJudge - 根据相似值对数表进行逐一判定,筛选出完全符合的数表
del _guess.tbl
set _nf=%2
set _count=
set /p _tmp= 正在猜测数据,请稍等……<nul
for /f %%f in (_guess.tmp) do (
set _ng=%%f
set /a _numa=0, _numb=0
for /l %%i in (0,1,3) do (
if "!_nf:~%%i,1!"=="!_ng:~%%i,1!" (
set /a _numa+=1
) else (
echo.!_ng!|find "!_nf:~%%i,1!">nul && set /a _numb+=1
)
)
if 1%3==1!_numa! if 1%4==1!_numb! (
echo %%f>>_guess.tbl
set /a _count+=1
)
)
set /p _tmp=<nul
if not exist _guess.tbl echo ERR5: 猜测失败,输入的相似值互相矛盾 & goto :eof

:IGSelect - 从筛选后的数表中随机选取一个作为新的猜测数
copy _guess.tbl guess_%5.txt > nul
copy _guess.tbl _guess.sel > nul
if exist _guess.tm2 (
copy _guess.tm2 _guess.sel > nul
del _guess.tm2
)
set /a rn=%random% %% _count + 1
for /f "tokens=2 delims=] " %%f in (
'find /v /n "" _guess.sel^|find ""'
) do (
set _guess=%%f
)
endlocal & set %1=%_guess%
goto :eof

:UJudge - 接受并保存用户输入的判定值
if "%1"=="" goto :eof
set _judge=
set /p _judge= %~3,请判定:
if /i "%_judge%"=="q" goto :eof
set /a _judge=1%_judge% 2>nul
if errorlevel 9167 echo ERR6: 数字无效,请重新输入 & goto :UJudge
if %_judge% lss 100 echo ERR7: 数字无效,请重新输入 & goto :UJudge
if %_judge% gtr 140 echo ERR8: 数字无效,请重新输入 & goto :UJudge
set /a _ab=10+%_judge:~1,1%+%_judge:~2,1%
if %_ab% gtr 14 echo ERR9: 数字无效,请重新输入 & goto :UJudge
set "%1=%_judge:~1,1%"
set "%2=%_judge:~2,1%"
goto :eof

:End - 游戏单局结束后处理
set Report=%sMode%猜%iDest%,第 %iCount%次猜至%sGuess:~-9,4%时%End%
echo.
echo. %Report%
set choose=
set /p choose= 重新开始吗(Y/N)
echo %Report%。步骤为:%sGuess:~12% >>guess.log
endlocal & if /i "%choose%"=="y" goto :%cMode%Guess
del _guess*.*
goto :ModeSelect


   此帖被 +2 点积分    点击查看详情   
评分人:【 yovie 分数: +2  时间:2007-9-26 14:32


2007-8-2 18:24
查看资料  发短消息  网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 11 楼』:   使用 LLM 解释/回答一下

tao0610
如果允许重复数字
你的:next也需要修改一下
否则可能会重复累加 B 值

2007-8-2 18:25
查看资料  发短消息  网志   编辑帖子  回复  引用回复
dosmania
初级用户





积分 172
发帖 54
注册 2007-1-2
状态 离线
『第 12 楼』:   使用 LLM 解释/回答一下

to qzwqzw:

呵呵``7月30号,大概也是我研究这个游戏的时候,没想到那时候你也在研究这个~
测试了一下你的 release 1版
四种模式都存在问题,具体看我的抓图:









Last edited by dosmania on 2007-9-25 at 02:11 PM ]

2007-9-25 14:09
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2343
发帖 636
注册 2004-3-6
状态 离线
『第 13 楼』:   使用 LLM 解释/回答一下

cmd的输出还搞什么截图
直接复制粘贴文字就可以了嘛 :)

你的错误我这里调试时无法复现
可能是运行环境的差异造成的影响
听闻你对此颇有研究
就请你代为跟踪调试一下代码
确定一下问题点
以利于我们共同解决问题
谢谢!

Last edited by qzwqzw on 2007-9-26 at 10:52 PM ]

2007-9-25 14:45
查看资料  发短消息  网志   编辑帖子  回复  引用回复
dosmania
初级用户





积分 172
发帖 54
注册 2007-1-2
状态 离线
『第 14 楼』:   使用 LLM 解释/回答一下

你有解释机会,可惜的是我没有道歉机会
我已经因此失去了成为本论坛内部群的机会
----------------------------------------------------------
话说清楚些误会就大可以避免,是一场误会...
你要知道我测试你那个代码也花了有10分钟...
得到的是别人的”不理解“,是人都会发火...
------------------------------------------------------------
关于那游戏的代码有兴趣就再浏览一次我那贴子...------------------------------------------------------------
最后,我道歉...

Last edited by dosmania on 2007-9-26 at 08:56 PM ]

2007-9-26 14:13
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
dosmania
初级用户





积分 172
发帖 54
注册 2007-1-2
状态 离线
『第 15 楼』:   使用 LLM 解释/回答一下

你有解释机会,可惜的是我没有道歉机会
我已经因此失去了成为本论坛内部群的机会
----------------------------------------------------------
话说清楚些误会就大可以避免,是一场误会...
你要知道我测试你那个代码也花了有10分钟...
得到的是别人的”不理解“,是人都会发火...
------------------------------------------------------------
关于那游戏的代码有兴趣就再浏览一次我那贴子...------------------------------------------------------------
最后,我道歉...

2007-9-26 21:28
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: