mgmg 1.4.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +51 -10
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +19 -24
- data/lib/mgmg/ir.rb +401 -373
- data/lib/mgmg/optimize.rb +21 -9
- data/lib/mgmg/option.rb +84 -0
- data/lib/mgmg/poly.rb +2 -2
- data/lib/mgmg/recipe.rb +172 -0
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +204 -222
- data/lib/mgmg/system_equip.rb +6 -0
- data/lib/mgmg/utils.rb +70 -2
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +186 -70
- data/mgmg.gemspec +4 -4
- data/reference.md +271 -49
- metadata +14 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7cadbd5fef7941e004310c08f8ec597ce06381b0b305369d0e42afa08cb5016
|
4
|
+
data.tar.gz: a0d9d53d2e0284274e4558c7d27f26aeb2af6eb2649faaa07d840a5cd4f5aed8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe3d521ee8e90ae3253dacf5389035a53e40d58d0a9e574c0685d346765fdef35de371412d772b77476809cf80a2bb384e1e0b20c0ada8c265f6155ad27fcf3a
|
7
|
+
data.tar.gz: 77638a9c41f22fa7a509f409645307d2a452822bd557aa83e5d0c8e96ac8e84c93f6d9fd3df265a04dc1e91abde3f143561f410c6b397a89fe599a0ee2dcc8f7
|
data/CHANGELOG.md
CHANGED
@@ -115,3 +115,26 @@
|
|
115
115
|
- `Mgmg.#find_lowerbound`, `Mgmg.#find_upperbound`を追加.
|
116
116
|
- 魔法の威力に対応する`Mgmg::Equip#magic2`を追加.
|
117
117
|
- `String#min_levels`およびその関連メソッドにおいて,重量1以外を指定できるようにした.
|
118
|
+
|
119
|
+
## 1.4.2 2022/06/09
|
120
|
+
- `Mgmg::Equip#reinforce`および`Mgmg::IR`を使うメソッド群に`reinforcement`キーワード引数を追加.
|
121
|
+
- スキルおよび料理による強化効果をシミュレートできるようになった.
|
122
|
+
- 料理については,プリセット料理名または`Mgmg.#cuisine`で生成される`Mgmg::Cuisine`オブジェクトを使う.
|
123
|
+
|
124
|
+
## 1.5.0 2022/06/22
|
125
|
+
- `Mgmg::Option`を実装し,search系メソッドを中心としたキーワード引数を,このクラスに集約してから受け渡すようにした.
|
126
|
+
- オプションオブジェクトは`Mgmg.#option`によって生成し,キーワード引数`opt`に渡す.従来のキーワード引数は廃止された.
|
127
|
+
- この変更で,一部の受け渡し忘れのバグが修正され,パフォーマンスが改善した.
|
128
|
+
- `Enumerable#search`で無駄な処理が発生していて,処理時間がかかっていたバグを修正.
|
129
|
+
- `String#min_level`,`Enumerable#min_level`の仕様を変更し,合成後の重量を目標値にするのに必要な鍛冶・道具製作Lvを計算するようにした.
|
130
|
+
- この変更に伴い,`Mgmg::Equip#min_level`を,`Mgmg::Equip#min_levels_max`に名称変更し,`String#min_levels_max`,`Enumerable#min_levels_max`を追加した.
|
131
|
+
- 関連して,`String#max_weight`,`String#min_weight`,`Enumerable#max_weight`,`Enumerable#min_weight`,`Enumerable#max_weights`,`Enumerable#min_weights`を追加した.
|
132
|
+
- `Mgmg::Option#smith_min`,`Mgmg::Option#armor_min`のデフォルト値を,`String#min_level`,`Enumerable#min_level`を用いて設定する仕様とし,その目標重量を`Mgmg::Option#target_weight`で指定するようにした.
|
133
|
+
- `String#min_comp`,`String#min_smith`,`Enumerable#min_comp`,`Enumerable#min_smith`において,既製品のみである,合成を行わないなど,該当スキルが必要ないレシピである場合の返り値を`-1`に変更した.
|
134
|
+
|
135
|
+
## 1.5.1 2022/06/24
|
136
|
+
- `Mgmg::Recipe`を実装し,レシピ`String`または`Enumerable`と,注目パラメータ`Symbol`,オプション`Mgmg::Option`をセットで取り扱えるようにした.
|
137
|
+
- `String#to_recipe(para=:power, allow_over20: false, **kw)`または`Enumerable#to_recipe(para=:power, **kw)`で生成できる.
|
138
|
+
- `Mgmg::Recipe#build`,`Mgmg::Recipe#search`など`String`等に対する操作と同様にでき,注目パラメータとオプションは,`to_recipe`でセットしたものがデフォルトで使われるようになる.各メソッド呼び出し時にキーワード引数を与えることで,一時的に上書きすることもできる.
|
139
|
+
- `String#to_recipe`にのみ,☆20制限のチェック機構を導入した.
|
140
|
+
- 計算を繰り返した際,複数装備の装備数が増加していってしまうバグを修正した.
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Excel版に比べ,入力のチェックがなされておらず,☆制限の
|
|
22
22
|
|
23
23
|
$ gem install mgmg
|
24
24
|
|
25
|
-
あるいは,http://cycloawaodorin.sakura.ne.jp/sonota/mgmg/mgmg.html
|
25
|
+
あるいは,[Ajax版](http://cycloawaodorin.sakura.ne.jp/sonota/mgmg/mgmg.html) を利用することもできます.Ajax版は一部の機能しか実装されていませんが,Ruby環境がない場合にも利用できます.
|
26
26
|
|
27
27
|
## 使い方
|
28
28
|
並列型多段合成杖を製作し,標準出力に出力する.
|
@@ -53,19 +53,36 @@ puts r.build(122, 139, 232)
|
|
53
53
|
#=> 複数装備9(武:1, 頭:1, 飾:2)[攻撃:15, 物防:34, 魔防:28, HP:241, MP:71, 器用:223, 素早:222, 魔力:6,604]
|
54
54
|
```
|
55
55
|
|
56
|
-
|
56
|
+
製作品の重量及び特定の重量にするために必要な鍛冶・防具製作Lvを確認する.
|
57
57
|
|
58
58
|
```ruby
|
59
|
-
|
60
|
-
|
59
|
+
r = 'サンダル(骨2皮1)+[重鎧(金3金3)+[フード(骨2宝1)+[重鎧(皮10金10)+軽鎧(鉄10皮1)]]]'
|
60
|
+
p r.min_levels # 各材料装備を重量1で作るのに必要な防具製作Lv
|
61
|
+
#=> {"サンダル(骨2皮1)"=>3, "重鎧(金3金3)"=>202, "フード(骨2宝1)"=>3, "重鎧(皮10金10)"=>162, "軽鎧(鉄10皮1)"=>68}
|
62
|
+
p r.min_levels(2) # 同重量2以下
|
63
|
+
#=> {"サンダル(骨2皮1)"=>3, "重鎧(金3金3)"=>102, "フード(骨2宝1)"=>3, "重鎧(皮10金10)"=>42, "軽鎧(鉄10皮1)"=>27}
|
64
|
+
p [r.min_weight, r.max_weight] # 最小重量と最大重量
|
65
|
+
#=> [5, 10]
|
66
|
+
p r.min_level # 最小重量で作るのに必要な防具製作Lv
|
67
|
+
#=> 202
|
68
|
+
p r.min_level(7) # 重量7以下で作るのに必要な防具製作Lv
|
69
|
+
#=> 102
|
70
|
+
p r.min_level(-1) # 最小重量+1=重量6以下で作るのに必要な防具製作Lv
|
71
|
+
#=> 162
|
61
72
|
```
|
62
73
|
|
63
|
-
|
74
|
+
注目パラメータやオプションパラメータを,レシピ文字列とセットにして取り回す.
|
64
75
|
```ruby
|
65
|
-
|
66
|
-
|
67
|
-
p
|
68
|
-
#=>
|
76
|
+
r = '[[斧(鉄10皮1)+剣(牙10皮1)]+剣(鉄10皮1)]+剣(鉄10皮1)'
|
77
|
+
r = r.to_recipe(:atkstr, target_weight: 5) # 注目パラメータを攻撃力+腕力,目標重量を5に設定
|
78
|
+
p [r.min_level, r.min_level(0)] # 必要な鍛冶Lvのデフォルトが目標重量ベースに
|
79
|
+
#=> [72, 168] # 鍛冶Lv72で重量5(目標)に,鍛冶Lv168で重量4(最小)になる
|
80
|
+
puts r.build(27, 42) # 変換前と同様に合成等もできる
|
81
|
+
#=> 斧8☆20(鉄鉄)[攻撃:1,112, 腕力:18] # 鍛冶Lv27だと重量8に
|
82
|
+
p r.para_call(27, 42) # 注目パラメータのみを計算
|
83
|
+
#=> 1130 # 1112+18=1130
|
84
|
+
puts r.build(nil) # 目標重量を達成する最小製作Lvで製作
|
85
|
+
#=> 斧5☆20(鉄鉄)[攻撃:1,436, 腕力:24] # 製作Lvを nil にすると,目標重量のための最小製作Lv (72, 42) で製作
|
69
86
|
```
|
70
87
|
|
71
88
|
近似多項式を得る.
|
@@ -91,7 +108,31 @@ p [sc, Mgmg.exp(*sc)]
|
|
91
108
|
#=> [[155, 376], 304969]
|
92
109
|
```
|
93
110
|
|
94
|
-
|
111
|
+
最小重量で製作できない鍛冶レベルを探索範囲に含める.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
r = '双短剣(金3皮1)+[杖(水1綿1)+[斧(玉5水1)+[杖(鉄1綿1)+[[斧(木2金3)+剣(鉄10皮1)]+[剣(木2綿1)+双短剣(鉄10皮1)]]]]]'
|
115
|
+
r = r.to_recipe(:atk_sd, target_weight: 9)
|
116
|
+
sc = r.search(2000) # to_recipe で注目パラメータを入れているので,ここでは不要
|
117
|
+
p [sc, Mgmg.exp(*sc)]
|
118
|
+
#=> [[70, 130], 38046] # オプションなしの場合は鍛冶Lv100以上を探索するため,[[100, 126], 41054] になる
|
119
|
+
```
|
120
|
+
|
121
|
+
探索の際,スキル及び料理を考慮する.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
r = '重鎧(皮2綿1)+[帽子(宝1宝1)+[重鎧(玉5金3)+[帽子(宝1宝1)+[重鎧(玉5金6)+[軽鎧(金3骨1)+[重鎧(皮2骨1)+軽鎧(鉄10綿1)]]]]]]'
|
125
|
+
r = r.to_recipe(:phydef, buff: %w|物防御UP アースドランと氷河酒の蒸し焼き ガードアップ|)
|
126
|
+
sc = r.search(100_000)
|
127
|
+
p [sc, Mgmg.exp(*sc)]
|
128
|
+
#=> [[120, 264], 152502]
|
129
|
+
puts r.build(*sc) # 実際に作って確認
|
130
|
+
#=> 重鎧8☆20(綿宝)[物防:100,396.0, 魔防:4]
|
131
|
+
puts r.build(*sc, buff: []) # 一時的に強化を解除して素の性能を確認
|
132
|
+
#=> 重鎧8☆20(綿宝)[物防:32,538, 魔防:4]
|
133
|
+
```
|
134
|
+
|
135
|
+
各メソッドの詳しい説明等は [リファレンス](./reference.md) を参照されたい.
|
95
136
|
|
96
137
|
### 表記ゆれについて
|
97
138
|
本ゲームでは,装備種別の名称に,下記の表のような表記ゆれが存在します.
|
data/lib/mgmg/cuisine.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
module Mgmg
|
2
|
+
using Refiner
|
3
|
+
class Cuisine
|
4
|
+
def initialize(vec)
|
5
|
+
@vec = vec
|
6
|
+
end
|
7
|
+
attr_accessor :vec
|
8
|
+
def initialize_copy(other)
|
9
|
+
@vec = other.vec.dup
|
10
|
+
end
|
11
|
+
|
12
|
+
def attack
|
13
|
+
@vec[0]
|
14
|
+
end
|
15
|
+
def phydef
|
16
|
+
@vec[1]
|
17
|
+
end
|
18
|
+
def magdef
|
19
|
+
@vec[2]
|
20
|
+
end
|
21
|
+
def to_s
|
22
|
+
"料理[攻撃:#{self.attack}, 物防:#{self.phydef}, 魔防:#{self.magdef}]"
|
23
|
+
end
|
24
|
+
alias :inspect :to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
SystemCuisine = {
|
28
|
+
'焼き肉' => Cuisine.new( Vec[ 5, 0, 0] ), # ☆1
|
29
|
+
'焼き金肉' => Cuisine.new( Vec[10, 0, 0] ), # ☆3
|
30
|
+
'焼き黄金肉' => Cuisine.new( Vec[15, 0, 0] ), # ☆5
|
31
|
+
'焼きリンゴ' => Cuisine.new( Vec[ 0, 5, 0] ), # ☆1
|
32
|
+
'焼きイチゴ' => Cuisine.new( Vec[ 0, 10, 0] ), # ☆3
|
33
|
+
'焼きネギタマ' => Cuisine.new( Vec[ 0, 15, 0] ), # ☆5
|
34
|
+
'サボテン焼き1' => Cuisine.new( Vec[ 5, 5, 0] ), # ☆1
|
35
|
+
'サボテンバーガー' => Cuisine.new( Vec[10, 10, 0] ), # ☆3
|
36
|
+
'サボテン焼き7' => Cuisine.new( Vec[15, 15, 0] ), # ☆7
|
37
|
+
'獣肉とカエン酒の丸焼き' => Cuisine.new( Vec[ 8, 0, 0] ), # 料理Lv0
|
38
|
+
'ドランギョと煉獄酒の丸焼き' => Cuisine.new( Vec[15, 11, 6] ), # 料理Lv15
|
39
|
+
'ドラバーンと煉獄酒の丸焼き' => Cuisine.new( Vec[23, 17, 9] ), # 料理Lv24
|
40
|
+
'フレドランと煉獄酒の丸焼き' => Cuisine.new( Vec[59, 0, 0] ), # 料理Lv27
|
41
|
+
'ダークドンと煉獄酒の丸焼き' => Cuisine.new( Vec[35, 26, 21] ), # 料理Lv27
|
42
|
+
'ダークドンと氷河酒の丸焼き' => Cuisine.new( Vec[26, 35, 15] ), # 料理Lv27
|
43
|
+
'ウッチと氷酒の蒸し焼き' => Cuisine.new( Vec[ 0, 11, 10] ), # 料理Lv0
|
44
|
+
'ゴッチと氷酒の蒸し焼き' => Cuisine.new( Vec[ 0, 15, 13] ), # 料理Lv3
|
45
|
+
'ガガッチと氷水酒の蒸し焼き' => Cuisine.new( Vec[ 0, 19, 15] ), # 料理Lv6
|
46
|
+
'ガガッチと氷河酒の蒸し焼き' => Cuisine.new( Vec[ 0, 22, 16] ), # 料理Lv12
|
47
|
+
'ドランギョと氷河酒の蒸し焼き' => Cuisine.new( Vec[ 6, 24, 11] ), # 料理Lv15
|
48
|
+
'ドラバーンと氷河酒の蒸し焼き' => Cuisine.new( Vec[10, 35, 19] ), # 料理Lv24
|
49
|
+
'アースドランと氷河酒の蒸し焼き' => Cuisine.new( Vec[ 0, 87, 0] ), # 料理Lv27
|
50
|
+
'ダークドンと氷河酒の蒸し焼き' => Cuisine.new( Vec[15, 52, 38] ), # 料理Lv27
|
51
|
+
'ダークドンと煉獄酒の蒸し焼き' => Cuisine.new( Vec[15, 52, 38] ), # 料理Lv27
|
52
|
+
'ウッチとカエン酒の蒸し焼き' => Cuisine.new( Vec[ 0, 10, 11] ), # 料理Lv0
|
53
|
+
'ゴッチとカエン酒の蒸し焼き' => Cuisine.new( Vec[ 0, 13, 15] ), # 料理Lv3
|
54
|
+
'ガガッチと爆炎酒の蒸し焼き' => Cuisine.new( Vec[ 0, 15, 19] ), # 料理Lv6
|
55
|
+
'ガガッチと煉獄酒の蒸し焼き' => Cuisine.new( Vec[ 0, 16, 22] ), # 料理Lv12
|
56
|
+
'ドランギョと煉獄酒の蒸し焼き' => Cuisine.new( Vec[ 9, 18, 15] ), # 料理Lv15
|
57
|
+
'ドラバーンと煉獄酒の蒸し焼き' => Cuisine.new( Vec[14, 26, 25] ), # 料理Lv24
|
58
|
+
'アクアドランと煉獄酒の蒸し焼き' => Cuisine.new( Vec[ 0, 0, 87] ), # 料理Lv27
|
59
|
+
}
|
60
|
+
SystemCuisine.keys.each do |k|
|
61
|
+
ary = k.scan(%r|(.+)と(.+)の(.+)|)[0]
|
62
|
+
if ary
|
63
|
+
c = case ary[2]
|
64
|
+
when '丸焼き'
|
65
|
+
'焼き'
|
66
|
+
when '蒸し焼き'
|
67
|
+
'蒸し'
|
68
|
+
else
|
69
|
+
raise UnexpectedError
|
70
|
+
end
|
71
|
+
SystemCuisine.store("#{ary[0]}の#{ary[1]}#{c}", SystemCuisine[k])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
MainFood = {
|
76
|
+
'獣肉' => Vec[10, 0, 0],
|
77
|
+
'ウッチ' => Vec[ 0, 10, 10],
|
78
|
+
'ゴッチ' => Vec[ 0, 12, 12],
|
79
|
+
'ガガッチ' => Vec[ 0, 14, 14],
|
80
|
+
'ドランギョ' => Vec[15, 15, 10],
|
81
|
+
'ドラバーン' => Vec[20, 20, 15],
|
82
|
+
'フレドラン' => Vec[50, 0, 0],
|
83
|
+
'アースドラン' => Vec[ 0, 50, 0],
|
84
|
+
'アクアドラン' => Vec[ 0, 0, 50],
|
85
|
+
'ダークドン' => Vec[30, 30, 30],
|
86
|
+
}
|
87
|
+
SubFood = {
|
88
|
+
'氷酒' => Vec[ 50, 70, 50],
|
89
|
+
'氷水酒' => Vec[ 50, 90, 50],
|
90
|
+
'氷河酒' => Vec[ 50, 110, 50],
|
91
|
+
'カエン酒' => Vec[ 70, 50, 70],
|
92
|
+
'爆炎酒' => Vec[ 90, 50, 90],
|
93
|
+
'煉獄酒' => Vec[110, 50, 110],
|
94
|
+
}
|
95
|
+
Cookery = {
|
96
|
+
'焼き' => Vec[50, 50, 30],
|
97
|
+
'蒸す' => Vec[30, 75, 75],
|
98
|
+
}
|
99
|
+
Cookery.store('丸焼き', Cookery['焼き'])
|
100
|
+
Cookery.store('すき焼き', Cookery['焼き'])
|
101
|
+
Cookery.store('焼く', Cookery['焼き'])
|
102
|
+
Cookery.store('焼', Cookery['焼き'])
|
103
|
+
Cookery.store('蒸し焼き', Cookery['蒸す'])
|
104
|
+
Cookery.store('ボイル', Cookery['蒸す'])
|
105
|
+
Cookery.store('蒸し', Cookery['蒸す'])
|
106
|
+
Cookery.store('蒸', Cookery['蒸す'])
|
107
|
+
|
108
|
+
class << Cuisine
|
109
|
+
def cook(cookery_s, main_s, sub_s, level)
|
110
|
+
begin
|
111
|
+
c = Cookery[cookery_s]
|
112
|
+
m = MainFood[main_s]
|
113
|
+
s = SubFood[sub_s]
|
114
|
+
v = Vec[1, 1, 1]
|
115
|
+
v.e_mul!(m).e_mul!(c).e_mul!(s.dup.add!(100+level)).e_div!(10000)
|
116
|
+
new(v)
|
117
|
+
rescue
|
118
|
+
arg = [cookery_s, main_s, sub_s, level].inspect
|
119
|
+
raise ArgumentError, "Some of arguments for cooking seems to be wrong. #{arg} is given, but they should be [cookery (String), main food (String), sub food (String), cooking level (Integer)]. Not all of cookeries and foods are supported."
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
module_function def cuisine(*arg)
|
125
|
+
case arg.size
|
126
|
+
when 3
|
127
|
+
if arg.all?{ |e| e.kind_of?(Integer) } then
|
128
|
+
Cuisine.new( Vec[*arg] )
|
129
|
+
else
|
130
|
+
raise ArgumentError, "All the cuisine parameters must be Integer."
|
131
|
+
end
|
132
|
+
when 1
|
133
|
+
SystemCuisine[arg[0]] or raise ArgumentError, "The cuisine name `#{arg[0]}' is not supported."
|
134
|
+
when 4
|
135
|
+
Cuisine.cook(*arg)
|
136
|
+
else
|
137
|
+
raise ArgumentError, 'The number of argument must be 1, 3 or 4.'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/lib/mgmg/equip.rb
CHANGED
@@ -13,7 +13,7 @@ module Mgmg
|
|
13
13
|
def initialize_copy(other)
|
14
14
|
@kind = other.kind
|
15
15
|
@weight = other.weight
|
16
|
-
@star = other.star
|
16
|
+
@star = other.star.dup
|
17
17
|
@main = other.main
|
18
18
|
@sub = other.sub
|
19
19
|
@para = other.para.dup
|
@@ -57,15 +57,15 @@ module Mgmg
|
|
57
57
|
@min_levels
|
58
58
|
else
|
59
59
|
@min_levels.map do |key, value|
|
60
|
-
[key,
|
60
|
+
[key, Equip.min_level(key, w)]
|
61
61
|
end.to_h
|
62
62
|
end
|
63
63
|
end
|
64
|
-
def
|
64
|
+
def min_levels_max(w=1)
|
65
65
|
if @kind == 28
|
66
|
-
ret = [
|
66
|
+
ret = [-1, -1]
|
67
67
|
min_levels(w).each do |str, ml|
|
68
|
-
if str.build
|
68
|
+
if str.build.kind < 8
|
69
69
|
if ret[0] < ml
|
70
70
|
ret[0] = ml
|
71
71
|
end
|
@@ -77,7 +77,7 @@ module Mgmg
|
|
77
77
|
end
|
78
78
|
ret
|
79
79
|
else
|
80
|
-
min_levels(w).values.append(
|
80
|
+
min_levels(w).values.append(-1).max
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -193,15 +193,9 @@ module Mgmg
|
|
193
193
|
def +(other)
|
194
194
|
self.dup.add!(other)
|
195
195
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
zero.history.clear
|
200
|
-
[zero, self]
|
201
|
-
else
|
202
|
-
raise TypeError, "Mgmg::Equip can't be coerced into other than 0"
|
203
|
-
end
|
204
|
-
end
|
196
|
+
Zero = self.new(28, 0, Vec.new(6, 0).freeze, 12, 12, Vec.new(9, 0).freeze, Vec.new(3, 0).freeze)
|
197
|
+
Zero.total_cost.freeze; Zero.history.clear.freeze
|
198
|
+
Zero.freeze
|
205
199
|
end
|
206
200
|
|
207
201
|
class << Equip
|
@@ -212,7 +206,7 @@ module Mgmg
|
|
212
206
|
end
|
213
207
|
private def build_sub0(stack, str)
|
214
208
|
SystemEquip.each do |k, v|
|
215
|
-
if
|
209
|
+
if SystemEquipRegexp[k].match(str)
|
216
210
|
stack << v
|
217
211
|
str = str.gsub(k, "<#{stack.length-1}>")
|
218
212
|
end
|
@@ -305,7 +299,7 @@ module Mgmg
|
|
305
299
|
|
306
300
|
ret = new(kind, ( weight<1 ? 1 : weight ), (main_s+sub_s).div(2), main_mc, sub_mc, para, ele)
|
307
301
|
ret.total_cost[kind < 8 ? 0 : 2] += ret.smith_cost(outsourcing)
|
308
|
-
ret.min_levels.store(str,
|
302
|
+
ret.min_levels.store(str, Equip.min_level(str))
|
309
303
|
ret
|
310
304
|
end
|
311
305
|
|
@@ -323,14 +317,14 @@ module Mgmg
|
|
323
317
|
[(main_s-1)*3, (sub_s-1)*3, l].max
|
324
318
|
end
|
325
319
|
|
326
|
-
def min_comp(str,
|
320
|
+
def min_comp(str, opt: Option.new)
|
327
321
|
str = Mgmg.check_string(str)
|
328
322
|
stack, str = minc_sub0([], str)
|
329
|
-
(minc_sub(stack, str, left_associative)[1]-1)*3
|
323
|
+
(minc_sub(stack, str, opt.left_associative)[1]-1)*3
|
330
324
|
end
|
331
325
|
private def minc_sub0(stack, str)
|
332
326
|
SystemEquip.each do |k, v|
|
333
|
-
if
|
327
|
+
if SystemEquipRegexp[k].match(str)
|
334
328
|
stack << v.star
|
335
329
|
str = str.gsub(k, "<#{stack.length-1}>")
|
336
330
|
end
|
@@ -352,14 +346,15 @@ module Mgmg
|
|
352
346
|
end
|
353
347
|
end
|
354
348
|
|
355
|
-
def min_smith(str,
|
349
|
+
def min_smith(str, opt: Option.new)
|
356
350
|
str = Mgmg.check_string(str)
|
357
351
|
stack, str = mins_sub0([], str)
|
358
|
-
(([mins_sub(stack, str, left_associative)]+stack).max-1)*3
|
352
|
+
ret = (([mins_sub(stack, str, opt.left_associative)]+stack).max-1)*3
|
353
|
+
ret < 0 ? -1 : ret
|
359
354
|
end
|
360
355
|
private def mins_sub0(stack, str)
|
361
356
|
SystemEquip.each do |k, v|
|
362
|
-
if
|
357
|
+
if SystemEquipRegexp[k].match(str)
|
363
358
|
stack << 0
|
364
359
|
str = str.gsub(k, "<#{stack.length-1}>")
|
365
360
|
end
|
@@ -373,7 +368,7 @@ module Mgmg
|
|
373
368
|
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
374
369
|
[mins_sub(stack, m[1], lassoc), mins_sub(stack, m[2], lassoc)].max
|
375
370
|
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
376
|
-
|
371
|
+
0
|
377
372
|
else
|
378
373
|
mins_sub2(str)
|
379
374
|
end
|