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

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

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

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

Q&A

解決済

6回答

15195閲覧

3人のジャンケンの勝敗判定で詰まりました。オブジェクト指向でジャンケンの手をクラスに変えるには?

gyro16

総合スコア89

Java

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

0グッド

1クリップ

投稿2016/05/14 00:56

編集2016/05/14 03:38

うーん、欲を言えば、オブジェクト指向でこなしたいです。
ヒントはもらっています。「ジャンケンの手をクラスにする」です。

オブジェクト指向でジャンケンの手のクラスにすると、どうなりますが、
extends 継承を使うにはどのように変えたらいいですか?
今はジャンケンの手はフィールドですね。

3人でのジャンケンの判定をしたいプログラムを作りたいのですが、詰まりました。

まず勝敗がつくパターンはジャンケンの手が2種類の時というのは分かりました。

①勝ったプレイヤーが2人の時、勝者のプレイヤー2人を返すメソッドで可能ではないような感じですし・・・

3人で勝敗がつくパターンは2人が同じ種類のジャンケンの手を出している
・・・2人が勝つパターンか、その他の1人が勝つパターン、です。

②同じ種類のジャンケンの手を出しているプレイヤーを判別認識させたい、です。

書籍のプログラムを改造しようと手を付けてみたものの、詰まってしまいました。

//@param player1 判定対象プレイヤー1 //@param player2 判定対象プレイヤー2 //@return 勝ったプレイヤー。引き分けの時はnullを返す。 private Player judgeJanken(Player player1, Player player2, Player player3){ Player winner = null; //プレイヤー1の手を出す int player1hand = player1.showHand(); //プレイヤー2の手を出す int player2hand = player2.showHand(); int player3hand = player3.showHand(); printHand(player1hand); System.out.print(" vs. "); printHand(player2hand); System.out.print(" vs. "); printHand(play3hand); System.out.print("\n"); int[] hands = { player1hand, player2hand, player3hand }; int type = 1; int maxType = 0; for(int i = 0; i < hands.length; i++){ for(int j = i + 1; j < hands.length ; j++){ if(hands[i] != hands[j]){ type++; } if(maxType < type){ maxType = type; } type = 1; } } } if(maxType == 2){ if(hands[0] == Player.STONE && hands[1] ==Player.STONE && hands[2] == Player.SCISSORS){ System.out.println(player1.getName() + "と" + player2.getName() + "が勝ちました!"); player1.winCount_++; player2.winCount_++; } else if(hands[0] == Player.STONE && hands[1] == Player.SCISSORS && hands[2] == Player.STONE){ System.out.println(player1.getName() + "と" + player3.getName() + "が勝ちました!"); player1.winCount_++; player3.winCount_++; } else if(hands[0] == Player.SCISSORS && hands[1] == Player.STONE && hands[2] == Player.STONE){ System.out.println(player2.getName() + "と" + player3.getName() + "が勝ちました!"); player2.winCount_++; player3.winCount_++; }

と、こんな風に書いて行けばいいのは分かりました。
_____________________________
うーん、欲を言えば、オブジェクト指向でこなしたいです。
ヒントはもらっています。「ジャンケンの手をクラスにする」です。

オブジェクト指向でジャンケンの手のクラスにすると、どうなりますが、
extends 継承を使うにはどのように変えたらいいですか?
今はジャンケンの手はフィールドですね。

/* if((player1hand == Player.STONE && player2hand == Player.SCISSORS) * ||(player1hand == Player.SCISSORS && player2hand == Player.PAPER) * ||(player1hand == Player.PAPER && player2hand == Player.STONE)){ * winner = player1; * } else if( * (player1hand == Player.STONE && player2hand == Player.PAPER) * ||(player1hand == Player.SCISSORS && player2hand == Player.STONE) * ||(player1hand == Player.PAPER && player2hand == Player.SCISSORS)){ * winner = player2; * } * //どちらでもない場合は引き分け(nullを返す) return winner; }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2016/05/14 03:56

質問を変えないでもらえますか。後に他の人が見た時に参考にならなくなります。 質問が変わるのであれば、別の質問を立てて下さい。
guest

回答6

0

解決済みですので蛇足ですが…
https://teratail.com/questions/34165
こちらの私の回答に、ジャンケンのソースをあげています。参考になれば幸いです。

私のソースでは、ジャンケンの手はクラスになっています。
手自体に強弱を持たせず、ルールが手の強弱を決めるという発想です。

投稿2016/05/16 01:20

i50

総合スコア227

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

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

gyro16

2016/05/16 04:01 編集

自分はオブジェクト指向はまだものに出来ていませんが、ジャンケンの手のクラスをどのようにあつかうのかが分かりました。補足ありがとうございました。
guest

0

ベストアンサー

オブジェクトで書くというのは、
そのオブジェクトがどういう性格なのかを決めて表現する、って事です。

↓例えば、このような感じで、内部情報に手と名前を持たせて、名前を取得する機能getName、じゃんけんする機能pon、手を取得する機能showHandという「性格」を表現してみる。

public class Player { private int _hand; private final String _playerName; public static final int SCISSORS = 1; public static final int STONE = 2; public static final int PAPER = 3; public Player(String playerName) { this._playerName = playerName; } public String getName() { return _playerName; } public void pon() { Random r = new Random(); this._hand = r.nextInt(3) + 1; } public int showHand() throws Exception { if(this._hand == 0) { throw new Exception("本メソッドを呼び出す前にジャンケンをしてください"); } if(this._hand < 1 || this._hand > 3) { throw new Exception("グーチョキパー以外の手が選択されています"); } return this._hand; } }

ポイントとしては、ゲーム進行とオブジェクトにしたいものをきっちり分けてあげて、
実装していく時に、ゲーム進行に実装すべきか、オブジェクトに実装すべきか、
整理・判断しながら進めていくと良いと思います。

ちなみに、ご参考までにゲーム進行の実装↓

public class GameProcess { private static final int MEMBER = 3; public static void main(String[] args) throws Exception { List<Player> players = new ArrayList<>(); for(int i = 0; i < MEMBER; i++) { players.add(new Player(String.format("プレイヤー%d", i+1))); } while(players.size() > 1) { janken(players); printVS(players); players = judgeJanken(players); } Player winner = players.get(0); System.out.println(String.format("勝者:%s", winner.getName())); } private static void janken(List<Player> players) { for(int i = 0; i < players.size(); i++) { Player player = players.get(i); player.pon(); } } private static void printVS(List<Player> players) throws Exception { for(int i = 0; i < players.size(); i++) { if(i > 0) { System.out.print(" vs "); } Player player = players.get(i); String handName = null; if(player.showHand() == Player.PAPER) { handName = "パー"; } if(player.showHand() == Player.SCISSORS) { handName = "チョキ"; } if(player.showHand() == Player.STONE) { handName = "グー"; } System.out.print(String.format("%s[%s]", player.getName(), handName)); } System.out.println(); } private static List<Player> judgeJanken(List<Player> players) throws Exception { List<Player> winners = new ArrayList(); for(int i = 0; i < players.size(); i++) { Player p1 = players.get(i); boolean winFlg = false; boolean loseFlg = false; for(int j = 0; j < players.size(); j++) { if(i == j) continue; Player p2 = players.get(j); switch (p1.showHand()) { case Player.PAPER: winFlg = (p2.showHand() == Player.STONE); loseFlg = (p2.showHand() == Player.SCISSORS); break; case Player.SCISSORS: winFlg = (p2.showHand() == Player.PAPER); loseFlg = (p2.showHand() == Player.STONE); break; case Player.STONE: winFlg = (p2.showHand() == Player.SCISSORS); loseFlg = (p2.showHand() == Player.PAPER); break; default: // アサーション break; } } if(winFlg || (!winFlg && !loseFlg)) { winners.add(p1); } } return winners; } }

投稿2016/05/14 06:26

TetsujiMiwa

総合スコア1124

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

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

gyro16

2016/05/14 07:32

勝者を複数返すやり方は分かりました。ありがとうございます。 ジャンケンの手をフィールドではなく、STONEやSCISSORSやPAPERをクラスにすることは可能でしょうか?書籍にはヒントとしてジャンケンの手をクラスにする、とあったのですが、どうですかね?どういう意味でクラスにするかを知りたかったんです。
gyro16

2016/05/15 23:38 編集

winners.addのところは 省略記法をつかうとうまく動きませんでした。 if((winFlg == true) && (loseFlg == false){ と丁寧に書かなければなりませんでした。 あと同じ人の手同士を比較しないようにif文でcontinueをしていましたけど、 やっていること、やりたいことは理解できますが、同じ人の同じ手同士を比較してもwinFlgもloseFlgも(勝ちも負けも)つかないので、省きました。 余計なロジックがあると動作時にJVMで誤動作しやすいので省きました。 やり方は学ばせて頂きました。ありがとうございました。 追加訂正 正常に動作するコードの一部 ●正 if((winFlg == true) && (loseFlg != true)){ ●正 case PlayerB.STONE: if(p2 == PlayerB.SCISSORS){ winFlg = true; } if(p2 == PlayerB.PAPER){ loseFlg = true; } ●正 if(i == j) continue;
guest

0

"java じゃんけん enum"
で google 検索すると、いろいろなプログアム例を見つけることができます。

例えば、こんなコードを参考にしてみては?
http://blog.goo.ne.jp/hishidama/e/ee5bacfceb7179b942d3392bb83e21a6

投稿2016/05/14 05:14

katoy

総合スコア22324

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

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

0

そもそも手は3の3乗通り、つまり27通りしかないので全列挙しても良いと思いますよ。

プログラムイメージ(動作未確認)
const int STONE = 0, SCISSORS = 1, PAPER = 2;
const String result[3][3][3] =
{"引き分け", //石、石、石の場合
"勝者:a,b", //石、石、鋏の場合
"勝者:c", //石、石、紙の場合
"勝者:a,c"//石、鋏、石の場合
…以下略
};

System.out.println(result[PlayerA.hand][PlayerB.hand][PlayerC.hand]);

投稿2016/05/14 02:32

HogeAnimalLover

総合スコア4830

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

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

gyro16

2016/05/14 03:40

ありがとうございます。理解できました。
guest

0

すみません。
勘違いしていました。

同じ手を出しているプレイヤーを識別したいなら、

JAVA

1hands[i] != hands[j]

ここを変更してみてはどうでしょうか。

投稿2016/05/14 02:25

編集2016/05/14 02:30
TEC_S

総合スコア79

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

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

0

*コードは読んでいません。
アルゴリズムとしては、以下が綺麗なのでは?
1,3人が同じ手 引き分け
2,3人が違う手 引き分け
3,2人が同じ1人だけ違う手 2種類の手のどちらかが勝ち。
さくっと書ける気がします。

投稿2016/05/14 01:02

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2016/05/14 01:34 編集

質問が更新されたんで、なんかマヌケな回答になってしまいましたね^^; またコードを見ないで回答しますが、以下でどうでしょう。(ちょっと修正) 1,3人の手を配列に突っ込む。重複を削除した新配列を用意。 2,配列の値が1種類 → あいこ 3,配列の値が2種類 → 組み合わせ判定 4,配列の値が3種類 → あいこ 5,元の配列に判定結果を反映 java書かないんで、配列の処理、簡単に実装できなかったらすみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問