第4回 プログラムは奥深く「4.プログラムの性格」
|
|
4−4 プログラムの性格
では「人間臭く」を具体的に考えるには、どうしたら良いのでしょうか? それは、簡単。人間であるあなたが考えれば良いのです。 例えば、あなたは連続してジャンケンをする時に、どうやって出す手を考えているのでしょうか? ジャンケンの手の出し方は、自分の癖や、相手の手や性格から推定して出すこともあります、また、本当に無意識のこともあるでしょうし、宇宙から電波が来ちゃうこともあるかもしれません。したがって、これらの方法のどれかをプログラミングすれば、人間臭いプログラムになるという事です。 人間臭いプログラム、いわば、プログラムの性格とでも言うのかもしれません。 そこで、今回は次のような性格を考えてみました。 「前回、相手が出した手以外の手を出す」 これは比較的理解しやすいですが、強いのか弱いのか謎です。 例えば、プレイヤーがグーを出したら、次のジャンケンでPalmはグー以外のチョキかパーを出しますので、比較的プレイヤーの動作に連動して出す手が変化します。 まぁ、確率は同じハズなので、あまり強くなることは期待できませんが、上手くツボにはまると、連敗するようです。そして、これもジャンケンの手の出し方の1つであることは確かです。 では、早速プログラムに移りましょう。 前の手、ということは、変数mode_myの「前回」の値が必要になります。 しかし、Palm側の手を決めるルーチンが処理されている時には、既にタップされ、mode_myは今回出す手の値になっているので、この変数mode_myの値を参照してもしかたがありません。 そう、そんなときも、グローバルな変数を1つ用意します。どこでも参照できるグローバル変数はもう定番ですが、このように、前の値を保存する場合にも活用できます。今回は、mode_Prevという変数を用意しておきましょう。 まず、Startupでmode_Prevを定義します。 Global mode_Prev as Integer 次に、同じ手が出ないような処理を作ります。 プログラム中で、条件によって処理を分ける方法にIf〜ThenやSelect Caseなど「条件分岐」を覚えましたが、ここではもう1つの重要な考え方である「繰り返し」を使ってみましょう。 繰り返しを処理するコマンドに、Do〜Loopというコマンドがあります。 Do〜Loopコマンドは、次のような書式で、DoとLoopの間の処理を繰り返し実行する働きをします。 Do 処理 Loop 繰り返しの事を「ループ」といいますが、このまま置いておけば、Palmデバイスの電池が切れるか、リセットするまで延々「処理」を処理し続けてしまう「無限ループ」になってしまいます。 そうならないために、何らかの方法でループから抜け出さなければなりません。 ループを強制的に抜け出すには、Exit Doコマンドを使います。 Doループは、このExit Doコマンドに合うと、ループから抜け出してLoopの次の行へ処理が移ります。 例えば、
Do
処理1
If 条件 Then
Exit Do
End If
処理2
Loop
処理3
のような場合、ループ内のIf文の条件が成立すれば、Exit Doに処理が移り、ループ内の処理2を実行することなく処理3へ移ります。したがって、Exit Doを使ってループから抜ける時は、条件式の位置によって、処理されない部分などが出てきますので、その位置が重要になります。 もう1つの方法は、ループ全体に条件をつける方法です。
Do While 条件
処理
Loop
又は、
Do Until 条件
処理
Loop
のいずれかの書式で、Whileは条件が「成り立っている間」又はUntilは条件が「成り立っていない間」ループが繰り返されます。ややこしいですが、WhileとUntilはお互いに逆の関係ですので、どちらかを覚えておけば問題ありません。 条件の書き方は、Ifと同じ要領で、例えば、
i=0
Do While i<5
i=i+1
処理1
Loop
とすれば、iが5未満の間は処理1が繰り返して処理され、5になったらループから抜けます。Untilを使うなら i>=5 ですね。 さて、ジャンケンに戻りましょう。 Do〜Loopを使って、
Do While mode_Palm=mode_Prev
mode_Palm = rand()*3+1
Loop
とすれば、mode_Palmとmode_Prevが同じである間、つまりPalmが今回出そうとしている手と、プレイヤーが前回出した手が同じである間はループが終わりません。したがって、ループを抜けた時は、必ず違う値がセットされているはずですね。ただ、一般的なBASICでは、条件をDoの後でなく、Loopの後にも置くことも可能で、この場合、最低1回のループを処理してから条件をチェックしますが、NS Basicではできませんのでちょっと注意が必要です。 前に条件があるループの場合、ループに入る前に、必ず条件がチェックされてしまいます。したがって、
Dim mode_Palm as Integer
Do While mode_Palm=mode_Prev
mode_Palm = rand()*3+1
Loop
とした場合、最初にDimで宣言していますので、ループの前の時点で変数mode_Palmには初期値の 0が入っています。一方、前の手である変数mode_Prevは少なくとも、1,2,3のいずれかですから、この条件は必ず成立してしまい、一度もループに入らずに進んでしまいます。 そこで、確実な初期値として変数mode_Palmに変数mode_Prevの値を入れておけば、両者は等しく、条件が不成立になるので、必ずループに入ります。
Dim mode_Palm as Integer
mode_Palm=mode_Prev
Do While mode_Palm=mode_Prev
mode_Palm = rand()*3+1
Loop
条件がLoopの後に置ければ問題はないのですが、ま、NS Basicの場合、ちょっとした工夫で乗り越えましょう。こうしてできたルーチンは、先ほども紹介しました通り「ツボ」にはまると連敗するようですので、前に作った「必勝法」ルーチンもある確率で出現するようにしておきます。また、完全に乱数だけのルーチンも出現するようにしておけば、Palm側の手に3つのロジックが組み込まれたことになります。
Dim mode_Palm as Integer
mode_Palm=rand()*3+1
If Rand()>0.45 Then
Do While mode_Palm=mode_Prev
mode_Palm = rand()*3+1
Loop
End if
If Rand()>0.75 Then
mode_Palm=Val(Mid("312",mode_my,1))
End if
こんなロジックでどうでしょう?まず、最初にmode_Palmの初期値を乱数で決めてみました。先ほどのループに入らない問題もクリアできますね。 次に、0.45より大きな場合、おおよそ55%の確率で「相手の前の手を出さない」ルーチンを処理しますので、Palm側の手が必勝の手に入れ替わる場合もあります。そして、最後に、約25%の確率で、最強(インチキ)ルーチンが入っており、1つのジャンケンロジックとしました。 また、忘れてはならないのが、mode_Prevの値を代入する部分です。これで、この回にプレイヤーが出した手を記憶しています。 こうして、3つのロジックを含んだジャンケンルーチンが完成しました。
Sub Form1004_after()
If mode_my<>0 Then
Dim mode_Palm as Integer
Dim f as Integer
mode_Palm=rand()*3+1
If Rand()>0.45 Then
Do While mode_Palm=mode_Prev
mode_Palm = rand()*3+1
Loop
End If
If Rand()>0.75 Then
mode_Palm=Val(Mid("312",mode_my,1))
End If
count_Game = count_Game + 1
f = Val(Mid("915591159",mode_my*3+mode_Palm-3,1))
If f=1 Then
count_Win = count_Win + 1
End If
DrawBitmap 1010+mode_Palm,8,20
DrawBitmap 1007+mode_my,88,55
Lbl1018.Label=Mid("Win!LoseEven",f,4)
Lbl1017.Label=Format(count_Win/count_Game * 100,"##0.0%")
mode_Prev=mode_my
End If
End Sub
一応、テストで試してみましたら、100回ジャンケンして、勝率15.8%でした。私が弱いのか、ロジックが強いのかわかりませんが、同じ手を出しつづけたら、若干勝率が上がりましたので、何らかの攻略法が存在しそうですね。今回は、ジャンケンのロジックを幾つか考えてみましたが、基本的に遅出しジャンケンでいかにゲーム性を高くするか、という点がポイントでした。要するに「プログラムはアイディア勝負」ということです。 今は、3つのルーチンしか含んでいませんが、このジャンケンゲームを色々な人がプログラミングすると、十人十色、様々な性格のジャンケンルーチンが出来あがるのではないでしょうか。 |
第4回 プログラムは奥深く「4.プログラムの性格」
|