Project1

标题: 请教计算自身携带物品中@description里被标记为"@药品"的数量 [打印本页]

作者: taeckle    时间: 2022-5-31 05:49
标题: 请教计算自身携带物品中@description里被标记为"@药品"的数量
本帖最后由 taeckle 于 2022-5-31 05:57 编辑

大家好,

我在数据库物品一栏的物品说明中最后都增加了一个"@类别名称", 用于给物品栏具体细分类别, 类似于这样: "己方单体 HP 回复。@药品",

请问下如何计算自身携带物品中在@description中被标记为"@药品"的物品数量呢?

还请大家指点指点,多谢了!

例子2.PNG (31.94 KB, 下载次数: 19)

例子2.PNG

作者: 灯笼菜刀王    时间: 2022-5-31 09:43
n  = 0
$game_party.instance_variable_get(:@items).each{|a,b| n += b if $game_items[a].description.split(/@/)[1] == "药品"}
return n
作者: RPGzh500223    时间: 2022-5-31 14:46
本帖最后由 RPGzh500223 于 2022-6-3 22:15 编辑
  1. class Game_Party
  2.   def medicine_number
  3.     @@medicine_idx ||= $data_items.inject([]) do |ary, item|
  4.       if item != nil
  5.         ary << item.id if item.description.include?("@药品")
  6.       end
  7.       ary  
  8.     end
  9.    
  10.     #下一行代码留着当个反面教材,当初应该可以写得更好的o(* ̄▽ ̄*)o
  11.     (@items.keys & @@medicine_idx).inject(0){|sum, idx| sum += @items[idx]}
  12.   end
  13.   
  14.   def num2
  15.     n = 0
  16.     @items.each{|a, b| n += b if $data_items[a].description.include?("@药品")}
  17.     return n
  18.   end
  19. end
复制代码


考虑到游戏物品越来越多,还是第一个思路好点

楼主有兴趣的话,可以试试图片上的测试

temp.jpg (46.97 KB, 下载次数: 20)

temp.jpg

作者: taeckle    时间: 2022-6-2 07:06
灯笼菜刀王 发表于 2022-5-31 09:43
n  = 0
$game_party.instance_variable_get(:@items).each{|a,b| n += b if $game_items[a].description.sp ...


大神请问下为什么我在那个class Game_Party里面没有找到这个instance_variable_get方法呢?
作者: alexncf125    时间: 2022-6-2 07:15
taeckle 发表于 2022-6-2 07:06
大神请问下为什么我在那个class Game_Party里面没有找到这个instance_variable_get方法呢? ...

https://blog.csdn.net/weixin_30835933/article/details/95456720

作者: taeckle    时间: 2022-6-2 07:42
alexncf125 发表于 2022-6-2 07:15
https://blog.csdn.net/weixin_30835933/article/details/95456720


还有大神那个.each{|a,b| n += b 中的a逗号b是神马意思啊?我猜b是每个被标记为药品的数量,a就猜不出是啥意思了。。
作者: taeckle    时间: 2022-6-3 03:32
本帖最后由 taeckle 于 2022-6-3 04:16 编辑

这是我自己的方法:
1. 在main上面增加这段代码:
RUBY 代码复制
  1. module RPG
  2.   class Item
  3.     def desc
  4.       desc = @description.split(/@/)[1]
  5.       return desc != nil ? desc : "普通物品"
  6.     end
  7.   end
  8. end



2.在 class Game_Party里面增加一个方法:
  1.   def item_des_number(descr_para="无")
  2.     item_d_num=0
  3.     for i in 1..999
  4.      if $data_items[i].desc.include?(descr_para) && $game_party.item_number(i) > 0
  5.       item_d_num+=$game_party.item_number(i)
  6.      end
  7.     end   
  8.     return item_d_num
  9.   end  
复制代码


3. 调用这个方法:
p $game_party.item_des_number("药品")
作者: taeckle    时间: 2022-6-3 04:08
灯笼菜刀王 发表于 2022-5-31 09:43
n  = 0
$game_party.instance_variable_get(:@items).each{|a,b| n += b if $game_items[a].description.sp ...

还有大神你这三行代码直接用会报错,貌似这个第二行有个方法没有被定义,惨不忍睹
作者: RPGzh500223    时间: 2022-6-3 15:15
本帖最后由 RPGzh500223 于 2022-6-3 22:33 编辑

图片是关于本贴中一些方法的效率测试

除非方法在整个游戏中只调用一次,我更习惯把重复的部分“固定下来”
RUBY 代码复制
  1. module RPG  
  2.   class Item
  3.     def desc
  4.       @description.split("@")[1] || "普通物品"
  5.     end
  6.  
  7.     @@idx = {}
  8.     #直接设定默认值的话可以 @@idx = Hash.new{|hsh, key| hsh[key] = []}
  9.     data_items = load_data("Data/Items.rxdata")
  10.     data_items[1..-1].each do |item|
  11.       (@@idx[item.desc] ||= []) << item.id
  12.     end
  13.  
  14.     def self.idx
  15.       @@idx
  16.     end
  17.   end
  18. end
  19.  
  20. class Game_Party
  21.   def item_des_number(descr_para = "")
  22.     (RPG::Item.idx[descr_para] || []).inject{|sum, id|sum += @items[id] || 0}
  23.   end
  24. end

temp.png (41.3 KB, 下载次数: 22)

temp.png

作者: guoxiaomi    时间: 2022-6-9 17:45
本帖最后由 guoxiaomi 于 2022-6-9 17:54 编辑

我也做了个benchmark:https://godbolt.org/z/93d6q8f14
意料之中,带缓存的end_with?是最快的,但是xp里没有这个函数,要等到va才有,那么include?就最快。
猜测其他算法相对来说慢的原因:
1. split要创建字符串数组
2. 正则表达式会修改全局变量
3. 下标会创建截取部分的字符串

@RPGzh500223




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1