第2回 とりあえず、ゲームでも「5.Palmで賭場を」

2−5 Palmで賭場を

 では、最初に「所持金」の初期値10を準備しましょう。
所持金は、ゲーム中、常に使用する値ですので、Globalで宣言する必要がありますね。コードは次の通りになります。

    Global money as Integer
    money=10

問題はこれを記述する場所です。
NS Basicでは、ユーザーが発生させるイベント(ボタンのタップなど)の他に、いくつかの特殊なイベントを持っています。
        プログラムの開始時に1回だけ発生するイベント:Program Startup Code
        プログラムの終了時に発生するイベント:Program Termination Code
        画面の描画の前後に発生するイベント:The Screen Before, The Screen After
Startup Codeは、Palmのメインメニュー(ランチャー)画面から、そのアプリケーションアイコンをタップして、起動したときに1回だけ発生するイベントです。Global変数の定義や、各種初期化はここで行います。したがって、所持金の設定コードはここに記述すれば良い訳です。
Termination Codeは、プログラムが終了するとき、通常は[ホーム]をタップして、ランチャー画面に戻るときに発生します。
次回起動するときのために、値を保存する場合は、このイベントモジュールを使います。
画面描画のイベントは、2種類です。画面の描画が始まる前と描画した後に発生します。大抵の場合は、プログラムの起動時に1回だけ発生しますが、プログラム中で、REDRAWコマンドで強制的に再描画した場合にも発生します。

 さて、所持金の初期値をStartupに入れます。Startupモジュールは、[Project]メニューにあります。

  

これで、Global変数moneyを使うことができ、プログラムの起動時に10がセットされます。

次はイベントモジュールです。「SyoBu!」ボタン(But1005)をタップしたときに処理するコードは、次の通りです。
Sub object1005()
    
    Dim Sai1 as Integer 
    Dim Sai2 as Integer 
    Dim Sai as Integer 
    Dim iCom as String
    Dim MySelect as Integer 
    
    money=money-1
    
    If Cho1008.Status=nsbChecked Then
        MySelect=1
    End If
        
    Sai1=rand()*6+1
    Sai2=rand()*6+1
    
    Sai=Mod(Sai1+Sai2,2)
    
    iCom=Mid("CHOHAN",Sai*3+1,3) + "!  "
    
    If MySelect=Sai Then
        iCom=iCom + "OMIGOTO!"
        money=money+2
    Else
        iCom=iCom + "ZAN-NEN!"
    End If
    
    Lbl1012.Label=Str(money)
    Lbl1009.Label="(" + Str(Sai1)+","+Str(Sai2) + ")" 
    Lbl1010.Label=iCom
    
    If money=0 Then
        MsgBox "You have no money." + Chr(10) + "GAME OVER"
        money=10
        Lbl1012.Label="10"
    End If
        
End Sub
では、順番に解説しましょう。
このモジュール内では、いくつかの変数を使用しましたが、変数の宣言はSubモジュールの最初にまとめて行うのが一般的です。
今回用意した変数は、
  • Sai1,Sai2:サイコロ1、2の出目用
  • Sai:サイコロの丁半が入る用(0:丁、1:半)
  • iCom:コメント表示用
  • MySelect:自分の賭けた目(0:丁、1:半)
です。

まず、所持金変数moneyから1差し引かれます。掛け金ですね。

    money=money-1

ちょっと見ると、おかしな式ですね。右と左で合っていない気がします。しかしこれは「代入」です。その意味を思い出してください。
そもそも、代入とは、「右側の結果を左側に入れる」ものでしたね。なので、この式では、右側で現在の所持金から1を引いて、その結果左側に代入しています。
A=A+1、このように記述できるのがプログラムの特徴ですので、覚えておいてください。

    

次は、自分が丁なのか半なのか、という部分ですが、If Cho1008.Status=nsbChecked Then という見なれないコマンドが出てきます。
これは「条件分岐」をする「If ○ Then 〜 End If」というコマンドです。
「もし ○が正しいならば、〜の処理をしなさい」と条件を判断させて、その結果で処理をするかどうか選択する場合に使います。
このモジュールの後半にも同じようにIfを使っている部分がありますが、後半は「If ○ Then 〜 Else ×× End If」という形になっています。
予想がつくこととは思いますが、「もし ○が正しいならば〜の処理を、そうでなければ××の処理をしなさい」という意味です。 構文中の「〜」や「××」のことを「節」といいますが、特に「××」の部分を「Else節」と言います。If Thenコマンドでは、Else節を省略することができますが、Then節は省略できません。
        If 条件式 Then
            条件が正しい時の処理
        Else             ※Else節は省略可
            それ以外の処理
        End If
したがって、最初の部分は、Cho1008(「HAN」の方)のStatusプロパティがNsbCheckedだったら、つまり、「選択がHANだったら」という条件で、その条件が成り立つときは、MySelect変数に 1を代入します。丁が選択されていれば、この条件が成り立ちませんので、Dimで宣言した時の初期値 0がMySelectには入っています。

次はサイコロを振る部分です。2つのサイコロ用の変数にそれぞれ値を代入しています。サイコロの振り方は前に説明しましたね。

そして、2つのサイコロから丁か半かを決める部分ですが、ここには、またまた初登場の関数、Mod()をつかいました。
Mod()は割り算の余りを返す関数で、Mod(X,Y)としたら、XをYで割った余りを返します。例えば、Mod(10,3)=1ですね。
今回の例ではSai1とSai2の合計を2で割った余りを求めていますが、偶数なら余りは0、奇数なら余りは1ですから、それぞれの値がそのまま変数Saiに入ります。
BASICによっては、X Mod Yという書式もありますが、NS Basicでは、Mod(X,Y)です。

次は、コメントの準備です。 Saiの値によって"CHO"か"HAN"を変数iComにセットしたいので、条件に合わせて処理をする条件分岐Ifを使おうと思いました。しかし、ここは別の方法を紹介します。

    iCom=Mid("CHOHAN",Sai*3+1,3)+"! "

新登場のMid(s,x,y)と言う関数(Mod()じゃないよ)は「文字列sの、x番目からy文字取り出す」という関数です。Mid("mizuno-ami",8,3)は"ami"ですね。
変数Saiは丁か半かによって 0か 1ですから、Sai*3+1という計算式は、 1か 4になりますね。それぞれ、変数Saiの値を入れて計算してみればすぐわかります。
その値で、"CHOHAN"という文字列の 1文字目もしくは 4文字目から 3文字取り出すので、"CHO"か"HAN"になるわけです。よろしいでしょうか?
丁と半を"CHO"、"HAN"と同じ3文字に合わせたのでMid()を使った方がIfを使うよりもスマートになりました。"Chou","Han"だとちょっと面倒クサイでしょうね。
ちなみに、Ifを使えば、
        If Sai=0 Then
            iCom="CHO!  "
        Else
            iCom="HAN!  "
        End if
になります。

そして次のIfは、先ほど説明した条件分岐ですね。 自分の選んだ目(MySelect)とサイコロの結果(Sai)が等しければ、当たりで"OMIGOTO!"(お見事!)です。そして、所持金moneyに 2を加えています(構文A=A+1ですね。)
当たりでなければハズレ、"ZAN-NEN!"(残念!)ですね。 A=A+1は、数字だけでなく文字列にも適用できます。したがって、先ほど"CHO"か"HAN"を代入した変数iComの後ろに更にコメントを付け加えることができます。

各ラベルへの文字の代入は、Hello,world!の時にしっかり実習しましたね。各ラベルのLabelプロパティに文字列を代入すれば完了です。

最後のIf分は、所持金がなくなったかどうかのチェックです。
この時点でmoney=0であれば、所持金0、いわゆるスッテンテンです。その場合は「GAME OVER」表示です。
MsgBoxを使っていますが、見慣れないChr(10)というモノがあります。これは、文字コードから文字を返す関数です。
NS Basicの実行レベルではなく、PalmOSのレベルで全ての文字の1文字1文字にコード番号がついています。それが、文字コードもしくはキャラクターコードです。
Chr(10)は文字コード10番を意味しますが、これは「改行」という機能を持った文字で、実際に表示されるものはなく、機能のみが働きます。
したがって、このMsgBoxでは「改行」の文字がありますので、2行にわたってメッセージが表示されます。
そして、MsgBoxで[OK]をタップすれば、新しいゲームになっても構わないと思われますので、所持金を初期値の10に戻して、表示も10にします。あえて「再ゲームしますか?(はい/いいえ)」の必要はないでしょう。

簡単なゲームでも、結構長かったですね。一気に説明してきましたが、どうでしょう?
今回は、変数という重要な部品について説明しました。これは、この後も使いますので、是非理解してください。
また、実際に「丁半賭博」してみたわけですが、ここでも新しいことがたくさん出てきました。できるだけ、平易なサンプルにしたつもりですが、難解な点はお許し下さい。
今回登場した様々なコマンドや関数の他に、もう1つ重要なのは「流れを整理する」ことです。
通常の賭場を再現したのでは、サイコロを振るタイミングを別のイベントに割り当てなければならないので、プログラムが煩雑になります。
問題のないように、プログラム流に整理することも大切なポイントです。
次回、その辺りを中心に、お話したいと思います。

※ご意見、ご要望などは、掲示板かメールでお願いします。

前へ     目次へ

第2回 とりあえず、ゲームでも「5.Palmで賭場を」