[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 neorobin 于 2012-4-12 20:17 编辑

回复 14# cjiabing
,15# netbenton


嘿嘿,  我很佩服 netbenton , 我可不服输哦, 本顿, 等着我什么时候嬴你啊, 到时好好庆贺哈! (水了, 可这帖本就发在水区的啊, 版主见谅啊)

TOP

回复 15# netbenton


    兄谦虚了!能作出这样的效果实属不易,学习了~!
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

认真看了两个net的生成的迷宫图;但我都不觉得那是生成迷宫;

那是一堆随即生成的废墟;毫无通路;

随机迷宫生成,远远没有完成。。。

TOP

回复 18# plp626

在边界几乎是随意选两个地方分别作为入口和出口就可以了啊, 内部任何一个点到别处都是通的

TOP

回复 18# plp626

前面 neorobin 和 netbenton 都是采用的 深度优先 算法, 都是生成的 perfect 型迷宫.

Maze Classification
http://www.astrolog.org/labyrnth/algrithm.htm

wikipedia 上的迷宫生成算法
http://en.wikipedia.org/wiki/Maze_generation_algorithm

TOP

回复 8# netbenton


    也写了一个,大致思路相同,只是实现方式不一样:
http://bbs.bathome.net/viewthread.php?tid=16385

TOP

本帖最后由 fatcat 于 2012-4-17 20:42 编辑



代码逻辑框架以及搜索算法和 7 楼(改正了严重的 bug, 已提速)是一致的, 生成规则作了变化, 使迷宫通路上显得清晰.

算法特点: 以二维数组 n[x,y] 记录必要的邻居分布状态, 数值采用一个 9 位的二进制数, 最中间一位表示自身已在通路上, 其余 8 位分别表示围绕的 8 个点是否是通路上.
将 1,2,4,8 都加上 0x10, 作为 4 个搜索方向的 ID:
{1,2,4,8} -> {17,18,20,24} -> {上,左,右,下}

将一个点及周围的 8 个邻居点 位置 编号如下(位置 4 为这个点自身):
012
345
678

上 位可通行条件:
相对于 上 位, 012345 位置均为墙, 位序列: 876543 均置 0
n_上 & 504 == 0

下 位可通行条件:
相对于 下 位, 876543 位置均为墙, 位序列: 012345 均置 0
n_下 & 63 == 0

左 位可通行条件:
相对于 左 位, 013467 位置均为墙, 位序列: 875421 均置 0
n_左 & 438 == 0

右 位可通行条件:
相对于 右 位, 124578 位置均为墙, 位序列: 764310 均置 0
n_右 & 219 == 0

  1. @echo off & setlocal enabledelayedexpansion & color f0
  2. set /a "wid=80,hei=40,iMax=wid*hei,cols=2*wid,row=hei+1"
  3. title maze !wid! col X !hei! row
  4. mode con cols=!cols! lines=!row!
  5. REM {1,2,4,8} -> {17,18,20,24} <-> {上,左,右,下}
  6. set "d17=y-=1" & set "d18=x-=1" & set "d20=x+=1" & set "d24=y+=1"
  7. set "maze="
  8. for /l %%y in (1 1 !hei!) do for /l %%x in (1 1 !wid!) do set "maze=!maze!█"
  9. set /a "x=2, y=2"
  10. set "dirs=" & set "cells=." & set "n!x!_!y!=0" & set "dc=17"
  11. for /l %%# in () do (
  12.   title maze !wid! col X !hei! row -- searching !x!,!y! ...
  13.   for %%a in (n!x!_!y!) do (
  14.     set /a "isBackTrack=%%a & 0x10"
  15.     if !isBackTrack! equ 0x10 ( rem 回溯点
  16.       if !dirs:~-2! equ 0x1f ( rem 回溯点所有方向都已搜索
  17.         set "dirs=!dirs:~0,-2!"
  18.         set "cells=!cells:~1!" & set "cells=!cells:*.=.!"
  19.         if "!cells!"=="." (
  20.           <nul set /p "=" & title Maze generation completed, any key to exit...
  21.           >nul pause & exit
  22.         )
  23.         for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  24.       ) else ( rem 回溯点还有未搜索的方向
  25.         for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  26.         set "dir=!dirs:~-2!"
  27.         set /a "visit=1, randS=!random! & 3, randE=randS|4"
  28.         for /l %%d in (!randS! 1 !randE!) do if !visit! neq 0 (
  29.           set /a "dc=1<<(%%d &3), visit=dir&dc,newd=dc|dir, dc|=0x10"
  30.           if !visit! equ 0 (
  31.             for %%r in (d!dc!) do set /a "!%%r!"
  32.             set "dirs=!dirs:~0,-2!!newd!"
  33.       ) ) )
  34.     ) else ( rem 待测试点
  35.       set /a "canPass=^!((dc-17)|(%%a&504)) | ^!((dc-24)|(%%a&63)) | ^!((dc-18)|(%%a&438)) | ^!((dc-20)|(%%a&219))"
  36.       if !canPass! equ 0 ( rem 不可通行点
  37.         for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  38.       ) else ( rem 可通行点
  39.         set /a "xin=x-2^x-wid,yin=y-2^y-hei,in=(xin&yin)>>31"
  40.         if !in! equ 0 ( rem 出边界
  41.           for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  42.         ) else ( rem 在边界内
  43.           set "cells=.!x!#!y!!cells!"
  44.           set /a "ind=(x-1)+(y-1)*wid+1, lL=ind-1, lR=iMax-ind"
  45.           for /f "tokens=1-3" %%a in ("!lL! !ind! !lR!") do (set maze=!maze:~0,%%a!·!maze:~%%b,%%c!)
  46.           cls & <nul set /p "=!maze:·=  !"
  47.           set "p=1"
  48.           for %%u in (-1 0 1) do for %%v in (-1 0 1) do (
  49.             set /a "xn=x+%%v, yn=y+%%u"
  50.             set /a "n!xn!_!yn!|=p, p<<=1"
  51.           )
  52.           set /a "dc=(1<<(!random!&3))|0x10"
  53.           set "dirs=!dirs!!dc!"
  54.           for %%r in (d!dc!) do set /a "!%%r!"
  55. ) ) ) ) )
  56. exit
复制代码
1

评分人数

TOP

回复 22# fatcat


    我也计划改成类似这样比较规整的格式,不过思路不是判断周围八格,而是每次走两个,感觉会比较简单

TOP

回复 23# CrLf
你的话启发了我
  1. @echo off & setlocal enabledelayedexpansion & color f0
  2. set /a "wid=60,hei=40,wid|=1,hei|=1,iMax=wid*hei,cols=2*wid,row=hei+1"
  3. title maze !wid! col X !hei! row
  4. mode con cols=!cols! lines=!row!
  5. set "maze="
  6. for /l %%y in (1 1 !hei!) do for /l %%x in (1 1 !wid!) do set "maze=!maze!█"
  7. REM {1,2,4,8} -> {17,18,20,24} <-> {上,左,右,下}
  8. set "d17=y-=2" & set "d18=x-=2" & set "d20=x+=2" & set "d24=y+=2" & set "d=0"
  9. set "w17=y+=1" & set "w18=x+=1" & set "w20=x-=1" & set "w24=y-=1" & set "w=0"
  10. set "dirs=" & set "cells=." & set /a "x=2, y=2"
  11. for /l %%# in () do (
  12.   if defined n!x!_!y! ( rem 回溯点
  13.     if !dirs:~-2! equ 0x1f ( rem 回溯点所有方向都已搜索
  14.       set "dirs=!dirs:~0,-2!"
  15.       set "cells=!cells:~1!" & set "cells=!cells:*.=.!"
  16.       if "!cells!"=="." (
  17.         <nul set /p "=" & title Maze generation completed, any key to exit...
  18.         >nul pause & exit
  19.       )
  20.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  21.     ) else ( rem 回溯点还有未搜索的方向
  22.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  23.       set "dir=!dirs:~-2!"
  24.       set /a "visit=1, randS=!random! & 3, randE=randS | 4"
  25.       for /l %%d in (!randS! 1 !randE!) do if !visit! neq 0 (
  26.         set /a "dc=1<<(%%d &3), visit=dir&dc,dir|=dc, dc|=0x10"
  27.         if !visit! equ 0 (
  28.           for %%r in (d!dc!) do set /a "!%%r!"
  29.           set "dirs=!dirs:~0,-2!!dir!"
  30.     ) ) )
  31.   ) else ( rem 可通行点
  32.     set /a "xin=x-2^x-wid,yin=y-2^y-hei,in=(xin&yin)>>31"
  33.     if !in! equ 0 ( rem 出边界
  34.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  35.     ) else ( rem 在边界内
  36.       set "cells=.!x!#!y!!cells!"
  37.       set "n!x!_!y!=1"
  38.       for %%r in (w!dc!) do for %%i in (1 2) do (
  39.         set /a "ind=(x-1)+(y-1)*wid+1, lL=ind-1, lR=iMax-ind"
  40.         for /f "tokens=1-3" %%a in ("!lL! !ind! !lR!") do (set maze=!maze:~0,%%a!·!maze:~%%b,%%c!)
  41.         set /a "!%%r!"
  42.       )
  43.       for %%r in (d!dc!) do set /a "!%%r!"
  44.       cls & <nul set /p "=!maze:·=  !"
  45.       set /a "dc=(1<<(!random!&3))|0x10"
  46.       set "dirs=!dirs!!dc!"
  47.       for %%r in (d!dc!) do set /a "!%%r!"
  48. ) ) )
  49. exit
复制代码
1

评分人数

    • CrLf: 效率相当高技术 + 1

TOP

回复 18# plp626


    OUT了吧,嘿嘿。

TOP

这迷宫还是随机生成的

TOP

新算法,生成的迷宫更美观。
  1. @echo off&rem 纯批处理迷宫随机生成器
  2. set a=!
  3. set b=!a!
  4. rem 变量多层嵌套初始化
  5. set r=7
  6. rem %r% 定义生成迷宫的属性:(0到9)值越小分支越多,值越大主线越长,分支越少。
  7. set /a 行=40,列=40,屏宽=列*2+1,屏高=行+1,出列=列-1,出行=行-1
  8. rem 定义迷宫大小。
  9. set sto=1$2$上
  10. rem 定义出口
  11. set 出=%行%.%出列% %出行%.%出列%
  12. rem 定义入口
  13. title r=%r%  行=%行%,列=%列%
  14. set/a r=r %% 10
  15. setlocal enabledelayedexpansion
  16. set "墙=■"
  17. set "路= "
  18. for /l %%a in (1,1,!行!) do (
  19. set L%%a=
  20. for /l %%b in (1,1,!列!) do set o%%a.%%b=%墙%&set L%%a=!L%%a!!a!o%%a.%%b!a!
  21. )
  22. set S右=!a!#上!a!$!a!#列!a!$下 !a!#行!a!$!a!#左!a!$右 !a!#下!a!$!a!#列!a!$上
  23. set S左=!a!#上!a!$!a!#列!a!$下 !a!#行!a!$!a!#右!a!$左 !a!#下!a!$!a!#列!a!$上
  24. set S上=!a!#行!a!$!a!#左!a!$右 !a!#行!a!$!a!#右!a!$左 !a!#下!a!$!a!#列!a!$上
  25. set S下=!a!#行!a!$!a!#左!a!$右 !a!#行!a!$!a!#右!a!$左 !a!#上!a!$!a!#列!a!$下
  26. set F右=!b!o!a!#上!a!.!a!#列!a!!b!!b!o!a!#上!a!.!a!#左!a!!b!!b!o!a!#行!a!.!a!#左!a!!b!!b!o!a!#下!a!.!a!#左!a!!b!!b!o!a!#下!a!.!a!#列!a!!b!
  27. set F左=!b!o!a!#上!a!.!a!#列!a!!b!!b!o!a!#上!a!.!a!#右!a!!b!!b!o!a!#行!a!.!a!#右!a!!b!!b!o!a!#下!a!.!a!#右!a!!b!!b!o!a!#下!a!.!a!#列!a!!b!
  28. set F上=!b!o!a!#行!a!.!a!#左!a!!b!!b!o!a!#下!a!.!a!#左!a!!b!!b!o!a!#行!a!.!a!#右!a!!b!!b!o!a!#下!a!.!a!#右!a!!b!!b!o!a!#下!a!.!a!#列!a!!b!
  29. set F下=!b!o!a!#行!a!.!a!#左!a!!b!!b!o!a!#上!a!.!a!#左!a!!b!!b!o!a!#行!a!.!a!#右!a!!b!!b!o!a!#上!a!.!a!#右!a!!b!!b!o!a!#上!a!.!a!#列!a!!b!
  30. ::  上
  31. ::左中右
  32. ::  下
  33. mode con: lines=!屏高! cols=!屏宽!
  34. for /l %%z in () do (
  35. for /f "tokens=1*" %%x in ("!sto!") do (
  36. set sto=%%y
  37. for /f "tokens=1,2,3 delims=$" %%7 in ("%%x") do (
  38. set/a #行=%%7,#列=%%8,#上=#行-1,#下=#行+1,#左=#列-1,#右=#列+1
  39. if "!random:~-1!" gtr "4" (set s%%9=!s%%9:~12!!s%%9:~,12!) else (set s%%9=!s%%9:~24!!s%%9:~,24!)
  40. for /f "tokens=*" %%a in ("!F%%9! !S%%9!") do for /f "tokens=1*" %%b in ("%%a") do (
  41. if "%%b" equ "%墙%%墙%%墙%%墙%%墙%" (
  42. set o!#行!.!#列!=%路%
  43. for %%A in (%%c) do (
  44. for /f "tokens=1,2,3 delims=$" %%1 in ("%%~A") do (
  45. set/a #行=%%1,#列=%%2,#上=#行-1,#下=#行+1,#左=#列-1,#右=#列+1
  46. for /f %%B in ("!F%%3!") do for /f %%C in ("%%B") do if "%%C" equ "%墙%%墙%%墙%%墙%%墙%" (
  47. if "!random:~-1!" gtr "%r%" (set sto=!sto! %%A) else (set sto=%%A !sto!)
  48. )
  49. )
  50. )
  51. )
  52. )
  53. )
  54. )
  55. if not defined sto call :fins
  56. )
  57. :fins
  58. for %%a in (%出%) do set o%%a=入
  59. cls&for /l %%a in (1,1,!行!) do for /f %%b in ("!L%%a!") do echo;%%b
  60. set /p in=计算结束,回车关闭。
  61. exit
复制代码

TOP

返回列表