動物将棋 (7)
駒が進める場所の評価を見直しました。駒が移動できる場所は、駒ごとにデータとして持っておかないと、後々面倒なことになるだろうというという判断です。
駒の移動範囲の指定
先手、後手の駒は、別々の駒と考えることにしました。下記のようなマトリックスを考え、駒は11にいると考えたときに、移動できる場所を、KomaMoveという配列にセットしました。
00 01 02
10 11 12
20 21 22
KomaMove = {} KomaMove[11] = { 10 } --先手ひよこの移動 KomaMove[12] = { 0, 1, 10, 12, 20, 21 } --先手にわとりの移動 KomaMove[13] = { 0, 2, 20, 22 } --先手ぞうの移動 KomaMove[14] = { 1, 10, 12, 21 } --先手きりんの移動 KomaMove[15] = { 0, 1, 2, 10, 12, 20, 21, 22 } --先手ライオンの移動 KomaMove[21] = { 12 } --後手ひよこの移動 KomaMove[22] = { 1, 2, 10, 12, 21, 22 } --後手にわとりの移動 KomaMove[23] = { 0, 2, 20, 22 } --後手ぞうの移動 KomaMove[24] = { 1, 10, 12, 21 } --後手きりんの移動 KomaMove[25] = { 0, 1, 2, 10, 12, 20, 21, 22 } --後手ライオンの移動
移動の評価
移動できるかどうかの評価について、先に、chkMove()という関数を作りました。動物将棋 (5)に書いていますね。100行くらいのプログラムになっていましたが、たった5行程度のプログラムになってしまいました。
移動先のマスを、(hx1*10+hy1)により計算し、移動前のマスを(hx*10+hy)として計算し、-11してセンタ位置からの差を出した後、それに移動先の値を足すことにより、現在座標での移動できる場所を求めています。
例えば、後手のひよこが、[2二]にいたとします。[2三]に移動できるかどうかを調べるとします。
22 - 11 = 11となります。
KomaMove[21][1] = 12 でなので、後手ひよこは11から12に進めることになります。そこで、11に12を足すと、11 + 12 = 23 となるので、[2三]に進めることが分かります。下記に修正したプログラムを書きます。
------------------------------------------ -- 駒が進めるかどうかのチェック -- 0:進めない, 1:進める ------------------------------------------ function chkMove( hx, hy, hx1, hy1, koma ) local i if( getPlyer(Ban[hx1][hy1])~=getPlyer(koma) )then for i=1, #KomaMove[koma] do if( hx1*10+hy1==KomaMove[koma][i]-11+hx*10+hy )then return 1 end end end return 0 end
ここで、getPlyer()関数は駒が、先手の駒か、後手の駒かを返す関数です。下記にこの関数も書いておきます。
------------------------------------------ -- 駒データから先手(1)か後手(2)を取得する関数 ------------------------------------------ function getPlyer( koma ) return math.floor(koma/10) end
先手/後手の指し順に対応
先手、後手の指し順をきちんと判断するようにしました。tejunという変数を用意して、動かせる駒にタッチしたときに、先手の駒か、後手の駒かを判断するようにしました。
local tejun = 1 --先手:1, 後手:2
if文で、getPlyer(ret)==tejun としているところが判断文です。
もう一つ、変更点があります。それは、動かせる駒にタッチできなかったときに、一度指を画面から離さないと、駒を選択できなくしました。touch(2)で、指が画面から離れるまで待っています。
while(true)do --駒にタッチするまで待つ x,y = touch(1) ret, hx, hy = getKomaNum() if( ret~=0 and ret~=-1 and getPlyer(ret)==tejun )then break end touch(2) --指が画面から離れるまで待つ end
後、一手指した後に、tejunの値を入れ替えるようにしました。1と2が入れ替わるので、単純に下記のようにしています。
tejun = 3 - tejun --手順を入れ替える
一応、修正変更したタッチ処理ソース全体を書いておきます。
------------------------------------------ -- タッチ操作処理 ------------------------------------------ function doTouchAction() local hx = 1 local hy = 1 local ret = 0 local x,y,s local i,j local hx1, hy1,ret1 local tejun = 1 --先手:1, 後手:2 while(true)do while(true)do --駒にタッチするまで待つ x,y = touch(1) ret, hx, hy = getKomaNum() if( ret~=0 and ret~=-1 and getPlyer(ret)==tejun )then break end touch(2) --指が画面から離れるまで待つ end if( hy~=-1 )then --盤上の駒を消す dput( hx, hy, 0 ) else --持ち駒の絵を消す mput( tejun, hx, 0 ) end --現在の画面をワークにキャッシュする canvas.getg( 0, 0, ViewWide-1, ViewHeight-1, 260, 0, 259+ViewWide, ViewHeight-1 ) while(true)do --駒移動ループ drawKoma( x, y, ret ) x,y,s = touch() --ワークから描き戻し canvas.putg( 0, 0, ViewWide-1, ViewHeight-1, 260, 0, 259+ViewWide, ViewHeight-1 ) if( s==1 )then break end --指が離れたら抜ける end ret1, hx1, hy1 = getKomaNum() --盤面から指が離れたときの状態が返ってくる if( ret1~=-1 )then if( hy==-1 and hy1~=-1 )then --持ち駒を打った if(ret1==0)then --空マスに打った --打てたので、持ち駒を削除します delMochiKoma( tejun, hx ) Ban[hx1][hy1] = ret tejun = 3 - tejun --手順を入れ替える end elseif( hy1~=-1 )then --盤上の駒を動かした if( chkMove( hx, hy, hx1, hy1, ret )==1 )then if( ret==11 and hy1==1 )then --ひよこの場合 --最前列ではにわとりになる ret = 12 elseif( ret==21 and hy1==4 )then --ひよこの場合 --最前列ではにわとりになる ret = 22 end --Ban[hx1][hy1]に駒がある場合は、自分の持ち駒となる if( Ban[hx1][hy1]~=0 )then --持ち駒に追加します addMochiKoma( tejun, Ban[hx1][hy1] ) end Ban[hx][hy] = 0 Ban[hx1][hy1] = ret tejun = 3 - tejun --手順を入れ替える end end end --盤上の駒を描く for j=1,4 do for i=1,3 do dput( i, j, Ban[i][j] ) end end --持ち駒を描く for i=1,6 do mput( 1, i, Mochi[1][i] ) mput( 2, i, Mochi[2][i] ) end canvas.putflush() end end