//Ex3.java
class X
{
int method(){
System.out.println("こんにちは。私はXのオブジェクトです。");
return 1;
}
}
class Ex3
{
public static void main(String[] args){
int d; //整数変数dの宣言(「整数dを使うよ」という意味)
X x = new X();
d = x.method();//考え込むと不思議な文ですが、次のような意味になります。
//まず、Xのmethodの中身が実行される。
//そして、このメソッドから返された値1がdに代入される。
System.out.println("methodから返された値="
+ d); //dの値の出力
}
}
ここで、methodはもちろんメソッドですが、実は、mainもメソッドなのでした。(mainは特別なメソッドです。)それで、上のプログラムは「メソッドmainがメソッドmethodを呼び出している」ということができます。呼び出されたmethodは呼び出したmainに値1を返しています。(「返す」と言っても、もともとあったものを返還するという意味ではないのでした。上のプログラムではdに1が代入されることを「返す」というのです。)
ここで、もし、dに1が代入されていなければ、(上の例では単純すぎますが)なんらかの原因でエラーがおこったと判断できます。このような返り値は成功・不成功の報告(エラーチェック)になるのです。
上の例のmethodはいつも1を返すように作ってありますが、いろいろな状況に応じて返す値を変える方が普通です。その場合は、エラーチェックというより、プログラムの進行の細かいチェックになるわけです。つまり、呼び出した側で返り値を見て次の作業をすすめるようにすることができるのです。
入門9では「大魔王とヒーローが対決するゲーム」(Game.java)をつくりましたが、Game.javaは、対決が一度きりなので、ゲームの体裁になっていませんでした。これを「決着がつくまで対決を繰り返すプログラム」に改造することは今までの知識だけでできるはずです。元気のある人は自分でも考えてみてください。
そこまで元気はないという人も、下のサンプルを見る前に、入門9のプログラムの流れをもう一度見ておいてください。
while(決着がつかない間){
taiketu();
}
while(true){
taiketu();
決着がついたかどうか調べ、ついていればループをぬける
}
//ヒーローつまり英雄ですね
class Hero
{
//ヒーローのパワー
private int power;
//ヒーローのコンストラクタ、ヒーローのパワーをはじめ100とした
Hero(){ power = 100; }
//「powerを返す」メソッド
int getPower(){ return power; }
//「ヒーローが攻撃する」メソッド。nは攻撃に使うパワー。
void kougeki_suru(int n){
System.out.println("悪党め。正義の攻撃を受けてみよ。");
System.out.println("どか〜ん!!!");
power -= n; //攻撃したのでパワーを減らします。
//もちろん本当にパワーをどこかにやったのではなく、単に数値を減らすだけでした。
//もしパワーがまだ0以上ならよし、もし、負になったら、使いすぎで負けとした。
//以下のifとelseはそういう意味です。
if(power >= 0){
System.out.println("現在のパワーは" + power + "だ。");
}
else{
System.out.println("しまった!パワーを使いすぎた。");
System.out.println("もうおしまいだ!!!がくっ。");
System.out.println("ヒーローは倒れました。");
}
}
//「ヒーローが攻撃される」メソッド。nは攻撃されて減らされるパワーの量。
void kougeki_sareru(int n){
System.out.println("くそっ。悪党の攻撃も当たることがあるのか。");
power -= n; //攻撃されてパワーが減る。
//以下の仕組みはkougeki_suru()とほぼ同じ。
if(power >= 0){
System.out.println("現在のパワーは" + power + "だ。");
}
else{
System.out.println("やられた。がくっ。");
System.out.println("ヒーローは倒れました。");
}
}
}
こうすると、例えば、youというHeroオブジェクトを参照する変数があった場合、
int temp;
temp = you.getPower();
と書けば、tempにそのときのyouのパワーが代入されるのです。大魔王にも同様のメソッドを付け足せば、kurikaesi_taiketu()の定義は次のようになるでしょう。(youがHeroで、buがMaoです。)
void kurikaesi_taiketu() throws IOException{
int temp;
while(true){
taiketu();
temp =
you.getPower();
if(temp < 0){
System.out.println("\n大魔王の前に正義のヒーローは敗れました。");
break;
}
temp = bu.getPower();
if(temp < 0){
System.out.println("\n正義のヒーローの前に大魔王は敗れました。");
break;
}
}
}
ここで、「throws IOException」をメソッド名の横に付けるは、内部でIOExceptionを投げるかもしれないtaiketuを使っているため、その処理方法を書く必要があるからです。もちろん、「throws IOException」は、「何もせずに例外を外に投げろ」という意味ですが、IOExceptionはこのように何らかの処理方法書く必要があるのでした。(入門9の最後を参照してください。)
上のメソッドは、また、you.getPower()などがそのまま返り値に変わるということを考えれば、一時変数tempを使わずに
void kurikaesi_taiketu() throws IOException{
while(true){
taiketu();
if(you.getPower()
< 0){
System.out.println(
"\n大魔王の前に正義のヒーローは敗れました。");
break;
}
if(bu.getPower() <
0){
System.out.println(
"\n正義のヒーローの前に大魔王は敗れました。");
break;
}
}
}
それから、taiketu
メソッドも少し変えます。攻撃はヒーローと大魔王が交互に行いますが、taiketuではいつもヒーローが先です。ここで、もしヒーローが先に大魔王を倒してしまえば(つまり大魔王のパワーが負になってしまえば)、次の大魔王の攻撃は行われないようにしなければなりません。そこで、taiketu内のヒーローの攻撃の後で、bu.getPower()を呼び出し、もし大魔王のパワーが負なら残りの部分(つまり大魔王の攻撃の部分)を実行する前に、taiketuを終了してしまうように改造します。メソッドを終了させる命令は「return」(taiketuは値を返さないメソッドなので「return;」ですね)です。これを利用することにします。
また、ヒーローや大魔王が攻撃した際にパワーを使いすぎて死んでしまうこともあるでしょうから、これについてもチェックをいれるよう改造します。(以上の詳細は下のサンプルをみてください。returnはbreakによくにていることがわかると思います。ループなどからぬけるのがbreakでメソッドからぬけるのがreturnなのです。)
あといくつか細かいこともあります。まず、入門9のGame.cでは、ユーザに攻撃をうながすときに
System.out.print("攻撃に使うパワー(100以下の数値)を入力してください。>>
");
としていました(printは「改行なしの出力」という意味でした)が、今度は、攻撃のたびにエネルギーが減っていくので、これを
System.out.print("攻撃に使うパワー(" + you.getPower() + "以下の数値)を入力してください。>>
");
とします。ちょっと見にくいですが、まず、「攻撃に使うパワー(」と「you.getPower()(返り値)」と「以下の数値)を入力してください。>>
」を文字列としてつないで出力するのです。これによって、現在のヒーローのエネルギーが表示されるようになります。
それから、ヒーローも大魔王もkougeki_suruメソッドやkougeki_sareruメソッドでパワーがつきると何か言ってから倒れるのですが、さらにその後に
System.out.println("ヒーローは倒れました。");
System.out.println("現在のパワーは" + power + "だ。");
を
System.out.println("(現在のパワーは" + power + "になった。)");
以上をまとめるとGame.javaは、次のように改良されます。
//Game2.java
import java.io.*; //読み込み処理のために必要
//ヒーローつまり英雄ですね
class Hero
{
//ヒーローのパワー
private int power;
//ヒーローのコンストラクタ、ヒーローのパワーをはじめ100とした
Hero(){ power = 100; }
//「powerを返す」メソッド
int getPower(){ return power; }
//「ヒーローが攻撃する」メソッド。nは攻撃に使うパワー。
void kougeki_suru(int n){
System.out.println("悪党め。正義の攻撃を受けてみよ。");
System.out.println("どか〜ん!!!");
power -= n; //攻撃したのでパワーを減らします。
//もちろん本当にパワーをどこかにやったのではなく、単に数値を減らすだけでした。
//もしパワーがまだ0以上ならよし、もし、負になったら、使いすぎで負けとした。
//以下のifとelseはそういう意味です。
if(power >= 0){
System.out.println( "(現在のパワーは"
+ power + "になった。)");
}
else{
System.out.println("しまった!パワーを使いすぎた。");
System.out.println("もうおしまいだ!!!がくっ。");
}
}
//「ヒーローが攻撃される」メソッド。nは攻撃されて減らされるパワーの量。
void kougeki_sareru(int n){
System.out.println("くそっ。悪党の攻撃も当たることがあるのか。");
power -= n; //攻撃されてパワーが減る。
//以下の仕組みはkougeki_suru()とほぼ同じ。
if(power >= 0){
System.out.println( "(現在のパワーは"
+ power + "になった。)");
}
else{
System.out.println("やられた。がくっ。");
}
}
}
//大魔王。実はヒーローとほとんど同じ構造!
class Daimao
{
//大魔王のパワー
private int power;
//大魔王のコンストラクタ、大魔王のはじめのパワーは100とした
Daimao(){ power = 100; }
//「powerを返す」メソッド
int getPower(){ return power; }
//「大魔王が攻撃する」メソッド。nは攻撃に使うパワー
void kougeki_suru(int n){
System.out.println("大魔王様の一撃をうけてみよ。");
System.out.println("どか〜ん。");
power -= n; //攻撃したのでパワーを減らします。
//もちろん本当にパワーをどこかにやったのではなく、単に数値を減らすだけでした。
//もしパワーがまだ0以上ならよし、もし、負になったら、使いすぎで負けとした。
//しかし、大魔王のパワーは秘密なので書かない。
if(power < 0){
System.out.println("しまった!!!パワーを使いすぎた。");
System.out.println("む、む、む。無念だ。がくっ。");
}
}
//「大魔王が攻撃される」メソッド。nは攻撃されて減らされるパワーの量。
void kougeki_sareru(int n){
System.out.println("くそっ。正義の味方の攻撃も当たることがあるのか。");
power -= n; //攻撃されてパワーが減る。
//以下の仕組みはkougeki_suru()とほぼ同じ。大魔王のパワーは秘密なので書かない。
if(power < 0){
System.out.println("やられた。がくっ。");
}
}
}
//対決場所のクラス(ヒーローや大魔王が「もの」なら、対決場所も「もの」ですね。)
class Taiketu_basyo
{
private Daimao bu; //対決場所にいる大魔王Bu!
private Hero you; //対決場所にいるヒーローYou!
private int bu_no_basho; //大魔王のいる場所(1〜5の数値)、これは後で決まる
private int you_no_basho; //ヒーローのいる場所(1〜5の数値)、これは後でユーザが決める
//対決場所のコンストラクタ
Taiketu_basyo() throws IOException {
bu = new Daimao();
you = new Hero();
bu_no_basho = (int)(Math.random()
* 5) + 1; //1〜5の中のでたらめな数(次回に説明)
System.out.println("あなたと大魔王ブーとの決戦です。\n");
System.out.println("大魔王ブーは座標1〜5のどこかに潜んでいます。");
System.out.println("あなたもどこかに身を潜めてください。");
System.out.println("身を潜める座標(1〜5の数値)を入力してください。");
BufferedReader br =
new
BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
//ユーザから入力を文字列として受け取る
you_no_basho = Integer.parseInt(str);
//その文字列を整数に変換してyou_no_bashoに格納
}
//「ヒーローと大魔王が対決する」メソッド
void taiketu() throws IOException {
String str;
//ユーザから文字列を受け取るいれもの
int iti, kougeki; //一時的に必要な「位置」と「攻撃量」の変数(いれもの)
System.out.println("さあ、あなたの攻撃です。");
System.out.print("攻撃の位置(1〜5の数値)を入力してください。>>
");
BufferedReader br =
new
BufferedReader(new InputStreamReader(System.in));
str = br.readLine();
//ユーザから入力を文字列として受け取る
iti = Integer.parseInt(str);
//その文字列を整数に変換してitiに格納
System.out.print("攻撃に使うパワー(100以下の数値)を入力してください。>>
");
str = br.readLine();
//ユーザから入力を文字列として受け取る
kougeki = Integer.parseInt(str);
//その文字列を整数に変換してkougekiに格納
System.out.println();
//改行という意味
you.kougeki_suru(kougeki); //ヒーローYouの攻撃
//攻撃量はkougekiに代入された値、この値だけヒーローのパワーは減る
//taiketu()の改造した場所
if(you.getPower()
< 0){ //攻撃のしすぎで、ヒーローのパワーが負になれば、、、
return;
//returnはそのメソッドの実行を終了させる
}
if(bu_no_basho == iti){ //もしbu_no_bashoとitiが一致したら、
//つまり、ねらったところに大魔王がいたら、という意味
bu.kougeki_sareru(kougeki * 2);
//攻撃を受けます。このとき大魔王は
//ヒーローが使ったパワーの2倍を消耗します。
//kougeki * 2とはkougekiの2倍という意味です。
//taiketu()の改造した場所
if(bu.getPower() < 0){ //攻撃されて、大魔王のパワーが負になれば、、、
return; //returnはそのメソッドの実行を終了させる
}
}
else{
System.out.println("あなたの攻撃ははずれたようです。"); //はずれたら、何も起こらない
}
System.out.println();
//改行という意味
System.out.println("大魔王の攻撃です。");
System.out.println("(エンターキーを押してください。)"
);
br.readLine();
iti = (int)(Math.random() * 5) + 1; //大魔王の攻撃の位置は乱数(ここでは1〜5までのうちのどれか)で決まる
kougeki = (int)(Math.random() * 100) + 1; //大魔王の攻撃の量も乱数(1〜100までのうちのどれか)で決まる
bu.kougeki_suru(kougeki); //大魔王Buの攻撃(大魔王のパワーが減る)
//taiketu()の改造した場所
if(bu.getPower()
< 0){ //攻撃のしすぎで大魔王のパワーが負になれば、、、
return;
//returnはそのメソッドの実行を終了させる
}
if(you_no_basho == iti){ //当たったら
you.kougeki_sareru(kougeki *
2); //攻撃された
}
else{ //はずれたら
System.out.println("大魔王ブーの攻撃ははずれたようです。");
}
}
void kurikaesi_taiketu() throws IOException{
while(true){
taiketu();
if(you.getPower() < 0){
System.out.println(
"\n大魔王の前に正義のヒーローは敗れました。");
break;
}
if(bu.getPower() <
0){
System.out.println(
"\n正義のヒーローの前に大魔王は敗れました。");
break;
}
}
}
}
class Game2
{
public static void main(String[] args)
throws IOException {
Taiketu_basyo dokoka = new
Taiketu_basyo(); //対決場所dokokaの生成
//ここでコンストラクタが働き、ヒーローと大魔王の位置が決められる。
dokoka.kurikaesi_taiketu();
//dokokaの対決
}
}
Fig.1 Game2の実行
まだまだ、不満はあります。たとえば、パワー切れで攻撃しても「どか〜ん」といってしまうところや、大魔王の攻撃が完全にランダムだというようなところです。でも、疲れましたね。今日はこの辺にしましょう。ゲーム作りがこの講座の目的ではないので(といっていいわけをしているような、、、)、このプログラムをおもしろくする方向の改造はみなさんにお任せして、以後はJavaの技法を学ぶ方向に進むことにします。