Java Console Game〜プロパティファイルを読む〜
イントロダクション
前回までで、リストとフィールド変数の扱いをやりました。
これで、簡易的にデータを保持する事が出来る様になりました。(フィールド変数はデータを保持します。)
ここまで来れば何かできそうな気がします。自分だけでしょうか?
配列の実装
プロパティファイル
何かを作るって、新しい知識や、技術…いろんなものが必要になります。(イメージしたものを作るために)あんな工夫、こんなアイディアなどとイメージの数だけ増えていきます。
しかし、人間一度に出来ることの量は決まっているので「不断の努力」でカバーします(笑)
さて、今回のタイトルにあるプロパティファイルですがこれはファイルを簡単に読み込む事が出来ます。Java APIにあるPropertiesクラスを使用します。このクラスは、今後扱います。Mapクラスの仲間です。→継承関係があるという事
これを使って?
入力したコマンドで自作したクラスを呼び出します。。。
とりあえずは、サンプルを作ってみたいと思います。続きは次回に。。。
実装してみて
プロパティファイルのパスが全ての環境で同じようにならないので注意が必要です。パス指定をするときに「/XXX.txt」と「XXX.txt」で場所が変わります。なので「resource/」をつけたりして試してみる必要があるかもしれません。
そして、ここまで実装してきたら何かのアイディアで簡単なゲームを作りたいと思うのは自分だけでしょうか? 基本のじゃんけんゲームでも作ってみますかね?
でわでわ。。。
Java Console Game〜フィールド変数でコマンド履歴を作る〜
イントロダクション
前回は、リストの使い方など記載しました。今回は実際に使ってみようと思います。でも、コマンドをベースにして実装するので、コマンドを実行した時にだけリストを使うのは、あまりメリットがあるように思えないので(今回の実装の場合です)クラスが起動している間、myClassのインスタンスがある間たデータを保持することを目的にリストを使おうと考えたわけです。
フィールド変数
フィールド変数というのはクラスの中で保持するデータ、クラス変数などです。具体的には、以下の様なコードです。
public class XXX { private List commandHistory; public void XXX() { ...} }
このcommandHistoryがフィールド変数です。この変数は、クラスがnewされた時→コンストラクタが動いた後からインスタンスが破棄される時までデータを保持しています。ちなみにコンストラクタの反対、インスタンスが破棄される→変数にnullを代入するとデータも破棄されます。
コンストラクタ
インスタンスを作る(new)ときにはコンストラクタが動きます。逆に言えばコンストラクタが動くとインスタンスが出来ます。これは頭ごなしに覚えて下さい。深い部分ではメモリ領域の確保とかあると思うのですが、それよりも他の事が忙しく。やっている暇がありません(笑)
コマンド履歴を作る
この様な処理を行う時にフィールド変数は、活躍します。今回のコンソールアプリは、クラスが破棄された時にゲームも終了しますので、データを保存するのに丁度良いです。
設計
コンストラクタで、フィールド変数にArrayListをセットしてコマンドを実行するたびに、コマンドのリストに登録してゲーム終了時に、使用したコマンドの一覧を表示する。
こんな感じの仕様にしようと思います。
<イメージ>
/** コンストラクタ */ public MyClass() { feeldList = new ArrayList(); } /** メインメソッド */ public static void main(String[] args) { String inStr = new Scanner(System.in); feeldList.add(inStr); }
これにプログラムが終了するまえにリストの中身を順番に出力するようにしてやればおっけ。あとはテストして…
詳細な記事
Java API
上のコードで使用しているScanner, ArrayListなどはJava APIで提供されているクラスで、よく使うものです。他にも、馬鹿みたいに沢山あるので、全部は覚えきれません。しかし全部どの様に使うのか説明が付いてます。これをJavaDocと呼び、「/* ... /」で括った部分をHTMLに出力したものです。
余談
ちなみに、面白いアイディアがあるのならばそちらの実装に着手してみる事を進めます。わからない部分は「わかんねー!」と思った時に学習するので遅くありません(笑)むしろ学習効率が高いかも?
実行結果
Java Console Game〜Listを使う〜
イントロダクション
前回は、dirコマンドの実装を行いました(オプション部分は未実装)
とりあえずで表示した、フォルダやファイルですが、Fileクラスの配列を取得して表示しました。(実装したらリンクを貼ります)
複数のオブジェクト(クラスや値)を扱う時は大体配列を使用します。
配列
前回の実装(実装したらリンクを貼ります)の様に指定したディレクトリ(フォルダ)の中を取得する時は「複数のオブジェクトを取得」する事が多いので配列でデータを取得しますが(Fileクラスの仕様)intやStringも同様に配列として扱う事が出来ます。
String[] strHaitetu = null; int[] nums = new int{1, 2};
Stringは、参照型なので、nullで初期化できますが、intはプリミティブ型(値)なのでnullが使えません。
よくあるコードとしては以下の様なループ文です。
for (int i = 0; i < strHairetu.length; i++) { ...}
配列のサイズ分繰り返す。という処理になります。「...」の部分にそれぞれやりたい事を実装します。
注意
int型では、プリミティブ型なのでnullが使えませんが、配列になると「参照型になります」のでnullが使えます。
int[] a = null;
低レベルな話をすると、値(int)はメモリの領域を確保しますが、配列(int[])はメモリの領域の先頭のポインタを参照します。なので、この様な違いがあります。 配列の実装と起動確認
List
上記の配列を使いやすくしたクラスがJavaでは提供されています。それがListインターフェースクラスです。 このクラスはインターフェースと呼ばれるクラスで、実体(処理)がありません。じゃ動かないんじゃ?と思われますが、中身を入れてやる必要があります。
Listインターフェース
インターフェースとは…と話すとややこしいですので、ここでは下の様に理解して下さい。
List型の変数には、ArrayListクラスとLinkedListクラスを入れる事が出来る。具体的には以下の様なコードが書ける
List arrayList =. new ArrayList(); List linkedList = new LinkedList();
それぞれ、ArrayListクラスとLinkedListクラスは別物ですが、インターフェースで宣言するとどちらのクラスも一緒に、同じ変数て扱う事が出来ます。ちなみに左のリンク先には、その他のListインターフェース型で使用可能なクラスが載っています。
addとsize
上のメソッドを使用してリストへ要素の追加と取得を行います。
arrayList.add("aaa"); for (int i = 0; i < arrayList.size(); i++) { String value = arrayList.get(i); System.out.println("要素: " + value); }
上のコードは「arrayList」の代わりにlinkedListを使用しても良いです。
配列とArrayList
ドキュメントを読むと可変長配列にしたものがArrayListだと記載がありますが、その通りに配列はサイズが決まっているのでデータの追加など器用な真似ができません、正確には配列のコピーを作りサイズを変更してやる必要がありますが、そういう面倒な部分をAPIがやってくれるというわけです。
そんなわけで、Listについて触れました、実装は後ほど。。。
まとめ
ディレクトリ検索などを行う時には複数のデータを取得する事が多いです。特にデータベースなどへのアクセスは大体複数のデータです。こんな時にListインターフェースは大活躍します。
でわでわ。。。
Java Console Game 〜コマンドを作る〜
イントロダクション
今迄に、
1. コンソール(標準)入力と出力
2. ゲームループ(無限ループの中からある条件でループを抜ける)
3. 計算式判定→文字判定
4. テストクラスの作成など
上記の事をやってきました。
このように列挙すると結構な量ですね(笑)
コマンド実行
既に作成した「入力がhelloの時〜」という処理について、この部分を「コマンド入力」という解釈をする事が出来ます。
つまり、コマンドプロンプトの様に「dir」コマンドが入力されたらカレントディレクトリのファイルを一覧する。というような処理を実装してやればそのように動きます。
<実装例>
if ("hello".equals(inStr)) { System.out.println("Hello World!"); } else if (inStr.matches("[0-9].*[0-9]")) { String answer = myClass.calculate(inStr); System.out.println("答えは:" + answer + "です。"); } else if("dir".equals(inStr)) { // Dirコマンドの実装を行う } else { System.out.println("想定外の入力です"); break; }
dirコマンド
上のサンプルコードで「// Dirコマンド〜」と記載している部分にdirコマンドの処理を実装する想定です。
Java版dirコマンドを作成してみようと思います。ここでは、カレントディレクトリがよくわからなくなってしまうのでEclipseのプロジェクトフォルダをカレントディレクトリとします。
ビルドパス
余談ではありますが、最近のプログラミング言語は「高レベル」なものが多く「ビルドパス」を気にしなくても実装出来ます。しかし、この様な「低レベル」な技術の上に「高レベル」な言語やAPIは成り立っています。
逆に言えば、「低レベル」がわかれば「高レベル」は理解できるという事です。
高レベルと低レベル
上に挙げたレベルという言葉は「高い程人間の感覚に近く、低い程パソコン(機械)に近い」という意味です。世間一般(プログラミング業界)で通用する言葉なので記載しておきます。
ルートを決める
Javaでは、プログラムを起動した時に指定したビルドパスによってカレントディレクトリが変わるので注意が必要です。もっと記載すると、ビルドパスに繋がっているところが全てカレントディレクトリになります。ちょっとややこしいですね(笑)
先程の「dirコマンド」を作成する話ですが、実際のコマンドのオプション部分は作成しません、単純にカレントディレクトリのファイルを表示するだけのものにしようと思います。それよりも、コンソールゲームの作成を進めたいからです。
コンソールゲームでは、ファイルの参照やDBへの接続も考えているので、今回からは、ファイルのコントロールに着眼して行こうと思います。
ファイルを参照、開く時に「どこのフォルダ?」にあるファイルなのか指定する必要があります。普段はGUIで表示されるものをクリックすれば開けますが、低レベルな所では以下の様な順序でファイルを開きます。
ファイルオーブン
- ファイルのあるディレクトリ(フォルダ)を指定する
- ファイルにアクセス(open)
- ファイルの中身を読み取る
以上の様な順序でファイルの中からデータを取得します。ここで、ファイルを開く時に「パーミッション(権限)」などのセキュリティ機能が働き開けない事件が起きることもあるので注意が必要です。
プログラムを書く
Javaではどの様に書くのか?この部分に触れたいと思います。今迄作成して来たコードをベースに記載します。
まずは、コマンドの実行部分ですが、これはシンプルにif文で分岐しようと思っています。ゲンナリされた方は、ご安心下さい、後でコマンドを好きなだけ追加できる方法を提示します。
余談ですが、上の実装にはインターフェースを使用します。なので、「インターフェース」の話題が出てきたら、コマンドを好きなだけ追加する実装をやるんだなと思って頂きたいと思います。
実装については、こちらの記事で記載します。
実行結果はこんな感じです。
でわでわ。。。
Java Console Game〜リファクタリングLv1〜
イントロダクション
前回は、テストコードを作ることに触れました。早い話が「コードの起動確認をしよう」という事です。やり方としては以下の様になります。
テストクラス
作成するクラスと同じパッケージをtestフォルダの下に作り作成クラス+Testという名前のクラスを作る。これでテストクラスと作成するクラスの区別がつきます。具体的には、下の様に作ります。
作成クラス: src/jp/zenryoku/sample/lv2
テストクラス:test/jp/zenryoku/sample/lv2
リファクタリング
これでリファクタリングの準備が出来ました。リファクタリングの目的は「キレイなコードを書く」です。変更したコードが今迄と同じ様に動くか確認しながらやります。
なので、修正する部分を決めてやる必要があります。今回の修正ポイントは「calculate()」メソッドです。
テストコードを書く
テストコードの目的は、修正したコードが壊れない事を担保する為のものです。
具体的には、これから作成しますが、要件として以下の点に注意します。
1. メソッドの処理結果が全く同じになる
2.何回テストしても結果は変わらない
プログラム設計
今回の修正メソッドは public String calculate(String fomula)
なので、引数のfomulaに入っている文字列が「?」+「+-*/のどれか」+「?」で、?には0〜9の数字一文字が入ります。この部分は正規表現でチェックしているので良しとします。
具体的に
引数に「1 + 1」と入っていた場合、計算して「2」を返却する事を確認するテストコードを作ります。
テストクラスから、テスト対象のメソッドを呼び出し実行します。
メソッドの引数には「1 + 1」の文字列を渡します。
そして、想定通りの結果が得られる事を確認しながら修正(リファクタリング)する。作成したコードはこちらにあります。
やり方
- プログラム(コード)をゆっくりと眺め、同じようなコードを探す
- 同じようなコードをメソッドに切り出す
- 切り出したメソッドをテストして問題がないことを確認する
実行サンプル
ここの記事に記載しました。動きとしてはこんな感じです。 記載内容に関して、リファクタリングを行う手順とコード、テストクラスの作成方法、及びサンプルコードを記載しています。
Java Console Game〜四足計算と文字列〜
イントロダクション
前回は四足計算をやりました。前提としてゲームループの中で「hello」か「数式(四足計算)を入力した時にそれぞれの処理を行い、コンソールに出力します。
詳細はこちらです。
続、四足計算
前回のプログラムには問題がありました。それは、「割り算」です。
割り算の場合、割り切れない場合があります。この場合は少数を使う必要があり今迄使用していた「int型」では少数を使う事が出来ません。少数を使う場合は「double型」を使います。他にも少数を使えるデータ型 はありますが、ひとつずつ確実に進むのが一番早いので、いっぺんにやりません。
データ型の違い
JavaプログラムではC言語と同じ記号を使います。「/」スラッシュを使って計算します。4/2=2の様にコードでは
double ans = 4 / 2;の様に書きます。この場合、ansには「2.0」が入ります。int型で初期化した場合→
int ans = 4 / 2;ansには「2」が入ります。
同様に次の様にコーティングします。
int ans = 4 / 3;この場合はansに1が入ります。割った結果の整数部分のみがセットされます。
double ans = 4 / 3;
この時はansに1.333 ...が入ります。
実装を修正する
今回の問題になっている「割り算の結果に少数が出ない」部分を解消します。
現状のソースはGitにあります。
結論から言うと、使用する変数を変えてやれば、おっけ!という事ですのでしゅしたコードは示しません(笑)
テストコード
開発を行う時に「この処理想定通りに動くかな?」と思うことか多々あります。これを解決するのがテストコードです。今回作成したテストコードでは、入力が計算式なのか判定する正規表現をテストしました。 こんな感じでテストと実装を交互に開発していく方法の事を「アジャイル」などと呼んでいる事が多いですが、世間巷の「人工知能」と同じ様に本来の意味とはずれています(笑)
でわでわ。。。
Java Console Game〜基本の実践〜
イントロダクション
[Javaの基本的な文法など](https://zenryokuservice.com/wp/2018/08/02/java-basic-summary-from-level1-to-5/]は、以前やりました。ある意味教科書的なもので「どー使うの?」と言う疑問が残る形だったと思いました。
Java Console Game
そこで、コンソールゲームを作りながらJavaを理解する方法を思いつきました。
ぢつは…
以前から、テキストRPGを作りたいと思っていたのですが、如何せんストーリーとか、ゲームシステムとかに悩んでしまい進まない状態だったのですが、これで基本をやれば、何か見えるかも?と思い現在に至る次第です。
最終的に
コンソールゲームとして遊べるモノを作ろうと思います。基本の積み重ねの上にアプリケーションがあるので、色々と都合が良いのです(笑)
ハローワールド
そんなわけで、一度やった事をゲーム作りに応用する形でハローワールドをやりました。
内訳
コンソールからの入力(標準入力を受け付けて「hello」と入力した時にハローワールドを表示、それ以外は「想定外の入力です」をコンソールに出力(標準出力)します。
Java Mid Basic
ここに記載したのが上に挙げた内容のコードとその意味です。ゲームループ付きなので、ちょっと面白いです(笑)
クラスの書き方やメソッドの書き方などはこちらです。簡単な設計と、その実装を記載していて、入力から四足計算を行う為の実装をしています。
ポイント
入力を受けた時に、計算式なのか判定する必要がありますが、ここでStringクラスのメソッド(matchies)を使用して「数字」+「+-*/の内どれか」+「数字」の形で入力されているか判定します。こんな形で入力判定して計算を行うか判定します。
そして、四足計算を行うのですが入力したもの(データ)は文字列(String型)なのでこれを数値型に変換してやる必要があります。この数値型には色々ありますがまずは、int型を使います。整数を扱う為のデータ型です。これで四足計算を行うのですが割り算の時に小数点が必要になる場合があるので、ちょいと工夫が必要です。この部分は次回に。。。
でわでわ。。。
Java OpenGL 〜家計簿アプリを作る〜
イントロダクション
今まで、Git BookのLWJGLを学習して来ました。(ここ2週間ほど。。。)
結局、レンダリング(描画)が理解出来ずやり直す事にしました。
ただ、やり直すだけでは勿体ないので家計簿アプリを作りながら理解します。
<写経して動いたもの>
https://mobile.twitter.com/java_takunoji/status/1057586067182804994
家計簿アプリ開発
描画処理で、大まかな流れは理解出来たが、具体的な処理をどうするか?がわからなかったので、描画(rendering)に戻ってやり直します。
アプリの仕様について
<L v1:データの表示>
3Dグラフを使って1ヶ月の支出や収入を一覧する機能を作ります。
見慣れた2Dグラフだと、表示出来る情報が少ないので3Dグラフを使う事にしました。
<Lv2:カテゴリ切り替えと登録>
初期表示では、単純に支出額のグラフを表示しますが、「必要な支出」と「不要な支出」のカテゴリ分けをしたい場合があると思います。そのための「カテゴリ」を編集する機能を作ります
<Lv3:レシートや領収書の入力>
はっきり言って、この機能が面倒なので家計簿を付けないという人が多いと思います。だからレシートや領収書を読み込む自動入力にしようと思います。
最近流行りの機械学習を使います。
環境構築〜画面表示
http://zenryokuservice.com/wp/2018/11/01/eclipse-アプリ作成-lv1〜家計簿を作る準備〜/
描画の時に指定する頂点の動かし方
http://zenryokuservice.com/wp/2018/11/03/eclipse-アプリ作成-lv2〜家計簿を作る土台作り〜/
Java 3DGame 家計簿アプリを作る
イントロダクション
3DGame作成フレームワークLWJGLの学習を始めて、ある程度進みました。
でも、読んである程度理解出来るのもここまで…
http://zenryokuservice.com/wp/2018/10/31/java-3dgame-lwjgl-gitbook-chapter8〜camera〜/
実際は読むだけで、表面的にしか理解していない…話をするだけなら出来るけど、肝心カナメの部分が分からんのじゃ話ならなん…
そんなわけで、読んでダメなら動かしてみれば良いので、アプリを作りながら理解します。
家計簿アプリ開発準備
画面上はグラフを表示、カテゴリの追加と表示、読み込みボタンがあるだけのシンプルなものを作ります。
ポイントは、上のGitBookで学習したとこより戻り、モデル表示〜やり直します。
開発
http://zenryokuservice.com/wp/2018/11/01/eclipse-アプリ作成-lv1〜家計簿を作る準備〜/
プロジェクト作成
http://zenryokuservice.com/wp/2018/11/01/eclipse-meven-開発手順〜プロジェクトの作成〜/
Java Game LWJGL〜その2キー入力〜
イントロダクション
前回までは開発環境のセットアップとか起動確認をやりました。
ここ最近は写経したり、3Dモデルの作り方など、理解するためのアプローチ方法を考えていましたが良い方法がありました。
基本を理解するのが一番早い
という訳で、下のサイトに良いものがありました。
Git Bookです。
コードです
今回やった事
画面を初期化して、十字キーで背景色を変更する。アプリの実装です。
段々と使用するクラスが増えてきます。
オブジェクト指向の考え方を理解するのにも使えると思います。
インターフェースを実装しているので、ポリモーフィズム第一弾といったところでしょうか(笑)
- Chapter2-2〜インターフェースの使い方と詳細〜
ちなみにLWJGLの基本部分のみを一通りやりました。
- Chapter1[外枠の表示のみ]
- Chapter2-1〜クラスの構成〜
- Chapter2-2〜インターフェースの使い方と詳細〜
- Chapter2-3〜GameEngineクラス(サンプルクラス)〜/li>
- Chapter2-4〜Windowクラス(サンプルクラス)〜
- Chapter3〜描画処理を読む〜
- Chapter4〜シェーダについて〜
- Chapter5-1〜レンダリングについて〜
- Chapter5-2〜レンダリング詳細〜
- Chapter6〜Projection(投影)〜
- Chapter7-1〜Cubeを作る〜
- Chapter7-2〜Texture〜
Java Basic一覧
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 9〜Training of for statement〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜
- サンプル実装〜コンソールゲーム〜
- Java Basic インターフェース・抽象クラスの作り方
- Java Basic クラスとは〜Step2_1〜
- Java Basic JUnit 〜テストスイートの作り方〜