/* package whatever; // don't place package name! */
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
final class SampleJanken002 {
/**
* プレイヤーの数
* ideoneだと20にするとRuntimeエラーになる
* メモリリークしてるのかなぁ?
*/
private static final int PLAYERCNT = 10;
/**
* じゃんけんの手
*/
private static enum Hands {
GU("グー"),
CHOKI("チョキ"),
PA("パー"),
NULL("不明");
private Hands
(final String pName
) { this.name = pName;
}
/**
* nullとかならとりあえずパー
* @param h
* @return
*/
private static Hands conv(final Hands h) {
if (Objects.isNull(h) || NULL.equals(h)) {
return Hands.PA;
}
return h;
}
/**
* 番号から手を出す
* Mapのほうがいいかなぁ?
* @param num
* @return
*/
private static Hands getHands(final int num) {
switch (num % 3) {
case 0:
return GU;
case 1:
return CHOKI;
case 2:
default:
return PA;
}
}
}
/**
* 結果
*/
private static enum Results {
WIN,
LOSE,
DRAW
}
private static final class MultiResults {
/**
* 勝った人たち
*/
private final Set<Player> winners = new TreeSet<>();
/**
* 負けたひとたち
*/
private final Set<Player> losers = new TreeSet<>();
}
/**
* 勝負判定
*/
private static final class Judgement {
/**
* 勝負する。h1から見た結果を返す
* @param enemy
* @return
*/
private Results judge(final Hands h1, final Hands h2) {
// 手を確定。null等値に問題があればパーとする
final Hands myhand = Hands.conv(h1);
final Hands enemyhand = Hands.conv(h2);
// 判定
// 同じ手であればあいこ
if (myhand.equals(enemyhand)) {
return Results.DRAW;
}
// 勝ちぱたーん
// 多分もっとスマートな方法があると思うが、今はこれにしておこう
switch (myhand) {
case GU:
// 自分の手はグー。相手がチョキなら自分の勝ち。
if (Hands.CHOKI.equals(enemyhand)) {
return Results.WIN;
} else {
return Results.LOSE;
}
case CHOKI:
if (Hands.PA.equals(enemyhand)) {
return Results.WIN;
} else {
return Results.LOSE;
}
case PA:
if (Hands.GU.equals(enemyhand)) {
return Results.WIN;
} else {
return Results.LOSE;
}
default:
// ここには来ないはずなので例外としよう
}
}
/**
* 指定した人たち全員で勝負。結果は、呼び出し元で作ったインスタンスに
* 反映させる。
* ここでインスタンスを作ると、勝負する度にインスタンスが作られ、
* 環境によってはVMが強制終了される可能性がある。
* @param players
* @param paramRes 結果。格納するインスタンスは呼び出し元で作成する必要がある
*/
private void multiJudge(final List<Player> players, MultiResults paramRes) {
// 複数でよろしく
if (players.size() < 2) {
}
// 結果クリア
paramRes.winners.clear();
paramRes.losers.clear();
// 3つの手が全部出てしまったか、1種類しか無い場合はあいこ
// まず、全体で何種類の手が出ているかをチェック
final Set<Hands> hands = new HashSet<>();
for (final Player p : players) {
hands.add(Hands.conv(p.hand));
}
if (hands.size() == 3 || hands.size() == 1) {
return;
}
// 出たパターン
final List<Hands> playHands = new ArrayList<>(hands);
// 2種類のはずだが、チェックしよう
if (playHands.size() != 2) {
}
// 勝ちの手を抽出
final Hands winhand;
final Results handres = this.judge(playHands.get(0), playHands.get(1));
if (handres.equals(Results.WIN)) {
winhand = playHands.get(0);
} else {
winhand = playHands.get(1);
}
// 勝った人と負けた人を分ける
for (final Player p : players) {
if (winhand.equals(Hands.conv(p.hand))) {
paramRes.winners.add(p);
} else {
// ここで、勝ちで無ければ負け。
// あいこで無い事は既に確認している
paramRes.losers.add(p);
}
}
}
}
/**
* じゃんけんする人
*/
private static final class Player implements Comparable<Player> {
/**
* 基本はパーとする
*/
private Hands hand = Hands.PA;
private Player
(final String pName
) { this.name = pName;
}
/**
* 名前でソートさせましょう
*/
@Override
public int compareTo(final Player pO) {
return this.name.compareTo(pO.name);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
return result;
}
@Override
public boolean equals
(final Object obj
) { if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Player)) {
return false;
}
final Player other = (Player) obj;
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!this.name.equals(other.name)) {
return false;
}
return true;
}
}
private SampleJanken002() {
// なし
}
public static void main
(final String[] args
) { final Judgement judgement = new Judgement();
// じゃんけんする人たち
final List<Player> players = new ArrayList<>();
for (int x = 0; x < PLAYERCNT; x++) {
final Player player = new Player("じゃんけんする人" + (x + 1));
players.add(player);
}
// 一人になるまで勝負
// 回数
int cnt = 1;
// 勝負結果が格納される
final MultiResults results = new MultiResults();
while (players.size() > 1) {
System.
out.
println("############" + cnt
++ + "回目############");
// 手を決めよう
for (final Player p : players) {
p.hand = Hands.getHands(rnd.nextInt(3));
System.
out.
println(p.
name + "が出した手→" + p.
hand.
name); }
// じゃんけん
judgement.multiJudge(players, results);
// あいこならそのまま
if (results.winners.isEmpty() && results.losers.isEmpty()) {
continue;
}
// 勝ち負け
System.
out.
println("[勝った人達]"); for (final Player p : results.winners) {
}
System.
out.
println("[負けた人達]"); for (final Player p : results.losers) {
}
// 勝った人だけでじゃんけん
players.clear();
players.addAll(results.winners);
}
System.
out.
println("******************************"); System.
out.
println("最後に勝った人→" + players.
get(0).
name); }
}