中国DOS联盟论坛

中国DOS联盟

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

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

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

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『楼 主』:  [原创]根据返回正确数字位数与个数猜数字的游戏

简单介绍以下这个游戏

有四位十进制数字,可猜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%:[%nDest%]-[%nCount%]: %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 楼』:  

曲高和寡。望尘莫及。



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





积分 50
发帖 20
注册 2007-6-17
来自 湖南常宁
状态 离线
『第 3 楼』:  

高手

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

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 4 楼』:  

看来没有人提供意见
自己贴一个反向猜解的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="^[^%_gss%]*$"
if "%_n%"=="1" set pattern="^[^%_gss%]*[%_gss%][^%_gss%]*$"
if "%_n%"=="2" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*[^%_gss%][%_gss%]*$"
if "%_n%"=="3" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*$"
if "%_n%"=="4" set pattern="^[%_gss%]*$"
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 "[%rn%]"'
) 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%:[%iDest%]-[%iCount%]: %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 楼』:  

好游戏。。。。。

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

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 6 楼』:  

很早以前写得猜数字.玩法差不多.
当时有写的点乱.也懒得改了.
@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
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 7 楼』:  

现在发布一个互动猜解版
:: 猜数字游戏(互动猜解版) : 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="^[^%_gss%]*$"
if "%_n%"=="1" set pattern="^[^%_gss%]*[%_gss%][^%_gss%]*$"
if "%_n%"=="2" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*[^%_gss%][%_gss%]*$"
if "%_n%"=="3" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*$"
if "%_n%"=="4" set pattern="^[%_gss%]*$"
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 "[%rn%]"'
) 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%于[%iCount%-%iGuess%]: %strGuess% >> guess.log
set strGuess=
endlocal & if /i "%choose%"=="y" goto :Start
del _guess*.*


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

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 8 楼』:  

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

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

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 9 楼』:  

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




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

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 10 楼』:  

现发布一个功能完整的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="^[^%_gss%]*$"
if "%_ab%"=="1" set pattern="^[^%_gss%]*[%_gss%][^%_gss%]*$"
if "%_ab%"=="2" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*[^%_gss%][%_gss%]*$"
if "%_ab%"=="3" set pattern="^[%_gss%]*[^%_gss%][%_gss%]*$"
if "%_ab%"=="4" set pattern="^[%_gss%]*$"
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 "^[^%_gss%]*[%_gss%][^%_gss%]*$" _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 "[%rn%]"'
) 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 [%date:~0,-4% %time%] %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
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 11 楼』:  

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

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





积分 172
发帖 54
注册 2007-1-2
状态 离线
『第 12 楼』:  

to  qzwqzw:

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









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

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

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 13 楼』:  

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 楼』:  

你有解释机会,可惜的是我没有道歉机会
我已经因此失去了成为本论坛内部群的机会
----------------------------------------------------------
话说清楚些误会就大可以避免,是一场误会...
你要知道我测试你那个代码也花了有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 楼』:  

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

2007-9-26 21:28
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


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



论坛跳转: