JavaStrategy模式
本文最后更新于:1 年前
整体的替换算法
1 - 表示猜拳游戏中的的”手势”类
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){ // 如果this战胜了h则返回true
return fight(h) == 1;
}
public boolean isWeakerThan(Hand h){ // 如果this战胜了h则返回false
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];
}
}
2 - 表示猜拳游戏中策略的类
public interface Strategy {
public abstract Hand nextHand();
public abstract void study(boolean win);
}
3 - 表示”如果这局猜拳获胜,那么下一局也出一样的手势”这一策略的类
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;
}
}
4 - 表示”根据上一局的手势从概率上计算出下一局的手势,从之前的猜拳结果计算下一局出各种拳的概率”这一策略类
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){
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);
}
private int getSum(int hv){
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += history[hv][i];
}
return sum;
}
@Override
public void study(boolean win) {
if (win){
history[prevHandValue][currentHandValue]++;
}else {
history[prevHandValue][(currentHandValue + 1) % 3]++;
history[prevHandValue][(currentHandValue + 2) % 3]++;
}
}
}
5 - 表示进行猜拳游戏的选手的类
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 " + "]";
}
}
6 - 测试程序行为的类
// 需要提前设置好args的参数
public class Main {
public static void main(String[] args) {
if (args.length != 2){
System.out.println("Usage: java Main randomSeed1 randomSeed2");
System.out.println("Example: java Main 314 15");
System.exit(0);
}
int seed1 = Integer.parseInt(args[0]);
int seed2 = Integer.parseInt(args[1]);
Player player1 = new Player("Taro", new WinningStrategy(seed1));
Player player2 = new Player("Hana", new ProbStrategy(seed2));
for (int i = 0; i < 15; i++) {
Hand nextHand1 = player1.nextHand();
Hand nextHand2 = player2.nextHand();
if (nextHand1.isStrongerThan(nextHand2)){
System.out.println("Winner: " + player1);
player1.win();
player2.lose();
}else if (nextHand2.isStrongerThan(nextHand1)){
System.out.println("Winner: " + player2);
player2.win();
player1.lose();
}else {
System.out.println("Even...");
player1.even();
player2.even();
}
}
System.out.println("Total result: ");
System.out.println(player1.toString());
System.out.println(player2.toString());
}
}
7 - 输出示例
Winner: [Taro:0 games, 0 win, 0 lose ]
Winner: [Taro:1 games, 1 win, 0 lose ]
Even...
Winner: [Hana:3 games, 0 win, 2 lose ]
Winner: [Hana:4 games, 1 win, 2 lose ]
Winner: [Hana:5 games, 2 win, 2 lose ]
Winner: [Hana:6 games, 3 win, 2 lose ]
Winner: [Taro:7 games, 2 win, 4 lose ]
Even...
Winner: [Hana:9 games, 4 win, 3 lose ]
Winner: [Taro:10 games, 3 win, 5 lose ]
Winner: [Taro:11 games, 4 win, 5 lose ]
Winner: [Hana:12 games, 5 win, 5 lose ]
Winner: [Hana:13 games, 6 win, 5 lose ]
Winner: [Taro:14 games, 5 win, 7 lose ]
Total result:
[Taro:15 games, 6 win, 7 lose ]
[Hana:15 games, 7 win, 6 lose ]
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!