Python3で引っかかるところ~print関数~
リスト内包表記の中にprint書けたりするの気持ち悪すぎでしょ。
純粋関数型言語でない以上、戻り値なしで副作用しかない関数も通常の関数として扱えるわけで、
その意味でprintを文としておくのは一貫性がないということで関数にしたんだろうけど。
>>>p = [print(n) for n in range(5)] 0 1 2 3 4 >>>p [None, None, None, None, None] >>>print(p) [None, None, None, None, None] >>>print( [print(n) for n in range(5)] ) 0 1 2 3 4 [None, None, None, None, None]
p = [print(n) for n in range(5)] なのに、
- print(p) と
- print( [print(n) for n in range(5)] )
で挙動違うの気持ち悪すぎ。
何で?
<追記>
記事を投稿してから冷静に考え直してみれば、挙動違うの当たり前だった。
リスト内包表記の中にprint書けるのは気持ち悪いが・・・
- p = [print(n) for n in range(5)]
- print関数を5回適用して、[None, None, None, None, None]を変数pに代入する
- print(p)
- リストpを表示するだけ
- print( [print(n) for n in range(5)] )
- print関数を5回適用して、[None, None, None, None, None]を表示する
だから何もおかしいところはなかった。
p = [print(n) for n in range(5)] が、実質2つの副作用を持っているのに、1行にまとまっているのがわかりにくかった。
変数pにはただリストが代入されてるだけなんだよね、printの処理は代入されない。
Python3で引っかかるところ~リストとイテレータ~
mapやzipがリストではなくイテレータを返すようになったので、挙動がややこしい。
>>>a = [10, 20, 30] >>>b = [1, 2, 3] >>>z = zip(a, b) >>>list(z) [(10, 1), (20, 2), (30, 3)] >>>list(z) [] >>>list(z) []
zip(a, b)がリストではなくイテレータオブジェクトであり、それにlist関数を適用している。
1回listを適用した時点でイテレータが終了するので、2回目以降listを適用しても戻り値は空。
>>>a = [10, 20, 30] >>>b = [1, 2, 3] >>>list(zip(a, b)) [(10, 1), (20, 2), (30, 3)] >>>list(zip(a, b)) [(10, 1), (20, 2), (30, 3)] >>>list(zip(a, b)) [(10, 1), (20, 2), (30, 3)]
この場合、毎回新しいイテレータオブジェクトzip(a, b)を生成しているので、戻り値は期待通り。
>>>a = [10, 20, 30] >>>b = [1, 2, 3] >>>z = list(zip(a, b)) >>>z [(10, 1), (20, 2), (30, 3)] >>>z [(10, 1), (20, 2), (30, 3)] >>>z [(10, 1), (20, 2), (30, 3)]
この場合、イテレータzip(a, b)をlistに変換したものを変数zに保存しているので、zの値は変わらず、出力は期待通り。
>>>a = range(5) >>>list(a) [0, 1, 2, 3, 4] >>>list(a) [0, 1, 2, 3, 4] >>>list(a) [0, 1, 2, 3, 4]
はぁ?
Python3だとrange関数はリストではなくイテレータを返すはずなので、2回目以降のlist(a)は空になるんじゃないの?
何で?
<追記>
公式リファレンスを見たが、rangeは組み込み関数ではなく組み込み型、クラスだった模様。
それにイテレータオブジェクトというわけではないようだ。と思うしかない。xrangeと統合されてメモリ使用効率がよくなっただけ。
と考えないと↓の挙動との違いが説明できないし。
>>>a = iter([1, 3, 5]) >>>list(a) [1, 3, 5] >>>list(a) [] >>>list(a) []
Python 勉強 ~5桁の数字を漢数字に変換してみる~
つくってみた。5桁なのは、6桁以上だと規則性が変わってむずそうだから。
というか桁数なんて際限がないしとりあえず5桁で。
# 1-99999 の5桁の数字を漢数字に直す def char_number(number): if not 1 <= number <= 99999: return "Error" answer = "" dict_number = { 1:'一', 2:'二', 3:'三', 4:'四', 5:'五', 6:'六', 7:'七', 8:'八', 9:'九', 0:'' } base_stlist = ['万', '千', '百', '十', '一'] number_list = [int(n) for n in str(number)] # 各桁の数字をリストに stlist = [dict_number[i] for i in number_list] # 各桁の数字を漢数字に z = zip(stlist, base_stlist) for index, one_tuple in enumerate(z): st1, st2 = one_tuple if st1 == '': # 0の桁は飛ばす continue if index == 0: answer += st1 + st2 elif 1 <= index <= 3: if st1 == '一': # 一百、一十とは言わない 一千は言うこともあるが、言わなくてもよい answer += st2 else: answer += st1 + st2 else: # 一の位 answer += st1 return answer
単方向連結リストの実装
あー疲れたー。
プログラミング・アルゴリズムの勉強がてら、連結リストを試しに実装してみたが、色々引っかかって数時間があっという間に飛んでいってしまった。
だがまあ、こうやって苦労してこそ理解も深まるというもの。決して無駄ではなかったと思いたい。
- 言語選択の理由は特にないが、やっぱりスクリプト言語は余計な記述をしなくて済むので書くのも読むのも楽
- とはいっても、型の情報くらいは書きたい気もする。動的型付け言語だと突然宣言されていない型も不明な怪しげな変数が出てくるので、読んでたり書いてたりするときにこれなんだよってなることはある気がする
- 色々いわれる例のself, やっぱり(書くのが)面倒くさい。インスタンス変数を弄るときにselfを書くのはともかく、メソッドの第一引数にいちいちselfを書くのは気味が悪い。
- 書き忘れでエラーが出るとムキーとなる
- 書くのは面倒だがその分読みやすいのは確か
- インスタンスを生成するときにnew演算子なりnewメソッドを使わないのが気持ち悪い。明示をよしとする言語でnew演算子がないのには、何か深い理由がありそうだが?
- range関数も正直わかりにくいし好きじゃないなぁ
- 最初addやdelete_lastメソッドは個別に実装していたが、insertやdeleteで流用できることに気づく。if A return B で Aが満たされないならNoneが返るのでこれでよいのだ。
- こうして苦労しながらコードを書いてみると、連結リストがシーケンシャルアクセスであるということが身にしみて理解できる。
- Pythonのイテレータへの理解がまだあやふや。for文で呼び出したら、まず__iter__()を実行して、次にraise StopIteration()されるまで__next__()が実行されて順番に値が取り出される、ってことかな?
class MyList: def __init__(self, value = "Dummy"): self.value = value self.pointer = None self.size = 0 # list[0]="Dummy", list[1]~list[self.size] def getindex_cellobject(self, index): # index番目のセルオブジェクトを返す if index <= self.size: tmp = self for i in range(index): tmp = tmp.pointer return tmp def __getitem__(self, index): # index番目のセルオブジェクトに含まれる値をself[index]でアクセスできるようにする if index <= self.size: return self.getindex_cellobject(index).value def add(self, value): # リスト最後尾に追加 return self.insert(self.size + 1, value) def delete_last(self): # 最後尾を削除 return self.delete(self.size) def insert(self, index, value): # index番目に挿入 if 1 <= index <= self.size + 1: leftcell = self.getindex_cellobject(index - 1) rightcell = leftcell.pointer newcell = MyList(value) leftcell.pointer = newcell newcell.pointer = rightcell self.size += 1 return self def delete(self, index): # index番目を削除 if 1 <= index <= self.size: leftcell = self.getindex_cellobject(index - 1) rightcell = leftcell.pointer.pointer leftcell.pointer = rightcell self.size -= 1 return self def show(self, a, b): # list[a] ~ list[b] if 0 <= a <= b <= self.size: for i in range(a, b + 1): print(self[i]) def showall(self): self.show(0, self.size) def addlist(self, anotherlist): # リストの結合 if anotherlist.size > 0: lastcell = self.getindex_cellobject(self.size) lastcell.pointer = anotherlist.pointer self.size += anotherlist.size def __iter__(self): self.tmp = self return self def __next__(self): if self.tmp == None: raise StopIteration() result = self.tmp.value self.tmp = self.tmp.pointer return result testList = MyList().add("aaa").add("bbb").add("ccc").insert(2, "2").delete_last().delete(1).add("LAST") another = MyList().add(1).add(10).add(100) testList.addlist(another) for value in testList: print(value) # 出力 # Dummy # 2 # bbb # LAST # 1 # 10 # 100
DCSS Fsimの使い方
この記事はRoguelike Advent Calendarの12/11分です。
今回はDCSSのFsim(やそれに関連するwizard mode)の使い方をまとめてみる。
というのは、存在自体知らないとか、あるいは知っていても使い方を知らないという人が意外といるのではないかと推測されるため。
・そもそもFsimって何よ?
Wizard modeで使用できる一機能であるFighting Simulatorの略称。
これを使うことで、今の@のステ・スキルでこの武器をこの敵に使うと大体どれくらいのダメージが期待できるか、という具体的な数値がわかる。非常に便利な機能である。
よく、@の溜まり場や海外の公式Forumで、今のこのスキルではどの武器を選ぶのがいいのかわからない、と初心者が質問しているが、
そんなことわざわざ人に聞かなくてもFsimかければわかるよっていうのが今回の記事の主旨。
それでは、実際にFsimを使ってみよう。以下で手順を詳述する。
・まずはゲームのダウンロードから
そこからかよ、って突っ込みが入りそうだが、これは一部のプレイヤーにとってとても大切なステップ。
というのは、DCSSはWebtileでもプレイできるのだが、WebtileではWizard modeが使えない。
なので、Webtile playerがFsimを使おうとしたら、まずゲームをダウンロードするというステップを踏む必要があるのだ。
ゲーム本体のダウンロードはこちらから → http://crawl.develz.org/trunk/
trunk(unstable)0.20のダウンロードができる。ここのWindows Tiles Buildでとりあえず話を進める。
・ゲーム起動、キャラ作成、Wizardモードに入る
&と入力することで、Wizardモードに入ることができる。
その際、Wizard modeに入ることでスコア対象外になるというご丁寧な警告文が出てくる。yesと入力してWizard modeに入りましょう。
ちなみに、Wizard modeに入ると、画面右上に *WIZARD* とご丁寧に表示される。
・Wizard modeのコマンドを実行する
&でWizar modeに入れると上で書いたが、実は&はWizard modeのコマンドを実行するときに最初に打つキーである。
Fsimを回す前に、まずは色々設定する必要があるので、適宜コマンドを入力してステータスやスキルなどを設定していく。
よく使う代表的なコマンドを挙げる。
&@:ステータスを設定する。@ 20 15 18と入力すれば、Str20 Int15 Dex18に設定される
&l:レベルを設定する。最初に何レベルにしたいか聞かれ、その後レベルアップに伴ってスキルを鍛えたいか聞かれる(yかnで返事)
&s:スキルを設定する。最初にどのスキルの値を変えるか聞かれ、その後変更後のスキルの値を聞かれる
&o:指定のアイテムを入手できる。まず最初に種類を問われる。対応する記号を入力すると、今度は具体的な名前を問われ、最後にもし必要であればエゴ名を入力する。
たとえば、battleaxe of freezingを入手したいなら、&o -> ) -> battleaxe -> freezingと入力すればいい。
その後、修正値を+9まで強化したいなら、&o -> ? -> enchant weapon と入力すればenchant weapon巻が12枚手に入る。
&r:種族を変更する
&p:別の形態に変異する(Dragon FormやStatue Formのように変異術魔法として変異できるものに限らず、fungsとかpigとかにも変異できる)
他にもコマンドはあるが、Fsim回す程度ならこのくらいのコマンドを知っておけば十分事足りる。
・Fsimを実際に使ってみる
レベル、ステータス、スキル、武器防具の設定を上記のコマンドで終えれば、いよいよFsimだ。
Fsimを回すには、&fと入力する。入力すると、どの敵に対してFsimを回すか問われるので、適当に敵の名前を入力する。
筆者はStone giantで試すのが好きなので、とりあえずStone giantで試してみる。
すると、ログにFsimの結果が表示される。
上のAttakingが、@からStone giantに対する物理攻撃の算出値。
下のDefendingが、Stone giantから@に対する物理攻撃の算出値。
各値の意味は、大体名前を見ればわかると思うが、
AvHitDamが、物理攻撃が命中したときの期待ダメージ
MaxDamが、最大ダメージ
Accuracyが、命中率
AvDamが、AvHitDam * Accuracy によって算出される値で、命中率を考慮した期待ダメージ
AvTimeが、1回の物理攻撃にかかるターン数(の100倍の値)を示しており、
AvSpeedは、1ターンに何回物理攻撃ができるかの数を示している(AvTime * AvSpeed = 100である)。
そして、一番右のAvEffDamという値が、最終的な1ターンにおける期待ダメージを示している。
今回は、&fコマンドでのFsimを試したが、
これは要するに@のスキルを現在値に固定したときにどのくらいのダメージが期待できるかを示したものに過ぎない。
スキルを変動させながら期待ダメージの変化を眺めたいときは、&Fコマンドを利用する。
&Fを入力すると、AttackとDefenseどちらの値が欲しいか問われるので、欲しい値を選択する。今回はAttackを選んでおく。
選ぶと、少々時間がかかるのだが、ログにスキルの変動(今回の例であれば斧スキル)を考慮したFsim結果が表示される。
ちなみに、これと同じ結果が、DCSSのcrawl.exeが入っているフォルダに、fsim.txtに出力されるようになっている。
複数回Fsimをかければ、その結果は既存のfsim.txtに追記されるので、Fsimを何回もかけるときに昔のFsim結果を逐一別ファイルに保存する必要はない。便利である。
以上が、基本的なFsimの使い方である。細かい設定・使い方などはまだあるが、いちいち書くときりがないし、とりあえずこの程度の操作ができるだけでも新たに見えてくるものはあるので、Fsimの使い方解説はここまでとしておく。
明日のカレンダーの記事は、dplusplus氏の「DCSS client luaを触る」です。
皆さん是非是非ご参加くださいな。
東方変愚 混沌の領域(オベロン後の127Fまで)雑感&騎兵雑感
<100~127F雑感>
東方変愚、ラスボスは一応オベロンなのだが、真・勝利するためには127Fにいる混沌のサーペント(以下Jと略記)を倒す必要がある。
東方変愚のJは、本家より大幅に強化されており、殴り合いで勝とうとするとかなりの確率で事故ってしまうことで非常に有名である。
どこが強いのか?
・殴り火力
大体本家の二倍くらいあるといわれている。
本家の殴りスペックは以下:
22d10 のダメージで体当たりして粉砕し、 22d10 のダメージで体当たりして粉
砕し、 10d12 のダメージで噛んで全ステータスを減少させ、触って充填魔力を
吸収する。
それに対して、東方変愚での殴りスペックは次の通り:
22d15 のダメージで体当たりして粉砕し、 22d15 のダメージで体当たりしてカオスで攻撃し、 15d15 のダメージで噛んで全ステータスを減少させ、 10d10 のダメージで飲み込んで魔力を吸い取る。
軒並みダイス目は増えるわ、AC軽減できない殴りが増えるわ、と凶悪すぎる。
・ヘル・ファイア
東方変愚には耐性で軽減不可能な地獄の業火属性という属性が存在する。
Powerfulフラグ持ちの敵によるヘル・ファイアのダメージは、
Lv * 4 + 100 + 10d10
である。JのLvは127なので、なんと618~708ものダメージをくらってしまう。
この数字がとんでもない値であることは、本家変愚をプレイしたことがある人なら一目で理解してくれるはずだ。
本家変愚であれば、HP800が安全ラインとされ、この数値を維持していれば即死に至ることは滅多にありえない。
一方、東方変愚では、この馬鹿げたダメージ数値を見ればわかる通り、ヘル・ファイア絡みで連続行動されたらかなりの高確率で死んでしまう。
HP1300程度を維持できれば、まあそうそう死なないだろうが、そんな状況は特殊な手段を使わない限り到底不可能である。
・波動砲
本家Jのクソ行動といえばなんといっても分解ブレス。近接戦なら、分解ブレスを吐かれ、予め整地した地形を崩されたら、戦場を変えるしかない。
東方変愚のJは、恐ろしいことにこの分解ブレスが超強化された波動砲を使ってくる。
分解ブレスのダメージはMAX150だが、波動砲はMAX555ダメージ。こんなトンデモダメージに壁分解効果がついているなんて、ひど過ぎて接近戦なんてたまったもんじゃない。
・他取り巻き
勝手版独特の要素として視界外隣接テレポートというものがあり、これを使ってくる深層ユニークが存在する。
ユニークだけならまだいいが、非ユニークまで使ってくるので……。
たとえばレッサー・アザー・ゴッドの群れがJ戦で現れるようなら阿鼻叫喚である。
その確率を少しでも下げるために、アザトートを120Fで狩っておく(アザトートの護衛として大量にレッサー・アザー・ゴッドが生成されることが多い)のが定石なのだが、このアザトートも曲者。何が強いって、大量に生成され視界外隣接テレポートを決めてくるレッサー・アザー・ゴッドもさることながら、アザトート本体の因果混乱ブレスも脅威の一言である(時空耐性がなければMAXで600もくらってしまう)。
また、127Fには必ずモルゴスと秩序のユニコーンが生成され、こいつらがJ戦に乱入してくる。モルゴスは*破壊*しても即座に復活、秩序のユニコーンは若干のタイムラグの後に復活。クッソだるい。
以上のような理由で、東方変愚のJは本家より大幅に強化されているのである。
遠距離戦なら本家とさほど難易度は変わらないのだが、近接戦なんてたまったもんじゃない。やられる前にやるくらいの高火力がなければ、ヘル・ファイア絡みの連続行動を引いて成仏である。
<騎兵雑感>
本家の騎兵は未プレイなので、本家との比較はし辛いのであるが、勝手版でも騎兵は強いしむしろ強化されているまでありうる。
弓と殴りを両立させるのが難しくなっているのは確かに弱体化ポイントなのだが、むしろ両手持ちが強くなっているので、本家以上の打点を出せる。
というか本家の騎兵って両手持ちしてもちゃんと馬操れたっけ?(勝手版では最終的には可能になる)
あと、本家では最終的な馬は変幻の魔公が一般的だったが、東方変愚では時空ワイアームが強い。本家から大幅に強化されており、酸耐性抜けという弱点はあるものの、HP8500という高耐久に加え、耐性なしの敵を階層からいなかったことにできる因果混乱ブレスが凶悪すぎる。
あと騎兵は射撃が得意で、両手に追加射撃をはめる余裕があるので、遠距離戦でJを戦い抜ける。実際、真・勝利間近まで達した。
うっかり箱開けて召喚即死したけどな!
後で知ったのだが、箱も含め召喚トラップを発動させてしまったときは、召喚された敵からターンが始まる。なので、大広間でうっかり召喚箱を開けてしまうと、このようにターンが@に回ってくる前に即死してしまうのだ……。
なぜ私はFire Stormを使いたがらないのか
挑発的なタイトルで、少しDCSSの妖術師ビルドについて考察してみる。
<定義>
便宜上、最終的に妖術スキルを20以上に上げて、かつLv9の破壊的魔術を習得し、破壊的魔術を主体に戦うビルドを妖術師ビルドと呼称しておく。
典型例でいうと、DECjみたいなビルドがイメージされる(もちろん、このスタートからでも妖術主体で戦わなくてもよいが、あくまで一般的には妖術をメインに戦うであろう)。
あと、ここで「破壊的魔術」といっているのは、TornadoやShatter、Lee's Rapid Deconstructionのように、妖術領域には含まれないものの攻撃魔法であるのは確かであり、Vehumetによる成功率補正がかけられるもののことを指している。
<炎? 氷? 地? 風?>
妖術師ビルドをやるときに決めないといけないのは、最終的には何を目指すかというルートである。これはプレイの前に決めるかもしれないし、プレイしている最中に引きを見ながら決めるかもしれない。
別に高レベル破壊的魔術などなくともルーンコンプは余裕だが、そんなことを言っているとこの記事を書く意味がなくなってしまうので、とりあえず高レベルの破壊的魔術を主体に戦うことを前提に話を進める。
・炎の高レベル魔法
Fire Storm(Conj/Fire Lv9)
・氷の高レベル魔法
Glaciate(Conj/Ice Lv9)
・地の高レベル魔法
Shatter(Earth Lv9)
Lehudib's Crystal Spear(Conj/Earth Lv8) 以下長いのでLCSと略記
・風の高レベル魔法
Tornado(Air Lv9)
Chain Lightning(Conj/Air Lv8)
Lv8以上を高レベルとするなら、こんなところだ。妖術師ビルドにおいて、どれを最初に取得するLv9スペルとするのか、どれを主体に戦うのか。
(もちろんプレイ中に引けない魔法は使えないので、引いているものから選ぶしかない。全部引いている前提でどれにするかを考えたい)
<最も一般的なルートは>
強力な範囲攻撃である炎ないし氷の最終攻撃魔法を取得し、それを主軸に戦いながら、何らかの無属性攻撃も確保する、というのが最も一般的な妖術師の有り様である。
<例>
例えば、「炎術師、地魔法使える」(Fire Stormによる範囲攻撃+LCSによる単体無属性攻撃+おまけでShatter)みたいなやつ。この「炎術師、地魔法あり」タイプは、自分の知る限り、昔のDCSS(ver0.13以下)では最もスタンダードなタイプの妖術師であった。範囲攻撃+無属性という意味では、「氷術師、他に何か使える」でもよさそうに見えるが、自分の知る限り、昔のDCSSではそのタイプは非常に珍しかった。
なぜかというと、昔の氷魔法の最終奥義は、Glaciateではなく、Ice Stormだったから。このIce Storm、非常に使い勝手が悪いスペルであった。そのため、ver0.14において、Glaciateにbuffされたという経緯がある。
<Ice Stormの使い勝手>
どこが使い勝手が悪かったかというと、攻撃範囲である。Fire Stormがスマイトターゲット型で、比較的お手軽に思ったところに撃ちやすい魔法なのに対して、Ice Stormはそうではなく、たとえるならFireballのような攻撃範囲の魔法だった。
視界の端まで通るわけもなく、かといって中距離の殺したい敵まで射線が通っている保障もなく、近距離の敵相手には自爆の恐れがある。耐性貫通率が高いというメリットはあるにせよ、攻撃範囲という意味での使い勝手が悪く、Fire Stormとの相対比較では非常に不人気だったのである(しかもFire Stormは、おまけでfire vortexを発生させ、敵の射線を切ることができた。@の射線も切れるが、Fire Stormはスマイトターゲットで攻撃できる魔法なのでただただ@に有利)。
<Glaciateの使い勝手>
一方で進化したIce StormことGlaciateであるが、これはIce Stormの攻撃範囲が大幅に改善されている。@を中心に、中距離までの広範囲な部分をターゲットとしているため、殺したい敵には大体当てることができる。視界の端までは通らないが、中距離までの攻撃範囲の広さはFire Stormを軽く凌ぐ広さであり(ただし、@から遠い攻撃範囲への威力は、@から近い攻撃範囲と比べて減衰処理がかかっている)、しかも自爆の心配もない。これで耐性貫通率も高いのだからもはや万能無敵の強さといっていいだろう……と個人的には思っているのだが、海外勢的にはFire Stormと比べるとそこまで評価は高くないようである。スマイトターゲット+視界外攻撃可能+おまけのvortexの評価がやはり高いようだ。
<Fire Storm vs Glaciate、結局どっち?>
領域の総合評価としての火 vs 氷ではなく、あくまでFire StormとGlaciate単体で見たときの比較であるが、個人的には攻撃範囲・耐性貫通率ともに満足のいくGlaciateを強く推しておく。
Fire Storm、スマイトターゲットやら視界外攻撃可能やらで強いのは間違いないのだが、耐性もち相手や近距離戦闘で非常に使い勝手が悪い。
・耐性もち相手
OoFの群れなど最悪である。Hell Sentinelの群れも辛い(おまけのvortex発生の利点を考えてもMP効率が悪い)。
curse toe相手にFire Storm連打で殺しきれずに混乱でハメころされてからは、Fire Stormの耐性貫通率45%は低すぎるとしか思わなくなっている。
・近距離戦闘
旧Ice Stormではないが、近距離戦闘では自爆の恐れがある。特に最近Square LOSが導入された関係で、以前に存在した「近距離の敵を自爆せずに叩けるターゲットポイント」が失われたらしい(原理は正直よくわからない)。
そもそも術師で近距離戦闘をするなといわれても、Vaults:5やらHellの敵湧きなど、正直ある程度の近距離戦闘は避けられない。
Fire Stormのこれら2つの欠点を解消するポイントはただ一つ、Fire Storm以外のスペルを取ることである。
LCSかIron Shotを取得し(OoDは近距離戦闘が不得手なので解答になりづらい)、近距離の群れ対策としてBolt of Fireも残しておく。あるいはいっそTornado取得に走る。
これくらいが対策だろう。実際、ver0.13までの火メイジはそのように対処していただろう。
炎術師が欠点を解消するのに、炎以外の魔法に解答を求める一方、氷術師はどうするか。
簡単である。
Glaciate! Glaciate! Glaciate! Glaciate! Glaciate!...
これでおしまい。耐性貫通率が高いから無属性攻撃など正直必要ではない。近距離戦闘も余裕なので他の魔法も正直要らない、もちろんあった方が楽ではあるけど。
視界の端まで届かないのはもちろん欠点だけれど、正直それで困る場面の数は、炎術師が近距離戦闘で辛い目をする場面よりは少ない(自分の経験上は)。
なんならDarknessで視界を狭めておけば、視界の端までGlaciateが届くようになるので、これがほぼ完全な解答になっている。
っつうわけで、Glaciateは非常にお手軽で楽ちん。最終的にはGlaciate以外要らないから。まさにゆとりスペル、術師初心者にオススメできる。
<余談>
・・・といいつつ、DEでGlaciate主体のビルドとかやると、結局趣味でShatter取ったりするんですけどね。Iron Shotはほぼ確実に取るし、趣味でLCSを取ることもある。
http://lazy-life.ddo.jp:8080/morgue/radinms/morgue-radinms-20160903-054840.txt
http://lazy-life.ddo.jp:8080/morgue/radinms/morgue-radinms-20150713-043914.txt
だったらFire Stormでもいいじゃん、と言われれば、まあ確かにそうなのかもしれない。
適性的に趣味ShatterやらLCSがきついビルドこそ、Glaciateが輝くのだけれど、まあそういうビルドはGlaciateの安定すらきつくて、Tornadoが一番現実的な解になるというのはなんとも。