LoginSignup
0
0

More than 5 years have passed since last update.

コンピュータ将棋の指し手の差分更新

Last updated at Posted at 2017-04-29

まず 指し手 って何なんだが、駒を動かすことだと思えばいい。

将棋のようなゲーム、将棋じゃないようなゲーム

将棋のようなゲームなら、将棋じゃなくても役に立つ記事だろう。

ここでいう将棋じゃないゲームとは、1手指すと 連鎖的に盤面全体に変更が及ぶようなゲームだ。

オセロとか ぷよぷよ とか 1手で盤面が変わってしまう。
将棋は 1手動かしても せいぜい

  • 動かした駒
  • 取られた駒

の2つぐらいしか変化がない。

全・再計算

Gazo

将棋盤がある。とくに こだわりが無ければ、長方形に作っておくのがよい。
日本列島みたいにナナメに伸びた陸地だと かなり無駄になるが しかたない。

Gazo

なんかマップに ユニットが初期配置されたとしよう。
初期配置では差分更新しない。

全部の駒を置き終わったタイミングで 何だか知らないが「全・再計算」を走らせる。

この「全・再計算」の結果は 「初期局面」 として記憶しておいて、いつでも ここに戻せるようにしておく。

これで、「全・再計算」の出番は終わり。あとは「部分・再計算」(=差分更新)があるだけ。

部分・再計算

Gazo

駒を なんか動かすのを Do Move (ドゥー・ムーブ) と呼ぶ。(コンピューター・チェス由来)

Gazo

あっ、待った! 今の無し、と戻すのを Undo Move(アンドゥ―・ムーブ) と呼ぶ。

アンドゥは単に 逆向きに動くこと なんだから ドゥーも アンドゥ―も同じじゃないか、というと けっこう動きが違う。

「盤外から駒が飛んできて その駒に下敷きにされた駒は進む」という動きは ゲームのルールにないし、

「成っている駒が 成る前の駒に戻りながら進む」という動きも ゲームのルールにない。

逆向き将棋は けっこう 正向き将棋 とは違う。

Do と Undo、両方 組んで、片方だけできていてもダメで、両方のテストが終わらないと「指し手の差分更新」とかいうやつはできない。

昇格

動き 通称 名前
Gazo そのまんま aa
Gazo 昇格 ab
Gazo そのまんま bb
Gazo 降格 ba

ゲームでは、成る とか プロモーション とか言ったりして、駒が強くなる動きがある。

しかし「差分更新」の世界では「逆向き将棋」も やらなければならないので
降格(デモーション)もある。

呼び分けるのがめんどくさいので aa, ab, bb, ba の4つの動かし方があるものとしよう。

指し手に記録されているフラグ

なにが煩わしいかというと、棋譜には「成った」しか情報がないことだ。
「そのままだ」「降格だ」とか 書いてない。

「成った」じゃないから 成ってない駒だな、というと わたしと同じ間違い で、「成っている駒」は 成ってなくても「成っている駒」だ。

キャプチャー

また、取られる駒が、有ったり無かったりする。

有るとき
Gazo
無いとき
Gazo

ここで おおまかにいって、差分更新では 「3つの駒のようなもの」 が登場する。

Gazo

t0(ティー・ゼロ)、t1(ティー・いち)、c(シー)だ。

タイム0、タイム1、キャプチャーの略。

持ち駒を打つような場合もあるが、単に駒台は t0 としておく。

DoMove

なまえ
Gazo
Gazo C+
Gazo T2C-
Gazo T2+
Gazo T1-

上図のように、駒を1個進めるのに、5ステップある。
(順番はこの通りでなくてもよい)

盤の上から 駒を進める例で示したが、べつに 駒台から打つときも このステップでいける。(盤上の駒を指すのと、駒台から駒を打つのは、if文で分ける)

  • 駒台に駒が増えた
  • 相手の駒が盤上から消えた
  • 移動先に駒が増えた
  • 移動元から駒が消えた

といった感じで、何が増えた何が減った を 追いかけるのが「差分更新」 だ。

UndoMove

なまえ
Gazo
Gazo T1+
Gazo T2-
Gazo T2C+
Gazo C-

アンドゥ・ムーブは さっきの画像を 逆さに並べる。

人間は ひょい っと駒を 取って、打つだけなので、
こんな図解を 置いておいても なにを わざわざ当たり前なことを 書いているのか、 と捉える向きもあるかもしれない。

それは 目の前に駒があって、駒を掴む指を持っている人間 だから 当たり前 なわけだ。
じゃあ、パソコンの前に駒があって、パソコンに指は付いているのか。駒は無いし、指もない。当たり前 とは別の状況が そこにあり、プログラマーがいるわけだ。

急ぎなので、話しをすっとばそう。ディスカバード・アタック

攻撃が届く範囲を、「利き」 という。

動かした駒は 利き も動くんだが、
駒を動かしたことで 遮られていた 利き が復活することがある。

Gazo

これ、ディスカバード・アタック。(塞ぎものを外してアタック)

そして 要点は

Gazo

じゃあ、カバー(塞ぐ)だってあるんじゃないの、ということだ。

どうも わたしのプログラムは ディスカバーも、カバーも 忘れているのか 貫通して駒が飛んでいく。

どこに飛び利きがあるのか、記憶して置いて 踏んづけたのか、離れたのか 判定した方がいいのだろうか?

//つづく

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0