私は初めてJava言語を勉強した時に最高な本を読んだ。是非Java言語の初心者にオススメです。 早速じゃんけんゲームの説明を入ります。まずはPlayer クラスから実装をしていきましょう。できあがりは Player.java になります。 なにはなくとも、クラスの定義からはじめましょう。
次に定数を定義してしまいましょう。前節で示した「グー」「チョキ」「パー」に対応する int 型の定数です。
Player の関数はコンストラクタと getName、getHand、selectHand の 3 種類です。はじめにコンストラクタですが、Mastermind の時に説明したように、コンストラクタでよく行われる処理として属性の初期化があります。Player クラスのコンストラクタも属性の初期化を行いましょう。とはいっても属性はプレイヤーの名前しかないのですが。
名前をかえす getName 関数は次のようになります。
selctHand 関数は Player クラスの中だけで使用され、他のオブジェクトからはコールされることはないので、private 関数にしてあります。
ところで、Mastermind の時にマジックナンバについて説明しましたが、selectHand 関数の中で使用している 3 という数字もマジックナンバです。じゃんけんの手の数は 3 以外になることはないと思いますが、やはり直接数字を使うよりは定数にしておきましょう。 これを変更した selectHand 関数は次のようになります。 selectHand の内部は乱数を用いて、手を選ぶという処理を行っています。random 関数は 0 から 1 までの乱数を出力します。手の数は 3 種類なので、手数を示す定数 maxSize をかけます。この値は double なので、int にキャストすると 0, 1, 2 のいずれかの整数になり、じゃんけんの手を表すことができます。
|
Judge クラスの実装 | ||||||
次に Judge クラスを実装していきましょう。完成版はこちらで参照できます Judge.java Judge クラスの属性は前節で示したように、Player オブジェクトをまとめる players と、じゃんけんの手を表す hands があります。
List クラスは java.util パッケージにあるので、一行目で import しておきます。players と hands の初期化はコンストラクタで行うことにしましょう。
親のクラスに成り代わることができると、なにがうれしいのでしょう。たとえば、List インタフェースをインプリメントした 2 つのクラス、ArrayList と LinkedList を考えてみます。ArrayList クラスはコレクションを作るのに配列を利用しています。かたや、LikedList はリスト構造と呼ばれる方法を用いてコレクションを作ります。2 つのクラスは実装はまったく異なるのですが、コレクションに要素を追加することや削除するなどの機能は同一です。List を使う側から見れば、実装が異なっていても、機能が同じであればまったく問題ありません。それならば、実装を表す ArrayList や LinkedList というクラスよりも、機能を表す List というインタフェースが重要になります。 同じことを車にたとえてみましょう。車のエンジンにはガソリンエンジンやディーゼルエンジンなど複数あります。ガソリンエンジンもレシプロやロータリーという種類もあり、カムやターボなども考えると多くの種類に分けることができます。しかし、ドライバから見れば、エンジンの種類は異なっても、同じ方法で運転はできます。車という機能さえ同じであれば、運転ができるわけです。 ただし、実装がどうでもいいというわけではありません。車でも、それぞれのエンジンの特性を知ってこそうまく乗りこなすことができるように、プログラムでも実装クラスの特徴を把握することでよりよいプログラムを書くことができます。 たとえば、ArrayList は要素へのアクセスは速いのですが、任意の場所に要素を追加したり削除するのは時間がかかります。これとは逆に LinkedList は要素へのアクセスは遅いのですが、要素の追加・削除は高速に行うことができます。 このような特徴はすぐに覚えられるものではないので、プログラミングの経験を積んでいくことでやしなっていく部分だと思います。 さて、プログラムに戻りましょう。 4 行目で初期化した players に要素を追加していくのが、7 から 9 行目の for ループです。プレイヤーの人数が分からないと要素数が決まらないので、コンストラクタの引数としてプレイヤーの人数をとるようにしました。 ループの中では Player オブジェクトを生成して、players に追加 (add) しています。Player クラスのコンストラクタはプレイヤー名が引数なので、players に追加する順番を名前にしています。 次にゲームのメインルーチンである playGame 関数を説明しましょう。
プレイヤーの手を問い合わせるために、4 行目に示したように players の要素をまず取り出します。List はどのようなオブジェクトでも持つようにするため、要素を取り出す get 関数の戻り値は Object クラスになっています。そこで、Players クラスにキャストすることが必要になります。 取り出した player に対して getHand 関数をコールして、手を問い合わせます。6 行目で問い合わせた手を hands に追加していきます。List には int や double などのクラスでないものは要素にできないので、int の代わりに Integer クラスを使用します。 10 行目で判定を行います。judge 関数については後で説明することにして、先に進みましょう。 12 から 19 行目で判定の結果を出力しています。勝者を要素に持つ winners の要素がなければ、「あいこ」なので、13 行目で出力します。要素数のチェックには isEmpty 関数を使用しています。もし、リストに要素がなければ isEmpty 関数の戻り値は true になります。 勝負がついた場合は 15 か 18 行目に示したように勝者を出力します。16 行目で winners から Player オブジェクトを取り出して、17 行目で Player オブジェクトの名前を出力するようにしています。 判定はいろいろな方法で行うことができるのですが、今回は次のように記述してみました。少し長いのですが、難しい処理はないので、容易に理解できると思います。
2. から 9. の処理が 8 行目から始まる if 文の中で行っています。たとえば、8 行目でグーがいるかどうか調べて、いなければ 9 行目の if 文でチョキがいるかどうか調べます。もし、チョキもいなければバーだけなのであいこになります。 勝負が決まったときは、勝った手の List オブジェクトを戻り値とします。あいこなら、勝者はいないので、たとえば 11 行目のように空の List オブジェクトを戻り値とします。 |
スタートアップルーチンの実装 | ||||
さて、ここまででじゃんけんゲームの実装ができたのですが、これをどうやって動かしましょうか。プログラムを動作させるには main 関数を使用することはお分かりですね。 Judge クラスに main 関数をつけてもいいのですが、これだと実行するときに
完成した Janken.java はこちらから参照できます Janken.java Janken クラスの main 関数を次に示します。
プログラムの引数は String の配列で渡されるので、引数の数を調べているのが 3 行目です。配列の大きさは length で調べることができます。引数の数が正しければ、5 行目で Judge オブジェクトを生成します。Judge クラスのコンストラクタは引数にプレイヤーの人数で int ですから、String を int に変換します。これには Integer クラスの parseInt 関数を使用することができます。parseInt 関数は static 関数なので、オブジェクトがなくても使用することができます。また、この関数は引数が数字に変換できないと NumberFormatException という例外を発生します。例外が発生したときは、7 行目で示したように、使い方を示して、プログラムを終了させます。 プログラムの引数の数が 1 以外の時は、7 行目と同様に使い方を示して、プログラムを終了させています。 生成された Judge オブジェクトに対して、15 行目で playGame 関数をコールします。playGame 関数がコールされると、ゲームが開始するわけです。 |
じゃんけんゲームの実行 | ||||
じゃんけんゲームができあがったので、コンパイルして、それから実行してみましょう。ここではソースが C:\java\janken にあった場合を示しています。
これを使用して Judge クラスの playGame 関数を書きかえてみました。
最後は現在のじゃんけんゲームではどういう方法で勝率が高いか、まだ色々研究をやっている。こんな素晴らしいアルゴリズムを提案する方を待っている。 |
【希少!廃番品!】3倍遊べる!かるた・じゃんけんゲーム・カードつなぎ!はなかっぱ かるた |
0 件のコメント:
コメントを投稿