import java.util.Scanner;
import java.util.Random;
public class RockPaperScissorsV2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Random rand = new Random();
// 1. 玩家暱稱
System.out.print("請輸入你的暱稱:");
String playerName = sc.nextLine();
// 2. 選擇對手
String[] opponents = {"劉備", "曹操", "蓋倫"};
String opponent = chooseOpponent(sc, opponents);
// 3. 遊戲主循環
int round = 1;
int playerScore = 0, cpuScore = 0;
String continueFlag = "y";
while ("y".equalsIgnoreCase(continueFlag)) {
System.out.printf("\n=== 第 %d 輪 ===\n", round);
System.out.println(playerName + "\tVS\t" + opponent);
// 玩家出拳
int playerMove = readMove(sc, playerName);
// 電腦出拳
int cpuMove = rand.nextInt(3) + 1;
// 顯示出拳
String[] moves = {"", "剪刀", "石頭", "布"};
System.out.println("你出拳:" + moves[playerMove]);
System.out.println(opponent + "出拳:" + moves[cpuMove]);
// 判定勝負
int result = judge(playerMove, cpuMove);
if (result == 1) {
System.out.println("🎉 你贏了!");
playerScore++;
} else if (result == -1) {
System.out.println("😢 " + opponent + "贏了!");
cpuScore++;
} else {
System.out.println("🤝 平局");
}
round++;
System.out.print("繼續下一輪?(y/n):");
continueFlag = sc.next();
}
// 4. 結算
printResult(playerName, opponent, playerScore, cpuScore, round - 1);
sc.close();
}
// --- 輔助方法 ---
static String chooseOpponent(Scanner sc, String[] opts) {
while (true) {
System.out.println("請選擇對手:1." + opts[0] + " 2." + opts[1] + " 3." + opts[2]);
if (sc.hasNextInt()) {
int idx = sc.nextInt();
if (idx >= 1 && idx <= 3) return opts[idx - 1];
}
System.out.println("輸入無效,請輸入 1-3");
sc.nextLine(); // 清理緩衝
}
}
static int readMove(Scanner sc, String name) {
while (true) {
System.out.print(name + "請出拳 (1剪刀 2石頭 3布):");
if (sc.hasNextInt()) {
int m = sc.nextInt();
if (m >= 1 && m <= 3) return m;
}
System.out.println("輸入無效,請輸入 1-3");
sc.nextLine();
}
}
/**
* 勝負判定:1=玩家贏, -1=電腦贏, 0=平局
* 規則:剪刀(1)勝布(3),石頭(2)勝剪刀(1),布(3)勝石頭(2)
*/
static int judge(int player, int cpu) {
if (player == cpu) return 0;
// (player - cpu + 3) % 3 == 1 表示玩家贏
return ((player - cpu + 3) % 3 == 1) ? 1 : -1;
}
static void printResult(String pName, String cpuName, int pScore, int cScore, int rounds) {
System.out.println("\n=== 遊戲結束 ===");
System.out.printf("共進行 %d 輪\n", rounds);
System.out.println("姓名\t得分");
System.out.println(pName + "\t" + pScore);
System.out.println(cpuName + "\t" + cScore);
if (pScore > cScore) System.out.println("🏆 " + pName + " 獲勝!");
else if (pScore < cScore) System.out.println("🏆 " + cpuName + " 獲勝!");
else System.out.println("🤝 雙方平手!");
}
}
| 知識點 | 應用位置 |
|---|---|
Scanner.hasNextInt() | 輸入類型預檢,避免異常 |
Random.nextInt(3)+1 | 生成 1-3 隨機數 |
| 模運算判定勝負 | (a-b+3)%3==1 一行搞定環狀規則 |
| 方法拆分 | 單一職責:選角、讀拳、判定、結算 |
| 格式化輸出 | printf 對齊顯示 |
// 1. 手勢枚舉
enum Gesture { SCISSOR(1), ROCK(2), PAPER(3); }
// 2. 玩家介面
interface Player {
Gesture play();
String getName();
void addScore();
int getScore();
}
// 3. 策略模式:勝負判定器
interface JudgeStrategy {
Result judge(Gesture p1, Gesture p2);
}
class ClassicJudge implements JudgeStrategy { ... }
// 4. 遊戲引擎
class GameEngine {
private final Player p1, p2;
private final JudgeStrategy judge;
// run(), statistics()...
}
List 存儲judge() 所有分支小遊戲是練習輸入處理、隨機數、邏輯判斷、方法拆分、面向對象設計的最佳載體。