本帖最后由 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 测试若该点可用并与路相接则设为终点并打印迷宫
- )
- )
- )
- )
- )
- )
复制代码
|