返回列表 发帖

[游戏娱乐] 批处理绘制迷宫

本帖最后由 CrLf 于 2012-4-15 03:37 编辑


(解谜宫代码见此贴:http://bbs.bathome.net/viewthread.php?tid=13619

其实思路上和 neor 与本顿的代码大同小异,主要是沾了 for 天生高效的光...话不多说,上原始代码:
@echo off
set>tmp
::设定
set "墙=█"
set "路= "
set 演示=rem
set /a 行=40,列=40
rem 参数设置初始化,"演示=rem" 代表不进行实时绘制
set /a 屏宽=列*2+1,屏高=行+3,endline=行*列-列,now=列+1
mode con: lines=%屏高% cols=%屏宽%
echo %time%
rem 改变窗口尺寸及显示时间
set "fail= "
rem 必要的变量初始化
setlocal enabledelayedexpansion
for /l %%a in (1 1 !列!) do set $=!$!!墙!
(
for /f "delims==" %%a in (tmp) do set %%a=
del tmp>nul
for %%b in (行 列 屏高 屏宽 墙 路 endline) do set %%b=
rem 清除作为常数的多余变量,以下仅以 %str% 的形式取值
for /l %%a in (3 1 %行%) do set $=!$!%$%
set $=%$%%路%%路%!$:~,-2!
rem 生成框架,将整个迷宫存储于变量 $
for /l %%a in () do (
set /a "ra=!random!%%4,ra=now+(^!~-ra*%列%-^!ra*%列%-ra/2+ra/3*2),test=ra%% %列%*(ra/%列%)*(-~ra%% %列%)*^!(ra/(%endline%))"
rem 随机取得延伸方向,并检测其是否在边界
for %%Z in (!ra!) do (
if "!fail: %%Z =!"=="!fail!" (
set "fail=!fail!%%Z "
if !test! neq 0 (
set tmp=!$:~%%Z!!$:~,%%Z!
set test=!tmp:~1,1!!tmp:~-1,1!!tmp:~-%列%,1!!tmp:~%列%,1!
rem 先将探测指针后与探测指针前的变量内容交换,可理解为将指针位置的坐标轴暂时设为原点
rem 便于以 c 语言指针的方式进行取值而避开对前后左右四个偏移量的计算
if "!test:%路%=!"=="%墙%%墙%%墙%" (
set $=!tmp:~-%%Z!%路%!tmp:~1,-%%Z!
set now=!ra!
set ok=!now! !ok!
set "fail= "
rem 当发现一个正确的目标点时,抵达该点,清空失败记录
rem 并修改该点的状态为 %路%,同时记录在过往路线中
%演示% echo !$!%$%&echo;
)
)
)
)
for /f "tokens=4" %%b in ("!fail!") do (
rem 当 !fail! 中的失败记录数达到四个时触发此循环
if defined ok (
for /f "tokens=1*" %%c in ("!ok!") do set now=%%c&set ok=%%d
set "fail= "
rem 按照成功记录回退,!ok! 中始终只记录一条路线,记录被清空时认为迷宫绘制完成
) else (
set /a "ra=!random!%%(%行%*2+%列%*2-6),ra+=-~ra/%列%,test=ra/%列%,tmp=ra%%%%,tmp=^!(test)*tmp+^!(test-1)*((tmp+1)*%%-1)+^!(test-2)*(%endline%+tmp-1)+^!(test-3)*(tmp+1)*%列%"
rem 随机设置终点位置
for %%Z in (!tmp!) do (
set tmp=!$:~%%Z!!$:~,%%Z!
set "test=!tmp:~1,1!!tmp:~-1,1!!tmp:~-%列%,1!!tmp:~%列%,1!"
rem 获取上下左右的状态
if "!test:%墙%=!"=="%路%" (
echo !tmp:~-%%Z!%路%!tmp:~1,-%%Z!
echo !time!
pause>nul&exit
rem 测试若该点可用并与路相接则设为终点并打印迷宫
)
)
)
)
)
)COPY
绘制迷宫效果:
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
3

评分人数

    • qzwqzw: 值得赞赏的贡献!技术 + 1
    • fatcat: 学习了技术 + 1
    • lllsoslll: 代码量大,不容易。。技术 + 1

回复 6# fatcat


    确属遗漏,大概知道是什么原因,回头有空改下,多谢!

TOP

回复 1# CrLf
下图中打圈处的点, 是否是被遗漏的:
1

评分人数

    • CrLf: 十分感谢PB + 10

TOP

回复 4# lllsoslll
不知失真是何意呢?
墙面用细线表示的这个提议,个人感觉对效率的影响较大且实现起来颇费手脚,更麻烦的是难以在解谜宫一贴的代码中通过边框上的出入口自动判断道路字符
路面已用全角空格代替,应可区别于墙面
箭头的提议不错,已在那个帖子中修改代码及附件。COPY

TOP

建议把墙用 细线表示;
我开始都分不清那个是墙,上面钉4个钉子的是墙还是不是墙,,,,不知其他人看后什么感觉。。。

演示出路的时候 用 箭头↑    →    ↓ 表示 。。。
1

评分人数

    • CrLf: 感谢建议PB + 5
SOS --- >> lllsoslll@163.com

TOP

顶楼下载的 绘制迷宫  自定义.bat
这个运行后图像失真,乱。。。
SOS --- >> lllsoslll@163.com

TOP

本帖最后由 CrLf 于 2012-4-15 04:08 编辑

为了能更自由地控制生成的迷宫,在原基础上改了一个扩展设置自定义版,代码中默认开启了实时显示,如要关闭则在扩展设置中修改 %演示% 为 0:
@echo off&setlocal enabledelayedexpansion
set>tmp
::设定
set "墙=█"
set "路= "
set /a 行=40,列=40
rem 基本设置
set /a 屏宽=列*2+1,屏高=行+3,endline=行*列-列,now=列+1
mode con: lines=%屏高% cols=%屏宽%
echo %time%
rem 改变窗口尺寸及显示时间
set /a 钜率=4,钜率衰减=400,起始点间隔下限=80,演示=1
rem 扩展设置
rem %钜率%控制走直线的概率,%钜率衰减%控制钜率随着绘制进度而降低
rem %起始点间隔下限%设置终点离起点至少有多远,%演示%设置实时绘制
for /l %%a in (1 1 %列%) do set $=!$!!墙!
if "%演示%"=="1" title 开始于%time%&set "_演示=echo ^!$^!%$%&echo;"
set /a "_间隔=(%行%*2+%列%*2-6-%起始点间隔下限%0/5)"
if defined 起始点间隔下限 (
set /a "1/(起始点间隔下限/(行+列-6)),起始点间隔下限=行+列-6" 2>nul
set "_间隔=%_间隔%+!起始点间隔下限!0/10"
)
if defined 钜率 (
set _钜率1=if ^^!random:~-1^^! gtr ^^!钜率^^! set /a "ra=^!random^!%%4,f=^^^!~-ra*%列%-^^^!ra*%列%-ra/2+ra/3*2"
set _钜率2=ra=now+f
if defined 钜率衰减 set _钜率衰减=set /a "num+=1,钜率-=^^^!(num%%%钜率衰减%)"
) else set "_钜率2=ra=^!random^!%%4,ra=now+(^^^!~-ra*%列%-^^^!ra*%列%-ra/2+ra/3*2)"
rem 扩展设置初始化
set "fail= "
rem 必要的变量初始化
(
for /f "delims==" %%a in (tmp) do set %%a=
del tmp>nul
for %%b in (
_钜率1 _钜率2 _钜率衰减 _间隔 _演示
endline 行 列 屏高 屏宽 墙 路 起始点间隔下限 钜率衰减 演示
) do set %%b=
rem 清除作为常数的多余变量,保证效率及可靠性,后文以 %str% 的形式取值
for /l %%a in (3 1 %行%) do set $=!$!%$%
set $=%$%%路%%路%!$:~,-2!
rem 生成框架,将整个迷宫存储于变量 $
for /l %%a in () do (
%_钜率1%
set /a "%_钜率2%,test=ra%% %列%*(ra/%列%)*(-~ra%% %列%)*^!(ra/(%endline%))"
rem 随机取得延伸方向,并检测其是否在边界
for %%Z in (!ra!) do (
if "!fail: %%Z =!"=="!fail!" (
set "fail=!fail!%%Z "
if !test! neq 0 (
set tmp=!$:~%%Z!!$:~,%%Z!
set test=!tmp:~1,1!!tmp:~-1,1!!tmp:~-%列%,1!!tmp:~%列%,1!
rem 先将探测指针后与探测指针前的变量内容交换,可理解为将指针位置的坐标轴暂时设为原点
rem 便于以 c 语言指针的方式进行取值而避开对前后左右四个偏移量的计算
if "!test:%路%=!"=="%墙%%墙%%墙%" (
%_钜率衰减%
set $=!tmp:~-%%Z!%路%!tmp:~1,-%%Z!
set now=!ra!
set ok=!now! !ok!
set "fail= "
rem 当发现一个正确的目标点时,抵达该点,清空失败记录
rem 并修改该点的状态为 %路%,同时记录在过往路线中
%_演示%
)
)
)
)
for /f "tokens=4" %%b in ("!fail!") do (
rem 当 !fail! 中的失败记录数达到四个时触发此循环
if defined ok (
for /f "tokens=1*" %%c in ("!ok!") do set now=%%c&set ok=%%d
set "fail= "
rem 按照成功记录回退,!ok! 中始终只记录一条路线,记录被清空时认为迷宫绘制完成
) else (
set /a "ra=!random!%%%_间隔%,ra+=-~ra/%%,test=ra/%%,tmp=ra%%%列%,tmp=^!(test)*tmp+^!(test-1)*((tmp+1)*%%-1)+^!(test-2)*(%endline%+tmp-1)+^!(test-3)*(tmp+1)*%列%"
rem 随机设置终点位置
for %%Z in (!tmp!) do (
set tmp=!$:~%%Z!!$:~,%%Z!
set "test=!tmp:~1,1!!tmp:~-1,1!!tmp:~-%列%,1!!tmp:~%列%,1!"
rem 获取上下左右的状态
if "!test:%墙%=!"=="%路%" (
echo !tmp:~-%%Z!%路%!tmp:~1,-%%Z!
echo !time!
pause>nul&exit
rem 测试若该点可用并与路相接则设为终点并打印迷宫
)
)
)
)
)
)COPY

TOP

返回列表