無痛入手 C++:應用教學 - 猜拳遊戲

更新 發佈閱讀 9 分鐘

須具備知識

  1. 無痛入手 C++:基礎系列5 - 條件判斷
  2. 如何產生亂數


遊戲設計

一開始會先印出遊戲的說明文字: 使用者需要輸入 r 來表示石頭,p 來表示布,以及 s 來表示剪刀:

======================================================
= Wellcome to rock paper scissors. =
= Enter r for rock, p for paper, and s for scissors. =
======================================================

我們讓電腦隨機產生一個介於 0 ~ 2 的整數,用 0 來代表石頭,1 來代表布,2 來代表剪刀。

再來就是比較使用者的輸入以及電腦產生的亂數,看誰獲勝。


方法一

最直觀的方式就是利用 if、else if、else 針對使用者和亂數的各種可能性判斷誰獲勝。完整的程式碼如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
cout << "======================================================\n";
cout << "= Wellcome to rock paper scissors. =\n";
cout << "= Enter r for rock, p for paper, and s for scissors. =\n";
cout << "======================================================\n";

// get user move
char userMove;
cin >> userMove;

// get random move
srand(time(0));
int randMove = rand() % 3;
// 0 for rock, 1 for paper, and 2 for scissors
if (randMove == 0)
cout << "r\n";
else if (randMove == 1)
cout << "p\n";
else
cout << "s\n";

// decide win or lose
if(userMove == 'r') {
if (randMove == 0)
cout << "Even.";
else if (randMove == 1)
cout << "You lose.";
else
cout << "You win.";
} else if (userMove == 'p') {
if (randMove == 0)
cout << "You win.";
else if (randMove == 1)
cout << "Even.";
else
cout << "You lose.";
} else {
if (randMove == 0)
cout << "You lose.";
else if (randMove == 1)
cout << "You win.";
else
cout << "You lose.";
}
return 0;
}

可以看到,我們需要處理 3 x 3 = 9種情況,寫起來非常麻煩,也容易看得眼花撩亂。


方法二

我們可以透過找規律的方式,把 9 種情況縮減成 3 種: 勝利、失敗、平手。

首先將使用者出的招從 r、p、s 轉換成 0、1、2。

char userMoveChar;
int userMove;
cin >> userMoveChar;
if (userMoveChar == 'r')
userMove = 0;
else if (userMoveChar == 'p')
userMove = 1;
else
userMove = 2;

如此一來,只要 userMove 和 randMove 相等,就表示平手:

if (userMove == randMove)
cout << "Even";


接著觀察使用者在什麼樣的條件下會輸:
1. 使用者出 0 (石頭),電腦出 1 (布) ->使用者輸
2. 使用者出 1 (布),電腦出 2 (剪刀) ->使用者輸
3. 使用者出 2 (剪刀),電腦出 0 (石頭) ->使用者輸

觀察 1 和 2 可以發現當 randMove = userMove + 1 的時候,代表使用者輸了。3 乍看之下不符合這個規律,這個原因是因為剪刀是"最大"的數字了,下一個招式是石頭,會繞回 0,我們可以利用取餘數來處理這類狀況: (布 + 1) % 3 == 石頭。

也就是說,當滿足以下條件的時候,代表使用者輸了:
(userMove + 1) % 3 == randMove

用相同的邏輯觀察使用者在什麼樣的條件下會贏:
1. 使用者出 0 (石頭),電腦出 2 (剪刀) ->使用者贏
2. 使用者出 1 (布),電腦出 0 (石頭) ->使用者贏
3. 使用者出 2 (剪刀),電腦出 1 (布) ->使用者贏

可以觀察到,當滿足以下條件的時候,代表使用者輸了:
(userMove + 2) % 3 == randMove

總結上述發現的規律:
1. userMove == randMove: 平手
2. (userMove + 1) % 3 == randMove: 使用者輸
3. (userMove + 2) % 3 == randMove: 使用者贏

利用這樣的規律,我們就可以把原本的 9 種狀況縮減成 3 種。完整的程式碼如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
cout << "======================================================\n";
cout << "= Wellcome to rock paper scissors. =\n";
cout << "= Enter r for rock, p for paper, and s for scissors. =\n";
cout << "======================================================\n";

// get user move
char userMoveChar;
int userMove;
cin >> userMoveChar;
if (userMoveChar == 'r')
userMove = 0;
else if (userMoveChar == 'p')
userMove = 1;
else
userMove = 2;

// get random move
srand(time(0));
int randMove = rand() % 3;
// 0 for rock, 1 for paper, and 2 for scissors
if (randMove == 0)
cout << "r\n";
else if (randMove == 1)
cout << "p\n";
else
cout << "s\n";

// decide win or lose
if (userMove == randMove)
cout << "Even.";
else if ((userMove + 2) % 3 == randMove)
cout << "You win";
else
cout << "You lose";

return 0;
}


程式技巧

  1. 有時候可以找出規律,縮減需要做的條件判斷數量。
  2. 可以用 % 來表示"從最後一個數字繞回第一個數字"。




留言
avatar-img
鏟薯員的窩
8會員
14內容數
程式設計 & 電腦系統 & 系統軟體
鏟薯員的窩的其他內容
2024/05/05
C 語言的函式庫定義了許多好用的函式,在寫 C++ 的時候可以拿來用。這是因為 C++ 當初在設計的時候,就有刻意把 C 涵蓋進來。 基本用法 首先要導入 C 語言的標準函式庫: #include <cstdlib> 以 c 作為開頭表示它是 C 語言的函式庫,只是被我們拿來 C++ 的程式
Thumbnail
2024/05/05
C 語言的函式庫定義了許多好用的函式,在寫 C++ 的時候可以拿來用。這是因為 C++ 當初在設計的時候,就有刻意把 C 涵蓋進來。 基本用法 首先要導入 C 語言的標準函式庫: #include <cstdlib> 以 c 作為開頭表示它是 C 語言的函式庫,只是被我們拿來 C++ 的程式
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
這篇內容,將會講解什麼是運算子,以及與運算子相關的知識。包括運算子的簡介、賦值運算子、算術運算子、遞增/遞減、比較運算子、邏輯運算子。
Thumbnail
這篇內容,將會講解什麼是運算子,以及與運算子相關的知識。包括運算子的簡介、賦值運算子、算術運算子、遞增/遞減、比較運算子、邏輯運算子。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
高中數學主題練習—C計算(一)
Thumbnail
高中數學主題練習—C計算(一)
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News