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

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

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

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

Q&A

解決済

3回答

901閲覧

Java Enum (ほぼ初めての)使い方は合っていますか?

opyon

総合スコア1009

Java

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

0グッド

4クリップ

投稿2018/09/20 09:27

編集2018/09/20 14:55

Java:「じゃんけんゲーム」でコンパイルしてもスコアが反映されない状態です・・・
上記質問への回答で幸いにもコメントを頂き、ほぼ初めてのEnumを使って実装し直してみました。
実装してみたものの3つの状態グーチョキパー1,2,3しか無いものでもEnumにするメリットがいまいち分からず、
戸惑いながらの実装でこのような使い方で合っているのか自信がありません。

コードの添削をteratailで依頼するのはいいか
添削については賛否があるようですが、差し支えない範囲で改善点や間違った使い方などあればご指摘ご教示頂けると助かります。

-追記-
ご教示頂いたことを意識して書き直しました。
なるべく人や物や行動などのオブジェクト指向も意識したつもりです。
まだまだ改善するところはあるかと思いますが自分なりにはとても満足しています。
ありがとうございました。

出力結果

CPU1 vs CPU2 グー  vs グー  引分 チョキ vs チョキ 引分 パー  vs パー  引分 チョキ vs パー  勝者 CPU1 グー  vs パー  勝者 CPU2 チョキ vs パー  勝者 CPU1 パー  vs パー  引分 チョキ vs グー  勝者 CPU2 チョキ vs グー  連勝 CPU2 パー  vs パー  引分 パー  vs チョキ 連勝 CPU2 チョキ vs パー  勝者 CPU1 最終勝者は CPU1

書き直したプログラム

java

1package _memo; 2 3import java.util.Random; 4 5public class memo_qa147649 { 6 7 public static void main(String[] args) { 8 9 Player[] players = new Player[2]; 10 players[0] = new Player("CPU1"); 11 players[1] = new Player("CPU2"); 12 13 System.out.printf("%n最終勝者は %s%n", game(players, 3).name); 14 15 } 16 17 private static class Player { 18 19 private String name; 20 private int wins; 21 private Hands hand; 22 23 Player(String name) { 24 this.name = name; 25 this.wins = 0; 26 } 27 } 28 29 private static Player game(Player[] players, int winCount) { 30 Player winner = null; 31 Player lastWinner = null; 32 Player theWinner = null; 33 34 Hands[] hand = new Hands[2]; 35 36 System.out.printf("%s vs %s%n", players[0].name, players[1].name); 37 38 while (theWinner == null) { 39 40 players[0].hand = Hands.choice(); 41 players[1].hand = Hands.choice(); 42 43 System.out.printf("%s vs %s ", players[0].hand.text, players[1].hand.text); 44 45 WLD wld = rsp(players[0].hand, players[1].hand); 46 47 if (wld == WLD.DRAW) { 48 System.out.println(WLD.DRAW.text); 49 continue; 50 } 51 52 if (wld == WLD.WIN) { 53 winner = players[0]; 54 } else 55 winner = players[1]; 56 57 if (lastWinner == winner) { 58 lastWinner = winner; 59 System.out.printf("連勝 %s%n", winner.name); 60 } else { 61 winner.wins += 1; 62 lastWinner = winner; 63 System.out.printf("勝者 %s%n", winner.name); 64 } 65 66 if (winner.wins == winCount) { 67 theWinner = winner; 68 } 69 } 70 return theWinner; 71 } 72 73 private static WLD rsp(Hands hand1, Hands hand2) { 74 WLD wld = WLD.DRAW; 75 76 if (hand1 != hand2) { 77 78 switch (hand1) { 79 80 // player1:グー 81 case ROCK: 82 if (hand2 == Hands.SCISSORS) { 83 wld = WLD.WIN; 84 } else { 85 wld = WLD.LOSE; 86 } 87 break; 88 89 // player1:チョキ 90 case SCISSORS: 91 if (hand2 == Hands.PAPER) { 92 wld = WLD.WIN; 93 } else { 94 wld = WLD.LOSE; 95 } 96 break; 97 98 // player1:パー 99 case PAPER: 100 if (hand2 == Hands.ROCK) { 101 wld = WLD.WIN; 102 } else { 103 wld = WLD.LOSE; 104 } 105 break; 106 } 107 } 108 return wld; 109 } 110 111 private enum WLD { 112 DRAW(-1, "引分"), LOSE(0, "負け"), WIN(1, "勝ち"); 113 private final int id; 114 private final String text; 115 116 private WLD(final int id, final String text) { 117 this.id = id; 118 this.text = text; 119 } 120 } 121 122 private enum Hands { 123 ROCK(0, "グー "), SCISSORS(1, "チョキ"), PAPER(2, "パー "); 124 125 private final int id; 126 private final String text; 127 128 private Hands(final int id, final String text) { 129 this.id = id; 130 this.text = text; 131 } 132 133 private static Hands choice() { 134 //r:1:グー s:2:チョ p:3:パー 135 Random rnd = new Random(); 136 return getHands(rnd.nextInt(3)); 137 } 138 139 private int getInt() { 140 return this.id; 141 } 142 143 private String getText() { 144 return this.text; 145 } 146 147 private static Hands getHands(final int id) { 148 Hands[] Handss = Hands.values(); 149 for (Hands hand : Handss) { 150 if (hand.getInt() == id) { 151 return hand; 152 } 153 } 154 return null; 155 } 156 } 157}

-以下初期プログラム-

java

1package _memo; 2 3import java.util.Random; 4 5import _memo.Enums.Jnk; 6 7public class qa147558 { 8 9 private static int rsp(Jnk h1, Jnk h2) { 10 int win = -1; 11 12 int a = Jnk.p.getInt(); 13 if (h1 != h2) { 14 15 switch (h1) { 16 17 case r: 18 // =1=グー 19 if (h2 == Jnk.s) { 20 win = 0; 21 } else { 22 win = 1; 23 } 24 break; 25 case s: 26 // =2=チョ 27 if (h2 == Jnk.p) { 28 win = 0; 29 } else { 30 win = 1; 31 } 32 break; 33 case p: 34 // =3=パー 35 if (h2 == Jnk.r) { 36 win = 0; 37 } else { 38 win = 1; 39 } 40 break; 41 } 42 } 43 return win; 44 } 45 46 public static void main(String[] args) { 47 48 int winner = -1; 49 int lastwin = -2; 50 int[][] players = { { 0, 0 }, { 1, 0 } }; 51 52 String[] m_p = { "CPU1", "CPU2" }; 53 System.out.printf("%svs%s%n", m_p[0], m_p[1]); 54 55 Random rnd = new Random(); 56 57 while (winner < 0) { 58 59 //Enum型 r:1:グー s:2:チョ p:3:パー 60 Jnk[] hand = new Jnk[2]; 61 hand[0] = Jnk.getJnk(rnd.nextInt(3) + 1); 62 hand[1] = Jnk.getJnk(rnd.nextInt(3) + 1); 63 64 int win = rsp(hand[0], hand[1]); 65 66 System.out.printf("%svs%s ", hand[0].getText(), hand[0].getText()); 67 68 if (win == -1) { 69 System.out.println("引分"); 70 continue; 71 } 72 if (lastwin == win) { 73 lastwin = -2; 74 System.out.printf("連勝 %s%n", m_p[win]); 75 } else { 76 players[win][1] += 1; 77 lastwin = win; 78 System.out.printf("勝者 %s%n", m_p[win]); 79 } 80 if (players[win][1] == 3) { 81 winner = win; 82 } 83 } 84 System.out.println(); 85 System.out.printf("最終勝者は %s%n", m_p[winner]); 86 } 87}

Enum

java

1package _memo; 2 3public class Enums { 4 public static enum Jnk { 5 //出力の桁合わせで「チョキ」は「チョ」としています。 6 r(1, "グー"), s(2, "チョ"), p(3, "パー"); 7 8 private final int id; 9 private final String text; 10 11 private Jnk(final int id, final String text) { 12 this.id = id; 13 this.text = text; 14 } 15 public int getInt() { 16 return this.id; 17 } 18 public String getText() { 19 return this.text; 20 } 21 public static Jnk getJnk(final int id) { 22 Jnk[] Jnks = Jnk.values(); 23 for (Jnk jnk : Jnks) { 24 if (jnk.getInt() == id) { 25 return jnk; 26 } 27 } 28 return null; 29 } 30 } 31}

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

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

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

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

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

guest

回答3

0

質問の本題から逸れますが…

3つの状態グーチョキパー1,2,3しか無いものでもEnumにするメリットがいまいち分からず、

逆です。3つしかないからこそEnumを使うメリットがあるのです。

仮にグーチョキパーをintで表すとします。グーチョキパーはそれぞれ1,2,3で表すことにします。
今、手を引数に取り手を出力するメソッドを作りたいとします。
手はintで表すことにしていましたから、引数の型はintになります。つまり、こうなります。

java

1public static void printHand (int hand) { 2 switch(hand) { 3 case 1: 4 System.out.println("グー"); 5 break; 6 case 2: 7 System.out.println("チョキ"); 8 break; 9 case 3: 10 System.out.println("パー"); 11 break; 12 } 13}

これをプログラムする側からしたら、このhandは1か2か3だという前提で組みます。しかし、使う側からすれば、それ以外の数値を入れることもできてしまうのです。
例えばこのメソッドに4を渡したとすると、メソッド名から何かを出力するはずなのですが、何も出力しません。これはまだ軽微なほうだと思われますが、「想定しているもの以外が引数としてわたる」というバグの温床になります。

ここでEnumを使うと、「手としてHand型を要求する」「Hand型のオブジェクトはr,s,pの3つのみで、これら以外が存在しない」事で、引数として渡せるものを制限し、バグの可能性を少なくできます。

投稿2018/09/20 11:33

swordone

総合スコア20649

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

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

opyon

2018/09/20 11:38

>3つしかないからこそEnumを使うメリットがある >引数として渡せるものを制限し、バグの可能性を少なくできます。 なるほど!!これまた目からウロコです!!! すみません、ベストアンサーどちらにも付けたいのですが1つしか無く。。。 白紙から作り直して精進します。
guest

0

ベストアンサー

連勝とかの計算は面倒なので、ジャンケン部分だけ。

Main.java

Java

1import rps.Game; 2import rps.Game.Result; 3import rps.Hand; 4 5 6class Main { 7 public static void main(String[] args) { 8 for(int i = 0; i < 10; ++i) { 9 Hand hand1 = Hand.choose(); 10 Hand hand2 = Hand.choose(); 11 12 Result result = Game.judge(hand1, hand2); 13 System.out.println( 14 String.format("%s %ss %s.", hand1, result, hand2) 15 ); 16 } 17 } 18}

rps/Hand.java

Java

1package rps; 2 3import java.util.Random; 4 5 6public enum Hand { 7 ROCK, PAPER, SCISSORS; 8 9 public static Hand choose() { 10 return values[ 11 random.nextInt(values.length) 12 ]; 13 } 14 @Override 15 public String toString() { 16 return this.name().toLowerCase(); 17 } 18 19 // 20 private static final Random random = new Random(); 21 private static final Hand[] values = Hand.values(); 22}

rps/Game.java

Java

1package rps; 2 3import rps.Hand; 4 5 6public class Game { 7 public enum Result { 8 LOSE, DRAW, WIN; 9 10 @Override 11 public String toString() { 12 return this.name().toLowerCase(); 13 } 14 } 15 16 public static Result judge(Hand mine, Hand other) { 17 if(mine == Hand.ROCK) { 18 if(other == Hand.SCISSORS) return Result.WIN; 19 if(other == Hand.PAPER) return Result.LOSE; 20 21 return Result.DRAW; 22 } 23 if(mine == Hand.PAPER) { 24 if(other == Hand.ROCK) return Result.WIN; 25 if(other == Hand.SCISSORS) return Result.LOSE; 26 27 return Result.DRAW; 28 } 29 { 30 // mine == Hand.SCISSORS 31 if(other == Hand.PAPER) return Result.WIN; 32 if(other == Hand.ROCK) return Result.LOSE; 33 34 return Result.DRAW; 35 } 36 } 37}

Wandbox

全体的にmainメソッドの仕事が多過ぎだと思います。

投稿2018/09/20 11:16

LouiS0616

総合スコア35658

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

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

opyon

2018/09/20 11:22

なるほど!!目からウロコです!!! Enumって定数保存しておく場所としか思っていませんでした^^; そういうことでしたか。。。 そこでじゃんけんの抽選もしてしまうとは私の頭が硬すぎました。 コードをよく見ながら自分なりに実装し直してみます。
opyon

2018/09/20 11:26

命名やクラスの分け方などもとてもシンプルで読みやすくスッと頭の中に入ってきてます。 どうしても1文字変数の癖が抜けなくてそこも直さなければいけないとおもいました。
opyon

2018/09/20 11:29

写経しないで白紙から作り直してみた後もう一度見比べてみます。 ありがとうございました。
guest

0

使い方あってると思いますよ。(動かしていないのであしからず)
気になったとこを上げると、
enumは同じソース内でいいと思います。個人の意見ですが。

投稿2018/09/20 11:06

yukkuri

総合スコア624

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

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

opyon

2018/09/20 11:16

ありがとうございます安心しました。 うまく認識しない気がして外に出してしまいました。 他の意見が無いようでしたら後ほどクローズさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問