fork(1) download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashSet;
  5. import java.util.List;
  6. import java.util.Objects;
  7. import java.util.Random;
  8. import java.util.Set;
  9. import java.util.TreeSet;
  10.  
  11. final class SampleJanken002 {
  12.  
  13. /**
  14. * プレイヤーの数
  15. * ideoneだと20にするとRuntimeエラーになる
  16. * メモリリークしてるのかなぁ?
  17. */
  18. private static final int PLAYERCNT = 10;
  19.  
  20. /**
  21. * じゃんけんの手
  22. */
  23. private static enum Hands {
  24. GU("グー"),
  25. CHOKI("チョキ"),
  26. PA("パー"),
  27. NULL("不明");
  28.  
  29. private final String name;
  30.  
  31. private Hands(final String pName) {
  32. this.name = pName;
  33. }
  34.  
  35. /**
  36. * nullとかならとりあえずパー
  37. * @param h
  38. * @return
  39. */
  40. private static Hands conv(final Hands h) {
  41. if (Objects.isNull(h) || NULL.equals(h)) {
  42. return Hands.PA;
  43. }
  44.  
  45. return h;
  46. }
  47.  
  48. /**
  49. * 番号から手を出す
  50. * Mapのほうがいいかなぁ?
  51. * @param num
  52. * @return
  53. */
  54. private static Hands getHands(final int num) {
  55. switch (num % 3) {
  56. case 0:
  57. return GU;
  58.  
  59. case 1:
  60. return CHOKI;
  61.  
  62. case 2:
  63. default:
  64. return PA;
  65. }
  66. }
  67. }
  68.  
  69. /**
  70. * 結果
  71. */
  72. private static enum Results {
  73. WIN,
  74. LOSE,
  75. DRAW
  76. }
  77.  
  78. private static final class MultiResults {
  79. /**
  80. * 勝った人たち
  81. */
  82. private final Set<Player> winners = new TreeSet<>();
  83.  
  84. /**
  85. * 負けたひとたち
  86. */
  87. private final Set<Player> losers = new TreeSet<>();
  88. }
  89.  
  90. /**
  91. * 勝負判定
  92. */
  93. private static final class Judgement {
  94.  
  95. /**
  96. * 勝負する。h1から見た結果を返す
  97. * @param enemy
  98. * @return
  99. */
  100. private Results judge(final Hands h1, final Hands h2) {
  101. // 手を確定。null等値に問題があればパーとする
  102. final Hands myhand = Hands.conv(h1);
  103. final Hands enemyhand = Hands.conv(h2);
  104.  
  105. // 判定
  106.  
  107. // 同じ手であればあいこ
  108. if (myhand.equals(enemyhand)) {
  109. return Results.DRAW;
  110. }
  111.  
  112. // 勝ちぱたーん
  113. // 多分もっとスマートな方法があると思うが、今はこれにしておこう
  114. switch (myhand) {
  115. case GU:
  116. // 自分の手はグー。相手がチョキなら自分の勝ち。
  117. if (Hands.CHOKI.equals(enemyhand)) {
  118. return Results.WIN;
  119. } else {
  120. return Results.LOSE;
  121. }
  122.  
  123. case CHOKI:
  124. if (Hands.PA.equals(enemyhand)) {
  125. return Results.WIN;
  126. } else {
  127. return Results.LOSE;
  128. }
  129.  
  130. case PA:
  131. if (Hands.GU.equals(enemyhand)) {
  132. return Results.WIN;
  133. } else {
  134. return Results.LOSE;
  135. }
  136. default:
  137. // ここには来ないはずなので例外としよう
  138. throw new IllegalStateException("判定に失敗");
  139. }
  140. }
  141.  
  142. /**
  143. * 指定した人たち全員で勝負。結果は、呼び出し元で作ったインスタンスに
  144. * 反映させる。
  145. * ここでインスタンスを作ると、勝負する度にインスタンスが作られ、
  146. * 環境によってはVMが強制終了される可能性がある。
  147. * @param players
  148. * @param paramRes 結果。格納するインスタンスは呼び出し元で作成する必要がある
  149. */
  150. private void multiJudge(final List<Player> players, MultiResults paramRes) {
  151. // 複数でよろしく
  152. if (players.size() < 2) {
  153. throw new IllegalArgumentException("複数人でお願いしますわ。");
  154. }
  155.  
  156. // 結果クリア
  157. paramRes.winners.clear();
  158. paramRes.losers.clear();
  159.  
  160. // 3つの手が全部出てしまったか、1種類しか無い場合はあいこ
  161. // まず、全体で何種類の手が出ているかをチェック
  162. final Set<Hands> hands = new HashSet<>();
  163. for (final Player p : players) {
  164. hands.add(Hands.conv(p.hand));
  165. }
  166. if (hands.size() == 3 || hands.size() == 1) {
  167. return;
  168. }
  169.  
  170. // 出たパターン
  171. final List<Hands> playHands = new ArrayList<>(hands);
  172. // 2種類のはずだが、チェックしよう
  173. if (playHands.size() != 2) {
  174. throw new IllegalStateException("ここで2種類以外の手はありえない。 手の数=" + playHands.size());
  175. }
  176.  
  177. // 勝ちの手を抽出
  178. final Hands winhand;
  179. final Results handres = this.judge(playHands.get(0), playHands.get(1));
  180. if (handres.equals(Results.WIN)) {
  181. winhand = playHands.get(0);
  182. } else {
  183. winhand = playHands.get(1);
  184. }
  185.  
  186. // 勝った人と負けた人を分ける
  187. for (final Player p : players) {
  188. if (winhand.equals(Hands.conv(p.hand))) {
  189. paramRes.winners.add(p);
  190. } else {
  191. // ここで、勝ちで無ければ負け。
  192. // あいこで無い事は既に確認している
  193. paramRes.losers.add(p);
  194. }
  195. }
  196. }
  197. }
  198.  
  199. /**
  200. * じゃんけんする人
  201. */
  202. private static final class Player implements Comparable<Player> {
  203. private final String name;
  204.  
  205. /**
  206. * 基本はパーとする
  207. */
  208. private Hands hand = Hands.PA;
  209.  
  210. private Player(final String pName) {
  211. this.name = pName;
  212. }
  213.  
  214. /**
  215. * 名前でソートさせましょう
  216. */
  217. @Override
  218. public int compareTo(final Player pO) {
  219. return this.name.compareTo(pO.name);
  220. }
  221.  
  222. @Override
  223. public int hashCode() {
  224. final int prime = 31;
  225. int result = 1;
  226. result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
  227. return result;
  228. }
  229.  
  230. @Override
  231. public boolean equals(final Object obj) {
  232. if (this == obj) {
  233. return true;
  234. }
  235. if (obj == null) {
  236. return false;
  237. }
  238. if (!(obj instanceof Player)) {
  239. return false;
  240. }
  241. final Player other = (Player) obj;
  242. if (this.name == null) {
  243. if (other.name != null) {
  244. return false;
  245. }
  246. } else if (!this.name.equals(other.name)) {
  247. return false;
  248. }
  249. return true;
  250. }
  251. }
  252.  
  253. private SampleJanken002() {
  254. // なし
  255. }
  256.  
  257. public static void main(final String[] args) {
  258. final Judgement judgement = new Judgement();
  259. final Random rnd = new Random();
  260.  
  261. // じゃんけんする人たち
  262. final List<Player> players = new ArrayList<>();
  263. for (int x = 0; x < PLAYERCNT; x++) {
  264. final Player player = new Player("じゃんけんする人" + (x + 1));
  265. players.add(player);
  266. }
  267.  
  268. // 一人になるまで勝負
  269. // 回数
  270. int cnt = 1;
  271. // 勝負結果が格納される
  272. final MultiResults results = new MultiResults();
  273. while (players.size() > 1) {
  274.  
  275. System.out.println("############" + cnt++ + "回目############");
  276.  
  277. // 手を決めよう
  278. for (final Player p : players) {
  279. p.hand = Hands.getHands(rnd.nextInt(3));
  280. System.out.println(p.name + "が出した手→" + p.hand.name);
  281. }
  282.  
  283. // じゃんけん
  284. judgement.multiJudge(players, results);
  285.  
  286. // あいこならそのまま
  287. if (results.winners.isEmpty() && results.losers.isEmpty()) {
  288. System.out.println("あいこ");
  289. continue;
  290. }
  291.  
  292. // 勝ち負け
  293. System.out.println("[勝った人達]");
  294. for (final Player p : results.winners) {
  295. System.out.println(p.name);
  296. }
  297.  
  298. System.out.println();
  299.  
  300. System.out.println("[負けた人達]");
  301. for (final Player p : results.losers) {
  302. System.out.println(p.name);
  303. }
  304.  
  305. // 勝った人だけでじゃんけん
  306. players.clear();
  307. players.addAll(results.winners);
  308. }
  309.  
  310. System.out.println();
  311. System.out.println("******************************");
  312. System.out.println("最後に勝った人→" + players.get(0).name);
  313. }
  314.  
  315. }
Success #stdin #stdout 0.06s 4386816KB
stdin
Standard input is empty
stdout
############1回目############
じゃんけんする人1が出した手→パー
じゃんけんする人2が出した手→チョキ
じゃんけんする人3が出した手→グー
じゃんけんする人4が出した手→パー
じゃんけんする人5が出した手→チョキ
じゃんけんする人6が出した手→チョキ
じゃんけんする人7が出した手→グー
じゃんけんする人8が出した手→パー
じゃんけんする人9が出した手→パー
じゃんけんする人10が出した手→チョキ
あいこ
############2回目############
じゃんけんする人1が出した手→チョキ
じゃんけんする人2が出した手→チョキ
じゃんけんする人3が出した手→グー
じゃんけんする人4が出した手→グー
じゃんけんする人5が出した手→グー
じゃんけんする人6が出した手→グー
じゃんけんする人7が出した手→チョキ
じゃんけんする人8が出した手→パー
じゃんけんする人9が出した手→パー
じゃんけんする人10が出した手→グー
あいこ
############3回目############
じゃんけんする人1が出した手→グー
じゃんけんする人2が出した手→グー
じゃんけんする人3が出した手→チョキ
じゃんけんする人4が出した手→グー
じゃんけんする人5が出した手→チョキ
じゃんけんする人6が出した手→グー
じゃんけんする人7が出した手→パー
じゃんけんする人8が出した手→グー
じゃんけんする人9が出した手→グー
じゃんけんする人10が出した手→パー
あいこ
############4回目############
じゃんけんする人1が出した手→チョキ
じゃんけんする人2が出した手→パー
じゃんけんする人3が出した手→パー
じゃんけんする人4が出した手→チョキ
じゃんけんする人5が出した手→パー
じゃんけんする人6が出した手→パー
じゃんけんする人7が出した手→パー
じゃんけんする人8が出した手→チョキ
じゃんけんする人9が出した手→パー
じゃんけんする人10が出した手→グー
あいこ
############5回目############
じゃんけんする人1が出した手→パー
じゃんけんする人2が出した手→グー
じゃんけんする人3が出した手→パー
じゃんけんする人4が出した手→パー
じゃんけんする人5が出した手→パー
じゃんけんする人6が出した手→チョキ
じゃんけんする人7が出した手→グー
じゃんけんする人8が出した手→チョキ
じゃんけんする人9が出した手→グー
じゃんけんする人10が出した手→パー
あいこ
############6回目############
じゃんけんする人1が出した手→グー
じゃんけんする人2が出した手→パー
じゃんけんする人3が出した手→パー
じゃんけんする人4が出した手→パー
じゃんけんする人5が出した手→グー
じゃんけんする人6が出した手→パー
じゃんけんする人7が出した手→チョキ
じゃんけんする人8が出した手→グー
じゃんけんする人9が出した手→チョキ
じゃんけんする人10が出した手→パー
あいこ
############7回目############
じゃんけんする人1が出した手→パー
じゃんけんする人2が出した手→チョキ
じゃんけんする人3が出した手→チョキ
じゃんけんする人4が出した手→グー
じゃんけんする人5が出した手→チョキ
じゃんけんする人6が出した手→グー
じゃんけんする人7が出した手→パー
じゃんけんする人8が出した手→パー
じゃんけんする人9が出した手→グー
じゃんけんする人10が出した手→パー
あいこ
############8回目############
じゃんけんする人1が出した手→グー
じゃんけんする人2が出した手→グー
じゃんけんする人3が出した手→グー
じゃんけんする人4が出した手→パー
じゃんけんする人5が出した手→グー
じゃんけんする人6が出した手→グー
じゃんけんする人7が出した手→パー
じゃんけんする人8が出した手→グー
じゃんけんする人9が出した手→グー
じゃんけんする人10が出した手→グー
[勝った人達]
じゃんけんする人4
じゃんけんする人7

[負けた人達]
じゃんけんする人1
じゃんけんする人10
じゃんけんする人2
じゃんけんする人3
じゃんけんする人5
じゃんけんする人6
じゃんけんする人8
じゃんけんする人9
############9回目############
じゃんけんする人4が出した手→グー
じゃんけんする人7が出した手→チョキ
[勝った人達]
じゃんけんする人4

[負けた人達]
じゃんけんする人7

******************************
最後に勝った人→じゃんけんする人4