设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 5821|回复: 4
打印 上一主题 下一主题

[原创发布] 随机迷宫生成[深度/广度]

[复制链接]

Lv1.梦旅人

梦石
0
星屑
180
在线时间
509 小时
注册时间
2010-10-1
帖子
97
跳转到指定楼层
1
发表于 2015-1-2 21:45:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
唔 我来6R好像没怎么发过东西呢 只知道用别人的 ..偶尔还是来一发做做贡献吧 不然觉得有点对不起大家呢OTZ
此货为迷宫生成算法,应该算是比较完善了吧
不知道有人写过没有 不过由于鄙人阅读脚本的能力甚是太好,别人写的基本都看不懂OTZ Umm..所以还是自己写好了
脚本如下:
RUBY 代码复制
  1. #==============================================================================
  2. # ■ Random_Maze
  3. #------------------------------------------------------------------------------   
  4. #   使用说明书:
  5. #     效果:生成一个随机迷宫数组。(0:地 1:墙)
  6. #     用法:
  7. #        广度优先 --> prim(X最大值,Y最大值,起始X[可省略],起始Y[可省略])
  8. #        深度优先 --> depth(X最大值,Y最大值,起始X[可省略],起始Y[可省略])
  9. #     制作:永远的塞尔达传说(7408) [2015.1.2]
  10. #==============================================================================
  11. class Random_Maze
  12.   #--------------------------------------------------------------------------
  13.   # ● 定义实例变量
  14.   #--------------------------------------------------------------------------
  15.   attr_reader   :pos_x                    # 当前 X 坐标
  16.   attr_reader   :pos_y                    # 当前 Y 坐标
  17.   attr_reader   :list                     # 可通行列表
  18.   attr_reader   :mark                     # 标记列表
  19.   attr_accessor :maze                     # 迷宫
  20.   #--------------------------------------------------------------------------
  21.   # ● 初始化对像
  22.   #--------------------------------------------------------------------------
  23.   def        initialize
  24.                 @maze = []
  25.         end
  26.   #--------------------------------------------------------------------------
  27.   # ● 广度优先
  28.   #--------------------------------------------------------------------------
  29.   def prim(xmax,ymax,start_x = nil,start_y = nil)
  30.     # 初始化
  31.     @maze = []
  32.     start_x = rand(xmax + 1) if start_x == nil
  33.     start_y = rand(ymax + 1) if start_y == nil
  34.     for x in 0..xmax
  35.       @maze[x] = []
  36.       for y in 0..ymax
  37.         @maze[x][y] = 1
  38.       end
  39.     end
  40.     @maze[start_x][start_y] = 0
  41.     @list = adjacent_wall(start_x,start_y)
  42.     # 生成迷宫
  43.     while !@list.empty?
  44.       id = rand(@list.size-1)
  45.       x = @list[id][0]
  46.       y = @list[id][1]
  47.       d = @list[id][2]
  48.       new_x = x + (d == 3 ? 1 : (d == 2 ? -1 : 0))
  49.       new_y = y + (d == 1 ? 1 : (d == 4 ? -1 : 0))
  50.       # 如果前面也为墙
  51.       if exist?(new_x,new_y) and @maze[new_x][new_y] == 1
  52.         @maze[x][y] = 0
  53.         @maze[new_x][new_y] = 0
  54.         @list = @list + adjacent_wall(new_x,new_y)
  55.         @list.delete_at(id)
  56.       else
  57.         @list.delete_at(id)
  58.       end
  59.     end
  60.     # 返回迷宫
  61.     return @maze.clone
  62.   end
  63.   #--------------------------------------------------------------------------
  64.   # ● 深度优先
  65.   #--------------------------------------------------------------------------
  66.   def depth(xmax,ymax,pos_x = nil,pos_y = nil)
  67.     # 初始化
  68.     @maze = []
  69.     pos_x = rand(xmax + 1) if pos_x == nil
  70.     pos_y = rand(ymax + 1) if pos_y == nil
  71.     for x in 0..xmax
  72.       @maze[x] = []
  73.       for y in 0..ymax
  74.         @maze[x][y] = 1
  75.       end
  76.     end
  77.     @pos_x = pos_x
  78.     @pos_y = pos_y
  79.     @maze[pos_x][pos_y] = 0
  80.     [url=home.php?mod=space&uid=25204]@mark[/url] = []
  81.     # 生成迷宫
  82.     while not_full?
  83.       all = passage_way(@pos_x,@pos_y)
  84.       if all.empty?
  85.         @pos_x,@pos_y = @mark.pop
  86.       else
  87.         coord = all[rand(all.size) - 1]
  88.         @maze[coord[0]][coord[1]] = 0
  89.         @maze[coord[2]][coord[3]] = 0
  90.         @pos_x = coord[2]
  91.         @pos_y = coord[3]
  92.         @mark.push([@pos_x,@pos_y])
  93.       end
  94.     end
  95.     # 返回迷宫
  96.     return @maze.clone
  97.   end
  98.   #--------------------------------------------------------------------------
  99.   # ● 存在否?
  100.   #--------------------------------------------------------------------------
  101.   def exist?(x,y)
  102.     return false if (x < 0) or (x >= @maze.size) or (y < 0) or (y >= @maze[0].size)
  103.     return true
  104.   end
  105.   #--------------------------------------------------------------------------
  106.   # ● 满否?
  107.   #--------------------------------------------------------------------------
  108.   def not_full?
  109.     delta_x = (@pos_x % 2 == 1 ? 1 : 0)
  110.     delta_y = (@pos_y % 2 == 1 ? 1 : 0)
  111.     xmax = (@maze.size / 2).floor
  112.     ymax = (@maze[0].size / 2).floor
  113.     for x in 0...xmax
  114.       for y in 0...ymax
  115.         return true if @maze[x * 2 + delta_x][y * 2 + delta_y] == 1
  116.       end
  117.     end
  118.     return false
  119.   end
  120.   #--------------------------------------------------------------------------
  121.   # ● Mark中存在此坐标否?
  122.   #--------------------------------------------------------------------------
  123.   def marked_coord?(x,y)
  124.     @mark.each do |this|
  125.       if this[0] == x and this[1] == y
  126.         return true
  127.       end
  128.     end
  129.     return false
  130.   end
  131.   #--------------------------------------------------------------------------
  132.   # ● 取得所有通路
  133.   #--------------------------------------------------------------------------
  134.   def passage_way(x,y)
  135.     result = []
  136.     # 循环四个方向
  137.     for d in 1..4
  138.       new_x_a = x + (d == 3 ? 1 : (d == 2 ? -1 : 0))
  139.       new_y_a = y + (d == 1 ? 1 : (d == 4 ? -1 : 0))
  140.       new_x_b = x + (d == 3 ? 2 : (d == 2 ? -2 : 0))
  141.       new_y_b = y + (d == 1 ? 2 : (d == 4 ? -2 : 0))
  142.       if exist?(new_x_b,new_y_b) and @maze[new_x_b][new_y_b] == 1 and !marked_coord?(new_x_b,new_y_b)
  143.         result.push([new_x_a,new_y_a,new_x_b,new_y_b])
  144.       end
  145.     end
  146.     return result
  147.   end
  148.   #--------------------------------------------------------------------------
  149.   # ● 获取相邻的墙壁
  150.   #--------------------------------------------------------------------------
  151.   def adjacent_wall(x,y)
  152.     result = []
  153.     # 循环四个方向
  154.     for d in 1..4
  155.       new_x = x + (d == 3 ? 1 : (d == 2 ? -1 : 0))
  156.       new_y = y + (d == 1 ? 1 : (d == 4 ? -1 : 0))
  157.       if exist?(new_x,new_y) and @maze[new_x][new_y] == 1
  158.         result.push([new_x,new_y,d])
  159.       end
  160.     end
  161.     # 返回结果
  162.     return result
  163.   end
  164. end


范例: 随机迷宫生成.rar (193.38 KB, 下载次数: 431)



具体看范例吧~嗯嗯 谢谢大家

评分

参与人数 4星屑 +303 收起 理由
chd114 + 3 凑303.。。
kuerlulu + 20 好厉害的样子
taroxd + 140 好厉害的样子
恐惧剑刃 + 140 好厉害的样子

查看全部评分

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

2
发表于 2015-1-3 16:39:12 | 只看该作者
本帖最后由 taroxd 于 2015-1-3 16:44 编辑
不过由于鄙人阅读脚本的能力甚是太好,别人写的基本都看不懂OTZ Umm..所以还是自己写好了


十分赞同楼主这一观点,于是我也写了一个玩了玩

果然 Ruby 写类似伪代码的东西就是舒爽

(暂时还没有定义访问方法和 each 系列的迭代方法,不过有了转成字符串的 to_s ,能输出就能凑合着玩了)

RUBY 代码复制
  1. class Maze
  2.  
  3.   def initialize(xsize, ysize, ox = rand(xsize), oy = rand(ysize))
  4.     @xsize = xsize
  5.     @ysize = ysize
  6.     prim(ox, oy)
  7.   end
  8.  
  9.   # 生成迷宫
  10.   def prim(ox, oy)
  11.     init_maze
  12.     init_list
  13.     remove_wall(ox, oy)
  14.     add_adjacent_wall_to_list(ox, oy)
  15.     while (pos_data = list_sample)
  16.       (x, y), (new_x, new_y) = pos_data
  17.  
  18.       if wall?(new_x, new_y)
  19.         remove_wall(x, y)
  20.         remove_wall(new_x, new_y)
  21.         add_adjacent_wall_to_list(new_x, new_y)
  22.       end
  23.  
  24.       remove_from_list(x, y)
  25.     end
  26.   end
  27.  
  28.   def wall?(x, y)
  29.     exist?(x, y) && !@maze[x][y]
  30.   end
  31.  
  32.   def to_s
  33.     @xsize.times.map { |x|
  34.       @ysize.times.map { |y| wall?(x, y) ? '●' : '○' }.join
  35.     }.join("\n")
  36.   end
  37.  
  38.   private
  39.  
  40.   def init_maze
  41.     @maze = Array.new(@xsize) { Array.new(@ysize) }
  42.   end
  43.  
  44.   def init_list
  45.     @list = {}
  46.   end
  47.  
  48.   def remove_wall(x, y)
  49.     @maze[x][y] = true if exist?(x, y)
  50.   end
  51.  
  52.   # 返回 [[墙X,墙Y], [前方X, 前方Y]]
  53.   def list_sample
  54.     @list.to_a.sample
  55.   end
  56.  
  57.   def add_adjacent_wall_to_list(x, y)
  58.     each_dx_dy do |dx, dy|
  59.       new_x = x + dx
  60.       new_y = y + dy
  61.       add_to_list(new_x, new_y, new_x + dx, new_y + dy) if wall?(new_x, new_y)
  62.     end
  63.   end
  64.  
  65.   def each_dx_dy
  66.     yield -1, 0
  67.     yield 1, 0
  68.     yield 0, -1
  69.     yield 0, 1
  70.   end
  71.  
  72.   def add_to_list(x, y, new_x, new_y)
  73.     @list[[x, y]] = [new_x, new_y] if exist?(x, y)
  74.   end
  75.  
  76.   def remove_from_list(x, y)
  77.     @list.delete [x, y]
  78.   end
  79.  
  80.   def exist?(x, y)
  81.     x.between?(0, @xsize - 1) && y.between?(0, @ysize - 1)
  82.   end
  83.  
  84. end
  85.  
  86. # puts Maze.new(15, 15)

点评

..连大大都来看我,好感动的说~0 0  发表于 2015-1-3 22:21
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9280
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

3
发表于 2015-1-3 16:58:20 | 只看该作者
随机生成的迷宫会自动保存到地图文件里吗?

点评

地图名什么的无所谓吧···主要是存一个新的地图文件···  发表于 2015-1-9 22:06
Umm..不会呢 都是临时更改 应该可以把地图直接save_data吧?而且大概..也要改下MapInfos来着  发表于 2015-1-3 22:13
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

Lv4.逐梦者

【欧皇】

梦石
3
星屑
2066
在线时间
1004 小时
注册时间
2013-8-19
帖子
3486

开拓者

4
发表于 2015-1-3 17:45:04 | 只看该作者
好东西啊,拥有了va的功能,收藏先

点评

VA看来很强大呢!  发表于 2015-1-5 15:01
QQ:2223942063
Q群:365819625
贪吃方1.4
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
180
在线时间
509 小时
注册时间
2010-10-1
帖子
97
5
 楼主| 发表于 2015-1-11 18:35:46 | 只看该作者
chd114 发表于 2015-1-3 16:58
随机生成的迷宫会自动保存到地图文件里吗?

Umm..貌似map对象访问不到来着 那就酱紫直接加载吧 不动默认脚本= =
RUBY 代码复制
  1. def save_map
  2.   map = load_data(sprintf("Data/Map%03d.rxdata", $game_map.map_id))
  3.   map.data = $game_map.data.clone
  4.   save_data(map,sprintf("Data/Map%03d.rxdata",$game_map.map_id))
  5. end

如果要保存成新的文件大概..就必须改Mapinfo了吧 毕竟编辑器就要靠它啦
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-27 15:50

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表