Java Mid Basic 〜Lv2_8_Javaの基本(Mapを使う)ゲームループ付き〜

イントロダクション

前回は、ファイルの読み込みを行いました。
こんな感じで動きました。

Mapを使う

今回は、Mapを使用します。java.util.Listと同じようにインターフェースです。このMapインターフェースは実装クラスにHashMapがあります。詳細はリンク先の「既知のすべての実装クラス」を見てください。
そして、今回はこのMap(HashMap)を使って、ゲーム上のマップ(目には見えない)を表現することを考えたいと思います。

目に見えないマップ

通常、ゲームのマップといえばキャラクターが動いて「〜の街に入る」とかの動きをするのですが、今回はテキストRPGを作ろうとしているので、その部分を表示しません。全て「プレーヤーの想像」に映し出せるようになんとか「文章」を考える必要があります。そしてBGMも大切です。。。が、まずは「Javaを理解する」を目的としているのでプログラムの方を優先します。
「目に見えないマップ」とは、プログラムの処理上では存在しているけど、ユーザー(プレイヤー)は見ることができない。。。という意味です。
例えば、ユーザーにDBからデータを取得するためのSQLを見る必要はないし、機密情報でもあるので画面には表示しません。
同様に、今回のコンソールゲームでは、なるべくプレーヤーの想像の中に「画面」を描画してもらえるように作成するので、目に見える マップは邪魔以外の何物でもないのです。(そういうコンセプトなのです(笑))

実行結果

処理内容

作成したコードはGitにあります。

/** 現在位置の情報を返却する */
public void showPositionInfo(String pos) {
    if (placeInfo == null) {
        System.out.println("現在位置の情報が設定されていません。(placeInfo = null)");
        System.exit(-1);
    }
    // 入力が「move 数字」になっていない場合はエラー
    if (pos.matches("move [0-9]") == false) {
        System.out.println("入力コマンドが不適切です。move [0-9]で入力してください");
        System.exit(-1);
    }
    // から文字を削除
    String place = pos.replaceAll("move", "");
    // moveを削除
    place = place.replaceAll(" ", "");
    System.out.println(placeInfo.get(place));
}

初めのif (placeInfo == null) {はフィールド変数にインスタンスが設定されていない場合の例外対応です。想定外の場合というのを考慮に入れています。が他の部分など、全対的にどのような流れで処理を行うのか考えていない状態なので、まぁ、勘弁してください。
そして、コマンドが「move 1」のように「1」の部分が数字で入力されている場合この時にMapに登録されている値を表示します。
ちなみにMapに登録する処理は以下のコードで実装しています。

/** 現在位置の情報を保持するMapを作成 */
public Map getInfoMap() {
    HashMap map = new HashMap<>();
    map.put("1", "マス1");
    map.put("2", "マス2");
    map.put("3", "マス3");
    map.put("4", "マス4");
    return map;
}

HashMapのインスタンスを生成して、”1”のキーには値: "マス1"を設定します。同様に2〜4まで設定したところで設定処理を終了しています。
プログラムの作成は今までにやってきているので、下の「関連ページ」を参照してください。

でわでわ。。。

関連ページ



Java Mid Basic 〜Lv3_1_Javaの基本(リファクタリングLv2)ゲームループ付き

イントロダクション

前回は、リファクタリングをやり、メインメソッドを整理しました。ここまで来た方、おめでとうございます。

ここから、オブジェクト指向プログラミングの始まりです。

今迄の事がわかれば何かしらの処理を自分で考えて作れるレベルになっていると思います。でわ、ここから何をやるか?ですが、基本の更に深いところ、オブジェクト指向について理解していこうと思います。

オブジェクト指向

オブジェクト指向については、色々な書籍があり、色々な事が書かれていますが、ネコとかイヌを例に出しているものは、混乱すると思います。(自分はハマりました(笑))

クラスの書き方をしたのように図にして見ました。ズバリUMLになります。

![](http://zenryokuservice.com/wp/wp-content/uploads/2019/08/スクリーンショット-2019-08-23-20.49.49-300x222.png)

「オブジェクト指向ってなによ?」という疑問がはじめに出てくると思います。諸説ありますが。。。

早い話が

「プログラムの資源を現実にあるモノ(オブジェクト)と同じように扱う(考える)ためのコードの書き方(考え方)」です。

具体的

プログラムを眺めてみると、1つのファイルに1000行を超える様なデカイ、ファイルになっているものがあったりします。申し訳ないがこういうプログラムは「オブジェクト指向」していません。何故か?再利用出来ないからです。

まずは概念

プログラムの動き、目に見えないので大雑把な概念からイメージの輪郭を拾います。この概念を理解するのにわかりやすいのがUMLだと思うのでUMLのクラス図を例に出したいと思います。

UMLの細かい部分に関しては下のリンクを参照下さい。

UMLツール Star UML〜ユースケース図を書いて見た〜

クラス図の書き方

オブジェクトの基本単位

Java言語の場合、オブジェクトの単位はクラスです。もっと言うと、全てがクラスで表現されます。だからオブジェクト=クラスで考えて良いです。

上のリンクは、UMLのユースケース図について記載しています。そして、クラス図の書き方も隣のリンクに記載しました。

早い話が、プログラムをどのように使うか?(ユースケース)とどんな構成で作るか?(クラス図)を絵にしたものがUMLです。

準備

オブジェクト指向プログラミングの準備として、どんなクラス構成でやるか?(プログラム・デザイン)を考えます。こんなデザイン(設計)、あんなデザイン…と最も美しい(効率の良い)デザイン(設計)をやります。もちろん「完璧なデザイン(設計)」は存在しないので、現時点での最高のもので良いと思います。

実装

準備の段階で作成したデザイン(設計)を元にコーディングを行います。

今回は、メインメソッドを整理した状態で再実装(リファクタリング)します。注意点は以下の通り。

  1. 作成したオブジェクトは再利用出来るように作る
  1. 各オブジェクト間の依存関係を分断してやる。なるべく「このクラスを使う時はあのクラスも必要…」とならない様にする

あとは「リーダブルコード」を読みましょう(笑)

おススメです。

コーディング開始

とは言っても、即コードを書くわけではありません。まずはコードを眺めます。そして、前回作成したメインメソッドを全体の流れとして考えます。

  1. 無限ループを作る
  2. プロパティファイルから値を取得
  3. 値が取得できない時は初めの実装の処理
  4. byeコマンドでコマンドリストを出力しアプリ終了

この部分はメインメソッドで実装してます。

本題

オブジェクト=クラスの構成とつかい方に関しては、下のリンクに記載しているので。。。

自作クラスの使い方(呼びたし方について記載します。

まずはしまめに、『クラスを使用する時にはまず「new」します。』という考えを捨てて下さい。必要なので「new」するという事です。

new演算子

クラスをインスタンス化するのはクラスに初期化処理が必要で、同じクラスを複数人で使用したい時など、クラスをnewします。

<例>

サーバーにユーザがアクセス、ログインした場合、LoginUserクラスをインスタンス化しない場合、LoginUserクラスはずっとユーザデータがセットされないので、クラスと言う型が存在しているだけになります。

しかし、インスタンス化してやるとユーザデータがセットされ1つのインスタンスとして存在できるので、サーバーのメモリが許す限り、ログインしたユーザを識別する事が出来ます。

まとめ

大雑把で良いので「クラス」「オブジェクト」という概念に対する偏見(ないのがベスト!)を捨てることができれば、おっけ!です。次回からは実際のコードと実行結果などを見ながら学んでいきたいと思います。

でわでわ。。。



Java Mid Basic 〜Lv2_7_Javaの基本(ファイルを読む)ゲームループ付き〜

イントロダクション

前回は、プロパティファイルの読み込みをやりました。
そして、今回はテキストファイルの読み込みをやります。

前回と何が違うのか?

前回の「プロパティファイル」は読み込むための処理が全てJavaAPIで実装されている状態なので、以下の実装がありません。

  1. ファイルを開く(Open)
  2. ファイルを読み込む(Read)
  3. データ(ファイルの中身)を取り出す

ちなみに、ネットワークでの通信処理もこのファイル操作と同様な処理を行うので、つまり概念も同じなので、理解しておくと後々楽ですし、面白いこともたくさんできます。

ファイル読み込み

ファイルの読み込みは上記の手順で行います。
サンプルコードです。テキストファイルは「title.txt」で、配置場所はresources/にあります。

/**
 * テキストファイル"title.txt"を読み込みコンソールに出力します。
 */
public void showTitle() {
    File file = new File("resources/title.txt");
    BufferedReader buf = null;
    try {
        buf = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8);
        // テキストファイルを出力する
        String line = null;
        while((line = buf.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("ファイル読み込みエラーです、アプリケションを終了します。");
        System.exit(-1);
    }
}

ソース全体はGitにアップしてあるのでそちらを参照ください。

処理内容

Fileクラスでtitle.txtをOpenします。

File file = new File("resources/title.txt");

そして、BufferedReaderでファイルの読み込みを行います。

buf = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8);

読み込んだデータ(ファイルの中身)を取り出します。

// テキストファイルを出力する
String line = null;
while((line = buf.readLine()) != null) {
    System.out.println(line);
}

そして、実行結果は下のようになります。

でわでわ。。。



Java Mid Basic 〜Lv2_5_Javaの基本(コマンド履歴を作る)ゲームループ付き〜

イントロダクション

前回は「dirコマンド」を実装しました。オプションとかは実装してませんが…
### 配列の使い方
Listについてやりますが、一応までに「[配列はこんな感じ](https://zenryokuservice.com/wp/2018/05/04/java-bassic-3/ "配列はこんな感じ")」というものを作成したので記載しておきます。


とりあえずは「コマンドを実行」という目的を達成する事が出来たので良しとします。

Listを使う

リストインターフェースなどに関してはこちらの記事を見ていただきたく思います。

今回はこのListを使ってコマンド履歴を作る事にします。今回はリストをフィールド変数にする事でアプリが起動している間データを保持する様にします。

現状の設計

はじめに、アプリを起動したら、コマンドの入力待ちをします。

  1. 「hello」が入力された場合はコンソールに「Hello World」を表示
  2. 「計算式(四則計算)→1+1など」が入力された場合は、計算の結果をコンソールに表示
  3. その他の入力はエラーにして、プログラムを終了

変更後の設計

上の「その他〜」の部分から変更します。

  1. 「hello」が入力された場合はコンソールに「Hello World」を表示
  2. 「計算式(四則計算)→1+1など」が入力された場合は、計算の結果をコンソールに表示
  3. 「bye」と入力されたらコマンドの履歴を表示してアプリを終了する
  4. その他の入力はエラー出力をして次の入力待ちを行う

実装

変更したところは「byeと入力されたら〜」の部分を追加しただけです。
なので、アプリが終了した時に入力されたコマンドの一覧をコンソールに出力する処理を実装します。

### 具体的に
入力されたコマンドは保持する必要があります。「登録する」とか「保存する」というのはDBやファイルに保存してアプリが終了してもそのデータが保存されることを指します。「保持する」というのはアプリケーションが起動している間など、一時的に保存することを指します。
その簡単な方法として「フィールド変数」を使用する方法がります。

### フィールド変数
フィールド変数は下のようにクラスの中に記載します。
ちなみに下のクラスは「人間」を表すクラスを作成しました。
#### クラスとは
フィールド変数とメソッドを持っている、カプセル化されたオブジェクトです。

public class Human {
   /** 名前 */
    private String name;
   /** 年齢 */
    private int age;
   /** 身長 */
    private int tall;
    /** コンストラクタ */
    public Human() {
        name = "デーモン閣下";
        age = 10040;
        tall = 160;
    }
    public void greet() {
        int num = 0;
        System.out.println("私は" + name + "と申します" + "年齢は" + age + "、身長は" + tall + "cmです"); 
        num = 10;
         System.out.println("num: " + num);
     }
     public void count() {
         int num = 0;
         num = 10;
         age++;
         System.out.println("num:" + num + " / age: " + age);
     }
}

処理内容
1. コンストラクタでフィールド変数に値を設定します
2. greet()で挨拶をします

このような形でフィールド変数を使用します。
### スコープ
ここで「スコープ」という言葉について記載したいと思います。この言葉は「変数の寿命」を意味します。上のコードで行くとフィールド変数はクラスのインスタンスがある間ずっと生きている変数になります。
具体的には下のコードでHumanクラスを実行した時にローカル変数「num」はメソッドが動いている間だけ生きている変数です。なのでクラスの中でiint num;というコードが複数あってもビルドエラーにはなりません。

public static void main(String[] args) {
    Human human = new Human();
    human.greet();
    human.count();
    human.greet();
}

このように処理を行った時、1回目のgreet()で「age」は10040と表示されますが、2回目は「10041」と表示されます。
対して「num」は何回実行しても「10」のままです。
スコープにより変数の寿命が違うのでこのような違いが出ます。

#### コマンドの一覧
実装方法に関してはこれまでに記載したので、作成したコードと実行結果を載せます。
[サンプルコードはGit](https://github.com/ZenryokuService/PracticeJava1/blob/master/PracticeJava1/src/jp/zenryoku/sample/lv2/Lv2_5_CommandHistory.java)に揚げてあります。
そして、起動結果です。

でわでわ。。。



Java Mid Basic 〜Lv2_4_Javaの基本(Dirコマンドを作る)ゲームループ付き〜

イントロダクション

前回は、作成したコードを整理整頓しました。前回のものはまだまだ初歩的なものなので創意工夫でより良いコードをかけるようにやって見てください。

Dirコマンド

コマンドプロンプトを叩いたことがある人は馴染みのコマンドだと思います。ちなみにリナックスやMacの場合は「ls」コマンドで同じことができます。
単純に現在開いているディレクトリ(カレントディレクトリ)にあるファイル(フォルダ)を表示するコマンドです。

JavaでDirコマンド

Javaでコマンドをそのまま実行することができます。
Rumtime.exec()を使用することで可能ですが、今回はJavaプログラムで同じようなことをやって見ます。

Fileクラス

このクラスを使用してディレクトリにあるファイルの一覧を表示する処理を実装します。

/**
 * Dirコマンドの処理を実装
 */
public void dirCommand() {
    File dir = new File(".");
    String[] files = dir.list();
    for (int i = 0; i < files.length; i++) {
        System.out.println(files[i]);
    }
}


こんな感じで実装すると、ビルドパス上の(Eclipseでの実装は設定の関係でプロジェクト直下がカレントディレクトリになります。
その実行結果はこんな感じです。

そして、今回作成したコードはGitにアップしてあります。
コマンドの処理部分は割愛しますが、Fileクラスを使用した実装部分について記載します。

Fileクラス

このクラスはファイルやディレクトリを表現するクラスです。実装したコードは上のようなものですが、1行ずつ内容を記載すると以下のようになります。

File dir = new File(".");

現在のディレクトリ(カレントディレクトリ)を示す"."を引数に渡してインスタンス化

String[] files = dir.list();

list()メソッドで対象のディレクトリにあるファイル(ディレクトリ)の一覧を取得します。

for (int i = 0; i < files.length; i++) {
    System.out.println(files[i]);
}

あとはループで表示するだけです、ちなみに指定するディレクトリにより取得するデータ(ファイルなど)の数が違うのでループ文で処理を行っています。

でわでわ。。。



Java Mid Basic 〜Lv2_3_Javaの基本(リファクタリング実践)ゲームループ付き〜

イントロダクション

前回は、リファクタリングについて触れました。
しかしコードまではいかなかったので、今回はコードの話をします。

リファクタ実践

まずは修正するコードを眺めます。
そーすると、だんだん同じような処理をしているところが見えてきます。

同じ処理をしているのはどこでしょう?

Switch文のところです、switch(kigo) {とコードを書いている部分が複数見当たります。しかも結構な行数を使っている。。。

そんなわけで、対象の部分をまとめてしまおうと考えるわけなのですが、キーワードは「同じような処理(コード)」です、同じような処理なので、値を変えてやれば、ちょっと工夫をすれば、なんとかなりそうです。

自分の出した答えは

「メソッドを作成する」です。そして、作成するメソッドは入力された計算式から「足し算なのか、引き算なのか。。。」を判定するメソッドを作成しました。実際にコードを記載します。

/*
 * judgeKigo()のテスト
 */
@Test
public void testJudgeKigo() {
    Lv2_3_Calculate test = new Lv2_3_Calculate();
    try {
        int kigo = test.jadgeKigo("1+1");
        assertEquals(0, kigo);
        int kigo1 = test.jadgeKigo("1-1");
        assertEquals(1, kigo1);
        int kigo2 = test.jadgeKigo("1*1");
        assertEquals(2, kigo2);
        int kigo3 = test.jadgeKigo("1/1");
        assertEquals(3, kigo3);
    } catch(Exception e) {
        e.printStackTrace();
        fail();
    }
}

処理の内容としては以下の通りです。

  1. テスト対象メソッド(jadgeKigo())に「1+1」を渡した時の結果が「0(足し算)」である事の確認。
  2. 同様に引き算(1)
  3. 掛け算(2)
  4. 割り算(3)

このメソッドが想定通りに動くのかテストします。作成したのはLv2_3_CalculateTestです。

問題

今度はswitch文を何度も書かなくて良いように修正して見てください。テストクラスで上のように、この値を渡したらこー返ってくる。というのを確認するメソッドがあれば、修正しても問題がないことをすぐに確認できます。

処理の実行するサンプルコードです。
そして、テストクラスです。

追伸

リファクタリング(メソッドで処理を分割しただけ)の後にテストを実行して見ました。

でわでわ。。。



  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜

Java Mid Basic 〜Lv2_2_Javaの基本(リファクタリング)ゲームループ付き〜

イントロダクション

前回は、四則計算を行うプログラム(ゲームループ付き)を作成しました。

しかし問題が。。。

このプログラムには致命的なバグがあります。これは計算結果を代入する変数が「int型」のため割り算の結果も整数になっていることです。本当は「少数」の答えが入るはずです。
つまり4 / 3 = 1.33333 ...の時に答えが「1」というのは間違いで、「1.33333 ...」というのが正しいということです。

ここでJUnit

上ような細かい部分に関しては、Javaに長く触っている人間(自分)でもよくわかっていない部分があります。
それは、「4>それは、「4 /3」の答えはdouble型で表示したらどうなるか?です。
なのでテストして見ます。「テストクラス」という言葉を前回使用しましたが、その部分には触れませんでした。
前回作成したテストクラスはジッソしたクラスと同じ名前になっています。名前になっています。これはよろしくないので以下のように作成しました。そして小数点で表示されない原因を探るべくJUnitテストを実行しました。

JUnitクラス

色々試した結果「割り算を行うときには(答えが小数点になるときは)」計算する値も小数点で計算する必要がある」という結論に至り、「割り算のときは数値を小数(double)で扱う」という仕様を追加することにしました。以下のようなコードになるということです。

// 割り算の場合
double sahenDouble = sahen;
double uhenDouble = uhen;
ansDouble = sahenDouble  / uhenDouble ;

つまり、割り算のときは「小数」を使用するということです。
そしてそれをコードにしたのがGitにアップしてあります。初めのコードと比較された形で閲覧することができると思います。

リファクタリング準備

そして、ソースが汚いのでこれを綺麗にしてやる必要があります。そのために必要なテクニックが「メソッドを作成する」です。「え?そんなのわかるけど?」と思った方はスキありで一本取られます(笑)

メソッドの作り方

先ほどの通りに「メソッドの書き方」は今までに説明しているのでわかると思います(基準をこのブログ記事を読んで学んでいる人に合わせるので。。。)。

どーゆーことか?

「メソッドを作るのはなぜか?」という問いに答えるということになります。現状のコードは汚いです。
何を持って「キレイ」「キタナい」の判断をするのか?は今後理解して行けば良いと思いますが、現状では「同じようなコードを何度も書いている」というところが「キタナい」というとこに着眼して話を進めます。というか問題(クエスチョン)にしようと思います。

問題

ここには記載せずGitにあるソースの話をします。switch文が何度も出てきているのでこれをなんとかしたいと思っています。どーしたら良いでしょうか?

ヒント:メソッドを作れば良いのです。

でわでわ。。。



Java Basic

  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜

Java Mid Basic 〜Lv2_1_Javaの基本(四則計算)ゲームループ付き〜

インントロダクション

前回、四則計算のプログラムを書くと記載しながら以下の内容に関して記載しました。

  1. クラスの作り方
  2. メソッドの書き方
  3. int型とString型の変数

この部分はこれから作成するプログラムを理解するために必要なことなので少し長い記述になりました。

四則計算をする

四則計算は算数でやったのと同じです。というかパソコンをコントロールするのがプログラム→電卓の大きなものをコントロールするので計算方法は電卓と同じです。

<注意>

ただし掛け算に関して「x」ではなく「*」を使用します。そのほか、べき乗など学校で習うような書き方ではなく(パソコンで入力ができない?)「^」キャレットを使用して表現します。

ソースコード

初めに作成したコードはこちらにありますが、これを修正していく形でどんどん大きなことを実装していきます。ちなみにプログラム引数を表示する処理が増えてます。

public class Lv2HelloWorld {
    public static void main(String[] args) {
        // プログラム引数の表示部分
        System.out.println("プログラム引数のサイズ:" + args.length);
        for (int i = 0; i < args.length; i++) {
            System.out.println("プログラム引数:" + args[i]);
        }
        // 標準入力を受ける
        Scanner input = new Scanner(System.in);

        while(true) {
            System.out.print("入力してください: ");
            String inStr = input.nextLine();
            if ("hello".equals(inStr)) {
                System.out.println("Hello World!");
            } else {
                System.out.println("想定外の入力です");
                break;
            }
            System.out.println("Next command ... ");
        }
        System.out.print("AP is fiinished. Bye!");
    }
}

このコードを拡張して四則計算を行うように修正します。
現状では。以下のような処理になっています。

  1. プログラム引数を表示する
  2. 標準入力を受ける(コンソールの入力を取得する)
  3. 入力値が「hello」の場合は「Hello World!」をコンソールに表示
  4. それ以外は「想定外の入力です。」と表示してプログラムを終了する(while文を抜ける)
  5. ループして2まで戻り繰り返す

上記のような処理をしています。このままでは「hello」以外の入力を行えばプログラムが終了してしまうので、ここの部分に、今回の「四則計算を行う」処理を追加します。

具体的に

以下のような処理を行うように設計します(多くの人は頭の中でやってしまいます、プログラムが小さいからです。)。

  1. プログラム引数を表示する
  2. 標準入力を受ける(コンソールの入力を取得する)
  3. 入力値が「hello」の場合は「Hello World!」をコンソールに表示
  4. 入力値が「?」 + 「計算の記号」 + 「?」が入力された時に四則計算を行い、計算結果をコンソールに表示する
  5. それ以外は「想定外の入力です。」と表示してプログラムを終了する(while文を抜ける)
  6. ループして2まで戻り繰り返す

このように設計しました。上の赤い字の部分が追加したところです。
この追加部分の処理について見ていきます。

追加した処理

まずはコード上で追加する部分を明確にします。
設計上では「4」の部分が追加しているところなので処理もその部分を見つけます。

if ("hello".equals(inStr)) {
    System.out.println("Hello World!");
} else {
    System.out.println("想定外の入力です");
    break;
}

の部分がこれにあたりますので、ここに「入力値がXXX」だったら。。。の処理を追加します。

自分の作成した答えはこちらです。プルダウンで開きます。
if ("hello".equals(inStr)) {
    System.out.println("Hello World!");
} else if (inStr.matches("[0-9].*[0-9]")) {
    int answer = myClass.calculate(inStr);
    System.out.println("答えは:" + answer + "です。");
} else {
    System.out.println("想定外の入力です");
    break;
}

IF文で使用している「"[0-9].*[0-9]"」の部分を「[正規表現](http://www.turtle.gr.jp/techno/regular-expression.html)」と呼び文字列に対してルールを強いるものです。
例えば、入力した文字列が「メールアドレスかどうか?」を判定するのにも正規表現を使用します。「XXXX@XXX.XXX」のように一定の文字の並びかたが正規表現で指定したものになっているかどうか?を判定するために使用します。
ここに簡単なサンプルを記載してあります。指定の文字列をから文字に変換(削除)する処理を作成しています。
ちなみにjava.lang.String#matchies()では正規表現を引数に持っています。詳細は[リンク先のJavaDoc](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#matches-java.lang.String-)を見てみてください。

一応ですが、「正しい答え」というものはありません。想定通りに動けばそれが正解です。人生の中で「正解」がないのと同じです。
ちなみに自分の作成したものは次のように動きました。

作成したコードはGitにあります。
ちなみに、テストクラスも作成しました。入力した文字を判定する処理のテストです。このクラスの名前にはお尻の部分に「Test」をつけて「Lv2__1_CalculateTest」とするのが規約に則ったやり方なのですが、つけ忘れてしまいました。
このまま修正しないでいると、後々に何かしらのミスをやります。。。

まとめ

ここで、実装のサンプルとかそんなものを記載しようかと思ったのですが、Gitにあげるまでにしておきます。
感覚としてはパズルとか、なぞなぞを解くような感じで追加で設計した部分を実装して見てください。

でわでわ。。。



  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜

Java Mid Basic 〜Lv2_Javaの基本(コードの書き方)ゲームループ付き〜

イントロダクション

前回は、とりあえず入力して画面に表示するものを作成しました。こんな感じです。

動画は、作成中にデバッックしたものです。ちなみにバグもあります。
とりあえずは「動いた!」という感動を味わっていただきたく思い中途半端ですが、アプリとして動くものを作成しました。
コードはGitにアップしています。

最終的にはコンソールゲームを作ります。

AP概要Lv2

標準入力を受け付けて、以下のような動きをします。

  1. 入力された文字が「hello」の時はコンソールに「Hello World!」と表示する。
  2. そのほかの文字を入力したら「想定外の入力です」を表示する。

四則計算をする

今回のメインになる実装を行います。前回の記事で問題を出しました。ちょっと難しい問題でした。上の動画はデバック中の動画になります。バグも残っています(笑)。

まずは書いたコードの理解

前回作成したコードをもう一度眺めてみます。

public class Lv2HelloWorld {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        while(true) {
            System.out.print("入力してください: ");
            String inStr = input.nextLine();
            if ("hello".equals(inStr)) {
                System.out.println("Hello World!");
            } else {
                System.out.println("想定外の入力です");
                break;
            }
            System.out.println("Next command ... ");
        }
        System.out.print("AP is fiinished. Bye!");
    }
}

頭(行の先頭)からコードの意味を記載していきます。

クラスの定義

上のコードで行くと、下の部分がクラス定義になります。

public クラス名{ .... }

このクラス名はなんでも良いのですが、下のルール(大雑把な規約)にしましょう。ちなみにCheckStyleというEclipseのプラグイン(標準装備)を使用すると簡単に規約違反が見つけられるので便利です。参考サイト

  • メタ文字:%/\&'*)など、これらはEclipseなどのIDE(開発ツール)を使用するとエラーが出るので安心です。
  • Javaのクラスはアッパーキャメルケース("AppaKyameru"のように書く)を使用します。
  • Javaのメソッドはキャメルケース("appaKyameru"のように書く)を使用します。

とりあえずはこんなところを気をつけましょう。

メイン・メソッドの定義

まずは動かしたいので「メインメソッド」を作成します。メインメソッドは以下のような特徴があります。

  1. メソッドの定義は1つだけ、ほかの書き方はない。
  2. 必ずこのメソッドが動く
  3. 引数は「プログラム引数」になる

プログラム引数

プログラム引数はEclipseで使用する場合は下のように値を渡してあげます。つまりString[] argsの部分が引数であり、下のように設定してアプリを起動すると変数「args」に"プログラム引数1"のように値を渡せます。
注意として、プログラム引数は「String」型のデータになります。

ちなみに「データ型」に関しては後々に触れますが、現在使用しているデータ型は「int」「String」があります。

int型

調べてみると「???〜???までの整数」などのように記載されてますが、早い話が、範囲指定はあるけど(正負の)整数です。Stringなどの「オブジェクト型」とか「参照型」など(同義です)と違い、直接の値(メモリの領域)を保持します。

String型

これはjava.lang.Stringというクラスの型になります。intと違い「クラス」なので「null」が存在します。よく「参照型」とか「オブジェクト型」などと呼ばれます。早い話が「NULLが存在する型」なんだな!と理解してくれればOK!今後深く理解していきます。int型などのように直接、値を持つ変数と違いオブジェクトへの参照(ポインタ)を変数に持ちます。だからNULLがあるのです。

次は実装

すでに書いたコードに追記・編集していきます。前回作成したメインメソッド部分では「Hello World」と「想定外 ....」を出力するだけだったので、この部分を拡張します。
元のコード

public static void main(String[] args) {
    System.out.println("プログラム引数のサイズ:" + args.length);
    for (int i = 0; i < args.length; i++) {
        System.out.println("プログラム引数:" + args[i]);
    }
    Scanner input = new Scanner(System.in);

    while(true) {
        System.out.print("入力してください: ");
        String inStr = input.nextLine();
        if ("hello".equals(inStr)) {
            System.out.println("Hello World!");
        } else {
            System.out.println("想定外の入力です");
            break;
        }
        System.out.println("Next command ... ");
    }
    System.out.print("AP is fiinished. Bye!");
}

編集後のコード

public static void main(String[] args) {
    // 今回は作成したこのクラスを使用します。
    Lv2_1_Calculatie myClass = new Lv2_1_Calculatie();

    Scanner input = new Scanner(System.in);

    while(true) {
        System.out.print("入力してください: ");
        String inStr = input.nextLine();
        if ("hello".equals(inStr)) {
            System.out.println("Hello World!");
        } else if (inStr.matches("[0-9].*")) {
            int answer = myClass.calculate(inStr);
            System.out.println("答えは:" + answer + "です。");
        } else {
            System.out.println("想定外の入力です");
            break;
        }
        System.out.println("Next command ... ");
    }
    System.out.print("AP is fiinished. Bye!");
}

具体的に下の部分が変わりました。

Lv2_1_Calculatie myClass = new Lv2_1_Calculatie();
} else if (inStr.matches("[0-9].*")) {
    int answer = myClass.calculate(inStr);
    System.out.println("答えは:" + answer + "です。");

new Lv2_1_Calculatie()の部分は作成したクラスのインスタンスを取得しています。
インスタンス化すると「インスタンスメソッド」が使えるようになります。

インスタンスメソッドとスタティックメソッド

インスタンスメソッド:A a = new A();のように「new」してから使用する
スタティックメソッド:A.staticMethod()のようにクラス名.メソッド名で呼ぶことができる
上のような違いがあります。

まとめ

クラスとメソッドの書き方、メソッドの種類について触れました。結局計算する部分には触れませんでしたので次回触れようと思います。
でわでわ。。。



  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜

Java Mid Basic 〜Lv1Javaの基本を理解する(ゲームループ付き)〜

イントロダクション

Javaの基本を改めてやろうと思います。
今までの「Java Basic」シリーズは基本的なことをやった後に「基本を使用して何かをする」というのが目的だったのですが、基本の練習をしていなかったことに気がつき。。。現在に至るという次第です。

ハローワールド

初めのプログラムとしてどの言語でも使用するプログラムです。このプログラムは応用範囲が広くいろんな場所で使用できます。
基本にするページは下のリンクになります。

Java Hello World はじめのプログラム 〜 Step1-1〜

ここの記事では、以下のようなことを記載しています。

  1. Javaは、メインメソッドが動く
  2. クラスやメソッドの書き方
  3. 練習問題

今回やること

Hello Worldの応用として、標準入力を使用したシンプルアプリケーションを作成してみようと思います。
この処理は、今後実装するSocket通信で使用することもできます。

問題(クエスチョン)

標準入力を受けて、受けた文字列により以下の文言をコンソールに表示するプログラムを作成してください。
[ヒント]Gitにアップしてあるコードを参考にしてみてください。

  1. IN: "hello" => OUT: "Hello World!"
  2. IN: "タイガー" => OUT: "マイコンジャー!炊きたて!"
  3. IN: "1 + 1" => OUT: "2"
    ただし、"2 * 4"などのように計算式の場合は計算した結果を表示する

イメージ

サンプルコード

JavaのCodeはGitにアップしてあります。

public class Lv2HelloWorld {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        while(true) {
            System.out.print("入力してください: ");
            String inStr = input.nextLine();
            if ("hello".equals(inStr)) {
                System.out.println("Hello World!");
            } else {
                System.out.println("想定外の入力です");
                break;
            }
            System.out.println("Next command ... ");
        }
        System.out.print("AP is fiinished. Bye!");
    }
}

これで、入力→コンソール表示の簡単なゲームが作成できると思います。
是非、遊んでみてください。

でわでわ。。。



  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜