質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

516閲覧

別クラスに分けるヒントをください

syunn

総合スコア78

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/06/03 08:11

前提・実現したいこと

実行クラスとは別にクラスを分けたい
自分で解くので、とっかかりのヒントをください

発生している問題・エラーメッセージ

メインクラスしかない

java

1import java.util.Random; 2 3public class Battle2 { 4 public static void main(String[] args){ 5 //プレイヤパラメータ 6 String p1 = "ダイゴ"; 7 String p2 = "北川景子"; 8 9 String m1 = "足軽隊"; 10 String m2 = "鉄砲隊"; 11 String m3 = "将軍様"; 12 13 int st1 = 60; 14 int st2 = 120; 15 int st3 = 280; 16 int da1 = new Random().nextInt(100);//0から99までの整数ランダム 17 int da2 = new Random().nextInt(200);//0から199までの整数ランダム 18 19 System.out.println("敵部隊が現れた"); 20 System.out.println("-----------------------"); 21 System.out.println(m1 + " HP:" + st1); 22 System.out.println(m2 + " HP:" + st2); 23 System.out.println(m3 + " HP:" + st3); 24 System.out.println("-----------------------"); 25 System.out.println(p1 + "の攻撃"); 26 System.out.println(m1 + "は" + da1 + "のダメージ"); 27 st1 = st1 - da1; 28 29 System.out.println(p2 + "の攻撃"); 30 System.out.println(m1 + "は" + da2 + "のダメージ"); 31 st1 = st1 - da2; 32 33 System.out.println(m2 + "は" + da2 + "のダメージ"); 34 st2 = st2 - da2; 35 36 System.out.println(m3 + "は" + da2 + "のダメージ"); 37 st3 = st3 - da2; 38 39 System.out.println("-----------------------"); 40 System.out.println(m1 + " HP:" + st1); 41 System.out.println(m2 + " HP:" + st2); 42 System.out.println(m3 + " HP:" + st3); 43 System.out.println("-----------------------"); 44 //足軽隊のHPが0以下だったら 45 if(st1 <= 0){ 46 System.out.println(m1 + "は倒れた"); 47 } 48 //鉄砲隊のHPが0以下だったら 49 if(st2 <= 0){ 50 System.out.println(m2 + "は倒れた"); 51 } 52 if(st3 <= 0){ 53 System.out.println(m3 + "は倒れた"); 54 } 55 56 //余裕判定(合計ダメージが50以下) 57 if(da1 + da2 <=50){ 58 System.out.println(m1 + "は余裕で微笑んだ"); 59 } 60 if(da2 <= 50){ 61 System.out.println(m2 + "は余裕で微笑んだ"); 62 } 63 64 65 //勝利判定 66 if(st1 <= 0 && st2 <= 0 && st3 <= 0){ 67 System.out.println("戦いに勝利した"); 68 } 69 } 70} 71 72

試したこと

プレイヤパラメータを別クラスに移そうとした

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2019/06/03 08:21

何を聞きたいかが摑めません。どんなとっかかりを求めているのですか?
m.ts10806

2019/06/03 08:22

「解く」って何のことでしょう。
syunn

2019/06/03 08:24

実行クラスを簡略化して、別クラスを作りたいです。 別クラスから実行クラスへ継承するのはわかるのですが。
syunn

2019/06/03 08:26

「解く」とは、最終的には自分でやるのでヒントをくださいということです。
m.ts10806

2019/06/03 08:49

表現変えたほうが良さそうですけどね。 「解く」という表現は「問題を解く」のように宿題・課題の雰囲気が出ます。
syunn

2019/06/03 08:55

ご指摘ありがとうございます。
ku__ra__ge

2019/06/05 08:46

質問と関係ないですが、変数名は長くていいので読める名前にすべきです。m1が敵の名前を格納する変数であることは名前から想像することができません。enamyName1などにしましょう。damageもdaという名前に省略する必要はありません。読みやすさは正義です。
guest

回答4

0

私は趣味でやっているので、その道の方とは方向性が違うかもしれません。
もしかしたら、禁じ手かもしれません。(例えば、さすがにやりませんが、グローバル変数をガンガン使うとか。)
それでもいいから、ヒントが欲しいっていうことだと思うので書きますね。


よい子のC++(オブジェクト指向完全理解)によると、「OOPは役割分担である」らしいです。

「オブジェクトだけが、(対象)データとその変動、処理内容を知っている」っていうことらしいです。

だから、「もし、これらを役割分担していくならどうしたいか」って考えますね。私なら。

オリジナルコードは(私が書きやすいように、問題のコードをそのままコピペすると...)

Java

1import java.util.Random; 2 3public class Battle2 { 4 public static void main(String[] args){ 5 //プレイヤパラメータ 6 String p1 = "ダイゴ"; 7 String p2 = "北川景子"; 8 9 String m1 = "足軽隊"; 10 String m2 = "鉄砲隊"; 11 String m3 = "将軍様"; 12 13 int st1 = 60; 14 int st2 = 120; 15 int st3 = 280; 16 int da1 = new Random().nextInt(100);//0から99までの整数ランダム 17 int da2 = new Random().nextInt(200);//0から199までの整数ランダム 18 19 System.out.println("敵部隊が現れた"); 20 System.out.println("-----------------------"); 21 System.out.println(m1 + " HP:" + st1); 22 System.out.println(m2 + " HP:" + st2); 23 System.out.println(m3 + " HP:" + st3); 24 System.out.println("-----------------------"); 25 System.out.println(p1 + "の攻撃"); 26 System.out.println(m1 + "は" + da1 + "のダメージ"); 27 st1 = st1 - da1; 28 29 System.out.println(p2 + "の攻撃"); 30 System.out.println(m1 + "は" + da2 + "のダメージ"); 31 st1 = st1 - da2; 32 33 System.out.println(m2 + "は" + da2 + "のダメージ"); 34 st2 = st2 - da2; 35 36 System.out.println(m3 + "は" + da2 + "のダメージ"); 37 st3 = st3 - da2; 38 39 System.out.println("-----------------------"); 40 System.out.println(m1 + " HP:" + st1); 41 System.out.println(m2 + " HP:" + st2); 42 System.out.println(m3 + " HP:" + st3); 43 System.out.println("-----------------------"); 44 //足軽隊のHPが0以下だったら 45 if(st1 <= 0){ 46 System.out.println(m1 + "は倒れた"); 47 } 48 //鉄砲隊のHPが0以下だったら 49 if(st2 <= 0){ 50 System.out.println(m2 + "は倒れた"); 51 } 52 if(st3 <= 0){ 53 System.out.println(m3 + "は倒れた"); 54 } 55 56 //余裕判定(合計ダメージが50以下) 57 if(da1 + da2 <=50){ 58 System.out.println(m1 + "は余裕で微笑んだ"); 59 } 60 if(da2 <= 50){ 61 System.out.println(m2 + "は余裕で微笑んだ"); 62 } 63 64 65 //勝利判定 66 if(st1 <= 0 && st2 <= 0 && st3 <= 0){ 67 System.out.println("戦いに勝利した"); 68 } 69 } 70}

ですよね。

RPGみたいな感じでやろうとしていますね。

少なくとも 戦うキャラの、戦国系だと、武将にあたるキャラが二人。(自分と敵。つまりプレイヤーとPC)

そして、それぞれの配下に足軽や鉄砲隊といった、駒がある。

Randomで生成しているのは、受ける攻撃力かなんか(すべては読んでいません。)だと思います。

そうすると、少なくとも、管理したいデータが、

  • メイン武将(プレイヤー vs. PC)

→ 配下に足軽等

  • 攻撃力等の指定
  • 将棋や囲碁でいう将棋盤とか、カードゲームとかでならフィールドと呼ばれる場所

ですよね。

まず、メイン武将は、「名前」, 「HP」あたりは必須だと思います。

なので、こいつらをフィールド(メンバ変数)として、保持します。

そして、これを「Commander」(総司令官) とします。

Java

1public class Commander{ 2 private String name_; 3 private int hp_; 4}

でもこのままではアクセスできないので、コンストラクタで名前とHP、そしてメソッドとして、攻撃した・された系のものをつける。

また、攻撃力がわからないので、これをコンストラクタで受けて、(上記には書いていなかったが)ap (攻撃力) をセットする。

Java

1public class Commander{ 2 private String name_; 3 private int hp_; 4 private int ap_; // 攻撃力 5 public Commander( String name, int hp, int ap ){ name_ = name; hp_ = hp; ap_ = ap; } 6 public bool attack( int damage ){ /* ??? */ } /* 要修正 */ 7 public bool attacked( int damage ){ hp_ -= damage; } /* 本来はif文で「攻撃できたか」云々をチェックする */ 8}

まずはメイン武将についてはここまで。

これ以降はほかの部分にバッティングするので。

そして、次は、メイン武将の配下にある、足軽とかそういうキャラ。

(配下にいるのは)常に3人以下なのか、HP = 人数 と考えておられるのか...とかによっても変わってくると思いますが、

足軽とかも、メイン武将みたいな感じで組んでいく。

そして、「足軽その他は、メイン武将の配下にある」と考えるなら、メイン武将のフィールドとして、List<>あたりで保持したほうが管理しやすそう。

もし、足軽クラスを Ashigaru, 鉄砲隊クラスなら Teppoutai ... とか。

で、上記には書いていませんが、 addServantメソッドで、

Java

1Ashigaru ashigaru = new Ashigaru(100); 2bushuo.addServant( ashigaru );

みたいに追加していく。

これが、常に三つまでならいいですが、後から追加する可能性もあるなら、List<> に含めたい。

でもそのままではできません。

List<int> に Stringとかを入れるようなものです。

なので、ここは継承を使います。

Ashigaru, Teppoutai ... は 「メイン武将の配下」であることから、ここは Subと考えて、

Sub インターフェース ( Javaなら interfaceがありますが、それです )を定義して、

攻撃する・されるとかのインターフェースを用意。

それを継承・実装して、Ashigaru とかができる...みたいな感じにしておく。

そうすれば、

Java

1public class Commander{ 2 private String name_; 3 ... 4 private List<Sub> subs_; 5 ... 6 public addServant( Sub sub ){ subs_.add( sub ); } 7}

みたいにすればいい。

あとは、しっくりくるように組み立てる。( キャラに関しては )

攻撃力の指定とかは、プログラムが指定してもいいですが、乱数を発行したり、あるいは前回の続きから行ったり...とかがありますよね。

なので、ここはメソッド化もしくはクラス化しちゃいましょう。

今回の場合は、メソッドで事足りるので、メソッドでいいです。

  1. 乱数を生成する(複数個)
  2. 生成した乱数をもとに、List<Sub> とかを生成して返す

みたいな感じで。

将棋盤に相当する場所は、遊〇王とかそういう、世界観を持つようなものじゃなくて、
単に戦わせるだけのフィールドなら、mainメソッドでもいいかも?
それがちょっと怪しいなら、別のメソッドを呼んで、間接的に操作...みたいに。


[追記1]

ああ、忘れていました。
多分、ご承知だとは思いますが、
攻撃する側からすれば、Subを受け取り、そのSubのattackedメソッド( 攻撃された系 ) を呼び出して、改変してもらう。

そして攻撃される側からすると、自分オブジェクトが攻撃者に渡され、
自身のattackedメソッドに、敵の攻撃力( ap_ ) が渡される。
そして、その値をマイナスしていく。(ふつうは攻撃されたらマイナスになるからねぇ。)

簡易的なものならこれでいいですが、ほとんどのRPGなんかは、「独自の攻撃や回復系魔法 等」を持っていますね。
これはどうするか、頭を悩ませますが、そういう風に考えていく。

あと、ポーションとか、ドラ〇ンボ〇ルでいう「仙〇」とかみたいな、回復したり、
逆に、爆弾とかそういう、攻撃系のアイテムがあったりします。

これも、キャラ系のやつとかみたいに、クラス化したり、インターフェースを設けて実装したり。
使った後は、使えなくするのが普通ですよね。
(さすがに食い物系や爆弾系で何度使っても...っていうのは不自然だし。仮にOKだとしても、「常に湧き出る水」みたいに、特殊条件を付けないといけないでしょうし。)

なので、C++でいえばdeleteに相当する処理をする。(Javaだと無いと思うので、単純にリストから省くとか)

あるいは、未使用・使用のチェックためにboolを追加しておく。これで「未使用」と判定されたものだけ使う...とか。


[追記2]

あと、なんとなく思いついたのですが、基本攻撃とかMPを使って行う攻撃や回復は、これもクラス化するかなぁ...

そしたら、オブジェクトを取り換えるだけでいい気がする...

投稿2019/06/05 02:33

編集2019/06/07 01:33
BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syunn

2019/06/05 12:01

ご丁寧にありがとうございます。大変参考になりました。
guest

0

ヒント:役割分担

作ろうとしているアプリケーションの全容と仕様を知っているのは質問者さんだけです。
その全体から役割分担を考えてください。
クラス等々はあくまで「道具」「パーツ」です。どのような道具、パーツを組み合わせて作り上げるかを考えてください。

投稿2019/06/03 08:48

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

Javaは門外漢なのですが、回答依頼をいただいたので、オブジェクト指向での観点から、回答させていただきます。
(間違っていたら、どうか他の回答者さん含み、マイナス評価とコメントください)
まず、クラス分けをするヒントとして、一番わかりやすい判断基準は、
同じような処理、形式をしているものを、一個のクラスにし、各々個別のデータはインスタンス化する です。
今回質問いただいた、処理で、それに該当するのは、
各プレーヤーと、モンスターです。

なぜかというと、プレーヤーという性質上、
名前やパラメーター(プログラム上のパラメータではなく、ゲーム上のです)が違うだけで、
プレーヤーという形式、仕組み自体は共通だからです。

例えを出すのはあまりよろしくないのですが、
クラスとインスタンスの関係は、よく設計図と、実際に作られた物に例えられます。
車は、設計図があるからこそ、大量生産できますよね?
それと同じで、プログラムも大量の処理をするときに、クラスという設計図があるからこそ、
同じ形式だが、少しずつデータが違うインスタンスを大量生成し、各プレーヤーを作ることができるのです。

なので、
今回の質問の処理で、プレーヤーをクラス分けするなら、下記のようになるでしょう。
※あらかじめ言いますが、Javaは門外漢なので、構文は間違ってるかもしれませんので、ご了承ください。

java

1import java.util.Random; 2 3public class Battle2 { 4 public static void main(String[] args){ 5 //プレイヤパラメータ 6 Player p1 = new Player("ダイゴ", 100); 7 Player p2 = new Player("北川景子", 200); 8 9 Monster m1 = new Monster("足軽隊", 60); 10 Monster m2 = new Monster("鉄砲隊", 120); 11 Monster m3 = new Monster("将軍様", 280); 12 13 int st1 = 60; 14 int st2 = 120; 15 int st3 = 280; 16 17 int da1 = new Random().nextInt(p1.ap);//0からダイゴの攻撃力までの整数ランダム 18 int da2 = new Random().nextInt(p2.ap);//0から北川景子の攻撃力までの整数ランダム 19 20 System.out.println("敵部隊が現れた"); 21 System.out.println("-----------------------"); 22 System.out.println(m1.name + " HP:" + m1.hp); 23 System.out.println(m2.name + " HP:" + m2.hp); 24 System.out.println(m3.name + " HP:" + m3.hp); 25 System.out.println("-----------------------"); 26 System.out.println(p1.name + "の攻撃"); 27 System.out.println(m1.name + "は" + da1 + "のダメージ"); 28 m1.damage(da1); 29 30 System.out.println(p2.name + "の攻撃"); 31 System.out.println(m1.name + "は" + da2 + "のダメージ"); 32 m1.damage(da2); 33 34 System.out.println(m2.name + "は" + da2 + "のダメージ"); 35 m2.damage(da2); 36 37 System.out.println(m3.name + "は" + da2 + "のダメージ"); 38 m3.damage(da2); 39 40 System.out.println("-----------------------"); 41 System.out.println(m1.name + " HP:" + m1.hp); 42 System.out.println(m2.name + " HP:" + m2.hp); 43 System.out.println(m3.name + " HP:" + m3.hp); 44 System.out.println("-----------------------"); 45 //足軽隊のHPが0以下だったら 46 if(m1.hp <= 0){ 47 System.out.println(m1.name + "は倒れた"); 48 } 49 //鉄砲隊のHPが0以下だったら 50 if(m2.hp <= 0){ 51 System.out.println(m2.name + "は倒れた"); 52 } 53 if(m3.hp <= 0){ 54 System.out.println(m3.name + "は倒れた"); 55 } 56 57 //余裕判定(合計ダメージが50以下) 58 if(da1 + da2 <=50){ 59 System.out.println(m1.name + "は余裕で微笑んだ"); 60 } 61 if(da2 <= 50){ 62 System.out.println(m2.name + "は余裕で微笑んだ"); 63 } 64 65 66 //勝利判定 67 if(m1.hp <= 0 && m2.hp <= 0 && m3.hp <= 0){ 68 System.out.println("戦いに勝利した"); 69 } 70 } 71} 72 73public class Player { 74 public String name; 75 public Int ap; 76 public Player(String name, Int ap) { 77 this.name = name; 78 this.ap = ap; 79 } 80} 81public class Monster { 82 public String name; 83 public Int hp; 84 public Monster(String name, Int hp) { 85 this.name = name; 86 this.hp = hp; 87 } 88 public void damage(Int dp) { 89 this.hp -= dp; 90 } 91}

今回の例だと、クラス分けの恩恵は受けずらいかもですが、
この、攻撃ターン自体もクラス分けすることによって、より、効率的に、
構築ができるようになるかと思います。
(すみません、そこまでやると、作業依頼レベルになるため、ここまでにしておきます・・・。)

投稿2019/06/03 08:47

編集2019/06/03 08:52
miyabi_takatsuk

総合スコア9528

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syunn

2019/06/03 12:37

ありがとうございました。ほとんど答えでしたね(笑) プレイヤークラス、モンスタークラスから作ればスムーズにいったかもしれません。
miyabi_takatsuk

2019/06/04 01:18 編集

> ありがとうございました。ほとんど答えでしたね(笑) ヒントと仰っているのに、答えの掲示になって申し訳ないです 汗 > プレイヤークラス、モンスタークラスから作ればスムーズにいったかもしれません。 もう一つヒントとして、物事を構成する手法で、演繹法と帰納法があります。 プログラムは、帰納法が向いているかな、と思います。 やりたい結果から、必要なものを考えていく、という手法です。 作りたい全体像 > 必要なもの > クラス化 > 必要なプロパティ、メソッド > もしかしたらまたクラスが必要かも って具合にです。 演繹法はその逆で、あるクラス < このクラスと組み合わせると < これができんじゃん って感じですね。 頑張ってくださいー そして、あくまで、私は、Javaはまだ勉強できておりませんので、Javaのことではしっかりと回答できませんので、どうかご了承ください 汗
syunn

2019/06/04 02:30

十分理解できました。やりたいクラスから作っていくってことですね。ありがとうございます。
guest

0

プレイヤーと敵のクラス。

投稿2019/06/03 08:22

sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syunn

2019/06/03 08:34

ありがとうございます。やってみます。
syunn

2019/06/03 08:42

プレイヤと敵のクラスに加えて、バトルクラス、バトル実行クラスの4つを作ればいいですね?
sazi

2019/06/03 09:23

バトルクラス、バトル実行クラスは作らない方がシンプルな気がします。 結果を元にメッセージを振り分けるクラス位はありかもしれませんが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問