日記

DARK SOULS III

数日前から『DARK SOULS III』をやっている――ということは一週間ほど前の日記でも触れた気がするが、とにかく、やっている。

終始こういう雰囲気のゲームだと思ってくれていい

「火の無い灰」と呼ばれる特殊な性質を持つ人間である主人公が、火防女と呼ばれる女やその他大勢の曲者達の助言に耳を傾けながら、各地に存在する強大な王を討伐し、その遺体から得られる薪を燃やすことでもって、活力が失われつつある世界を今一度救世すんぞ、というのがDARK SOULS IIIの筋書きだ。

……と思う。もう二回もエンディングを見ているというのに、この理解で本当に合っているのか一切の確信を持てないあたりが、ダークソウルシリーズたる所以の一つだと言える。流石の仄めかし力だ。明確には語られなかった物事の関係性を調べたり、プレイヤー達の考察をネットで調べたりしているうちに、再び自分でプレイしたくなる。そういう魅力がある。

Markdownパーサー

Markdownパーサーの実装を少し進めるつもりだったが、次に実装するものが大物なので、設計を考えることに時間を費やした。

これまではLeaf Blockと呼ばれる、Blockを内包しない類のBlockを実装していた。しかし、いま実装可能なすべてのLeaf Blockの実装を、遂に前回終えてしまった。故に次回からは、Container Blockと呼ばれる、Blockを内包する類のBlockを実装していく。といっても、MarkdownにおけるContainer BlockはBlock QuoteとListだけだ。

設計は次の通り。即ち、Container Blockの開始マーカーを受理するたびに、それを状態としてスタックに貯めていく。

> foo

例えば上のような文字列が行頭に現れたら、これはBlock Quoteの開始マーカーなので、スタックにBlock Quoteを積む。

また別途、Paragraphなどの受理中に行を受理していく際には、都度スタックを全走査して、対応する開始マーカーをその数だけ受理する。

> > foo
> > bar

baz

上の例では、> > foo まで受理した時点で、2つのBlock Quoteがスタックに積まれている。次の > > bar を受理するために、まずその2つのBlock Quoteの分だけの開始マーカーを、つまり > > を受理する。その上で、残された行である bar の受理を開始する。これで、Block Quoteの中にBlock Quoteが、その中にParagraphが、その中に foo\nbar というテキストノードが入っているというように、適切に抽象構文木を組み立てられる。

また、一連のブロックが空行などによって終了する際には、スタックを空にする。このとき、積まれていたContainer Blockと対応するノードの終了位置も確定するので、正しく設定しておく。