mgmg 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48ad2b791e601abcf8108fcfceabed64d97b5beeb949e3b409fcb0ef7de148ed
4
- data.tar.gz: 2154c226324c09f202a660bef0b344c3ee57a792dc14e889a9caedb79e5adfb8
3
+ metadata.gz: fa07550bf3367d160e4915d65e592b2295667cfb56284543f8cf43c2a92c375d
4
+ data.tar.gz: 062c07e9c53d9b4ffb20332b7f9365727cbad46e93d83be49d4592ec4cae8a17
5
5
  SHA512:
6
- metadata.gz: a40d7b79dd7666a8fc1aa3985bd79f074d80f26ddd28b3c92cdef826edb28406154f3151fe1de5583a4ec3139d6710f71390f7fa60e1c896f2d9452f3dd00b70
7
- data.tar.gz: cf7c8fe93611cad843f0bca7da77f02c24fbe5f7c2b932741f8ce94c80b73df1f355501521b6aabad99a17670d1649f5c7637721974bd096b6eb70726825d0b7
6
+ metadata.gz: 1272f84d6fb42b63dc4c6e2180552f16311a9f8d65b392a2b0628e882ac7e6854d65a13e3f42549507c91bd2cdb190b1c295c514a982c64f77678cd21017cd7e
7
+ data.tar.gz: 9792b236879eb2ffb01e2f25389647b235a4a2328a6a4446b8c2636b738a849ee047201c5998cbf2098799c686e0fc4bb9d803a0b52ddaa0866139e19aa9a0a1
data/CHANGELOG.md CHANGED
@@ -30,7 +30,7 @@
30
30
  - マニュアル等の不備を修正.
31
31
 
32
32
  ## 1.0.9 2019/05/30
33
- - 丸めを無視した多項式近似(変数は製作レベル)を表す `Mgmg::TPolynomial`およびこれを生成するメソッド String#poly を追加.
33
+ - 丸めを無視した多項式近似(変数は製作レベル)を表す`Mgmg::TPolynomial`およびこれを生成するメソッド`String#poly`を追加.
34
34
 
35
35
  ## 1.0.10 2019/06/29
36
36
  - 消費エレメント量を返す`Mgmg::Equip#total_cost`を追加.
@@ -87,3 +87,31 @@
87
87
  - `String#poly`のデフォルト引数を`:cost`に設定.
88
88
  - `Mgmg.#exp`,`String#eff`,`String#peff`,`String#min_levels`を追加.
89
89
  - `String#smith_search`, `String#comp_search`, `String#min_smith`, `String#min_comp`を追加.
90
+
91
+ ## 1.3.1 2020/08/31
92
+ - `String#poly`のキーワード引数`left_associative`が無視される場合があったバグを修正.
93
+ - `Mgmg.#exp`に3引数を与えられるように修正.
94
+ - `String#search`,`Enumerable#search`を追加.
95
+ - `Enumerable#min_levels`,`Enumerable#min_level`,`Enumerable#min_smith`,`Enumerable#min_comp`を追加.
96
+
97
+ ## 1.3.2 2021/05/18
98
+ - `Mgmg::TPolynomial`に比較演算子を追加.
99
+ - `String#phydef_optimize`,`String#buster_optimize`を追加.
100
+ - (`Enumerable#search`から呼び出される)`Enumerable#comp_search`における最大道具製作レベルチェックが間違っていたバグを修正.
101
+ - `String#search`および`Enumerable#search`において,総経験値量が等しい組み合わせの場合,目標パラメータが大きくなる製作Lvの組み合わせを返すように修正.
102
+
103
+ ## 1.4.0 2021/06/03
104
+ - `Mgmg::Equip#atk_sd`,`Mgmg::Equip#dex_as`,`Mgmg::Equip#mag_das`,`Mgmg::Equip#magmag`を,威力値の定数倍(常に`Integer`)から威力値そのもの(`Rational`)に変更.これに伴い,`Mgmg::Equip#power`の返り値も威力値とした.互換性のため,`Mgmg::Equip#fpower`はそのまま残した.
105
+ - ver2.00β12で導入された,合成の消費エレメントが地と火または水で折半される仕様に対応した.`Mgmg::Equip#comp_cost`は従来の値の半分となり,`Mgmg::Equip#total_cost`はver2.00β12以降の総消費エレメントとなった.
106
+ - `Mgmg::TPolynomial#<=>`を追加.
107
+ - `Enumerable#show`を追加.
108
+ - `Mgmg::Equip#pmdef`で,`Mgmg::Equip#phydef`と`Mgmg::Equip#magmag`のうち,小さい方を返すようにし,`String#poly`の引数に`:pmdef`を受け付けるようにした.
109
+
110
+ ## 1.4.1 2022/01/06
111
+ - [リファレンス](./reference.md)を[README](./README.md)から分離独立させた.
112
+ - `Mgmg::IR`を追加.
113
+ - これを生成するための`String#ir`および`Enumerable#ir`を追加
114
+ - `String#search`および`Enumerable#search`において,内部的にこれを利用することで高速化.
115
+ - `Mgmg.#find_lowerbound`, `Mgmg.#find_upperbound`を追加.
116
+ - 魔法の威力に対応する`Mgmg::Equip#magic2`を追加.
117
+ - `String#min_levels`およびその関連メソッドにおいて,重量1以外を指定できるようにした.
data/README.md CHANGED
@@ -25,29 +25,42 @@ Excel版に比べ,入力のチェックがなされておらず,☆制限の
25
25
  あるいは,http://cycloawaodorin.sakura.ne.jp/sonota/mgmg/mgmg.html にてAjax版を利用することもできます.Ajax版は一部の機能しか実装されていませんが,Ruby環境がない場合にも利用できます.
26
26
 
27
27
  ## 使い方
28
- 並列型多段合成杖を製作し,標準出力に出力.
28
+ 並列型多段合成杖を製作し,標準出力に出力する.
29
29
 
30
30
  ```ruby
31
31
  puts '[杖(水玉10火玉5)+本(骨10鉄1)]+[本(水玉5綿2)+杖(骨10鉄1)]'.build(112, 176)
32
32
  #=> 杖4☆20(骨綿)[攻撃:119, MP:104, 魔力:1,859, EL:水2]
33
33
  ```
34
34
 
35
- 複数装備を製作し,そのすべてを装備した場合の合計値を標準出力に出力.
35
+ 中間製作品の性能を確認する.
36
36
 
37
37
  ```ruby
38
- ary = %w|本(金3骨1)+[弓(骨1綿1)+[(金3金3)+[弓(綿1綿1)+[杖(10金6)+本(骨92)]]]] フード(石10骨9) 首飾り(宝10水10) 指輪(木10金10)|
39
- puts ary.build(122, 139, 232)
38
+ puts '[杖(水玉10火玉5)+本(骨10鉄1)]+[(水玉5綿2)+杖(10鉄1)]'.build(112, 176).history
39
+ #=> 杖1☆7(貴貴)[MP:15, 魔力:50, EL:水2]
40
+ #=> 本1☆5(骨鉄)[攻撃:44, 魔防:19, MP:20, 魔力:256]
41
+ #=> 杖2☆12(貴骨)[攻撃:56, MP:41, 魔力:650, EL:水2]
42
+ #=> 本1☆3(貴綿)[MP:8, 魔力:36]
43
+ #=> 杖1☆5(骨鉄)[攻撃:24, MP:32, 魔力:321]
44
+ #=> 本2☆8(綿骨)[攻撃:46, MP:35, 魔力:487]
45
+ #=> 杖4☆20(骨綿)[攻撃:119, MP:104, 魔力:1,859, EL:水2]
46
+ ```
47
+
48
+ 複数装備を製作し,そのすべてを装備した場合の合計値を標準出力に出力する.
49
+
50
+ ```ruby
51
+ r = %w|本(金3骨1)+[弓(骨1綿1)+[杖(金3金3)+[弓(綿1綿1)+[杖(宝10金6)+本(骨9鉄2)]]]] フード(石10骨9) 首飾り(宝10水10) 指輪(木10金10)|
52
+ puts r.build(122, 139, 232)
40
53
  #=> 複数装備9(武:1, 頭:1, 飾:2)[攻撃:15, 物防:34, 魔防:28, HP:241, MP:71, 器用:223, 素早:222, 魔力:6,604]
41
54
  ```
42
55
 
43
- 重量1または2で作るのに必要な防具製作Lvを確認.
56
+ 重量1または2で作るのに必要な防具製作Lvを確認する.
44
57
 
45
58
  ```ruby
46
59
  p ['重鎧(皮10金10)'.min_level, '重鎧(皮10金10)'.min_level(2)]
47
60
  #=> [162, 42]
48
61
  ```
49
62
 
50
- 合成レシピから必要製作Lvを確認.
63
+ 合成レシピから必要製作Lvを確認する.
51
64
  ```ruby
52
65
  p '[杖(水玉10火玉5)+本(骨10鉄1)]+[本(水玉5綿2)+杖(骨10鉄1)]'.min_levels
53
66
  #=> {"杖(水玉10火玉5)"=>92, "本(骨10鉄1)"=>48, "本(水玉5綿2)"=>12, "杖(骨10鉄1)"=>28}
@@ -62,13 +75,24 @@ puts '[斧(牙10金10)+剣(鉄10皮1)]+剣(鉄10皮1)'.poly(:attack).to_s('%.4g'
62
75
  #=> (0.02588S+3.364)C+(4.677S+699.9)
63
76
  ```
64
77
 
65
- 既成品の性能を確認.
78
+ 既成品の性能を確認する.
66
79
 
67
80
  ```ruby
68
81
  puts '小竜咆哮'.build
69
82
  #=> 弓1☆10(木骨)[攻撃:50, 器用:120, 素早:50]
70
83
  ```
71
84
 
85
+ 目標威力を最小のスキル経験値で達成する鍛冶Lvと道具製作Lvの組み合わせを探索し,必要な総経験値を確認する.
86
+
87
+ ```ruby
88
+ r = '双短剣(金3皮1)+[杖(鉄2綿1)+[斧(玉5鉄1)+[杖(綿1綿1)+[斧(玉5金3)+[剣(金3牙1)+[斧(木2牙1)+[剣(木2牙1)+双短剣(鉄10木1)]]]]]]]'
89
+ sc = r.search(:atk_sd, 1_000_000)
90
+ p [sc, Mgmg.exp(*sc)]
91
+ #=> [[155, 376], 304969]
92
+ ```
93
+
94
+ 各メソッドの詳しい説明等は[リファレンス](./reference.md)を参照されたい.
95
+
72
96
  ### 表記ゆれについて
73
97
  本ゲームでは,装備種別の名称に,下記の表のような表記ゆれが存在します.
74
98
 
@@ -84,211 +108,6 @@ puts '小竜咆哮'.build
84
108
 
85
109
  「正式な装備種別名」は「製作品ver1.22β37」が妥当であろうと考え,`Mgmg::Equip#to_s`などではこれを用いるようにしています.
86
110
 
87
- ## リファレンス
88
- 本ライブラリで定義される主要なメソッドを以下に解説します.
89
-
90
- ### `String#build(smith=-1, comp=smith, left_associative: true)`
91
- レシピ文字列である`self`を解釈し,鍛冶・防具製作Lvを`smith`,道具製作Lvを`comp`として鍛冶・防具製作及び武器・防具合成を行った結果を後述の`Mgmg::Equip`クラスのインスタンスとして生成し,返します.例えば,
92
- ```ruby
93
- '[杖(水玉10火玉5)+本(骨10鉄1)]+[本(水玉5綿2)+杖(骨10鉄1)]'.build(112, 176)
94
- ```
95
- のようにします.基本的に`[]`による合成順序の指定が必要ですが,不確定の場合,`left_associative`が真なら左結合,偽なら右結合として解釈します.
96
- ```ruby
97
- '法衣(綿10皮10)+歴戦の服'
98
- ```
99
- のように,既成品を含む合成レシピも解釈します.キャラクリ初期装備の劣悪な服,劣悪な小手以外のあらゆる装備を網羅しています.劣悪な服,劣悪な小手はキャラクリ以外での初期装備品として解釈します.`comp`を省略した場合,`smith`と同じ値として処理します.
100
-
101
- `self`が解釈不能な場合,例外が発生します.また,製作Lvや完成品の☆制限のチェックを行っていないほか,本ライブラリでは`武器+防具`や`防具+武器`の合成も可能になっています.街の鍛冶・防具製作・道具製作屋に任せた場合をシミュレートする場合は製作Lvを負の値(`-1`など,負であれば何でもよい)にします(製作Lv0相当の性能を計算し,消費エレメント量は委託仕様となります).
102
-
103
- ### `Enumerable#build(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true)`
104
- 複数のレシピ文字列からなる`self`の各要素を製作し,そのすべてを装備したときの`Mgmg::Equip`を返します.製作では`鍛冶Lv=smith`, `防具製作Lv=armor`, `道具製作Lv=comp`とします.1つしか指定しなければすべてそのLv,2つなら1つ目を`smith=armor`,2つ目を`comp`に,3つならそれぞれの値とします.`left_associative`はそのまま`String#build`に渡されます.製作Lvが負の場合,製作Lv0として計算した上で,消費エレメント量は街の製作屋に頼んだ場合の値を計算します.武器複数など,同時装備が不可能な場合でも,特にチェックはされません.
105
-
106
- ### `String#min_level(weight=1)`
107
- `self`を`weight`以下で作るための最低製作Lvを返します.`build`と異なり,合成や既成品は解釈できません.また,素材の☆による最低製作Lvとのmaxを返すため,街の鍛冶・防具製作屋に頼んだ場合の重量は`self.build.weight`で確認する必要があります.`weight`を省略した場合,重量1となる製作Lvを返します.
108
-
109
- ### `String#min_levels(left_associative: true)`
110
- 合成レシピの各鍛冶・防具製作品に対して,レシピ文字列をキー,重量1で作製するために必要な製作Lvを値とした`Hash`を返します.重量1以外は指定できません.
111
- 最大値は,`self.build.min_level`によって得られます.
112
-
113
- ### `String#min_comp(left_associative: true)`
114
- レシピ通りに合成するのに必要な道具製作Lvを返します.ただし,全体が「[]」で囲われているか,非合成レシピの場合,代わりに`0`を返します.
115
-
116
- ### `String#min_smith(left_associative: true)`
117
- レシピ通りに製作するのに必要な鍛冶・防具製作Lvを返します.製作物の重量については考慮せず,鍛冶・防具製作に必要な☆条件を満たすために必要な製作Lvを返します.
118
-
119
- ### `String#poly(para=:cost, left_associative: true)`
120
- レシピ文字列である`self`を解釈し,`para`で指定した9パラ値について,丸めを無視した鍛冶・防具製作Lvと道具製作Lvの2変数からなる多項式関数を示す`Mgmg::TPolynomial`クラスのインスタンスを生成し,返します.`para`は次のシンボルのいずれかを指定します.
121
- ```ruby
122
- :attack, :phydef, :magdef, :hp, :mp, :str, :dex, :speed, :magic
123
- ```
124
- これらは,`Mgmg::Equip`から当該属性値を取得するためのメソッド名と同一です.`left_associative`は`String#build`の場合と同様です.
125
-
126
- `para`として,複数の9パラ値を組み合わせた以下のシンボルを指定することもできます.
127
- ```ruby
128
- :atkstr, :atk_sd, :dex_as, :mag_das, :magmag
129
- ```
130
- これらは同名のメソッドと異なり,本来の威力値等に関する近似多項式を返し,4倍化や2倍化はされていません.また,自動選択の`:power`は指定できません.
131
-
132
- また,`:cost`を渡すことで,消費エレメント量に関する近似多項式を得られます.`self`に`"+"`が含まれていれば合成品とみなし,最後の合成に必要な地エレメント量を,それ以外では,武器なら消費火エレメント量を,防具なら消費水エレメント量を返します.ただし,`self`が既成品そのものの場合,零多項式を返します.
133
-
134
- ### `String#smith_seach(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true)`
135
- `para`の値が`target`以上となるのに必要な最小の鍛冶・防具製作Lvを二分探索で探索して返します.
136
- 道具製作Lvは`comp`で固定,鍛冶・防具製作Lvを`smith_min`と`smith_max`で挟み込んで探索します.
137
- `smith_min`が`nil`のとき,最小重量で製作するのに必要な鍛冶・防具製作Lv (`self.build.min_level`)を使用します.
138
- 重量を無視して,製作に必要な最小Lvである`self.min_smith`まで探索したい場合,明示的に指定します.
139
- `smith_min<smith_max`でないとき,`smith_max`で`para`が`target`以上でないときは`ArgumentError`となります.
140
- `para`は,`Mgmg::Equip`のメソッド名をシンボルで指定(`:power, :fpower`も可)します.
141
- 反転などの影響で,探索範囲において`para`の値が(広義)単調増加になっていない場合,正しい結果を返しません.
142
-
143
- ### `String#comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true)`
144
- `String#smith_seach`とは逆に,鍛冶・防具製作Lvを固定して最小の道具製作Lvを探索します.
145
- `comp_min`が`nil`のときは,製作に必要な最小の道具製作Lv (`self.min_comp`)を使用します.
146
- その他は`String#smith_seach`と同様です.
147
-
148
- ### `String#eff(para, smith, comp=smith, left_associative: true)`
149
- [`smith`を1上げたときの`para`値/(`smith`を1上げるのに必要な経験値), `comp`を1上げたときの`para`値/(`comp`を2上げるのに必要な経験値)]を返します.
150
- `para`は,`Mgmg::Equip`のメソッド名をシンボルで指定(`:power, :fpower`も可)します.
151
-
152
- ### `String#peff(para, smith, comp=smith, left_associative: true)`
153
- 近似多項式における偏微分値を使用した場合の,`String#eff`と同様の値を返します.`self.poly(para, left_associative: left_associative).eff(smith, comp)`と等価です.
154
-
155
- ### `Mgmg::Equip`
156
- 前述の`String#build`によって生成される装備品のクラスです.複数装備の合計値を表す「複数装備」という種別の装備品の場合もあります.以下のようなインスタンスメソッドが定義されています.
157
-
158
- ### `Mgmg::Equip#to_s`
159
- ```ruby
160
- "杖4☆20(骨綿)[攻撃:119, MP:104, 魔力:1,859, EL:水2]"
161
- ```
162
- のような,わかりやすい形式の文字列に変換します.上の例で「4」は重量,「骨」は主材質,「綿」は副材質を表します.各種数値が必要な場合は次以降に説明するメソッドをご利用ください.複数装備の場合は以下のような文字列になります.
163
- ```ruby
164
- "複数装備9(武:1, 頭:1, 飾:2)[攻撃:15, 物防:34, 魔防:28, HP:241, MP:71, 器用:223, 素早:222, 魔力:6,604]"
165
- ```
166
- 「9」は合計重量,(武:1, 頭:1, 飾:2)は武器を1つ,頭防具を1つ,装飾品を2つ装備していることを示します.装備している場合は「胴」「腕」「足」も記述されます.
167
-
168
- ### `Mgmg::Equip#inspect`
169
- `Mgmg::Equip#to_s`の出力に加え,0となる9パラ値を省略せず,総消費エレメント量を連結した文字列を出力します.すなわち,
170
- ```ruby
171
- "杖4☆20(骨綿)[攻撃:119, 物防:0, 魔防:0, HP:0, MP:104, 腕力:0, 器用:0, 素早:0, 魔力:1859, EL:火0地0水2]<コスト:火491地3150水0>"
172
- ```
173
- のような文字列を返します.
174
-
175
- ### `Mgmg::Equip#weight, star`
176
- それぞれ重量,☆数を整数値で返します.「複数装備」の場合,`weight`は総重量,`star`は装備数に関する値が返ります.
177
-
178
- ### `Mgmg::Equip#total_cost`
179
- 製作に必要な総エレメント量を,火,地,水の順のベクトルとして返します.ケージの十分性の確認には,下記の`comp_cost`を用います.
180
- ver2.00β12以降では,合成時の消費エレメントが,武器なら火,防具なら水エレメントと半々の消費に変更されていますが,現在,この変更には対応していません.
181
-
182
- ### `Mgmg::Equip#attack, phydef, magdef, hp, mp, str, dex, speed, magic, fire, earth, water`
183
- それぞれ
184
- ```
185
- 攻撃,物防,魔防,HP,MP,腕力,器用,素早さ,魔力,火EL,地EL,水EL
186
- ```
187
- の値を`Integer`で返します.
188
-
189
- ### `Mgmg::Equip#power`
190
- 武器種別ごとに適した威力計算値の4倍の値を返します.具体的には以下の値です.
191
-
192
- |武器種別|威力計算値の4倍|
193
- |:-|:-|
194
- |短剣,双短剣|攻撃x4+腕力x2+器用x2|
195
- |剣,斧|攻撃x4+腕力x4|
196
- |弓|max(器用x4+攻撃x2+腕力x2, 魔力x4+器用x2+攻撃+腕力)|
197
- |弩|器用x4+攻撃x2+腕力x2|
198
- |杖,本|max(魔力x8,攻撃x4+腕力x4)|
199
-
200
- 弓,杖,本では`self`の性能から用途を判別し,高威力となるものの値を返します.防具に対してこのメソッドを呼び出すと,9パラメータのうち最も高い値を返します.
201
-
202
- 防具の場合,9パラメータのうち,最大のものの2倍の値を返します.ただし,最大の値に魔防が含まれている場合,代わりに「魔防x2+魔力」を返します.
203
-
204
- 複数装備の場合,9パラメータの合計値の4倍を返します.ただし,HPとMPは4倍にしません.HPとMPの特例は,消費エレメント量の計算と同様とするものです.
205
-
206
- いずれの場合も,EL値,重量,☆は無視されます.
207
-
208
- ### `Mgmg::Equip#fpower`
209
- 武器または複数装備の場合,`Mgmg::Equip#power.fdiv(4)`を返します.防具の場合,`Mgmg::Equip#power.fdiv(2)`を返します.
210
-
211
- ### `Mgmg::Equip#atkstr, atk_sd, dex_as, mag_das`
212
- それぞれ
213
- ```
214
- 攻撃+腕力,攻撃x2+腕力+器用,器用x2+攻撃+腕力,魔力x4+器用x2+攻撃+腕力
215
- ```
216
- の値を返します.これらはそれぞれ
217
- ```
218
- (剣,斧,杖,本),(短剣,双短剣),(弓,弩),(バスターアロー)
219
- ```
220
- の威力の定数倍の値です.トリックプレーやディバイドには対応していません.
221
-
222
- ### `Mgmg::Equip#magmag`
223
- 「魔防x2+魔力」の値を返します.魔力の半分が魔防に加算されることから,実際の魔防性能に比例した値となります.
224
-
225
- ### `Mgmg::Equip#comp_cost(outsourcing=false)`
226
- `self`が合成によって作られたものだとした場合の消費地エレメント量を返します.地ケージ確保のための確認用途が多いと思うので短い`cost`をエイリアスとしています.`outsourcing`が真の場合,街の道具製作屋に頼んだ場合のコストを返します.
227
- ver2.00β12以降では武器なら火,防具なら水エレメントと半々の消費に変更されていますが,現在,この変更には対応していません.
228
-
229
- ### `Mgmg::Equip#smith_cost(outsourcing=false)`
230
- `self`が鍛冶・防具製作によって作られたものだったものだとした場合の消費火・水エレメント量を返します.`outscourcing`が真の場合,街の鍛冶屋・防具製作屋に頼んだ場合のコストを返します.
231
-
232
- ### `Mgmg::Equip#+(other)`
233
- `self`と`other`を装備した「複数装備」の`Mgmg::Equip`を返します.`self`と`other`はいずれも単品でも「複数装備」でも構いません.武器複数などの装備可否チェックはされません.
234
-
235
- ### `Mgmg::Equip#history`
236
- 多段階の合成におけるすべての中間生成物からなる配列を返します.
237
- 「複数装備」の場合,各装備の`history`を連結した配列を返します.
238
-
239
- ### `Mgmg::Equip#min_levels`
240
- レシピ中の,鍛冶・防具製作物の文字列をキー,重量1で生成するのに必要な最小レベルを値とした`Hash`を返します.
241
- 「複数装備」の場合,各装備の`min_levels`をマージした`Hash`を返します.
242
-
243
- ### `Mgmg::Equip#min_level`
244
- `min_levels`の値の最大値を返します.「複数装備」の場合,`[鍛冶の必要レベル,防具製作の必要レベル]`を返します.
245
-
246
- ### `Mgmg::TPolynomial`
247
- 前述の`String#poly`によって生成される二変数多項式のクラスです.最初のTはtwo-variableのTです.以下のようなメソッドが定義されています.
248
-
249
- ### `Mgmg::TPolynomial#to_s(fmt=nil)`
250
- 鍛冶・防具製作LvをS,道具製作LvをCとして,`self`を表す数式文字列を返します.係数`coeff`を文字列に変換する際,`fmt`の値に応じて次の方法を用います.
251
-
252
- |`fmt`のクラス|変換法|
253
- |:-|:-|
254
- |`NilClass`|`coeff.to_s`|
255
- |`String`|`fmt % [coeff]`|
256
- |`Symbol`|`coeff.__send__(fmt)`|
257
- |`Proc`|`fmt.call(coeff)`|
258
-
259
- 通常,係数は`Rational`であるため,`'%.2e'`などを指定するのがオススメです.
260
-
261
- ### `Mgmg::TPolynomial#inspect(fmt=->(r){"Rational(#{r.numerator}, #{r.denominator})"})`
262
- `Mgmg::TPolynomial#to_s`と同様ですが,鍛冶・防具製作Lvを`s`,道具製作Lvを`c`としたRubyの式として解釈可能な文字列を返します.つまり,係数をリテラル,掛け算を`*`で表現しています.`fmt`は`Mgmg::TPolynomial#to_s`と同様で,適当な値を指定することでRuby以外の言語でも解釈可能になります.例えば,精度が問題でないならば,`'%e'`とすると,大抵の言語で解釈可能な文字列を生成できます.
263
-
264
- ### `Mgmg::TPolynomial#leading(fmt=nil)`
265
- 最高次係数を返します.`fmt`が`nil`なら数値(`Rational`)をそのまま,それ以外なら`Mgmg::TPolynomial#to_s`と同様の方式で文字列に変換して返します.ただし,レシピの段数に応じた最高次数を返すため,レシピ次第では本メソッドの返り値が`0`となり,それより低い次数の項が最高次となることもあり得ます.そのようなケースでの真の最高次の探索はしません.
266
-
267
- ### `Mgmg::TPolynomial#[](i, j)`
268
- 鍛冶・防具製作Lvをs,道具製作Lvをcとして,s<sup>i</sup>c<sup>j</sup> の係数を返します.負の値を指定すると,最高次から降順に数えた次数の項の係数を返します.例えば`i, j = -1, -1`なら,最高次の係数となります.引数が正で範囲外なら`0`を返し,負で範囲外なら`IndexError`を上げます.
269
-
270
- ### `Mgmg::TPolynomial#evaluate(smith, comp=smith)`
271
- 鍛冶・防具製作Lvを`smith`,道具製作Lvを`comp`として値を計算します.丸めを無視しているため,実際の合成結果以上の値が返ります.
272
-
273
- ### `Mgmg::TPolynomial#smith_fix(smith, fmt=nil)`
274
- 鍛冶・防具製作Lvを`smith`で固定し,道具製作Lvのみを変数とする多項式として,`to_s(fmt)`したような文字列を返します.
275
-
276
- ### `Mgmg::TPolynomial#scalar(value)`
277
- 多項式として`value`倍した式を返します.
278
- alias として`*`があるほか`scalar(1.quo(value))`として`quo`,`/`,`scalar(1)`として`+@`,`scalar(-1)`として`-@`が定義されています.
279
-
280
- ### `Mgmg::TPolynomial#+(other)`, `Mgmg::TPolynomial#-(other)`
281
- 多項式として`self+other`または`self-other`を計算し,結果を返します.
282
- `other`は`Mgmg::TPolynomial`であることが想定されており,スカラー値は使えません.
283
-
284
- ### `Mgmg::TPolynomial#partial_derivative(variable)`
285
- 多項式として偏微分し,その微分係数を返します.
286
- `variable`はどの変数で偏微分するかを指定するもので,`"s"`なら鍛冶・防具製作Lv,`"c"`なら道具製作Lvで偏微分します.
287
-
288
- ### `Mgmg::TPolynomial#eff(smith, comp=smith)`
289
- 製作Lv(`smith`, `comp`)における鍛冶・防具製作Lv効率と道具製作Lv効率からなる配列を返します.
290
- 一方のみが欲しい場合,`Mgmg::TPolynomial#smith_eff(smith, comp=smith)`,`Mgmg::TPolynomial#smith_eff(smith, comp=smith)`が使えます.
291
-
292
111
  ## 謝辞
293
112
  面白いゲームを作ってくださった耕様および,高精度なシミュレータを作製し,本ライブラリの作製を可能とした,Excel版装備計算機の作者様に感謝いたします.
294
113
 
data/lib/mgmg/const.rb CHANGED
@@ -20,7 +20,8 @@ module Mgmg
20
20
  '兜': 8, '額当て': 9, '帽子': 10, 'フード': 11, '重鎧': 12, '軽鎧': 13, '服': 14, '法衣': 15,
21
21
  '盾': 16, '小手': 17, '手袋': 18, '腕輪': 19, 'すね当て': 20, 'ブーツ': 21, '靴': 22, 'サンダル': 23,
22
22
  'ブローチ': 24, '指輪': 25, '首飾り': 26, '耳飾り': 27,
23
- '額': 9, '帽': 10, 'フ': 11, '重': 12, '軽': 13, 'ローブ':15, '法':15, 'ロ': 15, '小': 17, 'グ': 18, 'グローブ': 18, '腕': 19,
23
+ '額': 9, '帽': 10, 'フ': 11, '重': 12, '軽': 13, 'ローブ':15, '法':15, 'ロ': 15,
24
+ '小': 17, '袋': 18, 'グ': 18, 'グローブ': 18, '腕': 19,
24
25
  '脛当て': 20, '脛': 20, 'す': 20, 'サ': 23, '指': 25, '耳': 26, '首': 27
25
26
  }
26
27
  EquipName = [
data/lib/mgmg/equip.rb CHANGED
@@ -9,7 +9,7 @@ module Mgmg
9
9
  @total_cost = Vec[0, 0, 0]
10
10
  @history, @min_levels = [self], Hash.new
11
11
  end
12
- attr_accessor :kind, :weight, :star, :main, :sub, :para, :element, :total_cost, :history, :min_levels
12
+ attr_accessor :kind, :weight, :star, :main, :sub, :para, :element, :total_cost, :history
13
13
  def initialize_copy(other)
14
14
  @kind = other.kind
15
15
  @weight = other.weight
@@ -52,10 +52,19 @@ module Mgmg
52
52
  end
53
53
  end
54
54
 
55
- def min_level
55
+ def min_levels(w=1)
56
+ if w == 1
57
+ @min_levels
58
+ else
59
+ @min_levels.map do |key, value|
60
+ [key, key.min_level(w)]
61
+ end.to_h
62
+ end
63
+ end
64
+ def min_level(w=1)
56
65
  if @kind == 28
57
66
  ret = [0, 0]
58
- @min_levels.each do |str, ml|
67
+ min_levels(w).each do |str, ml|
59
68
  if str.build(-1).kind < 8
60
69
  if ret[0] < ml
61
70
  ret[0] = ml
@@ -68,10 +77,14 @@ module Mgmg
68
77
  end
69
78
  ret
70
79
  else
71
- @min_levels.values.append(0).max
80
+ min_levels(w).values.append(0).max
72
81
  end
73
82
  end
74
83
 
84
+ def para_call(para)
85
+ method(para).call
86
+ end
87
+
75
88
  %i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |s, i|
76
89
  define_method(s){ @para[i] }
77
90
  end
@@ -79,13 +92,16 @@ module Mgmg
79
92
  attack()+str()
80
93
  end
81
94
  def atk_sd
82
- attack()*2+str()+dex()
95
+ attack()+str().quo(2)+dex().quo(2)
83
96
  end
84
97
  def dex_as
85
- attack()+str()+dex()*2
98
+ attack().quo(2)+str().quo(2)+dex()
86
99
  end
87
100
  def mag_das
88
- magic()*4+dex_as()
101
+ magic()+dex_as().quo(2)
102
+ end
103
+ def magic2
104
+ magic()*2
89
105
  end
90
106
  [:fire, :earth, :water].each.with_index do |s, i|
91
107
  define_method(s){ @element[i] }
@@ -94,35 +110,34 @@ module Mgmg
94
110
  def power
95
111
  case @kind
96
112
  when 0, 1
97
- atk_sd()*2
113
+ atk_sd()
98
114
  when 2, 3
99
- atkstr()*4
115
+ atkstr()
100
116
  when 4
101
- [dex_as()*2, mag_das()].max
117
+ [dex_as(), mag_das()].max
102
118
  when 5
103
- dex_as()*2
119
+ dex_as()
104
120
  when 6, 7
105
- [magic()*8, atkstr()*4].max
121
+ [magic()*2, atkstr()].max
106
122
  when 28
107
- (@para.sum*4)-((hp()+mp())*3)
123
+ @para.sum-((hp()+mp())*3.quo(4))
108
124
  else
109
125
  ret = @para.max
110
126
  if ret == magdef()
111
- ret*2+magic()
127
+ ret+magic().quo(2)
112
128
  else
113
- ret*2
129
+ ret
114
130
  end
115
131
  end
116
132
  end
117
133
  def magmag
118
- magdef()*2+magic()
134
+ magdef()+magic().quo(2)
119
135
  end
120
136
  def fpower
121
- if @kind < 8 || @kind == 28
122
- power().fdiv(4)
123
- else
124
- power().fdiv(2)
125
- end
137
+ power().to_f
138
+ end
139
+ def pmdef
140
+ [phydef(), magmag()].min
126
141
  end
127
142
 
128
143
  def smith_cost(outsourcing=false)
@@ -142,9 +157,9 @@ module Mgmg
142
157
  end
143
158
  def comp_cost(outsourcing=false)
144
159
  if outsourcing
145
- [(@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max
160
+ [(@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max.div(2)
146
161
  else
147
- [((@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max
162
+ [((@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max.div(2)
148
163
  end
149
164
  end
150
165
  alias :cost :comp_cost
@@ -167,8 +182,7 @@ module Mgmg
167
182
  end
168
183
  end
169
184
  @weight += other.weight
170
- @main = 12
171
- @sub = 12
185
+ @main, @sub = 12, 12
172
186
  @para.add!(other.para)
173
187
  @element.add!(other.element)
174
188
  @total_cost.add!(other.total_cost)
@@ -253,7 +267,9 @@ module Mgmg
253
267
 
254
268
  ret = new(main_k, main.weight+sub.weight, main_s+sub_s, main_sub, sub_main, para, ele)
255
269
  ret.total_cost.add!(main.total_cost).add!(sub.total_cost)
256
- ret.total_cost[1] += ret.comp_cost(outsourcing)
270
+ cc = ret.comp_cost(outsourcing)
271
+ ret.total_cost[1] += cc
272
+ ret.total_cost[main_k < 8 ? 0 : 2] += cc
257
273
  ret.min_levels.merge!(main.min_levels, sub.min_levels)
258
274
  ret.history = [*main.history, *sub.history, ret]
259
275
  ret
@@ -268,8 +284,8 @@ module Mgmg
268
284
  unless kind
269
285
  raise InvalidEquipClassError.new(m[1])
270
286
  end
271
- main_m, main_s, main_mc = parse_material(m[2])
272
- sub_m, sub_s, sub_mc = parse_material(m[3])
287
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
288
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
273
289
  para = Vec.new(9, 0)
274
290
  ele = Vec.new(3, 0)
275
291
 
@@ -288,11 +304,7 @@ module Mgmg
288
304
  weight = ( ( EquipWeight[kind] + SubWeight[sub_m] - level.div(2) ) * ( MainWeight[main_m] ) ).div(10000)
289
305
 
290
306
  ret = new(kind, ( weight<1 ? 1 : weight ), (main_s+sub_s).div(2), main_mc, sub_mc, para, ele)
291
- if kind < 8
292
- ret.total_cost[0] = ret.smith_cost(outsourcing)
293
- else
294
- ret.total_cost[2] = ret.smith_cost(outsourcing)
295
- end
307
+ ret.total_cost[kind < 8 ? 0 : 2] += ret.smith_cost(outsourcing)
296
308
  ret.min_levels.store(str, str.min_level)
297
309
  ret
298
310
  end
@@ -303,23 +315,14 @@ module Mgmg
303
315
  raise InvalidSmithError.new(str)
304
316
  end
305
317
  kind = EquipIndex[m[1].to_sym]
306
- main_m, main_s, = parse_material(m[2])
307
- sub_m, sub_s, = parse_material(m[3])
318
+ main_m, main_s, = Mgmg.parse_material(m[2])
319
+ sub_m, sub_s, = Mgmg.parse_material(m[3])
308
320
 
309
321
  q, r = ((weight+1)*10000).divmod(MainWeight[main_m])
310
322
  l = ( EquipWeight[kind] + SubWeight[sub_m] - q + ( r==0 ? 1 : 0 ) )*2
311
323
  [(main_s-1)*3, (sub_s-1)*3, l].max
312
324
  end
313
325
 
314
- private def parse_material(str)
315
- m = /\A.+?(\d+)\Z/.match(str)
316
- mat = MaterialIndex[str.to_sym]
317
- if m.nil? || mat.nil?
318
- raise InvalidMaterialError.new(str)
319
- end
320
- [mat, m[1].to_i, mat<90 ? mat.div(10): 9]
321
- end
322
-
323
326
  def min_comp(str, left_associative: true)
324
327
  str = Mgmg.check_string(str)
325
328
  stack, str = minc_sub0([], str)
@@ -384,8 +387,8 @@ module Mgmg
384
387
  unless kind
385
388
  raise InvalidEquipClassError.new(m[1])
386
389
  end
387
- main_m, main_s, main_mc = parse_material(m[2])
388
- sub_m, sub_s, sub_mc = parse_material(m[3])
390
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
391
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
389
392
  [main_s, sub_s].max
390
393
  end
391
394
  end