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

Project1

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

树结构

 关闭 [复制链接]

Lv1.梦旅人

粉蜘蛛秀秀

梦石
0
星屑
76
在线时间
39 小时
注册时间
2007-6-4
帖子
384

贵宾第1届Title华丽大赛新人奖

跳转到指定楼层
1
发表于 2008-9-24 17:14:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
如:暗黑式的技能加点和梦幻模拟战的转职 {/wx}
节点属性可自行添加 如:requireSkillPoint,requireLevel 等
这个范例只定义了基本的属性 名称,父节点名称,层 等

=begin
   
   树结构
   
   作者: 秀秀
   
   树结构示意图

            (父树)(0层)
               ●
              /  \               
             /    \               
            /      \  
           ●      ●   (子树)(1层)
          /      / | \  
         /      ● ● ●(子树)(2层)
        ●         |      
                   ●   (子树)(3层)
                   /\   
                 ●  ● (子树)(4层)

=end

  #--------------------------------------------------------------------------
  # ● 树的类
  #--------------------------------------------------------------------------
class Tree
  def initialize
    @topTree = nil
    @sonTrees = []
    @layerStruct = {}
  end
  
  #--------------------------------------------------------------------------
  # ● 建立父结点
  #    idName   为id标示
  #--------------------------------------------------------------------------
  def createTopTree(idName)
    return if @topTree != nil
    @topTree = CreateTopTree.new(idName)
    @layerStruct[@topTree.layer] = []
    @layerStruct[@topTree.layer] << @topTree.idName
    return
  end

  #--------------------------------------------------------------------------
  # ● 建立一个子树
  #    fatherLinkId    为父联结点标号
  #    idName          建立的为子树标号
  #--------------------------------------------------------------------------
  def createSonTree(fatherLinkIdName,idName)
    #----------------------
    # 遍历所有IdName  
    # 判断标号是否存在重名
    # 判断父标号是否存在   
    #----------------------
    @layerStruct.values.each{|n|
      break if n.include?(idName)
      if n.include?(fatherLinkIdName)
        @nowLayer = @layerStruct.rKey(n) + 1
        break
      end  
    }
    if @nowLayer == nil
      return  
    end
    @sonTrees << CreateSonTree.new(idName,@nowLayer,fatherLinkIdName)
    if @layerStruct[@nowLayer] == nil
       @layerStruct[@nowLayer] = []
    end  
    @layerStruct[@nowLayer] << idName
  end  
  
  #--------------------------------------------------------------------------
  # ● 删除一个结点
  #--------------------------------------------------------------------------
  def deleteALinkPoint(idName)
    return if idName == @topTree.idName
    # 如果存在删除此结点
    # 并且删除包含的全部子结点
    if checkIdNameExist?(idName)
      @tempId = []
      # 删除此结点
      @layerStruct.clone.values.each do |n|
        if n.include?(idName)
          @layerStruct[@layerStruct.rKey(n)].delete(idName)
        end
      end  
      @sonTrees.clone.each do |n|
        @sonTrees.delete(n) if n.idName == idName
        @tempId << idName if [email protected]?(idName)
        @tempId << n.idName if @tempId.include?(n.fatherLinkIdName)
      end

      # 删除所有子结点
      @sonTrees.clone.each do |n|
        @sonTrees.delete(n) if @tempId.include?(n.idName)
      end  

      @needDelete = []
      @layerStruct.clone.values.each{|n|
        n.each{|m|
          if @tempId.include?(m)
            @needDelete << m
          end
        }
        @needDelete.each{|k|
          @layerStruct[@layerStruct.rKey(n)].delete(k)
        }
      }  

      # 如果value为空 则删除key
      @layerStruct.clone.values.each do |n|
        if @layerStruct[@layerStruct.rKey(n)].empty?
          @layerStruct.delete(@layerStruct.rKey(n))
        end  
      end
      @needDelete.clear
      @tempId.clear
      return
    end

  end
  

  #--------------------------------------------------------------------------
  # ●指向上级父结点
  #--------------------------------------------------------------------------
  def pointFather(idName)
    return if idName == @topTree.idName
    @sonTrees.each do |n|
      if n.idName == idName
        @name = n.fatherLinkIdName
        break
      end  
    end  
    return @name
  end  
  
  #--------------------------------------------------------------------------
  # ●检查结点是否存在
  #--------------------------------------------------------------------------
  def checkIdNameExist?(idName)
    @layerStruct.values.each{|n|
      return true if n.include?(idName)
    }
    return false
  end
  
  #--------------------------------------------------------------------------
  # ●返回此结点当前所在层
  #--------------------------------------------------------------------------
  def rNowlayer(idName)
    return if idName == @topTree.idName
    @sonTrees.each do |n|
      if n.idName == idName
        @layer = n.layer
        break
      end  
    end  
    return @layer
  end
  
  #--------------------------------------------------------------------------
  # ●获取当前层上的节点数
  #--------------------------------------------------------------------------
  def rNowLayer_idCount(layer)
    return @layerStruct[layer].length
  end

  #--------------------------------------------------------------------------
  # ●获取树的总层数
  #--------------------------------------------------------------------------
  def rAll_layer_count
    return @layerStruct.keys.size
  end
  
  #--------------------------------------------------------------------------
  # ●获取树的总节点数
  #--------------------------------------------------------------------------
  def rAll_Id_count
    return @sonTrees.length + 1
  end


  #--------------------------------------------------------------------------
  # ●获取当前结点的最近子结点ID集合
  #--------------------------------------------------------------------------
  def rNowID_sonID_Count(idName)
    names = []
    @sonTrees.each{|n|
    names << n.idName if n.fatherLinkIdName == idName
    }
    return names
  end  
  
  #--------------------------------------------------------------------------
  # ●显示当前树结构
  #--------------------------------------------------------------------------
  def showTreeStru
    return @layerStruct
  end  
end

  #--------------------------------------------------------------------------
  # ● 建立一个祖先
  #--------------------------------------------------------------------------
class CreateTopTree
  attr_reader     :idName
  attr_reader     :layer      
  def initialize(name)
    @idName = name
    @layer = 0
  end
end

  #--------------------------------------------------------------------------
  # ● 建立子结点
  #--------------------------------------------------------------------------
class CreateSonTree < CreateTopTree
  attr_reader     :idName
  attr_reader     :layer
  attr_reader     :fatherLinkIdName
  def initialize(name,layer,fatherName)
    super(name)
    @layer = layer
    @fatherLinkIdName = fatherName
  end
end

class Hash < Object
  def rKey(avalue)
    self.each_pair{|key, value|
    if avalue == value
      @temp = key
      break
    end
    }
    if @temp != nil
      return @temp
    else
      return nil
    end  
  end
end

#--------------------------------------------------------------------------
# ● 以下是测试
#--------------------------------------------------------------------------
@t = Tree.new
@t.createTopTree("洋葱战士")

@t.createSonTree("洋葱战士","战士")
@t.createSonTree("洋葱战士","见习魔法师")
@t.createSonTree("洋葱战士","盗贼")

@t.createSonTree("战士","骑士")
@t.createSonTree("战士","圣骑士")

@t.createSonTree("见习魔法师","黑魔法师")
@t.createSonTree("见习魔法师","白魔法师")

@t.createSonTree("盗贼","刺客")
@t.createSonTree("盗贼","忍者")

# 检查是否存在节点 盗贼
p @t.checkIdNameExist?("盗贼")
# 显示节点 战士 下的子节点
p @t.rNowID_sonID_Count("战士")
# 显示节点 见习魔法师的当前层(第几次专职)
p @t.rNowlayer("见习魔法师")
# 显示忍者的父职业
p @t.pointFather("忍者")
# 显示职业结构
p @t.showTreeStru
# 删除节点 "见习魔法师"
@t.deleteALinkPoint("见习魔法师")
# 再显示职业结构
p @t.showTreeStru
http://rpg.blue/upload_program/files/hide_xiu_96911465.png

Lv1.梦旅人

梦石
0
星屑
129
在线时间
148 小时
注册时间
2008-2-11
帖子
429
2
发表于 2008-9-24 17:58:06 | 只看该作者
看不太懂

有什么用呢

(虽然明知我的游戏用不上)
要守护就守护到底,要放弃就别再回头。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2007-12-16
帖子
3454
3
发表于 2008-9-24 18:21:09 | 只看该作者
不太懂哎..
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
0 小时
注册时间
2008-1-5
帖子
730
4
发表于 2008-9-24 18:29:50 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
8 小时
注册时间
2007-2-14
帖子
149
5
发表于 2008-9-24 19:52:03 | 只看该作者
不明白樓主講緊乜。
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

6
发表于 2008-9-24 21:41:48 | 只看该作者
在pascal里用point。
2X树:
class Tree
def lt
  return @lt
end
def rt
  return @rt
end
def lt=(v)
  @lt = v
end
def rt=(v)
  @rt = v
end
def va
  return @va
end
def va=(value)
  @va = value
end
end

tt = Tree.new
a = [0,1,2,3,4,5]
make(0)
def make(n,t)
a.va=a[n]
if n+1 <= a.size-1
t.lt=Tree.new
t.rt = Tree.new
make(n+1,t.lt)
if n+2 <= a.size-1
make(n+2,t.rt)
end
end
end
差不多是这样的………………
树还是pascal方便
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

辉瑞中国首席研究员<

梦石
0
星屑
50
在线时间
142 小时
注册时间
2008-1-18
帖子
2129
7
发表于 2008-9-25 04:02:48 | 只看该作者
以下引用一路一风尘于2008-9-24 10:29:50的发言:

这个数据建立的本身倒不难,
只是一但涉及到技能排列与光标切换刷新的界面,除非是规则的矩阵,否则就麻烦了— —


深有同感,以前自己写仿暗黑技能树的时候,结构不难,就是写界面刷新和技能排列的时候
好麻烦 = =
来6r就是等某位仁兄的巨坑

褴褛着身行无端,囊中羞涩空心酸。
平生几无得意事,倒塔泡面宅寝室。
惟羡隔壁高帅富,雨露春风月夜声。
青丝无处觅其踪,只有硬盘苍井空。
莫云男儿空悲愁,鸿鹄岂不天际游。
坐断天下执鹿首,千百金帛万兜鍪。
夜深忽梦某年月,再见女神欲语迟。
吊丝终有逆袭日,木耳再无回粉时。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

逃兵

8
发表于 2008-9-25 05:13:32 | 只看该作者
同lS
不过,LZ的东西还是有用的~
至少不用写一遍树了~
「If you judge people, you have no time to love them.」—— Mother Teresa
回复 支持 反对

使用道具 举报

Lv1.梦旅人

粉蜘蛛秀秀

梦石
0
星屑
76
在线时间
39 小时
注册时间
2007-6-4
帖子
384

贵宾第1届Title华丽大赛新人奖

9
 楼主| 发表于 2008-9-25 06:56:41 | 只看该作者
深有同感,以前自己写仿暗黑技能树的时候,结构不难,就是写界面刷新和技能排列的时候
好麻烦 = =

用这个其实很简单 把节点自定义属性 如图标文件名,技能等级,威力等 定义为 attr_accessor
然后 更新遇到升级 需要refresh的时候 更新所有节点信息。。。- -
http://rpg.blue/upload_program/files/hide_xiu_96911465.png
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
0 小时
注册时间
2008-1-5
帖子
730
10
发表于 2009-6-12 08:00:00 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-16 04:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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