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

[其他] 批处理版迷宫

本帖最后由 neorobin 于 2012-4-18 11:07 编辑

批处理生成的迷宫, 如果代码未生成入口和出口, 那么在边界上任选两个可以和内部通路相连的点即可作为入口和出口.
图 1


图 2


图 3


此处几个版本生成的都是 perfect 型的迷宫, 通路上任意一点都可以通向其它任意一点, 且整个通路上没有环路.
参考资料:
迷宫生成算法:  http://en.wikipedia.org/wiki/Maze_generation_algorithm
Maze Classification:  http://www.astrolog.org/labyrnth/algrithm.htm
图 1 是 7 楼 的效果图, 8 楼 netbentonCrLf 的代码生成效果相同或相似;
图 2 是 22 楼 fatcat 版的效果, 通路显得更清晰.
图 3 是 24 楼 的效果, 更清晰, 算法也更显简单.
2

评分人数

    • CrLf: 良好的开头技术 + 1
    • plp626: 这是迷宫?死胡同嘛技术 + 1

本帖最后由 neorobin 于 2012-4-16 21:56 编辑

回复 5# gawk , 4# CrLf

3# wankoilz2# batman

2012.4.16, 找出之前代码数处严重的 bug, 并将所有 goto 语句移除, 而以 for 方式循环, 再次测试未发现死循环问题, 且速度提升. 重新贴出, 前版代码不予保留

2012-3-27, 实现基本想法, 效率可以用 无法忍受 来形容, 有时刚运行时甚至会出现假死的状态, 后查明为在开始搜索特定方向时出现死循环.
代码的算法最常见的是 广度优先 和 深度优先 树搜索算法.
wikipedia 上有一些介绍. 以下代码将已经搜索过的路径点和路径点已经搜索过的方向分别存储进两个堆栈, 另有一个二维数组记录已搜索过的结点的邻居数.
邻居数以自身算 4 个.

因为算法中的搜索控制是采用了随机数, 所以每次生成的格局也是随机的, 在一个较大的规模下, 两次生成一样的格局的可能性也是极低的.
这里采取了以 (2,2) 为搜索起点(边界内任何一点都可以), 但不是必须的, 另外入口和出口是可以随意选取的, 在规模足够大的情况下, 即使入口和出口靠得很近, 也可能必须走过一个很 辗转反侧 的路径.
  1. @echo off & setlocal enabledelayedexpansion
  2. set /a wid=40,hei=wid,iMax=wid*hei,cols=2*wid
  3. title maze !wid! col X !hei! row
  4. mode con cols=!cols!
  5. call :genMaze
  6. exit
  7. :setPoint Screen !x! !y! !pointStr!
  8.   set /a "ind=(%2-1)+(%3-1)*wid+1, lenL=ind-1, lenR=iMax-ind"
  9.   for /f "tokens=1,2,3" %%a in ("!lenL! !ind! !lenR!") do (set %1=!%1:~0,%%a!%4!%1:~%%b,%%c!)
  10. exit /b
  11. REM dir=dc|0x10 将方向值 1,2,4,8 构成的方向组合 [1,0xf] 统一成两位十进制数 [17,31]
  12. :genMaze
  13. set "d1=x+=1" & set "d2=x-=1" & set "d4=y+=1" & set "d8=y-=1"
  14. set "maze="
  15. for /l %%y in (1 1 !hei!) do for /l %%x in (1 1 !wid!) do set "maze=!maze!█"
  16. set /a "x=wid/2, y=hei/2"
  17. set /a "x=2, y=2"
  18. set "dirs=" & set "cells=." & set /a "n!x!_!y!=0"
  19. for /l %%# in () do (
  20.   for %%a in (n!x!_!y!) do if !%%a! geq 4 (
  21.     if !dirs:~-2! equ 0x1f (
  22.       set "dirs=!dirs:~0,-2!"
  23.       set "cells=!cells:~1!" & set "cells=!cells:*.=.!"
  24.       if "!cells!"=="." (
  25.         <nul set /p "=Maze GEN completed.  any key to exit...
  26.         >nul pause & exit
  27.       )
  28.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  29.     ) else (
  30.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  31.       set "dir=!dirs:~-2!"
  32.       set /a "visit=1, randS=!random! & 3, randE=randS|4"
  33.       for /l %%d in (!randS! 1 !randE!) do if !visit! neq 0 (
  34.         set /a "dc=1<<(%%d &3), visit=dir&dc,newd=dc|dir"
  35.         if !visit! equ 0 (
  36.           for %%r in (d!dc!) do set /a "!%%r!"
  37.           set "dirs=!dirs:~0,-2!!newd!"
  38.     ) ) )
  39.   ) else (
  40.     if !%%a! geq 2 (
  41.       for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  42.     ) else (
  43.       set /a "xin=x-2^x-wid,yin=y-2^y-hei,in=(xin&yin)>>31"
  44.       if !in! equ 0 (
  45.         for /f "tokens=1-2 delims=.#" %%x in ("!cells!") do (set x=%%x&set y=%%y)
  46.       ) else (
  47.         set "cells=.!x!#!y!!cells!"
  48.         (call :setPoint maze x y ·)
  49.         cls & <nul set /p=!maze:·= !
  50.         for %%r in ("xn+=1" "xn-=1" "yn+=1" "yn-=1") do (
  51.           (set xn=!x!&set yn=!y!)
  52.           set /a %%r
  53.           set /a "n!xn!_!yn!+=1"
  54.         )
  55.         set /a "n!x!_!y!|=4"
  56.         set /a "dc=1<<(!random!&3),dir=dc|0x10"
  57.         set "dirs=!dirs!!dir!"
  58.         for %%r in (d!dc!) do set /a "!%%r!"
  59. ) ) ) )
  60. exit /b
复制代码
1

评分人数

    • CrLf: 虽然不喜欢call,但还是先赞一个技术 + 1

TOP

回复 11# plp626

http://en.wikipedia.org/wiki/Maze_generation_algorithm


wikipedia 尽管不通俗, 但我用通俗的语言肯定说不到很好

TOP

本帖最后由 neorobin 于 2012-4-12 20:17 编辑

回复 14# cjiabing
,15# netbenton


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

TOP

返回列表