Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package chie13115538893;
- import java.util.ArrayDeque;
- import java.util.Arrays;
- import java.util.Deque;
- import java.util.EnumMap;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Queue;
- import java.util.Random;
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- Fighter[] fighters =
- {new OnlyRock(), new OnlyPaper(), new OnlyScissors(), new RandomHand(),
- new WinningPercentage()};
- Manager league = new LeagueManager(fighters);
- league.fight();
- System.out.println(league);
- Manager tournament = new TournamentManager(fighters);
- tournament.fight();
- System.out.println(tournament);
- }
- }
- abstract class Fighter {
- protected static int fighters = 0;
- protected final int id;
- protected Manager manager;
- public Fighter() {
- id = fighters++;
- }
- protected abstract Hand hand();
- public int id() {
- return id;
- }
- public void setManager(Manager manager) {
- this.manager = manager;
- }
- @Override
- public String toString() {
- return "Fighter " + id();
- }
- }
- abstract class Manager {
- protected final Fighter[] fighters;
- protected Queue<Match> result;
- public Manager(Fighter[] fighters) {
- this.fighters = fighters;
- if (fighters.length < 2) return;
- for (Fighter fighter: this.fighters)
- fighter.setManager(this);
- }
- public void fight() {
- result = new ArrayDeque<Match>();
- match();
- }
- public Queue<Match> getResult() {
- return result;
- }
- protected abstract void match();
- @Override
- public abstract String toString();
- }
- class BinaryTree {
- public class FightersAndParent {
- private final BinaryTree parent;
- private final Fighter primary;
- private final Fighter secondary;
- public FightersAndParent(
- Fighter primary, Fighter secondary, BinaryTree parent) {
- this.primary = primary;
- this.secondary = secondary;
- this.parent = parent;
- }
- public BinaryTree getParent() {
- return parent;
- }
- public Fighter getPrimary() {
- return primary;
- }
- public Fighter getSecondary() {
- return secondary;
- }
- }
- private Fighter fighter;
- private BinaryTree left;
- private int member;
- private BinaryTree parent;
- private int rank;
- private BinaryTree right;
- public BinaryTree(BinaryTree left, BinaryTree right) {
- this.left = left;
- this.right = right;
- member = left.member() + right.member();
- if (left.rank() > right.rank()) rank = left.rank();
- else rank = right.rank();
- }
- public BinaryTree(Fighter fighter, int rank) {
- this.fighter = fighter;
- this.rank = rank;
- member = 1;
- }
- public void add(BinaryTree newFighter) {
- if (fighter != null) {
- parent.fighter = null;
- BinaryTree newTree = new BinaryTree(this, newFighter);
- newTree.setParent(parent);
- if (parent.right.equals(this)) parent.right = newTree;
- else parent.left = newTree;
- setParent(newTree);
- newFighter.setParent(newTree);
- return;
- }
- if (left.member() < right.member()) {
- left.add(newFighter);
- return;
- }
- else if (left.member() > right.member()) {
- right.add(newFighter);
- return;
- }
- if (left.rank() < right.rank()) {
- right.add(newFighter);
- return;
- }
- else {
- left.add(newFighter);
- return;
- }
- }
- public Fighter getFighter() {
- return fighter;
- }
- public FightersAndParent getFighters(BinaryTree parent) {
- return new FightersAndParent(parent.left.fighter, parent.right.fighter,
- parent);
- }
- public BinaryTree getLeft() {
- return left;
- }
- public BinaryTree getRight() {
- return right;
- }
- public boolean hasNephew() {
- if (parent == null) return false;
- if (parent.left == null) return false;
- if (parent.right == null) return false;
- if (parent.left.equals(this) && parent.right.fighter != null) return true;
- if (parent.right.equals(this) && parent.left.fighter != null) return true;
- return false;
- }
- private void makeMatchAndCorrectTree(Queue<FightersAndParent> acc,
- Queue<Match> result, Deque<Fighter> losers) {
- for (FightersAndParent fap: acc) {
- Match match =
- TournamentManager.shouldMatch(fap.getPrimary(), fap.getSecondary());
- result.offer(match);
- updateFighter(match, fap, losers);
- }
- }
- public void matchQueue(Queue<Match> result, Deque<Fighter> losers) {
- Queue<FightersAndParent> acc = new ArrayDeque<FightersAndParent>();
- for (acc = queue(acc); acc.size() > 0; acc = queue(acc)) {
- makeMatchAndCorrectTree(acc, result, losers);
- acc.clear();
- }
- }
- public int member() {
- if (fighter != null) {
- member = 1;
- return 1;
- }
- member = left.member() + right.member();
- return member;
- }
- public Queue<FightersAndParent> queue(Queue<FightersAndParent> acc) {
- if (member() < 2) return acc;
- if (member() > 2)
- if (left.member() < right.member()) return right.queue(acc);
- else return left.queue(acc);
- acc.offer(new FightersAndParent(left.fighter, right.fighter, this));
- if (hasNephew())
- if (parent.left.equals(this)) return parent.right.queue(acc);
- else if (parent.right.equals(this)) return parent.left.queue(acc);
- else return acc;
- return acc;
- }
- public int rank() {
- int l = Integer.MIN_VALUE;
- int r = Integer.MIN_VALUE;
- if (left != null) l = left.rank();
- if (right != null) r = right.rank();
- if (l > rank) rank = l;
- if (r > rank) rank = r;
- return rank;
- }
- private void setFiter(Fighter fighter) {
- this.fighter = fighter;
- left = null;
- right = null;
- member = 1;
- }
- public void setParent(BinaryTree parent) {
- this.parent = parent;
- }
- private void updateFighter(Match match, FightersAndParent fap,
- Deque<Fighter> losers) {
- if (match.getResult() == Result.PrimaryWin) {
- winnerLoser(fap, fap.getPrimary(), fap.getSecondary(), losers);
- return;
- }
- winnerLoser(fap, fap.getSecondary(), fap.getSecondary(), losers);
- }
- private void winnerLoser(FightersAndParent fap, Fighter winner,
- Fighter loser, Deque<Fighter> losers) {
- fap.getParent().setFiter(winner);
- losers.offer(loser);
- }
- }
- enum Hand {
- Paper, Rock, Scissors;
- }
- class Human extends Fighter {
- @Override
- protected Hand hand() {
- Scanner in = new Scanner(System.in);
- Hand ret;
- while (true) {
- System.out.print("(r)ock, (p)aper, or, (s)cissors: ");
- String h = in.nextLine();
- if (h.equals("r")) {
- ret = Hand.Rock;
- break;
- }
- else if (h.equals("p")) {
- ret = Hand.Paper;
- break;
- }
- else if (h.equals("s")) {
- ret = Hand.Scissors;
- break;
- }
- else continue;
- }
- in.close();
- return ret;
- }
- }
- class LeagueManager extends Manager {
- public LeagueManager(Fighter[] fighters) {
- super(fighters);
- }
- private Map<Fighter, Integer> calcFreq() {
- Map<Fighter, Integer> freq = new HashMap<Fighter, Integer>();
- for (Fighter fighter: fighters)
- freq.put(fighter, 0);
- System.out.println(result);
- for (Match m: result)
- switch (m.getResult()) {
- case PrimaryWin:
- freq.put(m.getPrimary(), freq.get(m.getPrimary()) + 3);
- break;
- case SecondaryWin:
- freq.put(m.getScondary(), freq.get(m.getScondary()) + 3);
- default:
- freq.put(m.getPrimary(), freq.get(m.getPrimary()) + 1);
- freq.put(m.getScondary(), freq.get(m.getScondary()) + 1);
- break;
- }
- return freq;
- }
- private int findMax(Map<Fighter, Integer> freq) {
- int max = Integer.MIN_VALUE;
- for (Map.Entry<Fighter, Integer> e: freq.entrySet()) {
- if (e.getValue() <= max) continue;
- max = e.getValue();
- }
- return max;
- }
- @Override
- protected void match() {
- for (int i = 0; i < fighters.length - 1; i++)
- for (int j = i + 1; j < fighters.length; j++)
- result.offer(new Match(fighters[i], fighters[j]));
- }
- private Deque<Fighter> ranking() {
- Map<Fighter, Integer> freq = calcFreq();
- int max = findMax(freq);
- Deque<Fighter> ret = new ArrayDeque<Fighter>();
- while (ret.size() < fighters.length && max >= 0) {
- for (Fighter f: freq.keySet())
- if (freq.get(f) == max) ret.offer(f);
- max--;
- }
- return ret;
- }
- @Override
- public String toString() {
- Deque<Fighter> rank = ranking();
- StringBuilder sb = new StringBuilder();
- sb.append("Fighters: " + Arrays.toString(fighters) + "\n");
- sb.append("Result: " + result + "\n");
- sb.append("Gold: " + rank.poll());
- sb.append(", Silver: " + rank.poll());
- sb.append(", Bronze: " + rank.poll());
- return sb.toString();
- }
- }
- class Match {
- private final Fighter primary;
- private final Hand primaryHand;
- private Result result;
- private final Fighter secondary;
- private final Hand secondaryHand;
- public Match(Fighter primary, Fighter secondary) {
- this.primary = primary;
- this.secondary = secondary;
- primaryHand = primary.hand();
- secondaryHand = secondary.hand();
- result = Result.fight(primaryHand, secondaryHand);
- }
- public Fighter getPrimary() {
- return primary;
- }
- public Hand getPrimaryHand() {
- return primaryHand;
- }
- public Result getResult() {
- return result;
- }
- public Fighter getScondary() {
- return secondary;
- }
- public Hand getSecondaryHand() {
- return secondaryHand;
- }
- public void setResult(Result result) {
- this.result = result;
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("<Match " + primary + " vs " + secondary);
- sb.append(" : " + primaryHand.name() + ", " + secondaryHand.name());
- sb.append(" - " + result.name() + ">");
- return sb.toString();
- }
- }
- class OnlyPaper extends Fighter {
- @Override
- protected Hand hand() {
- return Hand.Paper;
- }
- }
- class OnlyRock extends Fighter {
- @Override
- protected Hand hand() {
- return Hand.Rock;
- }
- }
- class OnlyScissors extends Fighter {
- @Override
- protected Hand hand() {
- return Hand.Scissors;
- }
- }
- class RandomHand extends Fighter {
- private final Random random;
- public RandomHand() {
- super();
- random = new Random();
- }
- @Override
- protected Hand hand() {
- switch (random.nextInt(3)) {
- case 2:
- return Hand.Rock;
- case 1:
- return Hand.Paper;
- default:
- return Hand.Scissors;
- }
- }
- }
- enum Result {
- PrimaryWin, SecondaryWin, Throw;
- public static Result fight(Hand primary, Hand secondary) {
- switch (primary) {
- case Rock:
- switch (secondary) {
- case Scissors:
- return PrimaryWin;
- case Paper:
- return SecondaryWin;
- default:
- return Throw;
- }
- case Paper:
- switch (secondary) {
- case Rock:
- return PrimaryWin;
- case Scissors:
- return SecondaryWin;
- default:
- return Throw;
- }
- default:
- switch (secondary) {
- case Paper:
- return PrimaryWin;
- case Rock:
- return SecondaryWin;
- default:
- return Throw;
- }
- }
- }
- }
- class TournamentManager extends Manager {
- public static Match shouldMatch(Fighter primary, Fighter secondary) {
- Match match;
- int i;
- for (match = new Match(primary, secondary), i = 0; match.getResult() == Result.Throw ||
- i < 5; match = new Match(primary, secondary), i++)
- ;
- if (match.getResult() == Result.Throw) match.setResult(Result.PrimaryWin);
- return match;
- }
- private final Deque<Fighter> loser;
- private Fighter third;
- public TournamentManager(Fighter[] fighters) {
- super(fighters);
- loser = new ArrayDeque<Fighter>();
- }
- private BinaryTree buildTree() {
- BinaryTree primary = new BinaryTree(fighters[0], 0);
- BinaryTree secondary = new BinaryTree(fighters[1], 1);
- BinaryTree root = new BinaryTree(primary, secondary);
- primary.setParent(root);
- secondary.setParent(root);
- for (int i = 2; i < fighters.length; i++)
- root.add(new BinaryTree(fighters[i], i));
- return root;
- }
- @Override
- protected void match() {
- BinaryTree root = buildTree();
- while (root.member() > 1)
- root.matchQueue(result, loser);
- if (fighters.length > 3) {
- loser.poll(); // second place
- Fighter primary = loser.poll();
- Fighter secondary = loser.poll();
- Match m = shouldMatch(primary, secondary);
- if (m.getResult() == Result.PrimaryWin) third = primary;
- else third = secondary;
- result.add(m);
- }
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("Fighters: " + Arrays.toString(fighters) + "\n");
- sb.append("Result: " + result + "\n");
- if (fighters.length < 3) {
- Match match = result.poll();
- sb.append(victoryAndSecond(match));
- }
- else {
- Match finalGame = result.poll();
- sb.append(victoryAndSecond(finalGame));
- sb.append(", Thirad Place: " + third + "\n");
- }
- return sb.toString();
- }
- private String victoryAndSecond(Match match) {
- StringBuilder sb = new StringBuilder();
- if (match.getResult() == Result.PrimaryWin) {
- sb.append("Victory: " + match.getPrimary());
- sb.append(", Second Place: " + match.getScondary());
- }
- else {
- sb.append("Victory: " + match.getScondary());
- sb.append(", Second Place: " + match.getPrimary());
- }
- return sb.toString();
- }
- }
- class WinningPercentage extends Fighter {
- @Override
- public Hand hand() {
- Map<Hand, Integer> wins = initWins();
- winsInc(wins);
- return mostWinHand(wins);
- }
- private Map<Hand, Integer> initWins() {
- Map<Hand, Integer> wins = new EnumMap<Hand, Integer>(Hand.class);
- for (Hand h: Hand.values())
- wins.put(h, 0);
- return wins;
- }
- private Hand mostWinHand(Map<Hand, Integer> wins) {
- int max = Integer.MIN_VALUE;
- Hand ret = null;
- for (Hand h: Hand.values()) {
- if (max >= wins.get(h)) continue;
- max = wins.get(h);
- ret = h;
- break;
- }
- return ret;
- }
- private void winsInc(Map<Hand, Integer> wins) {
- for (Match m: manager.result) {
- int addee = 0;
- switch (m.getResult()) {
- case PrimaryWin:
- addee = wins.get(m.getPrimaryHand());
- wins.put(m.getPrimaryHand(), addee + 1);
- break;
- case SecondaryWin:
- addee = wins.get(m.getSecondaryHand());
- wins.put(m.getSecondaryHand(), addee + 1);
- break;
- default:
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement