Strategyパターン
委譲
% find . -name "*.java" -print0 |xargs -0 cat [] public class Hand { public static final int HANDVALUE_GUU = 0; public static final int HANDVALUE_CHO = 1; public static final int HANDVALUE_PAA = 2; /* クラス内だとプライベートのコンストラクタ呼べるのね。シングルトンと同じか */ public static final Hand[] hand = { new Hand(HANDVALUE_GUU), new Hand(HANDVALUE_CHO), new Hand(HANDVALUE_PAA), }; private static final String[] name = { "グー", "チョキ", "パー" }; private int handValue; private Hand(int handValue) { this.handValue = handValue; } public static Hand getHand(int handValue) { return hand[handValue]; } public boolean isStrongerThan(Hand h) { return fight(h) == 1; } public boolean isWeakerThan(Hand h) { return fight(h) == -1; } private int fight(Hand h) { if (this == h) { return 0; } else if ((this.handValue + 1) % 3 == h.handValue) { return 1; } else { return -1; } } @Override public String toString() { return name[handValue]; } } public class Main { public static void main(String[] args) { int seed1 = 100; int seed2 = 200; Player p1 = new Player("p1", new WinningStrategy(seed1)); Player p2 = new Player("p2", new ProbStrategy(seed2)); for (int i = 0; i < 10000; i++) { Hand nextHand1 = p1.nextHand(); Hand nextHand2 = p2.nextHand(); if (nextHand1.isStrongerThan(nextHand2)) { System.out.println("Winner:" + p1); p1.win(); p2.lose(); } else if (nextHand2.isStrongerThan(nextHand1)) { System.out.println("Winner:" + p2); p2.win(); p1.lose(); } else { System.out.println("Even.."); p1.even(); p2.even(); } } System.out.println(p1.toString()); System.out.println(p2.toString()); } } public class Player { private String name; private Strategy strategy; private int wincount; private int losecount; private int gamecount; public Player(String name, Strategy strategy) { this.name = name; this.strategy = strategy; } public Hand nextHand() { return strategy.nextHand(); } public void win() { strategy.study(true); wincount++; gamecount++; } public void lose() { strategy.study(false); losecount++; gamecount++; } public void even() { gamecount++; } @Override public String toString() { return "[" + name + ":" + gamecount + " games, " + wincount + " win, " + losecount + " lose]"; } } import java.util.Random; public class ProbStrategy implements Strategy { private Random random; private int prevHandValue = 0; private int currentHandValue = 0; private int[][] history = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }; public ProbStrategy(int seed) { this.random = new Random(seed); } @Override public Hand nextHand() { int bet = random.nextInt(getSum(currentHandValue)); int handValue = 0; if (bet < history[currentHandValue][0]) { handValue = 0; } else if (bet < history[currentHandValue][0] + history[currentHandValue][1]) { handValue = 1; } else { handValue = 2; } prevHandValue = currentHandValue; currentHandValue = handValue; return Hand.getHand(handValue); } @Override public void study(boolean win) { if (win) { history[prevHandValue][currentHandValue]++; } else { history[prevHandValue][(currentHandValue + 1) % 3]++; history[prevHandValue][(currentHandValue + 2) % 3]++; } } private int getSum(int hv) { int sum = 0; for (int i = 0; i < 3; i++) { sum += history[hv][i]; } return sum; } } public interface Strategy { public abstract Hand nextHand(); public abstract void study(boolean win); } import java.util.Random; public class WinningStrategy implements Strategy { private Random random; private boolean won = false; private Hand prevHand; public WinningStrategy(int seed) { random = new Random(seed); } @Override public Hand nextHand() { if (!won) { prevHand = Hand.getHand(random.nextInt(3)); } return prevHand; } @Override public void study(boolean win) { won = win; } }
Winner:[p1:9994 games, 3117 win, 3492 lose] Even.. Even.. Winner:[p1:9997 games, 3118 win, 3492 lose] Winner:[p2:9998 games, 3492 win, 3119 lose] Winner:[p2:9999 games, 3493 win, 3119 lose] [p1:10000 games, 3119 win, 3494 lose] [p2:10000 games, 3494 win, 3119 lose]