Advertisement
cd62131

RPS, rock paper scissors, じゃんけん

Nov 1st, 2013
753
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 14.96 KB | None | 0 0
  1. package chie13115538893;
  2.  
  3. import java.util.ArrayDeque;
  4. import java.util.Arrays;
  5. import java.util.Deque;
  6. import java.util.EnumMap;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import java.util.Queue;
  10. import java.util.Random;
  11. import java.util.Scanner;
  12.  
  13. public class Main {
  14.   public static void main(String[] args) {
  15.     Fighter[] fighters =
  16.       {new OnlyRock(), new OnlyPaper(), new OnlyScissors(), new RandomHand(),
  17.         new WinningPercentage()};
  18.     Manager league = new LeagueManager(fighters);
  19.     league.fight();
  20.     System.out.println(league);
  21.     Manager tournament = new TournamentManager(fighters);
  22.     tournament.fight();
  23.     System.out.println(tournament);
  24.   }
  25. }
  26.  
  27. abstract class Fighter {
  28.   protected static int fighters = 0;
  29.   protected final int id;
  30.   protected Manager manager;
  31.  
  32.   public Fighter() {
  33.     id = fighters++;
  34.   }
  35.  
  36.   protected abstract Hand hand();
  37.  
  38.   public int id() {
  39.     return id;
  40.   }
  41.  
  42.   public void setManager(Manager manager) {
  43.     this.manager = manager;
  44.   }
  45.  
  46.   @Override
  47.   public String toString() {
  48.     return "Fighter " + id();
  49.   }
  50. }
  51.  
  52. abstract class Manager {
  53.   protected final Fighter[] fighters;
  54.   protected Queue<Match> result;
  55.  
  56.   public Manager(Fighter[] fighters) {
  57.     this.fighters = fighters;
  58.     if (fighters.length < 2) return;
  59.     for (Fighter fighter: this.fighters)
  60.       fighter.setManager(this);
  61.   }
  62.  
  63.   public void fight() {
  64.     result = new ArrayDeque<Match>();
  65.     match();
  66.   }
  67.  
  68.   public Queue<Match> getResult() {
  69.     return result;
  70.   }
  71.  
  72.   protected abstract void match();
  73.  
  74.   @Override
  75.   public abstract String toString();
  76. }
  77.  
  78. class BinaryTree {
  79.   public class FightersAndParent {
  80.     private final BinaryTree parent;
  81.     private final Fighter primary;
  82.     private final Fighter secondary;
  83.  
  84.     public FightersAndParent(
  85.       Fighter primary, Fighter secondary, BinaryTree parent) {
  86.       this.primary = primary;
  87.       this.secondary = secondary;
  88.       this.parent = parent;
  89.     }
  90.  
  91.     public BinaryTree getParent() {
  92.       return parent;
  93.     }
  94.  
  95.     public Fighter getPrimary() {
  96.       return primary;
  97.     }
  98.  
  99.     public Fighter getSecondary() {
  100.       return secondary;
  101.     }
  102.   }
  103.   private Fighter fighter;
  104.   private BinaryTree left;
  105.   private int member;
  106.   private BinaryTree parent;
  107.   private int rank;
  108.   private BinaryTree right;
  109.  
  110.   public BinaryTree(BinaryTree left, BinaryTree right) {
  111.     this.left = left;
  112.     this.right = right;
  113.     member = left.member() + right.member();
  114.     if (left.rank() > right.rank()) rank = left.rank();
  115.     else rank = right.rank();
  116.   }
  117.  
  118.   public BinaryTree(Fighter fighter, int rank) {
  119.     this.fighter = fighter;
  120.     this.rank = rank;
  121.     member = 1;
  122.   }
  123.  
  124.   public void add(BinaryTree newFighter) {
  125.     if (fighter != null) {
  126.       parent.fighter = null;
  127.       BinaryTree newTree = new BinaryTree(this, newFighter);
  128.       newTree.setParent(parent);
  129.       if (parent.right.equals(this)) parent.right = newTree;
  130.       else parent.left = newTree;
  131.       setParent(newTree);
  132.       newFighter.setParent(newTree);
  133.       return;
  134.     }
  135.     if (left.member() < right.member()) {
  136.       left.add(newFighter);
  137.       return;
  138.     }
  139.     else if (left.member() > right.member()) {
  140.       right.add(newFighter);
  141.       return;
  142.     }
  143.     if (left.rank() < right.rank()) {
  144.       right.add(newFighter);
  145.       return;
  146.     }
  147.     else {
  148.       left.add(newFighter);
  149.       return;
  150.     }
  151.   }
  152.  
  153.   public Fighter getFighter() {
  154.     return fighter;
  155.   }
  156.  
  157.   public FightersAndParent getFighters(BinaryTree parent) {
  158.     return new FightersAndParent(parent.left.fighter, parent.right.fighter,
  159.       parent);
  160.   }
  161.  
  162.   public BinaryTree getLeft() {
  163.     return left;
  164.   }
  165.  
  166.   public BinaryTree getRight() {
  167.     return right;
  168.   }
  169.  
  170.   public boolean hasNephew() {
  171.     if (parent == null) return false;
  172.     if (parent.left == null) return false;
  173.     if (parent.right == null) return false;
  174.     if (parent.left.equals(this) && parent.right.fighter != null) return true;
  175.     if (parent.right.equals(this) && parent.left.fighter != null) return true;
  176.     return false;
  177.   }
  178.  
  179.   private void makeMatchAndCorrectTree(Queue<FightersAndParent> acc,
  180.     Queue<Match> result, Deque<Fighter> losers) {
  181.     for (FightersAndParent fap: acc) {
  182.       Match match =
  183.         TournamentManager.shouldMatch(fap.getPrimary(), fap.getSecondary());
  184.       result.offer(match);
  185.       updateFighter(match, fap, losers);
  186.     }
  187.   }
  188.  
  189.   public void matchQueue(Queue<Match> result, Deque<Fighter> losers) {
  190.     Queue<FightersAndParent> acc = new ArrayDeque<FightersAndParent>();
  191.     for (acc = queue(acc); acc.size() > 0; acc = queue(acc)) {
  192.       makeMatchAndCorrectTree(acc, result, losers);
  193.       acc.clear();
  194.     }
  195.   }
  196.  
  197.   public int member() {
  198.     if (fighter != null) {
  199.       member = 1;
  200.       return 1;
  201.     }
  202.     member = left.member() + right.member();
  203.     return member;
  204.   }
  205.  
  206.   public Queue<FightersAndParent> queue(Queue<FightersAndParent> acc) {
  207.     if (member() < 2) return acc;
  208.     if (member() > 2)
  209.       if (left.member() < right.member()) return right.queue(acc);
  210.       else return left.queue(acc);
  211.     acc.offer(new FightersAndParent(left.fighter, right.fighter, this));
  212.     if (hasNephew())
  213.       if (parent.left.equals(this)) return parent.right.queue(acc);
  214.       else if (parent.right.equals(this)) return parent.left.queue(acc);
  215.       else return acc;
  216.     return acc;
  217.   }
  218.  
  219.   public int rank() {
  220.     int l = Integer.MIN_VALUE;
  221.     int r = Integer.MIN_VALUE;
  222.     if (left != null) l = left.rank();
  223.     if (right != null) r = right.rank();
  224.     if (l > rank) rank = l;
  225.     if (r > rank) rank = r;
  226.     return rank;
  227.   }
  228.  
  229.   private void setFiter(Fighter fighter) {
  230.     this.fighter = fighter;
  231.     left = null;
  232.     right = null;
  233.     member = 1;
  234.   }
  235.  
  236.   public void setParent(BinaryTree parent) {
  237.     this.parent = parent;
  238.   }
  239.  
  240.   private void updateFighter(Match match, FightersAndParent fap,
  241.     Deque<Fighter> losers) {
  242.     if (match.getResult() == Result.PrimaryWin) {
  243.       winnerLoser(fap, fap.getPrimary(), fap.getSecondary(), losers);
  244.       return;
  245.     }
  246.     winnerLoser(fap, fap.getSecondary(), fap.getSecondary(), losers);
  247.   }
  248.  
  249.   private void winnerLoser(FightersAndParent fap, Fighter winner,
  250.     Fighter loser, Deque<Fighter> losers) {
  251.     fap.getParent().setFiter(winner);
  252.     losers.offer(loser);
  253.   }
  254. }
  255.  
  256. enum Hand {
  257.   Paper, Rock, Scissors;
  258. }
  259.  
  260. class Human extends Fighter {
  261.   @Override
  262.   protected Hand hand() {
  263.     Scanner in = new Scanner(System.in);
  264.     Hand ret;
  265.     while (true) {
  266.       System.out.print("(r)ock, (p)aper, or, (s)cissors: ");
  267.       String h = in.nextLine();
  268.       if (h.equals("r")) {
  269.         ret = Hand.Rock;
  270.         break;
  271.       }
  272.       else if (h.equals("p")) {
  273.         ret = Hand.Paper;
  274.         break;
  275.       }
  276.       else if (h.equals("s")) {
  277.         ret = Hand.Scissors;
  278.         break;
  279.       }
  280.       else continue;
  281.     }
  282.     in.close();
  283.     return ret;
  284.   }
  285. }
  286.  
  287. class LeagueManager extends Manager {
  288.   public LeagueManager(Fighter[] fighters) {
  289.     super(fighters);
  290.   }
  291.  
  292.   private Map<Fighter, Integer> calcFreq() {
  293.     Map<Fighter, Integer> freq = new HashMap<Fighter, Integer>();
  294.     for (Fighter fighter: fighters)
  295.       freq.put(fighter, 0);
  296.     System.out.println(result);
  297.     for (Match m: result)
  298.       switch (m.getResult()) {
  299.         case PrimaryWin:
  300.           freq.put(m.getPrimary(), freq.get(m.getPrimary()) + 3);
  301.           break;
  302.         case SecondaryWin:
  303.           freq.put(m.getScondary(), freq.get(m.getScondary()) + 3);
  304.         default:
  305.           freq.put(m.getPrimary(), freq.get(m.getPrimary()) + 1);
  306.           freq.put(m.getScondary(), freq.get(m.getScondary()) + 1);
  307.           break;
  308.       }
  309.     return freq;
  310.   }
  311.  
  312.   private int findMax(Map<Fighter, Integer> freq) {
  313.     int max = Integer.MIN_VALUE;
  314.     for (Map.Entry<Fighter, Integer> e: freq.entrySet()) {
  315.       if (e.getValue() <= max) continue;
  316.       max = e.getValue();
  317.     }
  318.     return max;
  319.   }
  320.  
  321.   @Override
  322.   protected void match() {
  323.     for (int i = 0; i < fighters.length - 1; i++)
  324.       for (int j = i + 1; j < fighters.length; j++)
  325.         result.offer(new Match(fighters[i], fighters[j]));
  326.   }
  327.  
  328.   private Deque<Fighter> ranking() {
  329.     Map<Fighter, Integer> freq = calcFreq();
  330.     int max = findMax(freq);
  331.     Deque<Fighter> ret = new ArrayDeque<Fighter>();
  332.     while (ret.size() < fighters.length && max >= 0) {
  333.       for (Fighter f: freq.keySet())
  334.         if (freq.get(f) == max) ret.offer(f);
  335.       max--;
  336.     }
  337.     return ret;
  338.   }
  339.  
  340.   @Override
  341.   public String toString() {
  342.     Deque<Fighter> rank = ranking();
  343.     StringBuilder sb = new StringBuilder();
  344.     sb.append("Fighters: " + Arrays.toString(fighters) + "\n");
  345.     sb.append("Result: " + result + "\n");
  346.     sb.append("Gold: " + rank.poll());
  347.     sb.append(", Silver: " + rank.poll());
  348.     sb.append(", Bronze: " + rank.poll());
  349.     return sb.toString();
  350.   }
  351. }
  352.  
  353. class Match {
  354.   private final Fighter primary;
  355.   private final Hand primaryHand;
  356.   private Result result;
  357.   private final Fighter secondary;
  358.   private final Hand secondaryHand;
  359.  
  360.   public Match(Fighter primary, Fighter secondary) {
  361.     this.primary = primary;
  362.     this.secondary = secondary;
  363.     primaryHand = primary.hand();
  364.     secondaryHand = secondary.hand();
  365.     result = Result.fight(primaryHand, secondaryHand);
  366.   }
  367.  
  368.   public Fighter getPrimary() {
  369.     return primary;
  370.   }
  371.  
  372.   public Hand getPrimaryHand() {
  373.     return primaryHand;
  374.   }
  375.  
  376.   public Result getResult() {
  377.     return result;
  378.   }
  379.  
  380.   public Fighter getScondary() {
  381.     return secondary;
  382.   }
  383.  
  384.   public Hand getSecondaryHand() {
  385.     return secondaryHand;
  386.   }
  387.  
  388.   public void setResult(Result result) {
  389.     this.result = result;
  390.   }
  391.  
  392.   @Override
  393.   public String toString() {
  394.     StringBuilder sb = new StringBuilder();
  395.     sb.append("<Match " + primary + " vs " + secondary);
  396.     sb.append(" : " + primaryHand.name() + ", " + secondaryHand.name());
  397.     sb.append(" - " + result.name() + ">");
  398.     return sb.toString();
  399.   }
  400. }
  401.  
  402. class OnlyPaper extends Fighter {
  403.   @Override
  404.   protected Hand hand() {
  405.     return Hand.Paper;
  406.   }
  407. }
  408.  
  409. class OnlyRock extends Fighter {
  410.   @Override
  411.   protected Hand hand() {
  412.     return Hand.Rock;
  413.   }
  414. }
  415.  
  416. class OnlyScissors extends Fighter {
  417.   @Override
  418.   protected Hand hand() {
  419.     return Hand.Scissors;
  420.   }
  421. }
  422.  
  423. class RandomHand extends Fighter {
  424.   private final Random random;
  425.  
  426.   public RandomHand() {
  427.     super();
  428.     random = new Random();
  429.   }
  430.  
  431.   @Override
  432.   protected Hand hand() {
  433.     switch (random.nextInt(3)) {
  434.       case 2:
  435.         return Hand.Rock;
  436.       case 1:
  437.         return Hand.Paper;
  438.       default:
  439.         return Hand.Scissors;
  440.     }
  441.   }
  442. }
  443.  
  444. enum Result {
  445.   PrimaryWin, SecondaryWin, Throw;
  446.   public static Result fight(Hand primary, Hand secondary) {
  447.     switch (primary) {
  448.       case Rock:
  449.         switch (secondary) {
  450.           case Scissors:
  451.             return PrimaryWin;
  452.           case Paper:
  453.             return SecondaryWin;
  454.           default:
  455.             return Throw;
  456.         }
  457.       case Paper:
  458.         switch (secondary) {
  459.           case Rock:
  460.             return PrimaryWin;
  461.           case Scissors:
  462.             return SecondaryWin;
  463.           default:
  464.             return Throw;
  465.         }
  466.       default:
  467.         switch (secondary) {
  468.           case Paper:
  469.             return PrimaryWin;
  470.           case Rock:
  471.             return SecondaryWin;
  472.           default:
  473.             return Throw;
  474.         }
  475.     }
  476.   }
  477. }
  478.  
  479. class TournamentManager extends Manager {
  480.   public static Match shouldMatch(Fighter primary, Fighter secondary) {
  481.     Match match;
  482.     int i;
  483.     for (match = new Match(primary, secondary), i = 0; match.getResult() == Result.Throw ||
  484.       i < 5; match = new Match(primary, secondary), i++)
  485.       ;
  486.     if (match.getResult() == Result.Throw) match.setResult(Result.PrimaryWin);
  487.     return match;
  488.   }
  489.   private final Deque<Fighter> loser;
  490.   private Fighter third;
  491.  
  492.   public TournamentManager(Fighter[] fighters) {
  493.     super(fighters);
  494.     loser = new ArrayDeque<Fighter>();
  495.   }
  496.  
  497.   private BinaryTree buildTree() {
  498.     BinaryTree primary = new BinaryTree(fighters[0], 0);
  499.     BinaryTree secondary = new BinaryTree(fighters[1], 1);
  500.     BinaryTree root = new BinaryTree(primary, secondary);
  501.     primary.setParent(root);
  502.     secondary.setParent(root);
  503.     for (int i = 2; i < fighters.length; i++)
  504.       root.add(new BinaryTree(fighters[i], i));
  505.     return root;
  506.   }
  507.  
  508.   @Override
  509.   protected void match() {
  510.     BinaryTree root = buildTree();
  511.     while (root.member() > 1)
  512.       root.matchQueue(result, loser);
  513.     if (fighters.length > 3) {
  514.       loser.poll(); // second place
  515.       Fighter primary = loser.poll();
  516.       Fighter secondary = loser.poll();
  517.       Match m = shouldMatch(primary, secondary);
  518.       if (m.getResult() == Result.PrimaryWin) third = primary;
  519.       else third = secondary;
  520.       result.add(m);
  521.     }
  522.   }
  523.  
  524.   @Override
  525.   public String toString() {
  526.     StringBuilder sb = new StringBuilder();
  527.     sb.append("Fighters: " + Arrays.toString(fighters) + "\n");
  528.     sb.append("Result: " + result + "\n");
  529.     if (fighters.length < 3) {
  530.       Match match = result.poll();
  531.       sb.append(victoryAndSecond(match));
  532.     }
  533.     else {
  534.       Match finalGame = result.poll();
  535.       sb.append(victoryAndSecond(finalGame));
  536.       sb.append(", Thirad Place: " + third + "\n");
  537.     }
  538.     return sb.toString();
  539.   }
  540.  
  541.   private String victoryAndSecond(Match match) {
  542.     StringBuilder sb = new StringBuilder();
  543.     if (match.getResult() == Result.PrimaryWin) {
  544.       sb.append("Victory: " + match.getPrimary());
  545.       sb.append(", Second Place: " + match.getScondary());
  546.     }
  547.     else {
  548.       sb.append("Victory: " + match.getScondary());
  549.       sb.append(", Second Place: " + match.getPrimary());
  550.     }
  551.     return sb.toString();
  552.   }
  553. }
  554.  
  555. class WinningPercentage extends Fighter {
  556.   @Override
  557.   public Hand hand() {
  558.     Map<Hand, Integer> wins = initWins();
  559.     winsInc(wins);
  560.     return mostWinHand(wins);
  561.   }
  562.  
  563.   private Map<Hand, Integer> initWins() {
  564.     Map<Hand, Integer> wins = new EnumMap<Hand, Integer>(Hand.class);
  565.     for (Hand h: Hand.values())
  566.       wins.put(h, 0);
  567.     return wins;
  568.   }
  569.  
  570.   private Hand mostWinHand(Map<Hand, Integer> wins) {
  571.     int max = Integer.MIN_VALUE;
  572.     Hand ret = null;
  573.     for (Hand h: Hand.values()) {
  574.       if (max >= wins.get(h)) continue;
  575.       max = wins.get(h);
  576.       ret = h;
  577.       break;
  578.     }
  579.     return ret;
  580.   }
  581.  
  582.   private void winsInc(Map<Hand, Integer> wins) {
  583.     for (Match m: manager.result) {
  584.       int addee = 0;
  585.       switch (m.getResult()) {
  586.         case PrimaryWin:
  587.           addee = wins.get(m.getPrimaryHand());
  588.           wins.put(m.getPrimaryHand(), addee + 1);
  589.           break;
  590.         case SecondaryWin:
  591.           addee = wins.get(m.getSecondaryHand());
  592.           wins.put(m.getSecondaryHand(), addee + 1);
  593.           break;
  594.         default:
  595.           break;
  596.       }
  597.     }
  598.   }
  599. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement