1. 程式人生 > >Java設計模式之從[剪刀石頭布AI策略]分析策略(Strategy)模式

Java設計模式之從[剪刀石頭布AI策略]分析策略(Strategy)模式

  策略模式是一個非常簡單的模式。它定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換。

  考慮到我在做一個剪刀石頭布的遊戲,可以和計算機對戰。計算機的難度等級分為2個等級:普通難度和無法戰勝難度。普通難度是指電腦會隨機出石頭、剪刀、布,而無法戰勝難度是指電腦會“作弊”,電腦會事先知道玩家出的是什麼手勢。如果玩家出的是剪刀,那麼電腦會出石頭,玩家永遠的無法取勝。

  那麼,這兩個難度分別代表兩種演算法,為了使得它們能夠被遊戲的主類裝載,它們都應該繼承於同一個介面或類,並暴露出電腦出手勢的方法,程式碼如下:

import java.util.Random;
import java.util.Scanner;

interface GameStrategy{
    int play(int player);
}

class FingerGuessing{
    Scanner playerScanner = new Scanner(System.in);
    public String toString(int finger){
        switch (finger){
        case 1:
            return "石頭";
        case 2:
            return "剪刀";
        case 3:
            return "布";
        default:
            return "錯誤!";
        }
    }
    public void start(GameStrategy comStrategy){
        boolean gameOver = false;
        while (!gameOver){
            System.out.println("請出拳(按回車確認):1、石頭;2、剪刀;3、布");
            int playerChoice = 0;
            while ( playerChoice <= 0 || playerChoice > 4){
                playerChoice = playerScanner.nextInt();
            }
            int comChoice = comStrategy.play(playerChoice);
            System.out.printf("你出的是%s,計算機出的是%s\n", toString(playerChoice), toString(comChoice));
            if (playerChoice == comChoice){
                System.out.println("平局");
            } else if (playerChoice + 1 == comChoice || playerChoice - 2 == comChoice){
                System.out.println("恭喜你獲勝了!");
                gameOver = true;
            } else {
                System.out.println("很遺憾你失敗了!");
                gameOver = true;
            }
        }
    }
}

class Normal implements GameStrategy{
    public int play(int player) {
        Random rnd = new Random();
        return rnd.nextInt(3) + 1;
    }
}

class Hard implements GameStrategy{
    public int play(int player) {
        switch (player){
        case 1:
            return 3;
        case 2:
            return 1;
        case 3:
            return 2;
        default:
            return 1;
        }
    }
}

public class Strategy
{
    public static void main(String[] args) {
        FingerGuessing guess = new FingerGuessing();
        System.out.println("一般難度:");
        guess.start(new Normal());
        System.out.println("你不可能獲勝的難度:");
        guess.start(new Hard());
    }

  電腦的出手勢方式繼承於GameStrategy介面,play方法返回的是電腦出的手勢(石頭、剪刀、布),傳入的引數player是玩家出的手勢(用於無法展示難度中作弊)。在遊戲類中,start方法接受一個滿足GameStrategy介面的物件,也就是相當於它接受不同的演算法。在main方法中,我們傳入了一個普通難度的演算法,以及一個無法戰勝難度的演算法,大家可以試著執行一下。另外,這個模式的優點是,假設要設計一種新的難度,十分方便,只要設計一個繼承於GameStrategy的類,並在play方法中編寫自己的演算法即可。