HSP3 ゲームのプログラミング | |
○×・ゲーム制作 |
(4) プレイヤーの処理
プレイヤーの処理はサブルーチンplayerに作成する。処理の概要は次の通りである。
- プレイヤーの順番かどうか判定する。
- どこがクリックされたか計算する。
- ○が置けるかどうか判定する。
- ○を置いて、順番をコンピュータにする。
- 画面を描画する。
「1.プレイヤーの順番か判定」は、変数junbanを調べる。0であればプレイヤー、1であればコンピュータなので、1のときreturn命令で戻るようにする。
if junban = 1 : return
「2.どこがクリックされたか計算」は、マウスをクリックしたときの座標から計算する。マウスをクリックしたときの座標はシステム変数mousex, mouseyに格納されている。それぞれのマス目は四角形で、その四角形の左上(座標1)と右下(座標2)で範囲を表すと次のようになっている。
nマス目 0 1 2 3 4 5 6 7 8 一般式 x座標1 0 100 200 0 100 200 00 100 200 y座標1 0 0 0 100 100 100 200 200 200 x座標2 99 199 299 99 199 299 99 199 299 y座標2 99 99 99 199 199 199 299 299 299 nx = x / 100 0 1 2 0 1 2 0 1 2 n = ny * 3 + nx ny = y / 100 0 0 0 1 1 1 2 2 2
表より、座標からマス目を計算する式は次のようになる。
n = mousey / 100 * 3 + mousex / 100
「3.○が置けるか判定」は、マス目のデータが格納されている配列ffが0であれば空いているので置けると判定できる。逆に、0以外であれば置けないのでメッセージを表示して戻るようにする。
if ff(n) ! 0 {
dialog "そこは選択できません。"
return
}
「4.○を置いて、順番をコンピュータにする。」および「5.画面を描画する。」は、次のようにする。
ff(n) = 1
junban = 1
gosub *display
(ox62.hsp)
プレイヤーの処理を作成する。
サブルーチンplayerとして、説明の順にプログラムを作成していく。
左クリックすると一度だけ○が描画される。
(5) コンピュータの処理
コンピュータの処理はサブルーチンcompに作成する。処理の概要は次の通りである。
- コンピュータの順番かどうか判定する。
- 中央(図の4番目)に置けるか判定する。
置ければ、×を置いて、画面を描画して戻る。- コンピュータのリーチの場所を探す。
リーチの場所があれば、×を置いて、画面を描画して戻る。- プレイヤーのリーチの場所を探す。
リーチの場所があれば、×を置いて、画面を描画して戻る。- 置ける場所を探して、×を置いて、画面を描画して戻る。
「1.コンピュータの順番か判定」は、変数junbanを調べる。0であればプレイヤー、1であればコンピュータなので、0のときreturn命令で戻るようにする。
if junban = 0 : return
2〜5の処理の最後は、「×を置いて、画面を描画して戻る。」が共通しているので、サブルーチンの最後に作成し、ラベルcomp2を付けておく。各処理で×が置けた場合、goto *comp2でジャンプすればよいようにする。
*comp2
ff(pn) = -1 ;pn=置ける場所
junban = 0
gosub *display
return
「2.中央(図の4番目)に置けるか判定」は、配列ff(4)の値を調べる。0であれば空いているので置ける。
if ff(4) = 0 : pn = 4
「3.コンピュータのリーチの場所を探す。」は、縦横斜めの3つのマス目を調べる必要がある。縦横斜めのマス目の番号をあらかじめ初期値として配列chkに格納しておく。
dim chk, 24
chk = 0,1,2, 3,4,5, 6,7,8, 0,3,6, 1,4,7, 2,5,8, 0,4,8, 2,4,6 ;チェック用添字データ
探し出した置き場所(0〜8)は変数pnに格納する。最初は-1で初期化しておく。チェックするデータは8セット(3つで1セット)あるので、8回の繰り返しで調べる。リーチかどうかは、3つのマス目のデータを加算して、コンピュータの場合は-2であればリーチと判定できる。リーチならば、3つのマス目から空きを探して、変数pnに番号を格納する。
pn = -1 ;置き場所なし
repeat 8
cnt1 = cnt * 3 ;cnt1=0,3,6,9,12,15,18,21
gk = ff(chk(cnt1)) + ff(chk(cnt1 + 1)) + ff(chk(cnt1 + 2)) ;合計値
if gk = -2 { ;コンピュータがリーチ
repeat 3 ;置き場所を探す
if ff(chk(cnt1 + cnt)) = 0 : pn = chk(cnt1 + cnt) ;発見
loop
break
}
loop
if pn ! -1 : goto *comp2
置き場所が「発見」されたところでgoto *comp2とすればよいようだが、ループの途中でループ範囲の外にジャンプするのはいけない。
if ff(chk(cnt1 + cnt)) = 0 : pn = chk(cnt1 + cnt) : goto *comp2 … ダメ
そこで、break命令でループを抜け出し、最後の行で goto *comp2 を実行するようにしている。
「4.プレイヤーのリーチの場所を探す。」も「3.自分のリーチの場所を探す。」と同じである。
プレイヤーの置いた場所のデータは1なので、リーチの場合は合計値が2になる。したがって、コンピュータがリーチ"if gk = -2"の部分が"if
gk = 2"に変わるだけである。
repeat 8
cnt1 = cnt * 3 ;cnt1=0,3,6,9,12,15,18,21
gk = ff(chk(cnt1)) + ff(chk(cnt1 + 1)) + ff(chk(cnt1 + 2)) ;合計値
if gk = 2 { ;プレイヤーがリーチ
repeat 3 ;置き場所を探す
if ff(chk(cnt1 + cnt)) = 0 : pn = chk(cnt1 + cnt) ;発見
loop
break
}
loop
if pn ! -1 : goto *comp2
最後に、「置ける場所を探して」の処理である。さしあたって、コンピュータもプレイヤーもリーチはないのでどこに置いてもよい。しかし、角(0, 2, 6, 8)に置くほうが有利である。
if ff(0) = 0 : pn = 0 : goto *comp2
if ff(2) = 0 : pn = 2 : goto *comp2
if ff(6) = 0 : pn = 6 : goto *comp2
if ff(8) = 0 : pn = 8 : goto *comp2
if ff(1) = 0 : pn = 1 : goto *comp2
if ff(3) = 0 : pn = 3 : goto *comp2
if ff(5) = 0 : pn = 5 : goto *comp2
if ff(7) = 0 : pn = 7 : goto *comp2
(ox63.hsp)
コンピュータの処理を作成する。
サブルーチンcompとして、説明にしたがってプログラムを作成していく。
クリックして、○が描画されると続いて×が描画される。○と×で9マスすべて埋まるとエラーが表示される。
×を置く場所がない場合の処理がないためである。
(ox64.hsp)
コンピュータ(×)の置く場所がない場合の処理を作成する。
置く場所がない場合、変数pnは-1である。
○×・ゲーム制作 | |
2007 © Hiroshi Masuda |