コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

動物将棋 (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