第4回 プログラムは奥深く「3.ジャンケン必勝法?」

4−3 ジャンケン必勝法?

さて、以前から、プログラムを作る場合、実際の流れをそのまま組み上げるのではなく、プログラム的に整理して作った方が良い、ということで作ってきましたが、この辺りはおぼろげながら理解されているのではないでしょうか。このことは、サイコロを振るタイミングやPalmがジャンケンの手を出すタイミングが、ボタンをタップしてからの決めていること、つまり「遅出し」であるけど、ちゃんとゲームとして成り立っていることからもわかります。
このように、遅出し、がゲームとして成り立ちますので、ジャンケンゲームには、まだまだ改良の余地がありそうです。そして、ここから更にプログラム作りが面白くなってきます。

では、手始めに、このジャンケンゲームをもっと強くしてみましょう。

強い、ということは、勝率が5割を超えれば良いのですが、ま、今回の目標は約9割を目指しましょう。
本当にジャンケンで9割勝てるようになれば、日常生活の様々なシーンで得をすることが多いでしょうが、そんな必勝法があるのでしょうか?
プログラムは、そこに組み込まれたロジック以外のことはできませんから、プログラマー側で必勝法のロジックを組み込まなければなりません。そこで、なんとか必勝法を確立しなければなりません。困りましたね・・・

しかし、プログラム的には可能です。なにせ「遅出し」をしていますから・・・ずるいでしょうか?いえいえ、プログラム的には良くあることです。
今まで作ってきたジャンケンやサイコロは、全て乱数だけで成り立っていますが、まず、この乱数について、ちょっとお話しておきましょう。

例えば「1から10の間のでたらめな数字を適当に100個ほど書き出して下さい」と言われて手作業で書き出したら、あなたの結果はどうなると思いますか?完全にでたらめであれば数字が偏ることはありませんから、例えば、平均値が、5.5(1〜10の中心は5.5ですよ)に近づけば「均等な」乱数であると言えるでしょう。(正確に言えば、平均が均等にでたらめであるかどうかの指標ではないのですが、目安にはなります。)
そして、手作業で数字を書き出すと、大抵の場合、均等にはならず、どこかに偏りが出るようです。
しかし、BASICで取り扱う乱数は、偏りのない均等な乱数なのです。

i=Int(Rand()*10)+1

この式で、i=1〜10の何れかを返しますね。これを、10回、100回、1000回・・・と繰り返し計算させてみました。

    

結果として、回数が少ないうちは多少のばらつきがありますが、回数を多くすると中心の5.5に近づいているのがわかるかと思います。
このように、乱数を使うとかなり公平な勝負なりますので、ツールとしては良いのですが、ゲームとしては面白くありません。

では、必勝法プログラムを紹介してみましょう。
(今回は、先ほど作った、Redrawを使うプログラムの方に手を加えますが、前回作った共通モジュールの方も同じ要領でできるはずです。興味のある方は、チャレンジしてみてください。)

方法としては、Palmの手が代入される変数mode_Palmに、必ず勝つ手を代入すれば、勝ちは確実ですよね。
ずるいかもしれませんが、下のように、代入部分を変更してみましょう。
        If Rand()>0.2 Then
            mode_Palm=Val(Mid("312",mode_my,1))        
        Else
            mode_Palm = rand()*3+1
        End If
Rand()関数は、0〜1未満の乱数を返すので、Rand()>0.2 が成り立つのは、0.2〜1.0の間の数値、つまり、おおよそ80%は成立する条件になります。そして、この条件のとき、必ず勝つ手を返すように、グー(1)にはパー(3)を、チョキ(2)にはグー(1)を、パー(3)にはチョキ(2)を返すようにMid()関数で調整します。
Val()関数は、Str()関数の逆で、文字列を数値に変換する関数ですが、Mid()で取り出されるのは文字列であるため、数値に変換して変数mode_Palmに代入しています。そして、これで、変数mode_Palmは、必勝の手が代入されるわけです。
一方、条件が成立しない時、およそ20%の確率の場合は、乱数によって手を決めるようにしてありますので、まあ、遊び心は入るでしょう。
したがって、必勝ルーチンの80%と乱数のみの部分の33%を加え、理論的にPalm側の勝率は8割6分程度になりますね。
そして、この勝率ならば、必勝法を身につけたジャンケンルーチンであるといえるのではないでしょうか?

パチンコやパチスロ、ゲームセンターのルーレット等など。このように、最初から当たりがわかっているルーチンが組み込まれていると思うと、ちょっと疑心暗鬼になっちゃうかもしれませんが、プログラム的には作りやすいことが理解できた可と思います。

        

作りやすさから言えば、どちらもあまり大差がないかもしれませんが、プログラムを制御することを考えると右側の方が優れています。
例えば、先ほどの必勝ジャンケンプログラムもちょっと条件を変えるだけで勝率を変えることができます。

さて、ここまで苦労して作ったジャンケンゲームですが・・・全然面白くないですね。
こう言ってしまってはガッカリするかもしれませんが、正直なところでしょう。では、どこに原因があって面白くないのでしょうか?

原因として考えられるのは、ゲームの中心が乱数だけに頼っているからです。
例えば、UFOが表示され、ミサイルで撃ち落す、という単純なゲームを作ったとしましょう。
UFOの動きが完全にランダムだと、あちらこちらにふらふらして、ミサイルで狙う意味がなくなります。
そうすると、砲台を動かす必要もなく、ま、適当にミサイルボタンを押していたほうがマシですね。

    
(一応、そんなつまらないゲームを作ってみました。ここからダウンロードできます。
 尚、基本的にオープンソースですので、ソースが欲しい方は、メールにてお気軽にお問い合わせ下さい。)

やはり、人間が何らかの動きを予測したり期待しできないと、ゲームとして面白くないので、完全に乱数に頼っては良くないようです。
では、どうしたら良いのでしょうか?

これには色々な方法がありますが、相手を「人間臭く」プログラミングする、という方法があります。
そして、この「人間臭く」と言うのが、プログラムの魅力の1つでもあります。


前へ     目次へ     次へ

第4回 プログラムは奥深く「3.ジャンケン必勝法?」