無痛入手 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
鏟薯員的窩
9會員
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
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
這篇內容,將會講解什麼是變數,以及與變數相關的知識。包括變數、資料型態、變數賦值、變數的命名規則、變數的作用區域、變數的可重複性、內建變數。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
這篇內容,將透過實戰教學,來講解「滑鼠點方塊」的程式碼。包括如何測試遊戲、座標系統、自訂參數和內建參數、if else、and、遊戲的邏輯設計、程式碼解析。
Thumbnail
這篇內容,將會講解什麼是運算子,以及與運算子相關的知識。包括運算子的簡介、賦值運算子、算術運算子、遞增/遞減、比較運算子、邏輯運算子。
Thumbnail
這篇內容,將會講解什麼是運算子,以及與運算子相關的知識。包括運算子的簡介、賦值運算子、算術運算子、遞增/遞減、比較運算子、邏輯運算子。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News