動物将棋 (11)
棋譜の書き方が違うというコメントを頂いたので、調べてみたら、A1、A2というような表記になっていました。棋譜の表記は下記のように配列に入れて書いていただけなので、マス目の座標は従来のままとして、表記だけを変更しました。
------------------------------------------ -- 将棋盤を描く ------------------------------------------ function drawSyogiBan() local i local yoko = { "C", "B", "A" } local tate = { "1", "2", "3", "4" } canvas.putg( Center.x-128, Center.y-96, Center.x+127, Center.y+95, 0, 0, 255, 191 ) for i=1,3 do canvas.putTextRotate( yoko[i], Center.x-117, (i-1)*55+(Center.y-55), 270, 24, color(0,0,0) ) end for i=1,4 do canvas.putTextRotate( tate[i], Center.x-80+(i-1)*55, Center.y-95, 270, 24, color(0,0,0) ) end --メッセージエリアを描く canvas.putRect( Msg.x0, Msg.y0, Msg.x1, Msg.y1, Msg.bgc, 1 ) --メニューエリアを描く canvas.putRect( Msg.x1+4, Msg.y0, Center.x+127-19, Msg.y1, color(216,245,223), 1 ) canvas.putTextBox( "おやつ", Msg.x1+4+16, Msg.y0+6, 18, color(0,0,0), 20 ) canvas.drawTextCenter( "どうぶつしょうぎ v"..Version, Center.x+1, 10+1, 20, color(0,0,0) ) canvas.drawTextCenter( "どうぶつしょうぎ v"..Version, Center.x, 10, 20, color(245,194,91) ) end
棋譜の表示も変更しました。また、今回は指し手を音声で読み上げるプログラムも追加したので、その部分の変更も入っています。下記がソースです。
------------------------------------------ -- 棋譜のテキストを作ります ------------------------------------------ function KifuText( plyer, x, y, koma ) local moji local yoko = { "C", "B", "A" } local tate = { "1", "2", "3", "4" } local doubutsu = { "ひよこ", "にわとり", "ぞう", "きりん", "ライオン" } local soundfile local soundyoko = { "c", "b", "a" } if( plyer==1 )then moji = "せんて " --音声データセット if( Kifu[KifuN-1]%100 == Kifu[KifuN-2]%100 )then soundfile = LuaridaPath.."/sonajiku.ogg" else soundfile = LuaridaPath.."/s"..soundyoko[x]..y..".ogg" end else moji = "ごて " --音声データセット if( Kifu[KifuN-1]%100 == Kifu[KifuN-2]%100 )then soundfile = LuaridaPath.."/gonajiku.ogg" else soundfile = LuaridaPath.."/g"..soundyoko[x]..y..".ogg" end end --音声読み上げ sound.setSoundFile(soundfile, 0, 0 ) sound.start(0) --画面にテキストを表示 moji = moji..yoko[x]..tate[y].." "..doubutsu[koma%10] msgDisp( moji ) end
棋譜表記の変更は、これだけで行けそうです。千日手は、また考えよう。
音声を追加する
指し手を読み上げるルーチンを追加しました。ただし、正式な読み上げルールを知らないので、超適当です。間違っていてもご容赦ください。とりあえず、先に動画でも。
公開を考えると絵がそのままではまずいと思って、動物キャラを自作しました。自作キャラは動画の後半に出てきます。なかなか味のある動物キャラでしょ(^^;。また、サウンドチャネルはBGM用に7番を空けています。最後の自主規制では、チャネル7番に割り付けたBGMを鳴らしています。
棋譜の読み上げ
読み上げ方をどうするか悩んだのですが、「指した場所の読み」「駒の名前」「打つ」「成る」この4パターンのデータファイルに分けることにしました。従って、場所読み用ファイルは26個、駒の名前は5個、打つ・成るはそれぞれ1つずつとなります。場所読み用ファイルの26個の内訳は、「先手〜」始まる指し位置(12個)、「後手〜」始まる指し位置(12個)、それと「先手、同じく」と「後手、同じく」の合計26個です。
ということで、SofTalkを使って全ての読み上げデータを作りました。サウンドチャネルへの割り当ては下記のようです。
- チャネル 0: 指した場所の読み。切り替えて使います。
- チャネル 1: ひよこの読み。
- チャネル 2: にわとりの読み。
- チャネル 3: ぞうの読み。
- チャネル 4: きりんの読み。
- チャネル 5: ライオンの読み。
- チャネル 6: 打つ・成るの読み。切り替えて使います。
- チャネル 7: GBM用に空けています。
駒の読みファイルをセットする
駒名の音声データ読み込みプログラムです。やっつけ感ありありのソースだなぁ・・・。
------------------------------------------ -- 音声の初期化 ------------------------------------------ function initSound() local soundfile soundfile = LuaridaPath.."/".."hiyoko.ogg" if( sound.setSoundFile(soundfile, 1, 0 )==-1 )then dialog( soundfile, "ロードに失敗しました",1 ) return -1 end soundfile = LuaridaPath.."/".."niwatori.ogg" if( sound.setSoundFile(soundfile, 2, 0 )==-1 )then dialog( soundfile, "ロードに失敗しました",1 ) return -1 end soundfile = LuaridaPath.."/".."zou.ogg" if( sound.setSoundFile(soundfile, 3, 0 )==-1 )then dialog( soundfile, "ロードに失敗しました",1 ) return -1 end soundfile = LuaridaPath.."/".."kirin.ogg" if( sound.setSoundFile(soundfile, 4, 0 )==-1 )then dialog( soundfile, "ロードに失敗しました",1 ) return -1 end soundfile = LuaridaPath.."/".."lion.ogg" if( sound.setSoundFile(soundfile, 5, 0 )==-1 )then dialog( soundfile, "ロードに失敗しました",1 ) return -1 end return 0 end
メインルーチンの最初に初期化の読み込みを追加しました。こっちでdialogを出すべきだな。
-- 音声の初期化 if( initSound()==-1 )then return end
指した場所の読み上げ
指した場所の読み上げのプログラムは、上で先に紹介しているKifuText()の中で行っています。Kifu[]配列の指し手をチェックして、同じ場所に差していれば、「同じく」となるようにしています。
if( Kifu[KifuN-1]%100 == Kifu[KifuN-2]%100 )then soundfile = LuaridaPath.."/sonajiku.ogg" else soundfile = LuaridaPath.."/s"..soundyoko[x]..y..".ogg" end
また、サウンドは別スレッドで動作するので、読み上げ始めると同時に駒処理は次に進みます。
駒の名前を読み上げる
駒の名前は、現在の盤面表示が全て終了してから読み上げることにしました。これの方が、遊んでいてストレスが無いです。
ただし、そうすると、駒を指したのか、手を止めたのかの違いが分からないので、指し手の状態を示すsoundNaruUtuという変数を用意しました。
local soundNaruUtu = 0 -- 0:音声ストップ, 1:成る, 2:打つ, 3:無音
0のときは、手を止めたので音声無し、1のときはひよこが成った場合、2は持ち駒を打った場合、3は普通に指した場合です。soundNaruUtuを使用するように追記したプログラムが下記です。
if( koma1~=-1 )then if( hy==-1 and hy1~=-1 )then --持ち駒を打った if(koma1==0)then --空マスに打った soundNaruUtu = 2 --打てたので、持ち駒を削除します delMochiKoma( tejun, hx ) Ban[hx1][hy1] = koma --棋譜の保存 Kifu[KifuN] = (koma+50)*100 + hx1*10 + hy1 KifuN = KifuN + 1 KifuText( tejun, hx1, hy1, koma ) tejun = 3 - tejun --手順を入れ替える end elseif( hy1~=-1 )then --盤上の駒を動かした if( chkMove( hx, hy, hx1, hy1, koma )==1 )then if( koma==11 and hy1==1 )then --ひよこの場合 --最前列ではにわとりになる koma = 12 soundNaruUtu = 1 elseif( koma==21 and hy1==4 )then --ひよこの場合 --最前列ではにわとりになる koma = 22 soundNaruUtu = 1 else soundNaruUtu = 3 end --Ban[hx1][hy1]に駒がある場合は、自分の持ち駒となる if( Ban[hx1][hy1]~=0 )then --持ち駒に追加します addMochiKoma( tejun, Ban[hx1][hy1] ) end Ban[hx][hy] = 0 Ban[hx1][hy1] = koma --棋譜の保存 Kifu[KifuN] = hx*1000 + hy*100 + hx1*10 + hy1 KifuN = KifuN + 1 KifuText( tejun, hx1, hy1, koma ) tejun = 3 - tejun --手順を入れ替える end end end --盤上の駒と持ち駒を描画します drawAll() -- 駒を読み上げます speakKoma( soundNaruUtu, koma ) soundNaruUtu = 0
上のspeakKoma( soundNaruUtu, koma )が駒を読み上げるプログラムです。最初のif文はガード句で、flgが0のときは何も無しで戻ります。あとはフラグの状態を見て、駒を読み上げます。ひよこが成ったときは、komaには、にわとりのデータが入っているので、ひよこに変更しています。
------------------------------------------ -- 駒を読み上げます ------------------------------------------ function speakKoma( flg, koma ) if( flg==0 )then return end --flgが0なら、読み上げなし local num = koma%10 if( flg~=1 )then while(sound.isPlay(0)==1)do end --指し位置読み上げ終了まで待つ --駒名の読み上げ sound.start(num) if( flg==2 )then --2なら「打つ」を付ける sound.setSoundFile(LuaridaPath.."/utu.ogg", 6, 0 ) while(sound.isPlay(num)==1)do end --駒名読み上げ終了まで待つ sound.start(6) end else --ここに来るときは、ひよこが成ったとき while(sound.isPlay(0)==1)do end --指し位置読み上げ終了まで待つ sound.start(1) --「ひよこ」 sound.setSoundFile(LuaridaPath.."/naru.ogg", 6, 0 ) while(sound.isPlay(1)==1)do end --ひよこ読み上げ終了まで待つ sound.start(6) --「成る」 end end
あとは、千日手判断の拡張ですね。