kdoo

書いてる人: ょゎ
hatena:id:yowa, Twitter/yowa, Gmail:yowaken
«前の日記(2010-03-31) 最新 次の日記(2010-06-01)» 編集

2010-04-02 [長年日記]

>> 将棋棋譜風言語「ModanShogi」で Hello, world! このエントリを含むはてなブックマーク

ModanShogi は プロの esolang 作家である yhara さんによる、将棋の棋譜にしか見えないプログラミング言語。

この言語のことは kinaba さんのエントリを読んで知ったので、激しくネタバレ後な気もするけど、気にせずに strict な(将棋の棋譜としておかしな点のない)"Hello, world!\n" を出力するプログラムを書いてみた。

いちおう advantage として、

  • 短い(92手)
  • インタプリタの実装に手を入れてない(桂馬は使わない)
  • 最終手で詰む(最終手は後手の玉移動→開き王手→先手玉が詰み)*1

みたいな。

▲2六歩    △6二銀    ▲6六歩    △7一銀    ▲5六歩    △6二金
▲6八金    △6四歩    ▲6九金    △6三金    ▲6八玉    △5二玉
▲5九金右  △6二金    ▲5八金直  △6三金    ▲5七金    △6二金
▲5九金    △6五歩    ▲6七金    △6三金    ▲5八金    △5一金
▲5九金    △5四歩    ▲5五歩    △5三玉    ▲5七玉    △4二銀
▲6八玉    △5二金    ▲5八金    △5一金    ▲5七金上  △5二金
▲5八金    △5一金    ▲5七金上  △5二金    ▲5八金    △3一銀
▲5七玉    △4二玉    ▲5四歩    △同 金    ▲5五歩    △5一金
▲5四歩    △4一金    ▲5六玉    △5一金    ▲6五玉    △5七歩
▲3六歩    △3二玉    ▲5九金    △6一金    ▲6九金    △5一金
▲5七金    △6二金    ▲5六玉    △6三金    ▲5八金上  △7四金
▲5五玉    △4四歩    ▲3四金    △同 歩    ▲5九金    △3五金
▲4八金    △3六金    ▲6七金    △2六金    ▲3八金    △3六金
▲4八金    △3三玉    ▲5七金上  △2六金    ▲4六金    △2五金
▲4五金    △同 歩    ▲3五歩    △同 金    ▲5七金    △4三金
▲5六金    △4二玉

言語の感想とか、コーディング過程の覚え書きとか。

歩(add 命令)は思い通りに動かすのが難しい。そこで、まず銀(mul 命令)で大きめの数を作っておいて、金(sub 命令)をメインに数字を削っていき、歩は微調整役となる。玉(putc 命令)を移動させやすい4〜6筋に、お目当ての数字と作るといい感じ。

定数命令はなくて、予めレジスタにセットされてる数字(1〜9)を使いまわすしかないので、1〜3、7〜9筋にはあまり動かさない(レジスタを破壊しない)ことが、柔軟な数値生成を行う上で重要だと思われる、とかなんとか。

持ち駒は、狙った命令を直接実行できるので、非常に強力。とは言っても二歩は許されないので、歩が使い辛いのはここでも一緒。

ただ持ち駒の歩には、「歩の叩き」という面白い使い方がある。「○○歩 同金」が、add と sub が相殺してnoop 相当になるので*2、金を副作用なしに移動させることができるわけ。応用編の「歩で叩いて同金、金の後ろに歩を打って同金」の4手一組で、副作用なしに相手に歩を2枚渡すことができることと合わせると、便利につかえるのではと、いま気づいた。

ここまでに出てない駒(香・桂・角・飛)は、正直微妙に扱いにくい。飛車角はジャンプ命令だけれど、

  • ジャンプ用ラベルの指定が「*1」という形式で、棋譜っぽくない
  • ラベルが任意の位置に置けるので、「まずジャンプ→望む配置に駒を動かす→ここにジャンプしてくる」という手段で strict 化できてしまうんじゃなかろうか説

という理由で利用しなかった。

また桂馬は kinaba さんの指摘にあるとおり、計算結果が Float になるので putc できない→そのレジスタは事実上使い道がなくなる、という問題点がある。

香車は……今になって考えると、強力な気がしてきた。香車の mod 計算がどうというより、9筋(or 1筋)で歩を交換して一歩ずつ持てば、9筋をアキュームレータっぽく使えるのではなかろうか。よくわかんないけど。

あと "Hello, world!\n" について。H と e を連続して出力してるのは意図的だけど、ll と o を連続して出力してるのは「まちがえて l より先に o を作ってた → 考え直すのめんどくせー→ じゃあ o 作る過程で l の準備しようぜ」という理由。

o と l は後からも出現するのでできれば残しておきたい、けど自由に使えるレジスタの数は限られているわけで……という葛藤の後、出番が早く数値の大きい o だけ残した。大きい数値を残すのは、メイン演算が金(sub 命令)だから。

r を 3筋に作った後、さて出力しようと思ったら、玉の現在位置は5筋と6筋だった。途中で4筋に移動してる後手玉をそこに固定して、他の出力は先手玉で行うように組み直し。

r → l → d のあたりは数値が減って行く上に、終盤なので多少のレジスタ破壊なら許容範囲なので、ちょっと気楽に。

と、ここで収束のネタ(開き王手で詰み)を思いつく。先手玉が5筋中段で、飛車角は移動させないので、後手の角筋を利用するしかない。つーことは「△3三玉で ! を出力」→「そこから動いて改行を出力」の流れは決定。あとはなんとか無理くりに押し込めた、と。

って、いま気づいたけど、最終局面から▲3三歩と無駄合ができるじゃん。美しくない……。どうせなら「合駒できれば助かるけど、二歩だから無理」みたいにすれば良かったと反省。

*1 追記: 終局図から▲3三歩と合駒できるけど、無駄合なのでカンベン

*2 x==y だとダメだけど

本日のツッコミ(全1件) [ツッコミを入れる]
>> 通りすがり (2010-04-02 12:16)

何を喋ってるのか意味がわからないwww


«前の日記(2010-03-31) 最新 次の日記(2010-06-01)» 編集
2005|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|09|
2010|01|02|03|04|06|07|

最近のコメント

あわせて読みたい