ver1.0.0
- はじめに
- 対象読者
- 注意点
- 登場人物
- 0章 さいころとの出会い
- 1章 さいころの洗礼
- 91章 さいころドリル(1)
おめでとうございます!
あなたは晴れて、「(株)オレンジレッドソックス」(以下ORS)という、オレンジなんだか赤なんだか、よく分からないブラック企業に就職することが出来ました。
ORSは業務系からサービス系まで幅広く扱うソフトウェア開発会社です。これからあなたはORSの中で様々な業務をこなしていかなくてはなりません。果たして、無事勤め上げることができるのでしょうか。
Javaの教科書を一通り読んだけど、いざ自分で何か作ってみようとしても、うまく作れない人。
- この本とは別に、なにか1冊Javaの教科書を用意してください。ORSはブラック企業なので、Javaの基本文法を懇切丁寧に教えてはくれません!
- 最初から順に読み進めて下さい。
- 文章の途中で 【Action!】 と書かれた箇所にであったら、実践課題の始まりです。実際にソースコードを書き、実行してみてください。
- 文章の途中で 【Boss!】 と書かれた箇所にであったら、ボス戦の始まりです。 【Action】 とやるべきことは同じですが、力ずくで解こうとすると、あなたはとんでもないダメージを食らいます。よく考えて、問題に取り組んで下さい。
- 分からない問題や解決に余りにも時間がかかりそうな場合、飛ばして先に進むことはできません。ほかの参考書等を参照して、必ず問題を解決してから、先に進んでください。
- ボス戦など、こんなのできるか!と思ってしまうような理不尽な問題に、直面することがあるかもしれません。しかしそれは、問題が理不尽なのではなく、あなたの実力が足りないのです。考え方を変えれば、必ず解決できるはずなので、じっくりと考えてみてください。
- ハラ部長 ・・・ORSゲーム開発部部長。リーダーシップ溢れる、頼れる上司。だが部下の評価に関しては冷酷な一面もあり、駄目だと判断した時の見切りも早い。
- ウツミグループ長 ・・・ORSゲーム開発部サイコロチームのグループ長。打たれ強い。
- サワムラ先輩 ・・・ORSゲーム開発部サイコロチームの先輩。力持ち。
- クワタさん ・・・ORSゲーム開発部サイコロチームの先輩。冷静で理論家。
- スガノ君 ・・・あなたと同期入社。ハラ部長の親戚で完全なコネ入社だが、実力は抜群。今年の新人王候補。
- クリヤマ部長 ・・・ORSハム開発部部長。口癖は「コロス」。なぜソフト会社でハムを作っているのかは謎。
- オオタニ君 ・・・あなたと同期入社。ソフトとハムの両方を開発する二刀流を目指している。なぜハムを作りたいのかは謎。
- 伝説のナガシマ ・・・かつてORSでDiceクラスを一人で開発した、伝説のプログラマー。現在は消息不明
- ナベツネ会長 ・・・ORS会長。ソフトウェア開発のことなどまるで分らないが、幅広い人脈と豊富な資金力で、社内外に多大な影響力を持つ。
入社初日。あなたはハラ部長に連れられて、「ゲーム開発部」と書かれた部屋に案内されました。そう。あなたはゲーム開発部門に配属されたのです。ゲーム開発部ではウツミグループ長のもとで、サイコロチームに所属することになりました。
席は先輩のサワムラさんの隣。何だかいかつくて、怖そうな先輩です。チームにはもう一人、クワタさんという方がいるそうなのですが、今は有休を取ってアメリカ旅行中なのだそうです。
自己紹介を終え、席について割り当てられたPCの電源を入れていると、早速ウツミ部長が話しかけてきました。
ウツミ「このチームでは、サイコロを使ったゲーム開発をやっているんだ。君にも早くサイコロを使いこなしてもらわないとね」
サイコロ?
ウツミ「そう、サイコロだ。サイコロゲームで一山当てるのが、このチームの目標だ」
サイコロ転がして金儲けできれば、だれも苦労しないだろうとあなたは思いましたが、入社初日から文句を言う事も出来ず、おとなしく聞いておくことにしました。
ウツミ「では、さっそくこのクラスを見てほしい」【Action!】
Eclipse の「プロジェクト・エクスプローラ」上で、src/ors/dice/Dice.java をダブルクリックし、 ソースコードを開いて下さい。開くことができましたか?
// works.work000.Main000_00.java
package ors.dice;
/**
* 6面体サイコロ
* @author nagashima
*/
public class Dice {
/** サイコロの面の数 */
private int face = 6;
/**
* サイコロを1回振ります
* @return 出た目の値(1~6)
*/
public int role() {
return (int)(Math.random() * face) + 1;
}
}これは?
ウツミ「これがわが社が誇るサイコロクラス Diceクラスだ。かつて会社に所属していた伝説のプログラマー『ナガシマ』氏が作成した最高傑作だ。どうだい、素晴らしい出来だろう」
はぁ。あなたはまだプログラミング初心者でプログラムの良し悪しなどわかりませんので、相槌を打つしかありません。
ウツミ「このクラスを使いこなせるようになるのが、君がまず取り組むべき課題だ。続いて、 works.work000.Main000_01.java を開けてみたまえ。」
// works.work000.Main000_01.java
package works.work000;
import ors.dice.Dice;
/**
* さいころの動作確認クラス
* @author sawamura
*/
public class Main000_01 {
public static void main(String[] args) {
// さいころを1つ用意します
Dice dice = new Dice();
// さいころを1回振ります
int value = dice.role();
// 出た目を表示します
System.out.println("さいころの目は" + value + "です");
}
}ウツミグループ長「これは、サワムラ君が用意しておいてくれた、Diceの使い方を学ぶためのサンプルだ。ささ、早速物は試しだ。動かしてみたまえ」【Action!】
先ほど見せてもらった、works.work000.Main.java をEclipse上で実行してみましょう。
「コンソール」に何と表示されましたか?
ウツミ「Diceの使い方は分かってくれたかな?では、君の始めての仕事だ。Diceのテストをひたすら行うのが君に与えられる役割だ。後はサワムラ君、任せたよ」
サワムラ「じゃあ、works.work000.Main000_02.javaを開けてくれるかな」【Action!】
// works.work000.Main000_02.java より抜粋
Dice dice = new Dice();
System.out.println("さいころの目は" + dice.role() + "です");
// TODO 問題0-02をやってみよう「さいころを3回振り、結果をコンソールに表示する」サワムラ先輩曰く、「俺が1回、試しに振っておいたから、あと3回繰り返すだけだ。簡単だろう?」 だそうです。
サワムラ「じゃあ、今日はここまで。明日から本格的なテストに入るから。お疲れさん」
強面のサワムラ先輩も、しゃべってみれば優しそうな先輩で、あなたはホッとしました。
明日も頑張ろう。そう思いながら、あなたは家路につくのでした。
サワムラ「おはよう。じゃあ、昨日の続きだ。機能さいころを3回振るテストをやったよね。あれを、あと1万回お願いしたい」
えっ?【Boss!】
サワムラ「優しい先輩だと言ったな。あれはウソだ」 works.work001.Main001_01.java に実装してください。
サワムラ「さいころを振るだけのゲームってつまらないと思うんだ」
そりゃそうですね。
サワムラ「なので、斬新なゲームを考えてみた。ちょっと見てくれ。こいつをどう思う?」
- さいころを1回振ります
- 出た目が3以下の場合は「あなたの負けです(N)」とコンソールに表示します。それ以外の値の場合は、「あなたの勝ちです(N)」と表示します
※Nにはさいころで出た目が表示されます
んー、どうでしょう?
ウツミ「おっ、ナガシマ先輩のマネか?」【Action!】
works.work001.Main001_02.java に実装してください。
サワムラ「1回しか遊べないのはつまらんな。5回くらいの連続勝負にするか」
繰り返すの、好きですね。【Action!】
works.work001.Main001_03.java に実装してください。
- さいころを1回振ります
- 出た目が3以下の場合は「あなたの負けです(N)」とコンソールに表示します。それ以外の値の場合は、「あなたの勝ちです(N)」と表示します
- 1~2 を計5回繰り返します。
※Nにはさいころで出た目が表示されます
???「あなた、ループ処理の中で、出た目の判定を書いてるの」
はい。
???「バカじゃないの?そういう時は判定処理をメソッドとして外に出すのよ。そうすれば、判定条件を後から変更したくなったときにループ処理を壊さずに安全に変更できるでしょ」
、、、どちら様ですか?
サワムラ「有休明けのクワタさん。俺の天敵だ。」
クワタ「サワムラも、何でも力ずくでやろうとすんじゃないわよ。」
サワムラ「。。。すんません」
怖い先輩がまた一人増えました!!【Action!】
works.work001.Main001_04.java に実装してください。 サワムラ「俺が、勝ち負けの判定をするjudgeメソッドのひな形をあらかじめ作っておいたから」
public static boolean judge(Dice dice) { // TODO 勝ち負け判定処理を実装しろ! return false; }サワムラ「今は必ずfalse、つまり負けを返すような仮の実装になっている。まずは、このメソッドの中身を以下の仕様で修正してくれ。
- 引数.diceを使って、さいころを1回振る 2. さいころの出目が3以下の場合はfalseを返します。それ以外の値の場合は、trueを返します。
サワムラ「次に、mainメソッドの実装だ。以下の仕様通りに作ってくれ」
- さいころを引数に、judgeメソッドを呼び出し、その戻り値を受け取ります
- 戻り値がtrue(勝ち)の場合は、「あなたの勝ちです」とコンソールに表示します。false(負け)の場合は「あなたの負けです」と表示します。
サワムラ「なんか、ゲームが退化してんな。」
退化、ですか?
サワムラ「ver1のころは『あなたの勝ちです(4)』って感じで、勝敗の後に出目を表示させてたじゃん?今回、勝敗判定をメソッドとして外に出したせいで、出目が何だったのかわかんなくなっちゃったよな。やっぱりクワタさんって口だけ。。。」
クワタ「あんたのメソッド設計が悪いのよ。何、単純にboolean型返してんのよ。そういう時は、判定結果と出目を持つオブジェクトを戻り値にすんのよ。」
クワタ「何にも考えずに基本型を戻り値にするから、拡張性のないメソッドになるのよ。バカ。筋肉バカ」
サワムラ「ぐぬぬ」【Action!】
works.work001.Main001_05.java に実装してください。 クワタ「わたしが、勝ち負けの判定をするjudgeメソッドのひな形をあらかじめ作っておいたわ」
public static JudgeResult judge(Dice dice) { // TODO 勝ち負け判定処理を実装しろ! return null; }サワムラ「今は必ずnullを返すような仮の実装になっているの。このままじゃ何の役にも立たないメソッドね。まずは、このメソッドの中身を以下の仕様で修正してくれる?
- ors.dice.JudgeResult クラスのインスタンスを作成します
- 引数.diceを使って、さいころを1回振る
- 1で作ったインスタンスのsetValue() メソッドを使って、さいころの出目をセットします。 4. さいころの出目が3以下の場合はfalseを1.で作ったインスタンスにsetWin()メソッドを使って値をセット返します。それ以外の値の場合は、trueをセットします。
サワムラ「次に、mainメソッドの実装よ。以下の仕様通りに作ってね」
- さいころを引数に、judgeメソッドを呼び出し、その戻り値を受け取ります
- 戻り値のisWin()メソッドを呼び出し、true(勝ち)の場合は「あなたの勝ちです(N)」とコンソールに表示します。false(負け)の場合は「あなたの負けです(N)」と表示します。
※Nにはさいころで出た目が表示されます。さいころの出目は、judgeメソッドの戻り値のgetValue() メソッドで取り出します。
サワムラ「さいころって、なんか空しいよな」
どうしたんですか、いきなり
サワムラ「だって、1から6までの目しか出ないんだぜ!そんで、4以上が勝ちってなんだよ、このゲーム。下らない」
サイコロチームを全否定してますけど、大丈夫ですか?
サワムラ「大丈夫だ。問題な、、」
ウツミ「言わせねーよ!」
クワタ「1振りのさいころは1~6しか出ないけど、3回振って合計すれば3~18よね」(ぼそっ)
ウツミ・サワムラ「イイね!」
なんだこれ?【Action!】
works.work001.Main001_06.java に実装してください。
- さいころを3回振り、出た目を合計します。
- さいころの出目に応じて、以下のようにコンソールに表示してください。
- 3の時: あなたのぼろ負けです!(N)
- 4~7の時: あなたの負けです(N)
- 8~12の時:引き分けです(N)
- 13~17の時:あなたの勝ちです(N)
- 18の時:あなたの圧勝です!(N)
※Nにはさいころで出た目が表示されます。
サワムラ「もう、俺はひな形なんて作らないからな。クラスとmainメソッドの宣言だけ書いておいたから、後は全部自分でやるんだ」
サワムラ「いいか、今まで学んだことを踏まえてプログラムを書くんだぞ。決してのびのび自由に書くんじゃないぞ。わかってるな」
サワムラ「もしのびのび書いてみろ、クリヤマ部長呼ぶからな。クリヤマさん呼んだらあれだぞ、お前、この本が終わるからな」
サワムラ「2章からはハム開発編が始まるからな。『問題02-01 豚肉を塩漬けしろ!』なんつって、俺とお前、ふたりでハムを作る作業に取り掛かるからな」
クワタ「誰か、こいつ黙らせて」
サワムラ先輩を黙らせる、文句ないコードをあなたが書くのです!
???「くだらん!」
ウツミ「か、会長!」
ナベツネ「何がさいころ3回だ、みみっちい。もっと大量のさいころをこう、ドバーッと振らせればいいじゃないか。」
ナベツネ「本当のさいころでは実現できないことをやってこそ、コンピュータじゃないのかね?1万個振らせればいい。男らしくな!」
ウツミ「おっしゃる通り!」
サワムラ「さすがです!」
クワタ「わたし、女ですけど」
もうやだ、この会社**【Boss!】**
works.work001.Main001_07.java に実装してください。
- さいころを1万回振り、出た目を合計します。
- 1で求めた値をコンソールに表示してください。
- 1~2 を10回繰り返してください。
クワタ「念のために聞くけど、さっきのゲーム、forループの中にもう一個、forループ書いたりしてないでしょうね?」 書きましたけど、なにか? クワタ「サワムラー!!、ちょっとサワムラー!!!!」 サワムラ「どうも、私がサワムラです。愛称は『サワムー』でお願いします。」 クワタ「あなた、案外メンタル強いわね」 サワムラ「『サワムラー』だけは勘弁してください。ポケ○ン的な意味で」【Action!】
works.work001.Main001_08.java に実装してください。
クワタ「ループの中にもう一つループを入れるのを俗に、『ループがネスト(nest)する』っていうの。」
クワタ「ループがネストすると、他の人がソースコードを読んだときにとても読みにくいし、読みにくいがゆえに、バグも起こしやすい。」
サワムラ「だから、2重ループになりそうだと感じたら、二つ目のループ処理をメソッドに切り出すといいってことだな」
クワタ「なんであんたが結論言ってんのよ。」
- さいころをN万回振り、出た目を合計した結果を返す rollTimes() メソッドを実装してください。
- 1で実装したメソッドを使用して、さいころてんこ盛りゲームを作りなおしてください。
この章以降は、これまでの各章でつまずいたポイントを克服するための練習問題を掲載します。 どんどん解いて、理解を深めましょう
サワムラ「さいころを使ったゲームに役立ちそうな関数をいくつか作っておこうと思うんだ。これから言う関数を作ってくれないか」
works.work001.Main091_01.java に実装してください。
さいころの出目を引数に取り、+1した値を返す add1 メソッドを作って下さい。
サワムラ「さいころの出目に1点ボーナスを与える機能だな。」
works.work001.Main091_02.java に実装してください。
さいころの出目を引数に取り、+10した値を返す add10メソッドを作って下さい。
mainメソッド内でさいころを1回振り、コンソールに「さいころの出目はMで、+100した値はNです。」と表示してください。
※N…さいころの出目、M…+100した値
クワタ「+100点なんて、ボーナス過ぎじゃない?サイコロの出目、あんまり関係ないじゃん。」
サワムラ「クイズ番組で、最終問題は得点が100倍です!とか、良くあるじゃないですか」
works.work001.Main091_03.java に実装してください。
さいころの出目と足したい値の2つの引数を取り、足し算した値を返す addNメソッドを作って下さい。
mainメソッド内でさいころを1回振り、足し算したいお好きな値を使ってaddNメソッドを呼び出してください。
コンソールに「M+N=Lです。」と表示してください。
※M…さいころの出目、N…足し算したい値、L…addNメソッドの戻り値の値
クワタ「このメソッド一つあれば、add1メソッドもadd100メソッドも必要ないわよね。」
works.work001.Main091_03.java に実装してください。
さいころの出目と足したい値の2つの引数を取り、足し算した値を返す addNメソッドを作って下さい。
mainメソッド内でさいころを1回振り、足し算したいお好きな値を使ってaddNメソッドを呼び出してください。
コンソールに「M+N=Lです。」と表示してください。
※M…さいころの出目、N…足し算したい値、L…addNメソッドの戻り値の値
クワタ「このメソッド一つあれば、add1メソッドもadd100メソッドも必要ないわよね。」
works.work001.Main091_04.java に実装してください。
クワタ「和風さいころブームの予感がする。。。」
サワムラ「まじすか?」
さいころの出目を引数にとり、対応する漢数字を返す toKanji メソッドを作って下さい(例: 1-> 一、5->五)。引数に1~6以外の値が渡されたときは空文字列("")を返してください。
mainメソッド内でさいころを5回振り、それぞれについて、さいころの出目とtoKanjiメソッドを呼び出した結果を、コンソールに表示してください。
works.work001.Main091_05.java に実装してください。
さいころの出目を引数にとり、出目の個数分"○"を羅列した文字列を返す toMark メソッドを作って下さい(例: 3-> ○○○)。引数に1~6以外の値が渡されたときは空文字列("")を返してください。
mainメソッド内でさいころを5回振り、それぞれについて、さいころの出目とtoMarkメソッドを呼び出した結果を、コンソールに表示してください。
- 2013/10/19 ver1.0.0 初版作成