Python ネタなら俺の出番だ。
要するにこれは「class の直下で変数宣言をしたい」「でも普通にそれをやるとクラス変数になってしまう」という問題なわけだな。こういう場合にどうするかというと、プロパティを使うのが多分スマートだろう。
class Hoge(object):
def __init__(self):
self.name = 'hoge'
def name():
def get(self):
return self.__name
def set(self, value):
self.__name = value
return get, set
name = property(*name())
プロパティに使われる getter/setter を内部関数として定義し、その関数の名前をプロパティ名と同一にし、シャドーイングでその存在を隠蔽してるのがちょっとしたポイントだけど、これは別にやらなくてもいい事なのでどうでもいい。
プロパティの宣言が多くなるとウザったいかもしれないけど、プロパティの宣言がウザく感じるほど外部仕様としてのアクセサが多いというのは俺の感覚としてはクラスの設計かコーディングスタイルが間違っていると思う。これは Python に限らず、他の言語でも同じ。例えば Java は「getter/setter うぜえ」って話をよく聞くけど、俺に言わせりゃ getter/setter のコードが他の部分のコードを読む上で支障になるような設計あるいはコーディングスタイルという事それ自体が終わってる。
ちなみに俺の方針としては、
というのがバランスのとれたやり方かなと思ってる。
追記:hiratara さんより返信。デコレータを使った書き方は "Changed in version 2.6: The getter, setter, and deleter attributes were added." とある通り、 2.6 以降でしか使えないですね。もしも 2.6 以降を動作環境として想定できるのであれば、そちらの方が高階関数とシャドーイングを使ったやり方よりも、より宣言的でわかりやすくなると思いますね。
あと「シャドーイング」という言葉に関しては、これは本来「上位のスコープで定義されたシンボルの参照先を下位のスコープで切り替える」事を示す言葉で、例えば次のコードのようにフィールドへのアクセスが仮引数へのアクセスで隠されるような状態に対して使う……はずだけど、もしかして一般的な言葉じゃない?
class Foo {
String foo;
void bar(String foo) {
dosomethingToFoo(foo); //←この時の foo へのアクセスは仮引数へのアクセス
//同じ事はローカル変数でも起こる
}
}
それで先に出した property の例は、先に定義した name() 関数へのアクセスを後に定義した name プロパティで隠しているので、本来のシャドーイングとは実は全然違うのだけど、シャドーイングとしてしまった方がわかりやすいかなと。参照先を切り替える/隠すというニュアンスは変わってないと思うし(あーでも混乱の元になるか、こういう書き方は)。
値段ほど美味しくなかった。多分これは二度と買わない。
数日前より毎日ちょっとずつ作ってきた Creole 1.0 とおおよそ互換の Wiki 文法のライブラリが一応完成した。なんかもういろいろ面倒なんで、使い方はぶっちゃけソース読めって感じなんだが、何しろ初めての Haskell ソフトウェアなのでコードのクォリティは凄まじくアレだと思われる。
今の仕事では Mercurial のホスティングサービスである bitbucket を使っており、そいつの Issue Tracker も活用してるんだが、俺はこいつの入力フォームにはちょっと問題があると思う。何が問題かというと、 Issue の種類と担当者のドロップダウンリストがテキストエリアの右側にあるのがダメだ。これは少なくとも、俺が Issue Tracker を使うときのフローを反映していない。
bitbucket の Issue Tracker のインターフェースは、最初に Issue のタイトルと本文を埋めるような設計になっていると思う。少なくとも、文字の流れる向きが左から右の文化圏ならそうなるんじゃないかな。そして本文を書き終わった後に視点がどこにあるかというと、おそらく "Report issue" のボタンだろう(preview まで目を通していると特に)。そうなると "Properties" の項目を設定し忘れるというケースが出てくることが予想される、というか俺は毎回のように忘れて後から直してる(別に実働部隊が俺一人なんだから気にしなくてもいいかもしれないが、あんま悪い習慣を付けたくないのよ)。
なので俺はこういったアプリケーションのインターフェースは縦長の極めてシーケンシャルなものが適してると思うんだけど、実際のところどうなのかな。アンケート取ったり統計を集めたわけじゃないんで、いまいちよくわからん。
これの参加者を twitter で募っていた時の心温まるやりとり
というわけで(どういうわけだ)圏論に興味のある人は思い切って参加したらいいんじゃないかな。宿泊組もそうでない方も、まだまだ参加できますぜ。
俺はこれまでの生活を改める事にした。具体的にどこを改めることにしたかというと、とにかくまず飯を自分で作ることにした。これまでは松屋とか吉野家とかコンビニ弁当が殆どと言うのが二年以上続いており、流石にこれはまずいと思い始めたのだ。そしてちょうど在宅の仕事になって時間的に余裕ができたので、その時間を使って自炊する事にした。
そもそも俺は社会人になりたての頃、朝昼晩と飯(弁当)を作っており、これまでのような終わってる食生活にはなっていなかったのだ。それがいつ崩れたかというと、某泥沼プロジェクトに巻き込まれ、時間的余裕も精神的余裕も削られ、結果としてまったく料理をする気が失せてしまったのだ。そのプロジェクトが終わった後は比較的時間に余裕があったはずだが、かなりの長期にわたって気力が萎え気味だったのは否めず、時間が余ってるといっても一日の殆どをボーッとして過ごすような暇な仕事や最初から終わってるような R&D で別の角度から HP と MP を削られ、半分ぐらい人生を投げているような状態が長く続いていた。
が、そんな憂鬱な日々は先々月の末で終わったので、これからはもうちょっと人間らしい生活を送ることにした。というかだな、まともな生活をしてないと怒られるというかなんというか。
というわけで早速料理をしようと思ったが、サラダ油とかを買い忘れているのに気がついたので、日本人の魂であるところの卵かけご飯にすることにした。あと明日はいろいろ忙しいので、「ちーちゃんのお料理日記」は明後日からの予定。俺のモットーは「ド素人が手間暇かけても旨くならねえ」「火の通ったものを食べてる限り人間は死なない」「調味料は食べながら足すものだから適当にやる」であり、さらに割とマジで「天体戦士サンレッド」のオマケに載ってるレシピを参考にしてたりするので、なんていうかあんまり期待しないでくれ。
今日は大学時代の友人達との飲み会だった(まあ俺は殆ど飲めないんだがな)。実際には俺の転職祝いというかなんというか。どんだけ俺は転職を周囲から望まれていたんだか。それでまあ、集まった面子はいろんな意味で相変わらずで、それは俺も同じだったので、何というか安心した。
今日の昼ご飯(晩ご飯もだけど)は野菜炒め。野菜炒めのいいところは、「具材を切って炒めて適当に味付け」というだけなので、どんなバカでもそこそこ程度なら作れるところだ。使った素材はもやし100g弱、キャベツ1/4弱、にんじん1本弱、ピーマン一個、豚肉を適当に。味付けはごま油と醤油のみで、塩コショウ? 買い忘れたんで今回は使ってない。スープは余った具材をコンソメと一緒にブチ込んで、野菜炒めを作ってる合間に煮込んで作った。決して旨くはないがまずくもないという代物で、スープに関しては余り物の整理の意味合いが強い。
勘を取り戻せてないせいかサラダ油を使いすぎて少々油っぽくなったが、まあまあ食える物にはなった。復帰第一段がこれなら、これからもまあ何とかなるだろ。
「ダン←ダム」を買った。 RPG と銘打ってるけど、これは戦術シミュレーションの類だろう(戦闘に関してはリアルタイム)。基本的には傭兵を雇って街を防衛したり、モンスターの棲むダンジョンに殴り込みをかけたりというゲームなのだが、モンスターに叩き壊された街の施設の修復をしないといけないのはまだいいとして、あんまり酷使しすぎると戦闘員が疲労・衰弱したり、挙句の果てには追加報酬なしじゃ働いてくれなかったりするという、妙に世知辛いゲームだ。あとなんか場合によってはキャラクターがロストに近い扱いを受けるっぽい。
とりあえずチュートリアルを済ませて多少進めているが、まずそのチュートリアルの最終ミッションがそれなりに難しく、いきなり施設にそれなりの被害が出たりと実に大変。ってかそのチュートリアルが終わるまでセーブ不可とか一体いつの時代のゲームだ。しかもチュートリアルと言っても実戦なので(OJT で超クリティカルな仕事とかどこのブラック企業だ)、そこで下手を打つと後々響くというか響いてるというか。序盤の印象としては、絵柄の可愛さとは裏腹に割と殺る気満々といったところ。
ん? もしかしてダン←ダム、ダンジョンに進攻しないと話が進まないのか? となると延々防戦してるだけでレベルが上がってくのか。もっともレベルの上がり方は普通はどんどんしょっぱくなってくんで、流石にそんなにやりはしないけど。それからこのゲームは戦闘が殆どオートで、街の防衛はせいぜい配置を変えるぐらいしかやることが無いんだが、街の施設と同じ数の舞台を投入すると完全に放置できる。この先敵の強さがどんぐらいインフレするのかによるけど、おそらく編成で下手を打たない限りは大丈夫だろう。
あとは現在のところメンバーが10人までしか登録できないので、固定キャラの2人を含めて12人、1パーティ4人が基本なので、合計3パーティまでしか編成できない。防衛しなければならない施設が3あるので、このままではダンジョンに進攻できないのだが、まずは酒場に投資して拡張しないとな。
今日のご飯は何にしようか散々迷った末に、ドライカレーを作ることにした。材料は以下の通り。
まずはフライパンにサラダ油をひいて、玉ねぎを炒める。炒める時間とかは適当というか、ぶっちゃけ焦げなきゃいいんじゃね?
玉ねぎがいい感じになってきたら、ミックスベジタブルとピーマンと肉を突っ込んで炒める。ついでに塩コショウで味を整えるが、これまた適当でいい。濃くなるよりは薄くなった方が調整しやすいので、手心を加える感じで。
その後にカレー粉を大体40gぐらい突っ込む。
ちなみに使ったカレー粉はこれ。スプーン1杯で10gぐらいの分量なのでとっても便利。
あとは適当に炒めて出来上がり。
「適当」とか「いい感じ」とか具体的な時間・分量があんまり出て来ないのはどういうことかというと、俺は勘とうろ覚えのレシピだけで料理しているからだ。このドライカレーのレシピだって、クックパッドで適当に検索して出てきた奴を流し読みして、それで作ったんだから。まあそんなに難しい料理を作ろうとしなけりゃ、割合何とかなるもんだ。
あとこのドライカレーは大体4食分の分量なので、明日の晩飯までこれで食いつなぐ予定だ。
「ダン←ダム」は2体目のボスまではたいして苦労しなかったけど、その次のダンジョンは敵がかなり強くなっている。一回の防衛戦で重傷を負って前線から戻さざるを得ないキャラが結構出てしまう。研究所と鍛冶屋で装備を整えればマシになるとは思うけど、このゲームに限らずアイテム集めて合成してどうのこうのってのはイマイチ好みではなかったりする。研究所でのアイテム精製の結果がかなりランダムなのも気にかかる。
あとダンジョンの敵に一気に打撃を与えるダムの放流だけど、どうにも貯水量が戻るまでが時間かかりすぎで微妙だ。それなりに強化しないとあまり使えなさそうな予感。
玉ねぎとかミックスベジタブルが余っていたので、炒飯を作ることにした。
ぶっちゃけドライカレーと途中の手順はほぼ同じ。使った具材は玉ねぎとミックスベジタブルとピーマンとかまぼこで、分量は適当。どこで見聞きしたか忘れたけど、ご飯に卵をかけた混ぜた状態で炒めるとパラッとした仕上がりになりやすいというのを聞いたので試してみたが、どうにも微妙。まあ、俺の腕が悪いというのが真実だろうが。
というわけで完成。気の迷いで水餃子を添えてみたが、ぶっちゃけこれは無くても良かった。スープは前と同じく余りものをコンソメで煮込んだだけ。しかし料理しながら写真撮るのは面倒にもほどがあるな。
今日は肉じゃがを作ったぜ。分量は大体三食分で、使った材料は以下の通り。
調味料はこんな感じ。
ぶっちゃけ肉じゃがの作り方は殆どカレーと一緒なので、カレーが作れるなら楽勝。
まずは肉と玉ねぎを炒める。目安としては肉の色が変わるぐらい。
肉の色が変わったら、人参とじゃがいもを突っ込んで炒める。別にきっちり炒める必要はないというか、どうせ後で煮込むんだしここは野菜に油がまわるぐらいにちゃっちゃとやればいいらしい。
そしたら水を適当に入れる。本当は出汁を2カップらしいが、んなもん俺が用意できるわけない。水と塩あるいはコンソメでいいだろ。そもそも計量カップなんぞもっていないので、これはマジで適当にやった。どうせあとで煮詰めるんだし、そんなに神経質にならなくてもいいだろ。
当然あくが出まくるので、それをきっちり取る。ここまで大体8分程度煮込めばよさげ。
後は調味料を入れて煮詰める。大体煮汁が70%ほど飛ぶまで煮詰めるものらしい。ちなみに手元の料理本には「落し蓋をして煮詰める」とあるが、俺がそんなもの持ってるはずないだろう。
煮詰めたらしばらく寝かせて味を滲み込ませるらしいが、腹が減ってしかたがないので早速食べることにした。ちょっと味付けが薄かった気がしなくもないが、まあこれはこれで食えるからいいや。当然明日の昼と晩はこの肉じゃがなのだが、その頃にはもっと味が滲み込んでおいしくなってるはずだ。
例えば次のような関数のテストをしていたとして、その作業は何らかのタスク管理システムに登録されているものとする。
import bar
def foo(arg):
a = do_something(arg)
b = bar.buz(a)
...
それで
という時に、 foo のテストと bar の修正を同時にコミットするのは好ましくないというか問題大有り。どうしてかというと、事前に登録されたタスク以上の事をコミットに含めてしまっているので、タスク管理システム側からは「bar モジュールに問題があった」という事実が見えなくなってしまうから。もちろんコミットログを見れば一目瞭然かもしれないけど、でもコミットログとタスク管理の間に齟齬があるのって事故の元だと思わない?
俺は今一人で開発してるし、何よりプロトタイプ的な意味合いもあるのでそこまで神経質にならなくても(今のところ)問題ないけど、でも本当にトレーサビリティを気にするのなら、コミットを細かく分けるとか一つのコミットに複数のタスクやチケットを紐付けて管理するとか、そういう配慮が必要だよな。
ちなみに darcs はコミットをしようとするとファイル単位どころか同じファイルの中でも変更点が切り分けられて(まあ連続した行への変更をまとめてるだけっぽいが)、それを対話的に選ばせるというインターフェースになっている。かったるいといえばそうかもしれないけど、でもこっちの方が理屈の上では健全な気もする。
Python では動的にモジュールオブジェクトを変更したり生成したりできるのは常識なので、次のようなことが可能となる。
簡単に書くと、こんな感じ。
import foo
funcs ={
'bar': some_higher_order_function(foo.bar)
'buz': some_higher_order_function(foo.buz)
}
mod = types.ModuleType('newmod')
mod.__dict__.update(funcs)
ここまでは普通にできる。それじゃ、ここでラップしてる foo モジュールの中身がこうなっていたらどうしよう。
def bar(arg):
...
buz() # 内部で buz を呼んでる
...
def buz(arg):
...
この時 bar の中で参照している buz の実体はラップされた後の bar ではなく、ラップされる前の foo モジュールにおける buz となる。当たり前だとしかいいようがないが、時々参照先もラップした後の関数になっていてほしい事がある。例えばメモ化を後入れする時がそうだ。メモ化を次のような高階関数として実装したとする(わかってると思うけどこれ手抜きだからな。コピペして使ったりするなよ)。
def memoize(f):
cache = {}
def wrapper(arg):
if (f, arg) in cache:
return cache[(f, arg)]
else:
r = f(arg)
cache[(f, arg)] = r
return r
return wrapper
最初に例示したコードのような手法を使えば全てのモジュール関数がメモ化されたモジュールを生成することができるが、これが上手く行くためにはある関数から別の同一モジュール内の関数を呼んでいない時に限られる。先の foo モジュールを例にもう一度コード書くと、
import foo
funcs ={
'bar': memoize(foo.bar)
'buz': memoize(foo.buz)
}
mod = types.ModuleType('newmod')
mod.__dict__.update(funcs)
ここで mod から bar と buz を呼び出す限りそれらはメモ化された関数なのだが、その mod.bar から呼ばれる buz はメモ化される前の foo.buz のままになる。一応ラップされた関数から func_closure と func_globals を辿り元の関数の func_globals を書き換えるという大技があるにはあるが、だったら元のモジュールの辞書を直に update するのと同じじゃんという話だ。
いっそ copy.deepcopy でモジュールをまるごとコピーして中身を書き換えようかとも思ったが、そういや copy.deepcopy 関数はモジュール、関数、スタックフレームなどを扱えないのだった。なので特定のモジュール全体をラップして、なおかつモジュール内部の参照もラップ後の関数で置換したい場合、諦めてモジュールそれ自体のアイテムを更新してしまい、その処理を行う関数をメモ化するか再入不能にして、何度もラップ処理が走らないようにするしかなさそうである。
まあ、そこまでしなくてもいいような設計にするというのが一番の正解だとは思うけどな。
新しい仕事がそれなりに大変だったり勉強しないといけないことが山のようにあったりと、まあいろいろあってあんまりギターを弾けてなかったのだが、流石にこのままじゃヤバいと思って Black Sabbath が自らの名前を冠した名曲 "Black Sabbath" を弾いてみた。ちなみに今回はヴォーカルなし。晩飯食った後に突貫工事で録音したんで。ミキシングに至っては完全にやっつけなので、ベースが全然聞こえないとかそもそも曲の冒頭がおかしいとか、まあ勘弁してくれ。ソフトウェアの都合上、 WAV へのエクスポートに時間がかかってかったるいんだ。
それでぶっちゃけろくに練習しないで弾いた割には、ちったぁ聴ける出来にはなってると思うけど、やっぱリズムがずれまくり。この曲、 BPM が大体 60 ちょいでノタクタと進むパートが続く上にドラムがちと変則的で、とにかく入り込みにくい。ギターソロは原曲を踏まえてインプロヴァイズしたといえば聞こえがいいが、要するにソロの構成を大まかにしか把握してなかったんで、その場しのぎで適当に弾いたというのが正解。
というわけでいつも通りのグダグダな出来栄えなので、そのうち歌も入れてきちんとしたバージョンを録音したいなあ。
層圏トポス勉強会第五回に行ってきたのだが、今回は大変だった。何が大変だったかというとだな、今日は出かける直前に急に腹が痛くなり、それで待ち合わせの時間に間に合わなかったのだ。ということはつまり俺は自力で矢上キャンパスまで行く必要があったのだが、俺は大変な方向音痴なので、まず矢上キャンパスにたどり着くのに苦労した。というか最初間違えて日吉キャンパスの方に向かってしまい、結果として一時間以上の遅刻だった。
それで今日の内容は、米田のレンマの積み残し部分と復習をやってから随伴関手という流れだった。随伴関手自体の定義はシンプルなのだけど、竹内本の記述が例によって端折りまくりあるいは「ここはテメーで考えろ」だったので、定理の証明が中途の状態で時間切れ。というか本を持っていて尚且つ積んじゃってる人は、p78の定理8の 1)=>2) を証明してみよう。今回はこいつに引っかかってそれでお開きだった。
今日はちょっと冒険してゴーヤチャンプルを作ってみたんだが、今回はちょっと失敗した。俺はあんまり苦味がキツいのは好きじゃないのでゴーヤを塩もみして苦味を飛ばそうとしたんだが、どうもそれが不十分だったらしい。まあ、食えないわけでは無いのでいいっちゃいいんだが。
今日は鶏肉のカレー風煮込みを作った。材料は以下の通り。
にんじん、ピーマン、玉ねぎは適当に切っておく。これは本当に適当で良い。
サラダ油を鍋にひいて、にんにくと赤唐辛子をさっと炒め、適当な大きさに切った鶏肉をカレー粉とトマトケチャップを入れた上でこれまたさっと炒める。大体1〜2分も炒めれば良さげ。何か塩コショウもやった方がいい気がするが、まあ気にしない。
野菜類を突っ込んで、鶏ガラスープを入れる。分量は多分、1.5カップぐらいの水に市販の鶏ガラスープの元を小さじ1.5ぐらい溶いたような気がする。鍋に蓋をして中火で15分ぐらい煮込んだあと、蓋を取って水分を飛ばせば……。
出来上がり。なかなか美味いぞ。
今日のご飯は野菜炒め。
作り方とか材料は、先週の時と大体同じ。今日はちょっと片栗粉でとろみを付けてみたけど、写真じゃわかんねーな。あと俺は独立欲望国家・千葉国の国民であり、千葉には「年間12本以上のマックスコーヒーを消費すること」という法律があり(背いたら酌量の余地なく死刑)、そこにこの度緊急で「マックスコーヒーの新種が出たらかならず飲むこと」という条文が追加されたのでマックスコーヒーVを飲んでみた。ただでさえ何かの法律に引っかかりそうなぐらい甘ったるいマックスコーヒーにバニラがぶち込まれているので、マックスコーヒーを飲みなれていない人にはきつい気もするが、少なくとも千葉に長く住んでいるクリーチャーであればマックスコーヒーには慣れ親しんでいるはずなので多分問題はないだろう。
話は変わるけど、最近は普通のご飯じゃなくて白胡麻ご飯を食べてる(ってこの写真だとわかりにくいな)。ご飯を炊くときに炒り胡麻を適当に混ぜてるだけ。ほんのちょっと硬めに炊くのが良さげだ。
打ち合わせで俺の書いたコードを読んだ檜山さんから「__init__.py にいろいろコードが書かれてるのと空っぽの場合とがあるけど、あれ何?」という質問を受けたので、 Python におけるパッケージとかモジュールの設計の指針についてちょっと書く。
まず最初に言葉の定義。 Python におけるモジュール及びパッケージというのは、オフィシャルの下記の文書に書かれている通りである
ざっくりと抜き出すと
となる。これらの仕様の大元の文書は次の奴だな。
なので基本的な Python におけるモジュールとパッケージの使い分けは
となりそうなものだ。ちなみに Python の標準ライブラリを見てみると、 2.5 の時点でパッケージになっているのはあまりない。そんな中でパッケージになってるモジュールの __init__.py をいくつか見ていくと、
とまあ、割といろいろな書き方がされているので、一通り読んでみるといいかもしれない。
以下、エキスパート C プログラミングより引用。ちょっと極端過ぎる例だけど、言語独自の慣習・標準などを無視することの一つの到達点がこれだ。
「CはAlgolではない」
1970年台の後半、ベル研でUNIX Version 7用のシェルを開発する際に、Steve Bourneはプリプロセッサの機能を使って、CをAlgol-68風に使おうとした。
(中略)
#define STRING char * #define IF if( #define THEN ){ #define ELSE }else{ #define FI ;} #define WHILE while { #define DO ){ #define OD ;} #define INT int #define BEGIN { #define END }
これらを使うと、プログラムはこんな風に書けるようになる。
INT compare(s1, s2) STRING s1; STRING s2; BEGIN WHILE *s1++ == *s2 DO IF *s2++ == 0 THEN return(0); FI OD return(*--s1 - *s2); END
(中略)
このAlgol風C言語Bourne方言は、International Obfuscated C Code Competition−−作成したプログラムの読みにくさと複雑さを競う異様なコンテスト−−を誕生させるきっかけになった。
この Bourne シェルの開発エピソードから読み取れる教訓は、自分にとって自然な記法が他人にとっても自然とは言いきれないということだ。例えば俺は Python の組み込み型が小文字で始まっていることがそこまで不自然だなんて思ってない。仮に組み込み型の名前が大文字で始まっていた方がいいと思う人が大多数を占めたとして、組み込み型の名前を変えたり __builtin__ を直接いじるような変更をおいそれとやるのはどうかと思う。
あと件の記事の発端は「ローカル変数に心置きなく str などを使いたい」というものだが、そもそも str だの dict だのは変数名としてはまったくもって無意味で、本当に何かしら意味のある名前を付けなければならない場合には使えない。そして別に意味のある名前である必要性がない場合(lambda s: s.strip().lower() なんてλ式の仮引数名を誰が気にするんだ?)は一文字変数で別にいいだろう。
何にせよ、組み込み型にエイリアスを付ける事にそこまでの意義は感じられない。ただローカル関数に str などと付けられるというだけのメリットが、そのコードを読んだ第三者に「この Str とは何だ?」と余計な事を考えさせ、時に混乱させ、場合によってはポータビリティの問題を抱えるかもしれないというデメリット(__builtin__ を変更してる事に依存したコードを、それと気づかず別の環境で動かそうとして、 __builtin__ を変更するコードが入ってなかったらどうなるかな?)に本当に見合っていると思っているなら別に止めはしない。そのコードが International Obfuscated Python Code Competition の起源にならないことを祈るよ。
今日の昼飯及び晩飯はほぼ完全に我流の多分だけど回鍋肉と思われるもの。今回は微かな記憶と勘のみで作ったんだけど、その割には上手く行った。
使った食材は
で、調味料はこんな具合……だったはず。
というかだな、そもそも事の発端はちょっと余り気味のピーマン & 玉ねぎとネタで買ったパプリカをどうするかだったのだ。それで何となく「これと豚バラを豆板醤で炒めたら回鍋肉じゃね?」と思ったので、残りの具材を買ってきて、「どうせ炒めて調味料入れるだけだろ」と完全になめた態度で料理開始。
豚バラを適当な大きさに切って塩コショウをまぶしたら
炒める。しっかり炒める。親の仇のように炒める。そしたら野菜を突っ込んで炒めて、その後調味料を入れる。この辺のプロセスの写真はデジカメの電池切れにより撮れなかった。ってか予備のバッテリーぐらい用意しとけという話か。
でまあこれは当然昼間にできたてを撮影したものではなく、さっき電子レンジで温め直した奴なんだが。冒頭に書いた通り、適当に作った割には結構美味しかったな。ちなみに今回は3食分ほど一気に作ったので(2食分にするつもりが目測を見誤った)、明日の昼ご飯もこれ。
twitter に書いた内容のまとめになっちゃうけど、 "Writing software is an art" という文について。俺はこの文自体は違和感無く読めるけど、これが日本語に訳されると違和感を感じることが多い。多くの場合この文は「ソフトウェアを書くことは芸術である」と訳されるけど、これに対してちと違和感を感じる。
というのも日本語で芸術と言ってしまった場合、まず絵画や音楽などの美術が念頭に置かれてしまい、そこから感じ取ることのできるニュアンスというのは才能・美意識・ひらめきなどだけで、原語の art の持つニュアンスは失われていると思うからだ。俺は間違ってもネイティブじゃないしそんなに英語が得意でもないので、ネイティブの連中が本当にどう感じているかは知らない。でも Oxford Practical English Dictionary で "art" を調べると以下の順で意味が出てくる。
2番目に "skill" という言葉が出てくること、例文として文章を書く能力が出されていること、また4番目とはいえ人文科学の学問分野が引き合いに出されていることから、英語の "art" はもっと人文科学などの学術・技術のニュアンスを持っているはずで、日本語の「芸術」のようにそれらのニュアンスと切り離された言葉ではないと思う。そもそも liberal art って言葉があるんだから、芸術の事だけを指し示す言葉のはず無いのに。
これとはまたちょっと違うけど、 "literate programming" が「文芸的プログラミング」になるのは違和感があるというか訳しすぎというか、これまた変といえる(これはときどきの雑記帖の中の人は前から問題意識を持っていた)。で、同じように "literate" を Oxford Practical English Dictionary で調べると
とある。これが「文芸」になるのは literacy という言葉との整合性を考えてもおかしい。
なので俺はいっそのこと "literate programming" は「教養あるプログラミング」としてしまい、プログラミングやソフトウェア開発の文脈では "art" は学問としてしまった方が、今までのように「文芸」「芸術」などとするよりはナンボかマシだと思う。
追記:「art は技芸とする例もある」との意見をもらった。なんかそっちの方が良さそう。
昨日は昼と晩が回鍋肉で、今日の昼もその残り物としつこいものが続いたので、今日の晩ご飯はあっさりめに洋風湯豆腐。作り方は単純。豆腐、キャベツ、玉ねぎ、ベーコンを鶏ガラスープで煮込んで醤油や塩コショウで味を整えるだけ。まったく手間がかからない、洗い物も少ない、その割に旨いと大変便利な一品。
Python ではモジュールを動的に作るどころか、モジュールクラスを継承して独自のモジュールクラスを作ることができる。例えばこうすると、そのモジュールに存在しないアイテムへのアクセスに対して単に 0 を返すだけのλ式を返すというわけのわからんモジュールができる。
import types
class NewMod(types.ModuleType):
def __getattr__(self, name):
if not (name.startswith('__') and name.endswith('__')) and name not in self.__dict__:
return lambda : 0
else:
return types.ModuleType.__getattribute__(self, name)
また、こうして作られたモジュールは sys.modules に追加することで、普通のモジュール同様に import できるようになる。
# newmod.py NewMod は上にある通りの定義
import sys
m = NewMod('foobar')
funcs = {
'foo': lambda: 'foo',
'bar': lambda: 'bar',
}
m.__dict__.update(funcs)
sys.modules[m.__name__] = m
del m
# 以下は別のファイル
import newmod
import foobar
print foobar.foo() # 'foo' が出力される
print foobar.bar() # 'bar' が出力される
print foobar.buz() # 0 が出力される
「一体何が嬉しいんだ」「十中八九混乱を招くだけだろ」というのは、ぶっちゃけ割とその通りだ。ただまあ、フレームワークとか作ってると柔軟性を出すためだとかで独自のモジュールクラスとかモジュールの動的生成をしたくなることがたまにある。流石に俺もこういったメタプログラミングの類をアプリケーションレベルで濫用するのは気違い沙汰だと思うので、ライブラリやフレームワークの中で本当に必要な部分で使うにとどめた方がいいとは思う。
今日の昼ご飯は焼きそば。もう完全に手抜きに思えるが、これは余った野菜を手軽に消費するための手段なので断じて手抜きではないといっても説得力ゼロで、というか実際に手抜きだ。
「ダン←ダム」をクリアしたので感想とか攻略法とかをいろいろ書く。例によってネタバレ全開。割と面白いと思える部分が多かった反面、「これはどうよ」な部分もてんこ盛りだった。
まずこのゲームは RPG と銘打ってるけどぶっちゃけシミュレーションゲームというのは前に書いた通りで、さらにプレイヤーがやることはパーティ編成と防衛部隊・探索部隊・侵攻部隊の編成、装備品の調達、そして街の施設への投資で、敵との攻防はほぼフルオート。つまりプレイヤー(主人公)は現場の人間ではなく管理職というわけだ。戦闘においては危なくなった部隊を待機させて回復を図ったり、それでもダメなら撤退させたりというのはできるが、このゲームは HP が 0 になっても一定時間放置すると復活するのでひたすら馬車馬のように働かせていればいい(防衛部隊はそうも行かないが、侵攻と探索はそれでいい)。どこのブラック企業だ。
HP が低下した状態で一日を終えると「負傷」や「重体」のステータスになってしまい、そうなると日中に HP が回復しきらない、不満度が大きく溜まってしまうというペナルティがあるにはある。が、日中に回復しきらなくても薬品を持たせて配備すれば敵と戦う前に完治したりするし、不満度が溜まったところで序盤は再雇用のコストは大したこと無く、終盤は滅多に重体になって戦闘終了にならない。とどのつまりは馬車馬のように働かせてればオーケーという非人道的なプレイスタイルになる。
というわけでプレイヤーが戦闘においてやることはパーティのメンバーを雇って必要な装備品をあたえ、そして後は死ぬまで働かせるだけなのだが、このゲームにはもう一点、敵の襲撃で半壊した街の復興という目的がある。復興の資金は街の人からの寄付とダンジョンで手に入れたアイテムや資源の売却なのだが、ダンジョン探索ができるようになるまでは時間があるので、序盤は寄付のみで街を発展させることになる。街を発展させるといろいろ良い事があるので、一定資金がたまったら施設を発展させていくのがいい。
とはいってもすべての施設を平等に発展させる必要は無い。雇用可能人数と日中の回復量、不満度の上昇値を決定する「酒場」が最重要施設で、とアイテムのストック数を決定する「倉庫」あたりが次点。「鍛冶屋」は発展させると装備品を修理する費用が安くなるのでなかなか良さげだが、「研究所」はそこまで魅力を感じない。鍛冶屋も研究所も発展レベルと生成可能アイテムに関連がないようで、アイテムを精錬したり装備品を合成したりした結果の良し悪しに関わる乱数と、作業にかかる費用にしか影響が無い。「養生所」は発展させても回復アイテムのバリエーションが増えるだけで、ゲームクリアまで一番安い回復薬で十分なのが存在感の薄さに拍車をかけている。え、タイトルにもある「ダム」はどうしたって? あんなもん、飾りだ。
このゲームのダムは放水ルート上の敵パーティを(水量にもよるが)洗い流し、敵の出現拠点であるゲートを弱体化させるという能力があり、ここだけ聞くと強そうだが実は全然そんなことは無い。先にも書いた通りプレイヤーが戦闘に介入できる余地が皆無に近いので、戦闘の結果はすべて事前のセッティングにかかっている。そのため、交戦中にキツいことがわかっても後の祭りで、放水しようと思ったらダンジョン内で交戦中の味方も巻き添えにすることになる。このゲーム、 HP が 0 になっても死なない代わりにダムの放水に巻き込まれるとロストの可能性があるので、ますます持って使いにくい。重装備をさせれば放水に耐えられる度合いが上がるが、もっともバランス的に厳しいダンジョンである「炎の迷宮」が、よりによって重装備してると HP が減りつづけるというギミック持ちだ。
というわけで事前のセッティング重要という話になり、ここで自分ならではのパーティを組みたい所なのだが、雇用可能な職業の強さには明確なバラツキがあるので実際のところそれほど戦略の幅は広くない。前述の通り HP が 0 でも死なないゲームなので、回復担当はそこまで必要ではない。むしろ全員火力担当にしたほうが、戦闘での被害が少なくて済む。全体回復ができるシェフはまだ有用だが、ヒーラーに関してはちと微妙だ。攻撃担当にしても、ストライカーは火力が低いので槍術士に転職せざるをえないが、だったら安く雇えて攻撃力のあるウォリアーでいい。アーチャーはそこそこ強く、同じ後衛職のウィザードとどっちを運用するかで迷うが、最終的に弱点属性(ぶっちゃけ水属性だけでいいんだが)で大ダメージを、それもより安い武器で与えられるウィザードの方が有用な場面が多い気がする。
火力担当以外に目を向けると、罠解除のできるシーフは侵攻・探索に必須の存在で、武器さえきちんとしてれば一応の火力にもなる。ポーターは持ち帰ることのできるアイテムが増えるので、ぶっちゃけこいつを転職させる必要性はあまり無い。職人は施設の修理もできれば戦闘にも運用でき、ダンジョン探索では採掘も行える。転職可能な上位職が3つあるが、修理と採掘の両方で運用できるのは職人だけなので、これまた転職させなくても問題ない。
装備品は序盤は別に気にしなくてよく、炎の迷宮あたりで侵攻部隊の武器を整え、あとはラストダンジョンで一気に整えるぐらいでもいい。というか最大で40人にもなるパーティメンバーに対して、
というステップを武器と最大4ヶ所に装備可能な防具に対して繰り返すのはいくらなんでも面倒過ぎる。こういうリソース稼ぎとキャラクター育成が好きな人にはいいのだろうが、俺はそこまで育成マニアじゃないからな。
そういやいくつかの職業は特定イベントを見ないと雇えなかったり転職できなかったりするので、俺は以下の職業を一切使っていない。
あと学者は最初からいる奴以外雇えなかったから、これもイベント絡みだろう。正直な話、このゲームで一番ダメな部分だと思う。
まあそんなこんなで頭数と装備を揃えた後は「テクノロジー×頭数=軍事力」の図式に従って戦闘開始なのだが、どうも戦闘アルゴリズムが若干タコのようで、攻撃を一体に集中して敵の頭数をまず減らす、敵の回復役を真っ先に倒して補給を断つといった事を一切してくれず、ちょっとのダメージにも神経質に回復薬を使い、そしてそこにプレイヤーが介入することもできないので、戦闘を見ているとむしろストレスになる。しつこいようだが死ぬまで戦わせても問題ないゲームシステムなので、戦闘開始したら放置しておけばいい。そんな事やってたら洗い物してるうちにラスボスを倒してしまい、ラストバトルをやり直したのは秘密だ。
あとこのゲームは
というサイクルで進み、毎日のように小芝居を見せつけられるんだが、これは非常にテンポが悪い。「ロックス・クエスト」のようにある程度のボリュームの戦闘をさせたあとにストーリーを進めるという手法の方が良かった気がする。ストーリーは結構シリアスというか途中がやや鬱展開なので、半端な尺でイベントを細切れにするのが一層悪く思える。
というわけで決してクソゲーではないものの、粗が目立つ上にかなり人を選びそうな気がする。例えば RPG とかでアイテムコンプリートの類を楽しくやれる人なら、ルーチンワークになりがちなアイテム稼ぎのための戦闘を完全放置できるので、割と快適に遊べそうな気がする。逆に俺のように細かく戦闘に介入してバトルを楽しみたいという手合いには、そこそこ程度の凡作に思えるな。資金繰りに頭を悩ませたり、パーティ編成を試行錯誤してるうちは楽しかったが、それがルーチンワークになるとなあ。
あとあれだ、エルアに「ツイてる」のは罠か何かか?
追記:書き忘れてたことがいくつかあった。
職業についてはクノイチへの転職も結局できるようになってなかった。どうも職人とポーターそれぞれの上位職とヘヴィナイトと槍術士以外は全滅で、これらのうち槍術士はイベントで残りは無条件に使えるようになるっぽい。
ストーリーについては例え敵の拠点やボスを倒しても、規定のイベントを見ていないと先に進めないのはかなりどうかと思った。多分、その間に探索で装備品を整えろということなのだろうが、装備を整えないといけないのは終盤になってからで、その頃には消化しないといけないイベントが少なくなってる。
DQ9 を始めた。俺は今の今までドラクエシリーズをちゃんと遊んだことはなく、これが初めてのドラクエだ。現在の進み具合としては、仲間を集めて最初のボスらしき物を倒して、次の村に進んだところだ。
それでファーストインプレッションだが、ビギナーへの配慮だろうけど仲間を集めて自由にパーティを組めるようになるまで約2時間というのは流石にタルい。あと主人公の職業って決めるタイミングが無かった気がするんだけど、俺が見落としただけか? 俺はよほど戦闘で不自由しない限り、主人公は盗賊とかのダーティな職業で遊ぶのが好きなんだが。仲間の編成は試しに「僧侶」「魔法使い」「武闘家」でやってみているけど、まだ何とも言えず。とりあえず黒騎士は主人公 Lv8 で、仲間は全員 Lv5 で倒せた。そういや仲間がイベントシーンで消えるんだが、まあ雇われの身なわけだし別にいいだろう。
戦闘バランスは今のところぬるい気がする。徐々にキツくなってくのか、それともこのままなのかが気になるところ。流石に世界樹シリーズのような苛烈さ(最大レベルのパーティでも下手を打つと雑魚に蹂躙される)はないだろうが。あとスキルシステムが何か割と直線的で振り直しとかも無さそうなので、どんだけ戦略の幅が広がるかが不明。敵の姿が見えてるシンボルエンカウントについては、後ろから接触すると先制攻撃などの要素が欲しかった気も。
そういやあのガングロ妖精は想像以上にウザかった。俺、本来はこういうはっちゃけ系のキャラが好きなんだけどな。世界観の中で浮いてるのは別にいいとして、その浮き方が問題というかなんというか。
というわけでまだ3時間ぐらいしか遊んでないけど、とりあえず最序盤の感想はこんなもん。次の感想はクリアしてからになるかなー。
というわけで(どういうわけだ)今日はスパゲティ料理にチャレンジ。作ったのはたっぷり野菜のカレー風スープスパゲティ。材料(2食分)は以下のとおり。
というか野菜はカレーで味付けして安全そう奴なら何でもいい。調味料は
これまた味見しながら調整すること。ぶっちゃけ今回も既存のレシピとか見ないで勘で作ったので(だって探すの面倒だったんだもの)、とりあえず食えるものにはなってるけど味はそこまで保証しないぞ。
まずは野菜を適当に切って鶏ガラスープで煮込む。わざわざ鶏ガラスープにしたのは、まあぶっちゃけ何となく。
その後ウィンナーとカレー粉を入れて煮込んで、塩コショウで味を整える。一連の作業と平行してスパゲティを茹でておく。
というわけで完成。もうちょっと煮込んで味を染み込ませれば良かったかなーと思いつつ、適当に作ってこの味ならまあ別にいいんじゃねという程度の味にはなった。このレシピの通りに作ると味がちょっと薄い気がするので、追加でちょっとケチャップ入れてみるとか工夫の余地はかなり残ってるな。というか流石に野菜が多すぎたかも。
DQ9 の中間報告。今現在カルバドの集落〜カズチャ村まで進めており、編成は次の通り。
一つ前のボスが防具をそれなりに整えないと致死ダメージを一撃で与えてきたのだが、逆に防具を整えたら苦戦する要素がゼロになってしまった。そんときのレベルは上と同じ順に20,19,20,19だった。特に転職はしておらず、ということは当然稼ぎの類もしておらず、クエストなんぞはなから全無視なので、とにかくお金が常に足りない状態だ。それでも戦闘の難易度がたいして高くなく感じるのはどういうことだろうな。確か事前に開発者が「難しくてみた」とかなんとか言っていたはずだけど。
今のところの感想としては、5点満点で1点付けるような出来ではないけど、だからといって満点付ける気はさらさらなく、まあ3点ってところだろう。そういやガングロ妖精のサンディがウザく感じる理由だが、これはキャラクターの造型というよりももっと別のところからきてることに気が付いた。それについては最終的な感想の時に書くことにする。
とりあえず現状、可も不可もないゲームとしか。
今日のご飯はピリ辛炒飯。材料(2食分)は以下の通り。
これをベースに、お好きなように調整してくれや。
作り方の詳細な手順は省略。だって炒飯だし。というかだな、一人で写真撮りながら料理すんのって結構大変なんだよ。
今日はというか今日もレシピを考えるのがタルかったので、何も考えずに作れる野菜炒め。とはいってもまったく同じものの繰り返しじゃアレなので、今日は片栗粉でとろみを付けつつ豆板醤と鶏ガラで味付けしてみた(いつもは醤油)。感想としては、俺は鶏ガラよりも醤油をベースにした方が好きだなあ。
作り方は好きなように野菜と肉を切って炒めて味付けしろとしか。
何か首というか頚椎のあたりが痛くて料理をするのがかったるかったので、今日の昼ご飯は全力で手抜き。豚肉を塩コショウをまぶして炒めただけ。
一昨日あたりから、また ANTLR を使ったタスクに突入しているのだが、今日は軽く ANTLR ネタ。いや、 ANTLR に限った話じゃないか。
ANTLR 2.x 系(3.x は知らん)では、多分次のように Parser のサブクラスのコードを文法ファイルに埋め込んでしまうことが結構あると思う。
class HogeParser extends Parser;
{
// ホスト言語のコード
// 主に共通で使われるメソッドなどの定義
}
parse:(
t1:TOKEN1 {
// TOKEN1 を処理するコード
}
| t2:TOKEN2 {
// TOKEN2 を処理するコード
}
)*
ところがこれだと以下のような問題が出てきてしまう。
というわけで、文法ファイルからなるべくホスト言語のロジックを切り分けたいと思うのが普通だろう。最初にパッと思いつくやり方は、次のようにトークン毎に処理メソッドを分けてしまうことだ。
class HogeParser extends Parser;
{
def handle_token1(self, token): raise NotImplementedError
def handle_token2(self, token): raise NotImplementedError
}
parse:(
t1:TOKEN1 {
self.handle_token1(t1);
}
| t2:TOKEN2 {
self.handle_token2(t2);
}
)*
あとはホスト言語の方で HogeParser を継承して、宣言されたメソッドを実装していけばよい。要するにジェネレーションギャップパターンの変化球みたいなもんだ。というかこの程度のレベルだったら Parser のベースクラスも自動生成できそうなもんだが。
第6回層・圏・トポス勉強会に行ってきた。今回も前回に続いて随伴関手の定理の証明を延々と。前回課題として積み残されていた部分をきちんとやって、その後に残った定理の証明の2/3を終えたところで終了。「層・圏・トポス」は入門書だけあって「圏論の基礎」なんかよりもずっとやさしい反面、記述があまりにも簡潔だったり詳細な証明が略されていたりするので、そこを咀嚼してくとやっぱり時間がかかる。
今回の宿題は、P78から始まる定理8のうち、条件3の「ある関手が表現可能である」という前提から条件1である「左随伴関手が存在する」を導き出した後、そこで導き出された関手の性質(射の対応付けの方法)が不明で、教科書どおりの証明が結局できず、条件2の「普遍射が存在する」を経由することで証明したところ。そもそも「層・圏・トポス」には普遍射などという言葉は出てこなくて、「圏論の基礎」に表現可能関手と普遍射についての記述があるところから手がかりを掴んだもので(確かそうだよね?)、「層・圏・トポス」の記述だけを頼りに証明できるものなのかがわからん。
あとこれは毎度の事だけど、やっぱ7時間ぶっ続けだと消耗するなあ。特に米田のレンマ以降はただでさえ内容の難度が上がってる上に、定理の証明の簡潔さというか「後は自分で考えろ」っぷりも上がってる気がする。まあ、あまり手取り足取り懇切丁寧に書きすぎても、読み手の実力にはなりにくいのかもしれないけどな。
追記:hiratara さんが板書のアップをしてくれてます。
板書のラスト三枚が、 hiratara さんも書かれている宿題の部分。
俺があんな極端な事例を出したのは、あれが「ソースコードの見た目を変えるだけで意味をまったく変えない事例」のわかりやすい事例だからなんだがな。 typedef は適切に使えばコードの意味をより明確にする事ができるけど、俺が例に出した C 風 Algol のコードは単に C のコードの見た目を Algol 風にしてるだけで、コードの意味をより明確にするという効果はないといって良いだろ。
list へのエイリアスとして List を作るなんてのは、まさにこの見てくれだけの問題で、別に list が List になったからといってコードの意味は変わらないだろ。それはどっちにしてもリストだからだ。だったら俺の出した例に近いものとして挙げられてる「Array = list」の方が良し悪しは別としてソースコードの意味への影響は大きく、少なくとも「リストではなく配列として考える」という意図が見える。こっち方がより typedef によるコードの意味の明確化に近いニュアンスで、「List = list」よりは意味がある。まあ、だったら「class Array(list): pass」とでもして、将来において実装を変えたくなったときに備えた方が良いとは思うけど。
自分好みの見てくれのコードを書きたいという欲求はわからないでもない。ただ、それを実現するためにコードの意味をまったく変えない別名定義を、よりによって素の組み込み型に対してすることはどうなんだと俺は言っている。コードの意味を変えない別名定義が有効なのは、長かったり複雑だったりする型への略称として使い、コードの可読性を上げる(より意図を伝えやすくする)ためのものだろう。特に C 言語は様々な修飾子が存在し、また関数ポインタの絡んだ型が煩雑になりがちなので、そこで typedef を使うのは利に適っていることが多いと思う。では「List = list」が複雑な型名による可読性の低下を軽減してるかというと、とてもそうは思えない。むしろその言語の慣習・標準を無視することで(本人以外の多くの人にとっての)可読性は低下しており、その極北の一つが Bourne Shell のコードなのだ。
『「List = list」としてエイリアスを追加するだけのことを、こんな極端なものと同じように扱われるのはとても心外』とあるが、制御構造に踏み込んでないだけ組み込み型にコードの意図が変わらない無駄なエイリアスを付ける方がまだマシ程度で、手前勝手な見てくれのコードを書くために元の言語のやり方を無視して余計な混乱を招くという意味で、この極端な例とは五十歩百歩、目くそ鼻くそを笑う、どんぐりの背比べだと俺は言っているのだ。
DQ9 をクリアしたので、総合的な感想を書くことにする。俺はこれが初のドラクエなので、過去のドラクエと比較してどうこうなどということは書けない。あくまでも一本の RPG としての感想になる。当然だが、ネタバレ全開だ。
結論としては俺にとっては割とゲームバランス・ゲームシステムともに結構破綻したゲームで、五つ星が最高とした時に星一つで酷評する程でもないが、甘く付けても星三つが妥当だろうといった評価だ。俺は RPG に対して未知のダンジョンの踏破と強敵とのデスマッチを求めており、そして RPG における真のストーリーというのはそのゲームの世界観と前述のようなゲームプレイからプレイヤーの内面に構築されるものだと思っているので、この点では DQ9 はそれほど期待に答えてくれるものではなかった。反面、 RPG の育てゲー的側面に価値を見出し、自分の思い通りにキャラを育てて俺TSUEEEE!!をしたい向きにはかなり良いゲームかもしれない。
まず DQ9 をプレイしはじめて感じたのは、序盤が極めてかったるいということだ。最初の2時間程度を終えるまでは仲間を登録することもできず、ちょっとの戦闘を挟んで延々と三文芝居を見せつけられるのには正直辟易した。ただ、 DS の普及台数とドラクエのネームバリューから相当数いるであろう新規参入ユーザへのイントロダクションを考えると、これは仕方がないことかもしれない。ある程度以上の経験があるゲーマーならいきなりゲーム世界に放り出されても大丈夫だろうが、ゲームそのものあるいは RPG に慣れてない人にはそれじゃ酷だろう。ここはある種のトレードオフだし、まあ最初の2時間を終えればいいことだし、なんだかんだいって俺は鳥山ファンで、その鳥山デザインのキャラが動くアニメーションが見れたので、結局別にマイナスには思ってない。
仲間を登録して職業編成をアレコレ考えるのはとても面白かった。やはり RPG というのはシナリオライターの用意した仲間が機械的に入ってくるよりは、自分でキャラメイクできた方がずっと良い。というか、キャラメイクできない RPG を俺は RPG と認めない。回復手段は僧侶に一任するか、それとも旅芸人や盗賊も活用して分業してみるか? 物理アタッカーと魔法アタッカーのバランスはどうするか? 物理アタッカーは戦士と武闘家と盗賊のどれを選ぶか? こういった編成と育成の方針を考えて悩むのは俺にとっての RPG の醍醐味の一つだ(後述するが、これは最終的に期待外れな結果に終わった)。その仲間がイベントシーンで空気になるのも別に問題には感じなかった。そもそも俺は RPG においてシナリオというのはあくまでも縁の下の力持ち、ゲームへの没入度を高めるためのフレーバー程度でいいと思っているので、主人公が喋らない事もかなりの好感触だ。そのシナリオで起こった物事をどう感じるのかはプレイヤーに委ねられているべきで、プレイヤーの操作するキャラクターが勝手に三文芝居をうつのは俺の嗜好に反する。
なのでシナリオ・演出については本来なら文句は無いのだが(話が特に面白いとは感じなかったが、だからといって酷いとも思わん)、「あの」妖精サンディがすべてをぶち壊しにしてくれた。俺は本来であればこういった「お前ちょっと空気読めよ」な浮いた、あるいは壊れたキャラは嫌いではなく、変化球としてはアリだと思う。が、そのキャラが金魚の糞のごとくくっついてきて、イベントシーンで手前勝手な口上を述べるのは正直興醒めだった。実は最初は世界樹などと同様にプレイ記録のページを作ろうかとも思っていたが、完全にプレイヤーサイドの存在が喋りまくるものだからその計画は破綻した。おそらくこれはサンディをどんなデザインにしてもダメだっただろう。
シナリオの話はこれで終わりにするとして、ゲーム本体に話を移す。そもそも RPG と言えば Wiz 系のダンジョン探索メインの RPG を想起する俺にとってはダンジョンの作りが面白いかどうかはなかなか重要な問題なのだが、これについては完全に期待はずれだったと言わざるを得ない。最初からマップが表示されているために、未知のダンジョンを探索・踏破する楽しみが完全にスポイルされており、ダンジョン自体のギミックの無さも相まって、単なるボスまでの通過ポイントに成り下がっている。他の DS のソフトだと「キミの勇者」もあまりダンジョンに芸が無い部類だったが、正直な話 DQ9 はそれにすら劣ると感じた。最初から最後までダンジョンを惰性のみで通り抜けたゲームは初めてかもしれない。
そして俺が重視するポイントの筆頭である戦闘バランス・システムだが、ゲームの途中からボスを撃破したときのレベルを書いていたので、ちょっとそれをまとめてみよう。ちなみに錬金は一切行っておらず、そもそも錬金自体、シナリオの都合で酒場に戻ったときに気がついたぐらいだ。なので装備もそこまで良いものが揃えられたわけではない。
ギュメイ将軍でいきなりパラディンとレンジャーが出現してるのがポイントだ。このゲームで詰まったのはギュメイ将軍のところが初めてで、それまでは転職もせず、レベル上げもせず、適当に進めても普通にボスを倒せてしまった。反面ギュメイ将軍に対しては正攻法で戦うと勝ち目が薄く、そして DQ9 には搦め手から攻める手段が絶無に等しく、また敵の状態異常を事前に防ぐ手段も殆ど無い。その上でギュメイ将軍のやってくる攻撃に「切り上げで行動キャンセル」「魔神斬りでクリティカル」など完全に運ゲーと化すものが含まれており、レベルを上げるか転職するかの2択であった(ちなみにラスボスも同様に運ゲーだろこれという攻撃が多い。ほぼ必中の睡眠とか)。そこで初めて転職してスキルポイント稼ぎなどをやっていたのだが、どうもこの転職システムが気にくわない。
DQ9 の転職システムというのは、とどの詰まりはステータスの底上げだ。おかげでやろうと思えば魔法使いなどの防御力を思いっきり底上げする事も可能で、やりこみ次第でどんどんキャラクターが強くなっていく。そして俺はこれが気にくわない。こういった経験値稼ぎでいくらでもキャラクターが強くなると、戦闘が勢い火力勝負のデッドリーなものになりがちで、的確に敵の行動を封じて搦め手から攻めるような戦いや、敵の編成に応じたスキルのチョイスなどが無価値なものになってしまう。実際のところ DQ9 は正面からの殴り合いを推奨する戦闘システムで、正面から殴り合うよりも回りくどく戦って後ろから刺す戦いが好きな俺は多いに不満を感じる。おそらくさらにやり込めば別の解法も見えるのだろうが、あまりにもやりこみがマゾ作業に過ぎるとも思う。
途中で急激に戦闘の難度というか理不尽さが上がり、そこへの対処方法が経験値稼ぎなのだが、それまでは特に経験値を稼ぐ必要性は無い。このバランスはあまり褒められたものではなく、だったら途中のボスも相応の歯ごたえにしないといけないと思う。ここが DQ9 に感じる最大の破綻ポイントで、恐らくキャラ育成で俺TSUEEE!!をさせたいのだろうが、特に育成の必要がない戦いが延々と続く。ここで途中のボスがもっと強ければ、もっといろいろ転職して、経験値稼ぎをしてから挑むという流れになったはずなのだが、まったくそういう流れがあるとは思えなかった。最初からキャラ育成を楽しんでる人にはそれでもいいのだろうが、俺TSUEEE!!なパワーゲームが嫌いでややこしめな連携狙いのパーティが好きな俺などは、まったく育成のモチベーションがわかなかった。
散々面倒だと言われているクエストは、確かに面倒ではあるが、経験値稼ぎのついでに受けて、単純作業になりがちな経験値稼ぎのモチベーションの足しにするという遊び方をすれば良いので、面倒だからと言って叩くのはお門違いに感じる。もっとも上級職への転職クエストは例外で、ここは完全なるクソだと断言したいが、それを除けばあとはクエストの報酬なんぞついでもいいところだと思う。この辺りはセブンスドラゴンとまったく同じ方向性で、そして逆の理由で失敗していると思う。
先に述べたようにクエストは単なるモチベーション維持のためのオマケだと俺は思うのだが、セブンスドラゴンは経験値を稼いで俺TSUEEE!!なゲームでは全くなく(そういう遊び方するとつまらんと思う)、世界観の補強以外にクエストの存在意義がまったく感じられない(なので全然やってない)。対する DQ9 は殆どのケースにおいて経験値稼ぎの必要がなく、稼ぐ必要が出てきた頃には普通にメタルスライム系を淡々と狩っていた方が効率がいい(魔獣の洞窟ではぐれメタル狩りとか)。なんにしろゲームの終盤は寄り道よりもクリアの方に意識が行っているので、経験値稼ぎのついでにクエストでも受けるなんて事には序盤から中盤に比べてなりにくいと思うのだ。
恐らく製作者側の意図としては、クエストをこなしたり通信プレイで仲間とワイワイ遊んでるうちにレベルが上がり、そのレベルでもって強いボスと戦わせようというものだと思うのだが、少なくとも俺はこの程度の難度のボスでは到底キャラを育てようとは思えない。もちろん DQ9 を難しいと感じる人もいるだろうし、そういった人には経験値稼ぎを中心にクエストやら通信プレイなどが上手くかみ合って、やり込むモチベーションが沸いてくるフィードバックループが発生しているケースがあるのではないかと思う。だが残念ながら、俺にはそのフィードバックループは発生しなかったようだ。
賛否両論のシンボルエンカウントだが、これはゲームバランスの調整をプレイヤーに委ねる措置だ。実際のところ普通のランダムエンカウントの場合、多分もっと高いレベルで進むことになって、極めて温いゲームになった可能性もある。そしてちょっと敵との戦闘を回避しすぎたと思ったら、経験値稼ぎのカモと効率よく戦う事もできる。なので俺はシンボルエンカウントは特に否定しないが、やはり根本的に戦闘に緊張感が無いのが致命的だ。恐らく DQ9 を難しいと感じてる人の幾ばくかは、タルい戦闘を回避した結果として低レベルアタックを意図せずやってしまっているものと思われる。そこから前述のフィードバックループに入り込めれば、「難しい!」から「面白い!」に評価が変わるんじゃないかと思う。
セーブデータが一個しかない事については、通信プレイの要素や DS の普及台数を考えれば、別にいいんじゃないのと思う。一家に一台の据え置きゲームと違って一人一台の域に達してる DS なんだし。不満を感じるのは一人だけで遊ぶとしても複数データを用意して進めたいという人だろうが、むしろその遊び方はゲームプレイの密度を薄める結果になって損な遊び方に思える。複数セーブができない、あるいはできてもやらないことでゲーム中の選択肢の重みが増し、それによって面白みが増すと俺は思うのだが。というか俺にとってはセーブデータを複数用意して進めるという行為は軟弱極まりなく、世界樹Iのプレイ記録に至ってはフルコンプのデータを消してやり直した。
ここから先はゲーム本編というよりもインターフェースの話。実はインターフェースにも多いにストレスを感じていたんで。
DQ9 に限った話では無いが、休息を取る行為とセーブをする行為の間に何ステップもあるのは我慢しがたい。素直に宿屋でセーブさせろというのが、初めてドラクエに触れての正直な感想である。エルミナージュでも一旦街の外に出ないとセーブできないのがちとアレだと思ったが、あっちはボタンを数個ポンと押すだけで良かったのでまだ気にならなかった。ドラクエの伝統なのかも知れないが、その伝統がまったく面白くないというのが本音である。
それでセーブポイントの教会だが、セーブしたあとにBボタンを連打してたらゲームを終了し出したのには思わず閉口した。Bボタンというかキャンセルボタンには、処理の取り消し・巻き戻しなど、積み上げられた状態遷移のスタックを元に戻す操作があてがわれるべきなので、この仕様はおかしい。恐らくBボタンには「いいえ」を割り当てるというデザイン上の決定があり、問題となった部分では「まだゲームを続けるか?」という選択肢が出てくるので、そこでBボタン連打してるとゲームを終了してしまうという事なのだろう。
だったら質問文を「ゲームを終了するか?」にして「いいえ」にフォーカスを当てておけば、たとえBボタンだろうがAボタンだろうが、適当に押してもいきなりゲーム終了にはならない。そもそもゲームをやめたいなら電源を切れば良いので、この機能の存在自体がナンセンスだ。
隊列が酒場でしか変えられないのも問題がある。 DQ9 では敵が一体しかいない場合の単体攻撃や全体攻撃など、選択の余地の無い行動についてはそのコマンドを選んだ瞬間に対象の選択まで自動で行われる。これは小さな親切大きなお世話という奴で、対象の数によって必要なボタンを押す回数が異なるので、むしろ操作のテンポは悪化する側面がある。特に隊列の最後尾に僧侶などのヒーラーがいる場合、うっかり通常攻撃を選んだときに確実な破滅が待っている。そういった悲劇を防ぐには僧侶などは隊列の先の方に持ってくることが必要なのだが、この問題に気がついたのが酒場から離れた後だと非常にストレスになる。
最初に書いた通り、俺にとっては結構破綻したゲームだった。キャラメイクと育成システムを手探りでやってるうちは割と面白かったのは事実だし、一部のボス戦などで敵の戦力を分析して突破に必要な能力を考えるのも楽しめたといえばそうだが、戦闘システムの底が見えるにつれ、ただダルいだけのゲームに成り下がって行った。これまた繰り返しだけど、経験値やアイテムを稼いで自分好みのキャラを作るのが RPG の醍醐味の人にとっては、キャラの見た目は変わるし、そのキャラが戦闘中は動き回ってくれるし、やり込む要素は多いし、とても良いゲームの可能性はある。そういったやり込み要素で楽しませるという方向性は別に否定しないが、国民的 RPG を標榜するなら本編の戦闘・ダンジョン探索がもっと面白くても良かったんじゃないかと思う。
プレイ時間は大体32時間だが、ギュメイ将軍まで到達するのにかかったのが20時間で、その後のレベル上げなどでの停滞でやたら時間がかかったのが特筆すべき所だろう。もちろん試行錯誤の時間も含まれてるし、レベルがギリギリだと戦闘の時間が長引くのもそうなのだが、それ以上に経験値稼ぎが面倒で、はぐれメタル狩りの情報を仕入れてなかったらもっと大変だっただろう。
これまた俺個人の嗜好なのだが、経験値さえ稼げば OK なゲームの場合、最適解を簡単にチョイスさせないために経験値稼ぎがマゾくなるのが気にくわない。レベルの上限が途中で頭打ちになり、パーティ編成やスキルの振り分けで勝負させるゲームであれば、最終的にレベルの価値がたいしたこと無くなるので、景気良く稼ぎポイントを設定して経験値を稼がせる事が可能となる。「レベルカンストすれば余裕」ではなく「レベルカンストして最終決戦のスタートライン」程度の調整なら、マゾくて単調な経験値稼ぎの負荷は減ると思うんだが、どうもそういったゲームの需要は限られているようだ。
あとこれはまったくもってどうでもいいけど、 Amazon で星一つの酷評レビュー投稿してる連中の大半は実際にちゃんと DQ9 プレイしてないだろ。
DQ9 の感想の補足。ちょっと期待とは違っていた転職システムだが、魔法引き継ぎ不可にした部分は評価したい。それができたらそれこそ万能キャラを作れてしまうわけで、一人遊びするにしても通信して協力するにしても、万能キャラというのは作った直後は達成感があるけど使っていて面白いかは疑問だからな。特に多人数で集まったのに全員やることがまったく同じというのは、間違いなくその場で冷める。
「キャラメイクできないとか RPG じゃねえ」ならその他多くの RPG はなんなのだという話だが、それこそいわゆる JRPG じゃねえの? 俺はキャラメイクしてダンジョンに潜ってみたいな古典的 RPG とストーリーとキャラクター主導の JRPG は割と分けて考えてる。俺の好みは明らかに古典的 RPG だが、別に JRPG がダメとは思わないし、中には面白いものも当然あるだろう。海外の RPG はよく知らん。
DQ9 の Amazon レビューとか見てて思うんだけど、未だに買ってない奴がレビュー投稿できるってどういう事だろうな。楽天の方は買った奴だけがレビュー投稿できるみたいだけど、どちらにしてもレビューの文字数が限られすぎでまったくもって役に立たん。俺が一昨日書いた感想文は他の人の参考になるかどうかはわからんが、それでも一通りの感想を書こうとすると7000文字オーバーの分量になる。
こういうユーザがレビュー投稿できるところには、レビューの文字数でフィルタリングをかけられる方がいいんじゃないのか。絶賛するにしろ酷評するにしろ、「最高です!」とか「最悪です!」しか書いてないようなものは読んでも仕方ないし。
今日のご飯は強烈に手抜き。材料は以下の通り。
どうだ、このやる気の無いレシピ。それでこいつをどうするかというとだな
ただ鍋に打ち込んで煮る。ひたすら煮る。時間? 適当だそんなもん。鍋が焦げ付かず、野菜が柔らかくなればそれでいい。
というわけで出来上がり。しょっちゅう食いたくなる代物では決してないが、たまに手抜き料理として食べる分には問題ない。これにローリエ入れたりいろいろ工夫すれば、もうちょっとちゃんとしたものになると思うんだが。