移動ルーチンを考える
これまでの移動ルーチン
これまでの移動ルーチンはソース公開許可が下りていない通信将棋で多くは解説できないのだが、駒クラスから派生させたクラスのgetMovePoint関数で実装していた。
つまり簡潔に言うと一回一回プログラムで計算していた。
これをデータ化出来ないかな、と考えた結果を報告する。
実装してみた
なぜかAccess2000。久々過ぎてむしろ苦労した。
http://tsuge.astgate.biz/blog/shogitest.zip
※DAOがないと動かない。
大体こんな感じのデータがあればオッケーだと思う。
フォーム1とかの適当なものを実行してくれれば動作は確認できる。
ソースコードはいい加減もいいところなので決して真似しないでほしい。こんなソースを出したというだけで懲戒免職をくらいかねない:p
一応軽く解説しておくと、以下二つのテーブルを作成。
T_MST_KOMA | |
---|---|
PK | KOMA_ID |
KOMA_NAME | |
FK | CHANGE_KOMA_ID |
T_MST_KOMA_MOVE | |
---|---|
PK,FK | KOMA_ID |
PK | X |
PK | Y |
Pierce | |
OverlapEnemy | |
OverlapFriend |
※いまいちテーブル記法に慣れていない。お目汚し失礼。
わかりづらい部分を補足するとPierceが貫通フラグ(香車、飛車、角が1、その他は0)、CHANGE_KOMA_IDは裏になった時の駒のID。自己参照なので「データ上は」複数回クラスチェンジする駒も作れる。もしこんな駒を将棋で使うと訳わからんくなるがね。
Overlap系は後述。このテーブル構成を見ればデータも想像つくと思うのでデータは割愛。Accessがあれば見てやってほしい。
あとは駒の移動の際に邪魔になる味方の駒、敵の駒を、OverlapEnemyならびにOverlapFriendを見て消しつつ、Pierceが1の場合はその後の貫通移動も消すという処理を入れればいい。実はこの貫通移動を消すという処理と、貫通移動を別々に処理するのは意外に面倒なのだが、それは別件なので未記述とする。
まだ確定していない部分
持ち駒の処理をどうするかが不明。
Pierceに2を作って、0が通常移動、1が貫通移動、2をワープ移動と定義して、2が定義されていれば自身の相対位置から+X, +Yの全ての位置に移動出来るとし、こんな感じのデータを作るといい気もするのだが。
T_MST_KOMA | ||
---|---|---|
KOMA_ID | KOMA_NAME | CHANGE_KOMA_ID |
10 | 持ち駒状態の歩 | 歩のID |
T_MST_KOMA_MOVE | |||||
---|---|---|---|---|---|
KOMA_ID | X | Y | Pierce | OverlapEnemy | OverlapFriend |
10 | 100 | 100 | 2 | false | false |
10 | -100 | 100 | 2 | false | false |
10 | 100 | -100 | 2 | false | false |
10 | -100 | -100 | 2 | false | false |
Overlapは重なれるかどうかを示すフラグとし、敵にも味方にも重なれず、盤のどこにでも移動出来るという駒が出来る。
ちなみにOverlapFriendがtrueの駒というのが存在した場合の挙動というのは決めていない。
この作りを前提として作ってやると
実はチェスなどは特殊ルールが多く難しい気もするのだが、少なくともサーバ側のDBは汎用的に作っておいて損はない気がしてきた。
本将棋ではない将棋程度であれば十分トレース出来そうなのと、外駒の移動ルーチンが定義出来れば囲碁もオセロも基本的に出来るためである。
で、この作りで行くなら駒テーブル、駒移動テーブル、盤テーブルなどの編集権はユーザに解放してやってもいい気がしてきた。
ためしに盤を横17x縦9にして将棋を打ってみたのだが、角が自由になってまったく別もののような動きをした。こんな将棋を打ちたいユーザもいるかもしれないし、その願いはかなえてもいい気がする。
なんて一人で先走っているが、この手の汎用性をクライアントプログラムに求めると、当然スクロール処理などが必須になるので正直実装者、つまり社長なわわけだが、難色を示されてしまいそう。私のイメージの伝達不足によって発生する不具合などもあるだろう。
「こんな事も出来るデータ構造だよ」という辺りに落としておいて、10月以降に私の方でクライアントを作って機能解放するというフローで行くしかないかな。