【Java】
第2回 Javaでオセロを作成しよう
ボード上にオセロを置く処理を実装しよう
投稿日 2020/12/05 更新日 2020/12/10
こんにちは。当サイトの管理者「元木皇天」です。
さて、Javaでオセロを作ろうの第2回です。第1回の続きですので、まだの方はこちらから作成をしてください。
今回は前回作ったオセロのボード上に、オセロを置く処理を実装していきましょう!
開発環境
OS:macOS
Java:11.0.7
Eclipse:2020-03
今回の目標
今回の目標は、ボード上の座標を指定してオセロを配置する処理の実装です。完成サンプルは以下になります。
オセロを開始します. | |1|2|3|4|5|6|7|8| |1| | | | | | | | | |2| | | | | | | | | |3| | | | | | | | | |4| | | |◯|●| | | | |5| | | |●|◯| | | | |6| | | | | | | | | |7| | | | | | | | | |8| | | | | | | | | 横の座標を1~8の半角数字で入力してください 1 <- キーボードから入力 縦の座標を1~8の半角数字で入力してください 1 <- キーボードから入力 | |1|2|3|4|5|6|7|8| |1|●| | | | | | | | |2| | | | | | | | | |3| | | | | | | | | |4| | | |◯|●| | | | |5| | | |●|◯| | | | |6| | | | | | | | | |7| | | | | | | | | |8| | | | | | | | |
パッケージ・クラスの作成
まず、パッケージとクラスを前回のものに追加で作成していきます。以下の画像を参考に次のものを作成してください。
赤で囲んでいる箇所が今回の追加対象です。
パッケージ
middleware
model
クラス
CheckInputValue.java
ReverseOsero.java
オセロを置く座標を入力する
ではさっそく作成に取り掛かりましょう!
まず初めに、オセロを置く座標をプレイヤーにキーボードから入力してもらえるように、入力を受け付けるプログラムを作成します。
Main.javaを以下のように編集します。
赤線を引いてある箇所が今回追加するコードです。
--Main.java--
package osero; import java.util.Scanner; import osero.config.StartConfig; import osero.view.ShowBoard; public class Main { //オセロの情報 public static String white = "◯"; public static String black = "●"; //ボードの情報を保存する public static String board[][] = new String[9][9]; //入力値の情報を保持する private static int inputX; private static int inputY; public static void main(String[] args) { //インスタンスの作成 StartConfig SC = new StartConfig(); ShowBoard SB = new ShowBoard(); Scanner sc = new Scanner(System.in); System.out.println("オセロを開始します."); //ボードに初期値をセットする SC.boardInitValue(); SC.boardSetup(); //ボードを表示する SB.showBoard(board); //x座標を入力する処理 System.out.println("横の座標を1~8の半角数字で入力してください"); inputX = sc.nextInt(); //Y座標を入力する処理 System.out.println("縦の座標を1~8の半角数字で入力してください"); inputY = sc.nextInt(); } }
ではこちらのコードを解説いたします。
まず、Scannerクラスをインポートしているのがわかります。Scannerクラスを使用することで、ユーザからキーボードで入力を受け付けることができるようになります。
実際にこのクラスを使用する際は、インスタンスの作成が必要なので「Scanner sc = new Scanner(System.in)」というコードを記載しています。
また、フィールドに「//入力値の情報を保持する」というコメントで記されたint型の「inputX」「inputY」を作成しています。 これは、Scannerクラスで入力した値を保存しておくための変数となっています。 また、このフィールドはこのMainクラスでしか使用しないためprivateでカプセル化しています。
そして最後の方の行に、x・y座標の数字を入力させる処理を書いています。 inputX・inpiutYがint型のため、nextInt()でキーボードからの入力を受け付け、値を保存しています。
ここまでできたので、次は入力した値(座標)を元に、オセロをボード上に配置する処理を書いていきましょう。
入力値からボードにオセロを配置する
キーボードから入力した値は、それぞれフィールドの変数「inputX」「inputY」に保存されています。
この値を使用して、オセロを指定したボード上の座標に配置する処理を書いていきます。
ReverseOsero.javaに以下のプログラムを書いてください。
--ReverseOsero.java--
package osero.model; import osero.Main; public class ReverseOsero { //入力した座標にオセロをおく public void putOsero(int x, int y) { Main.board[x][y] = Main.black; } }
putOseroというメソッドを作成しました。
このメソッドは、引数に渡された値のボードの座標上にオセロを配置するというコードになっています。
ですので、このメソッドを使用する際は変数「inputX」「inputY」を指定します。
ではこのメソッドをMain.javaで使用するため、コードを書いていきましょう。
--Main.java--
package osero; import java.util.Scanner; import osero.config.StartConfig; import osero.model.ReverseOsero; import osero.view.ShowBoard; public class Main { //省略 public static void main(String[] args) { //インスタンスの作成 StartConfig SC = new StartConfig(); ShowBoard SB = new ShowBoard(); Scanner sc = new Scanner(System.in); ReverseOsero RO = new ReverseOsero(); //省略 //x座標を入力する処理 System.out.println("横の座標を1~8の半角数字で入力してください"); inputX = sc.nextInt(); //Y座標を入力する処理 System.out.println("縦の座標を1~8の半角数字で入力してください"); inputY = sc.nextInt(); //入力した座標にオセロを置く RO.putOsero(inputX, inputY); //ボードを表示する SB.showBoard(board); } }
まず最初に、ReverseOseroクラスをインポートしています。その後、ReverseOseroのインスタンス「RO」を作成しています。
次に「putOsero」メソッドを呼び出し、引数にinputXとinputYを渡します。
最後に、ちゃんとオセロがボード上に配置されたか確認するためにshowBoardメソッドを使用しています。
これで数字を入力すれば問題なくオセロをボード上に配置することができるようになりました。
しかし、これで終わりではありません。もしユーザが半角数字以外を入力してしまったらどうなるのでしょうか? 試しに「A」を入力した場合の結果が以下になります。
InputMismatchException(エラー)が発生しています。これはinputX・inputYがint型で定義されているにもかかわらず、String型を入れようとしているためエラーが出ています。
エラーが起きるとオセロはその時点で停止してしまうので、ゲームとしてそのような仕様はNGです。
最後に今回の仕上げとして、このエラーを起こさないようにして完成としましょう。
1〜8の半角数字のみ入力可能にする
まず、エラーが起きる原因として変数「inputX」「inputY」にキーボードからの入力値をそのまま入れている、ということが1つ問題です。
ですので、別の変数(String型)を用意して、一時的にそこに入力値を格納するようにしましょう。
以下のコードを参考に、Main.javaを編集します。
--Main.java--
package osero; //省略 public class Main { //省略 //入力値を一時保存する static String x = "0"; static String y = "0"; public static void main(String[] args) { //省略 //x座標を入力する処理 System.out.println("横の座標を1~8の半角数字で入力してください"); x = sc.next(); //Y座標を入力する処理 System.out.println("縦の座標を1~8の半角数字で入力してください"); y = sc.next(); //入力した座標にオセロを置く RO.putOsero(inputX, inputY); //ボードを表示する SB.showBoard(board); } }
新たにフィールドに「String x」と「String y」を作成しました。
そしてキーボードからの入力値をここに保存するように処理を書き直します。 元々は「inputX = sc.nextInt()」という処理だったものを、「x = sc.next()」に変更しています。
保存先の変数をinputXからxに変えたのと、保存先の型がint型からString型に変わったためnext()に書き直しています。
これでInputMismatchExceptionは発生しなくなりました。 ただし、このままではinputX・inputYには何もセットしていない状態です。 また、これらの変数に「String x」「String y」の値を代入した場合、また同じエラーが出てしまいます。 ですので、今回は変数「x」「y」の値に対して正規表現を使用し、「1~8の半角数字」である場合のみ、 int型に変更して代入するという処理にしたいと思います。
正規表現を用いてチェックを行うメソッドを「CheckInputValue」クラスに記載します。 以下のコードを書いてください。
--CheckInputValue.java--
package osero.middleware; public class CheckInputValue { //入力値が1~8の半角数字かチェックする public boolean checkInt1_8(String str) { //入力値が1~8ならtrue if(str.matches("[1-8]")) { return true; } //文字やそれ以外の数字を入力したらfalse return false; } }
引数には入力した値(変数「x」「y」)を渡します。
そしてif文の条件式に設定されている正規表現[1-8]」を使用して、入力値が半角の1~8の値か判定します。
では最後に、このメソッドをMain.javaで使用して、形を整えて完成としまししょう。
--Main.java--
package osero; import java.util.Scanner; import osero.config.StartConfig; import osero.middleware.CheckInputValue; import osero.model.ReverseOsero; import osero.view.ShowBoard; public class Main { //オセロの情報 public static String white = "◯"; public static String black = "●"; //ボードの情報を保存する public static String board[][] = new String[9][9]; //入力値の情報を保持する private static int inputX; private static int inputY; static String x = "0"; static String y = "0"; public static void main(String[] args) { //インスタンスの作成 StartConfig SC = new StartConfig(); ShowBoard SB = new ShowBoard(); Scanner sc = new Scanner(System.in); ReverseOsero RO = new ReverseOsero(); CheckInputValue CIV = new CheckInputValue(); System.out.println("オセロを開始します."); //ボードに初期値をセットする SC.boardInitValue(); SC.boardSetup(); //ボードを表示する SB.showBoard(board); while(true){ //x座標を入力する処理 System.out.println("横の座標を1~8の半角数字で入力してください"); x = sc.next(); if(CIV.checkInt1_8(x)) { inputX = Integer.parseInt(x); }else { System.out.println("!!!!!!!!!!その値は無効です!!!!!!!!!!"); System.out.println("1~8の半角数字を入力してください"); } } while(true){ //Y座標を入力する処理 System.out.println("縦の座標を1~8の半角数字で入力してください"); y = sc.next(); if(CIV.checkInt1_8(y)) { inputY = Integer.parseInt(y); }else { System.out.println("!!!!!!!!!!その値は無効です!!!!!!!!!!"); System.out.println("1~8の半角数字を入力してください"); } } //入力した座標にオセロを置く RO.putOsero(inputX, inputY); //ボードを表示する SB.showBoard(board); } }
解説いたします。
まず、CheckInputVale.javaのインスタンスを作成します。
次にオセロを置く横の座標を入力してもらいます。この時、「CheckInt1_8()」メソッド を使用し、trueが返ってきた場合のみ値を「inputX」に入力値をint型に変換して代入します。 違った場合は、違った値を入力している旨を表示し、もう一度入力させます。 半角の1~8が入力された場合はwhile文を抜けることができます。
同様にy軸の入力に対してもおこなっています。
いかがでしょうか?実際に動かすと、半角の1~8が入力されない限り処理が終わらなくなったはずです。 もしそうなっていないようであればどこか間違えているので見比べて確認してみてください。
次回
次回は少し休憩ということで、今回ほどヘビーな内容ではないことをします。
オセロをやっていると白と黒どっちが今多いのか気になりますよね? ということで、今ボード上に白と黒がそれぞれいくつあるのかをカウントして表示するプログラムを作成します。 お楽しみに。ではまたあいましょう。ありがとうございました。