Java設計模式之從[剪刀石頭布AI策略]分析策略(Strategy)模式
阿新 • • 發佈:2018-12-26
策略模式是一個非常簡單的模式。它定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換。
考慮到我在做一個剪刀石頭布的遊戲,可以和計算機對戰。計算機的難度等級分為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方法中編寫自己的演算法即可。