Java 设计模试之Strategy Pattern

本文介绍了一种使用不同策略进行猜拳游戏的模拟程序。通过WinningStrategy和ProbStrategy两种策略,模拟了两个玩家之间的猜拳比赛,并记录了比赛结果。程序采用面向对象的设计,包括Hand、Strategy、Player等类。

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 isStrogerThan(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;
        }
    }
    public String toString(){
        return name[handvalue];
    }
}

interface Strategy{
    public abstract Hand nextHand();
    public abstract void study(boolean win);
}

class WinningStrategy implements Strategy{
    private Random random;
    private boolean won = false;
    private Hand prevHand;
    public WinningStrategy(int seed){
        random = new Random(seed);
    }
    public Hand nextHand(){
        if (!won){
            prevHand = Hand.getHand(random.nextInt(3));
        }
        return prevHand;
    }
    public void study(boolean win){
        won = win;
    }
}

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);
    }
    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;
    }
    public void study(boolean win){
        if(win){
            history[prevHandValue][currentHandValue]++;
        }
        else{
            history[prevHandValue][(currentHandValue + 1) % 3]++;
            history[prevHandValue][(currentHandValue + 2) % 3]++;
        }
    }
}

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++;
    }
    public String toString(){
        return "[" + name + ":" + gamecount + " games," + wincount +
        "win, " + losecount + " lose" + "]";
    }
}
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 < 1000; i++){
            Hand nextHand1 = Player1.nextHand();
            Hand nextHand2 =  Player2.nextHand();
            if (nextHand1.isStrogerThan(nextHand2)){
                System.out.println("Winner:" + Player1);
                Player1.win();
                Player2.lose();
            }
            else if (nextHand2.isStrogerThan(nextHand1)){
                System.out.println("Winner:" + Player2);
                Player1.lose();
                Player2.win();
            }
            else {
                System.out.println("Even...");
                Player1.even();
                Player2.even();
            }
        }
        System.out.println("Total result:");
        System.out.print(""+ Player1);
        System.out.print("" + Player2);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值