(『半自動 囲いっぽさ 計算機』 ソースコード: Git hub )
「 暗記で覚えている人の知らない 将棋の囲いの理(ことわり)を教えてやろう☆」
「 計算式の論拠は デモンストレーションのあとで解説する☆」
「 ↑ とりあえず 囲い の定義を、 将棋マンとしてではなく、プログラムマンとしての見方で 説明する☆
つまり、 固いとか 長所とかではなく、 囲いと認識するのは何故か? について話す☆
例えば 金無双 で説明しよう☆」
「 ↑ 玉からスタートして、金銀の上を 利きを頼りに移動しろだぜ☆
この時選べる 金・銀 が 囲いの構成要素 だぜ☆
中住まい は 囲いではなく 戦法☆! 将棋マンは 納得しないだろうけど☆」
「 なんで 玉に向かっている方向じゃなくて、玉から離れていく方向にスタートすんの?」
「 利きは後ろからフォローされてるから、前が壁になるんだぜ☆ 一番うしろは玉☆」
「 ただ つながってるだけなら 存在可能な囲い は 計算で完全解析できるんじゃないの?
名前が付いてないだけで」
「 金の延べ棒 とか序盤で作れないやつを除けば、計算量はかなり減るぜ☆
2枚の囲い、3枚の囲い に限定すれば 現実的だろう☆」
「 ↑ 定義上、 囲いに見えない ケースも出てくるが、 囲いっぽさ が低い囲いだぜ☆
つまり、 囲いっぽさが高い囲い のことを将棋マンは 囲い と呼んでいる☆
囲いっぽさ の点数の付け方を説明しよう☆ 上の図は 3点☆」
「 ↑ 上図で、 玉を除き、囲いの構成要素で、 お互いに紐づいているところは 4点、
一方通行の紐づきがあれば、 2点、 紐づいていないところは 1点 だぜ☆
金無双は 囲いっぽさ 5点 ☆」
「 紐の出元と行き先で駒2枚だから2点☆ 双方向なら4点☆ 紐がなければ出元の駒が1枚なので1点☆」
「 ↑ 総矢倉は 8点 ☆
駒から伸びる紐は 迷路は 閉路を描かない……、つまり輪っかを作らないものとするぜ☆ 」
「 単に 計算が 複雑だから 省くんだぜ☆
計算が簡単でない計算式は 親しまれない☆」
「 ↑ 金無双は 銀が下にいた方が 囲いっぽさが 6点 で高くない?」
「 ↑ 天空ダイヤモンド美濃 は 囲いっぽさが 12点 だが、これは囲いなのか☆?」
「 では 逆の見方をしよう☆ 0点~12点の 囲いっぽいものを 例示していこうぜ☆?」
「 裸玉は 味方の駒が盤上にいなくて 玉1枚 という意味だが、まあ 裸感あるよな☆」
「 お父んの定義では 片美濃と ちょんまげ美濃 を区別できないが、どうするのか☆?」
「 ↑ 数え方によるが、 四枚美濃 は 9点 にも 10点 にもなるぜ☆」
「 ↑ 11点 の囲いは見つからなかったが、例えば こんな形だぜ☆」
「 わざわざ こんな形にするメリットが無いのかもしれないな☆」
「 こんな感じで、存在しうる全ての 囲いっぽい ものは プログラムの for文 ですぐに出せるだろうな☆」
「 スタート地点と 方向と、良いとこ取りがあるから もっと手間がかかるわよ」
「 ↑ 盤上に1個しかない玉をスキャンし、スタート地点にしろだぜ☆ 最初の カレント だぜ☆」
「 ↑ そこに金か銀があれば、そこにカレントを移動して、既に調べたマスを除く、8方向を調べろだぜ☆」
「 ↑ あとは 再帰 で 囲いの構成要素 は すべて見つかるな☆」
「 ↑ 点数を最大化する 経路 は どうやって選ぶんだぜ☆?」
「 最初は 玉をスタート地点にしたが、見つけた 囲いの構成要素 の金、銀をスタート地点にして それぞれ隣だけ探索しろだぜ☆」
「 ↑ そしたら 成分 を 総和 しろだぜ☆ これで作れたものを 有向グラフ と呼ぶ☆」
「 有向グラフ が作れれば、あとは どうとでも調理できるわね」
「 ↑ 囲いの構成要素 の金、銀 をスタート地点にして、 閉路 ……、つまり 輪っか を描かないように 描ける 線 をすべて 洗い出せ だぜ☆
この線は いわゆる 経路 だぜ☆」
「 ↑ 洗い出すと、 お前はわたしの部分 みたいなやつがでてくることがあるから……☆」
「 ↑ そいつらを消せだぜ☆ つまり 包含(ほうがん;Implication) してるやつを消した☆」
「 こういうの お巡りさん が得意よね。 棚から 落とし物届け出書 が 一瞬で出てくるのよ。
何分に落としましたか?」
「 士のつく職業や SPI やってるやつ、 Mensa とかは こんなブログ読まなくていい……☆
このブログは もっと ほのぼの してるんで……☆」
「 ↑ ひとふでがき(オイラー路; Eulerian trail) が完成しているやつは、点数が高い方を選べばいい☆
点数が同じなら どっちでも同じだが、
どっちでもいいときの どれを選ぶかは 囲いの数学的定義 を揺るがすものではないので、ここでは定義しないものとする☆」
「 ↑ そういうときは、 1回目に確定した 囲いの構成要素 から 再探索しろだぜ☆」
「 これを繰り返すと いずれ プレイアウト(満局) が完成するので 点数が分かるぜ☆」
「 このように 洗い出された 問題のありえる状態 を 塗りつぶしていくことを 動的計画法 (Dynamic Programming; DP) という☆」
「 なんで こんな単純な話に ダイナミック・プログラミング みたいな すごそうな名前が付いているかというと、
アメリカの研究所が 国から予算を取るときに 名前に ダイナミック と付いていると 予算を取りやすかったからという話しは 何度も書いた☆」
「 人に受け入れられやすいのは重要なのよ。
結局 ミーム性、バイラル性 が勝つのよねぇ。
すると 最初は 面白い面白い と思われて 流行るんだけど、燃料はそのうち尽きるのよ。
クリエイターが ミーム性、バイラル性 のないところを掘り続けることを諦めたら、ぽっと出の ど素人 が原液提供して 面白さに 負けるのよ」
「 ウケのいいことを否定する理由は それが上手く行っている間は 見つからないからな☆
売れることと と 人気が出ること と 興味深いこと の3つを区別できないやつが ライフハックに手を出してしまう☆
最初は 上手く行きそうに見えるんだが、上手く行っているか行っていないかは ゴールにたどり着くかどうかとは 関係ない☆
足りないピースを見つけることこそが 真実だぜ☆
真実は 自分がまだ持っていない 興味深いこと の中にある☆ ミームは言ってしまえば足りている……☆
ミームも バイラルも 目、耳から シャットダウンだぜ☆」
「 ↑ その前に 定番の 自然数を並べろ だぜ☆
むしろ 並んでいるものは自然数だぜ☆」
「 ↑ 矢印に 原理的に 一意の名前を付けることができたな☆」
「 ↑ これだけ 画像素材を作ればいいのかだぜ☆ 17 だと どんな長方形にしても 1 はみ出るな……☆」
「 王さんから伸びてる 8方向の グレーの矢印が要るんじゃない?」
「 何の成果も出さず 8月 に変わってるのを見て、いつものことだと思えるぐらい
戦いへの覇気を失った おっさん は、今日も一日 ぼんやり と すごすぜ☆」
「 9時までには 動くものが作れるレベルの プログラムなんじゃないの?」
「 ↑ 頭が ぼんやり してるんで 座標をメモっておこうぜ☆ CSSの設計者の意図が分けわからんが、座標は マイナスになる☆」
<img src="img/mapchip.png" style="object-fit: none; object-position:-64px -0px; width:64px; height:64px;"><br>
「 ↑ 例えば こんな風に書けば 上向きの矢印を Crop(クロップ;切り抜き) できるぜ☆」
「 ↑ 開発環境は こんな感じだぜ☆
画像を描くのを楽したいだけなんで、HTMLタグのベタ張りで画像を並べて、スクリーンショットを獲れればいい☆
ソフトウェアを作ろうとはしていない☆」
「 ↑ 盤の上に 物置くのも 座標の調整でやるんだぜ☆
ただ 今回は 駒も背景扱いにして、上に矢印を置きたいんだぜ☆」
「 ↑ 正確には、矢印は ヨコ、タテ、ナナメ の位置にある☆」
「 しかし 10歳のプログラマーが 元素をゲーム感覚で覚えられるプログラムを作ってんのに なんで 40過ぎの おっさん が スタイルシートいじって
お絵描きしてるんだぜ☆?」
「 ↑ めんどくせ☆ 4行の Python で将棋盤作る……☆」
「 ↑ コピー貼り付けして 属性のセットは JavaScript で済ます……☆」
09:05
「 ↑ 将棋の符号を入れれば 並ぶと思うんだが、 わたしは 将棋の符号とか すぐに出てこないんで☆
香は 9の9 かだぜ☆」
「 ↑ タテとか 座標どこなんだぜ……☆ トライ&エラーしか☆」
「 できてる、できてる! グラフィックの配色を 調整しましょう!」
「 ↑ わたしの色彩能力では 色を薄くするぐらいしか……☆」
「 縮小は Webブラウザーの機能でやってしまおう☆ プロダクトではないんで☆」
「 Godot で こういう メニュー画面を作ったらいいんじゃないか☆?」
「 ↑ モデル&ビュー構造にしたんで、データを切り出せたが……☆」
「 ↑ 2020年現在 最高難度にしてWebフロントエンドの激戦区のプログラム言語 Java Script の表現力を持ってすれば
1つのデータ構造でいけるな☆」
「 ↑ まずは ベタ打ち で作ってみて、あとで それを変数に置き換えていくのは
モデル&ビュー を使った 定番の画面の作り方だぜ☆」
「 ↑ プログラムから 値のハードコーディングを取り除き、代わりに id=""
というのを振っているな☆
値がないのになんで表示できるかと言うと……☆」
「 ↑ id を使って検索して、そこに値をセットする、という手順を踏んでいるからだぜ☆
これを ビューと モデルの 分離という☆」
「 ↑ はい JSON化した☆
営業の人とか JSON とか言われても分からんので JSON 禁止の職場もある☆
会社を辞める心の準備が整うよな☆」
「 CSS にそんな機能あるかだぜ☆? 調べてみるか……☆」
「 画像のトリミングは出てくるが、 div エレメントのトリミングなんか出てこないな……☆」
「 iframe を使うと楽かと思ったんだが、スクロールバーを消すとスクロールできない……☆」
「 JavaScript でスクロールバーを非表示にしながらスクロールできないのかだぜ☆?」
「 外側のページから、内側のページを操作しようとすると、クロスサイト・スクリプティング なんで
弾かれるんだぜ☆」
「 ↑ 枠に 8px あって うまくいかないが 見逃せだぜ☆」
「 ↑ インナーフレームにボードを、外側に 計算結果を置いて、
データは JSON ファイルにするのがベストなんだが Webに置いて URLでアクセスするのめんどくさいので
JSファイルに関数にして入れておくぜ☆」
「 ↑ 半自動化でけたな☆ ナナメの符号が分けわからんが……☆」
「 ↑ あっ、矢印の種類が違うぜ☆ 人力入力によるミスは 目視確認でないと 見つからない……☆」
「 そこを 自動化できないのかだぜ☆? 矢印は自動で置けるだろ☆?」
「 まさか、人力で 画像を生成しようとは 思っていないような☆?」
「 JavaScript ファイルを新たに用意するか……☆」
「 前に書いたアルゴリズムは 実装に手間がかかってしまう☆ もっと簡単な実装を考えてみようぜ☆?」
「 木の全状態を洗い出して、点数が1番高いやつを選ぶだけでいいのよ」
「 ↑ 分岐するんだが、これが 再帰 だけで表現できないぜ☆
恐らく 棋譜を残しておいて、まだ作っていない棋譜が作れる限り プレイアウトを繰り返す、という作りだぜ☆」
「 ↑ 同じパターンを2度 繰り返さない 仕掛けが必要だぜ☆
すべて散らばる というのは 統計学ではありえない☆ 暗号とか、乱数の世界だぜ☆ むずかしい☆」
「 サイコロ振るのを止めて、全ての選択肢をプレイアウトすればいいわけかだぜ☆」
「 ↑ 開発に入る前に カンニング・ペーパーを作っておこう☆」
「 ↑ こういう 局面評価値 の算出は 葉ノードでやるより、探索中に 枝1本ずつ 加算していった方がいいのかだぜ☆?」
「 木構造で 後ろ向きに戻ってくるときは 情報を捨てるもんなんだが、
枝の情報をキープしながら 戻ってきたり、あるときは 枝の情報を捨てたり という
切替の判定方法が分からん……☆」
「 上図の1番では、途中で、後ろ向きに戻るのではなく、後ろ向きに進んでいるところがあるんだぜ☆」
function get_data() {
return {
"enclosureName": [
"左美濃囲い", "天守閣美濃", "Hidari Mino Gakoi", "Tensyukaku Mino"
],
"board": [
[96, "pc_0"],
[86, "pc_0"],
[76, "pc_0"],
[56, "pc_0"],
[87, "pc_k"],
[67, "pc_0"],
[88, "pc_0"],
[78, "pc_s"],
[58, "pc_g"],
[99, "pc_0"],
[89, "pc_0"],
[69, "pc_g"]
],
"arrow": [
["d87", "k48"],
["d78", "a4884"],
["d68", "a62"],
["c58", "a1"]
]
};
}
「 ↑ k48
なら ナナメ だから、 d
は自動的に決まるな☆ 自動で決まるものは省こうぜ☆?」
「 というか、その arrow は 全自動で計算するから要らんという話しだぜ☆」
「 矢印は、ドロップ・シャドウ のように置くことにするぜ☆
つまり だいたい 右下に置かれると想像して 符号を指定しろだぜ☆」
21:28
「 ↑ もっと のんびり解説したかったんだが、夜の21時を回ったので 解説なしの問答無用でコーディングした☆」
「 ↑ テストだな☆ 自動で一番いい点数を本当に付けているのか、頭で確認だぜ☆」
「 ↑ バグが出るケースを たくさん集めて共通点を探そうぜ☆?」
「 ↑ 中住まいで、なんて玉の右隣の銀に 線が引かれないのか……☆?」
「 JavaScript で、再帰処理の中で使える スリープ が無い気がするぜ☆
async/await 使うか……☆」
「 ↑ アニメーション機能を 充実させると デバッグに良さげだな……☆」
「 ↑ アニメで見ると 全ての分岐を通ってるんだが、最後の結果は分岐を消してしまうみたいだな☆
どうやって 分岐を保持するか……☆」
「 全分岐で プレイアウトしなくちゃいけないのに、
普段の勘で サーチをしてしまう……☆」
「 同じ手を指さないプレイアウトを できなくなるまで やればいいのよ」
18:51
「 ↑ 楽しくプログラミング解説している余裕なく 5時間ぐらい プログラム練り直して コーディングして とりあえず
これぐらいの複雑さなら 半自動計算してくれるところまで でけたぜ☆」
「 じゃあ ミレニアム囲い にリベンジできるか やってみようぜ☆?」
「 ↑ カニ囲いは、王さまと 金が 同じ銀 指してるのが ダメだぜ☆
そうか、葉 に 塗りつぶし済みチェック が入ってないのか☆」
「 ↑ ループ中に 内部状態が変わっているのに気づいてなかったんで ループの中に2つ目のチェックを入れたぜ☆
カニ囲いは、直った☆」
「 ↑ ミレニアム囲いは まだ間違ってるぜ☆
チェックを入れたんだが 他に もっといい経路があるのに探さずに終わってしまったぜ☆」
「 塗りつぶしボードをクリアーするのを忘れているんじゃないかだぜ☆?」
「 ダメだぜ☆ 同一棋譜チェックをしているんだが、前半部分一致で 多くの状態を弾かれてしまう☆」
「 同一棋譜のチェックを止めればいいのよ。
モンテカルロ木探索と違って 全幅探索なのだから、同じ棋譜なんか 探索しないわよ」
「 そうしてみたら 同じ経路のプレイアウトを 繰り返し始めたぜ☆」
「 ダイナミック・プログラミングで 先に 全ての状態のあり方 を洗い出した方が 良かったのかだぜ☆?」
「 じゃあ ランダムのプレイアウトで 数の力で押した方がマシか……☆」
「 モンテカルロ木探索よりむずかしいなら、モンテカルロ木探索にすれば 良かったのか……☆
UCB1 も要らね、 ただの ランダム木探索 で十分……☆」
「 ↑ 変更してみたぜ☆ ドッグ・フーディングしてみようぜ☆?」
「 ↑ ルビの Furigana の位置が気にならないかだぜ☆!?」
<次の記事へ>
Crieitは個人で開発中です。
興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!