簡體   English   中英

C++石頭剪刀布

[英]C++ Rock Paper Scissors

我正在嘗試用 c++ 制作石頭剪刀布游戲。我在 codecademy.com 上測試了我的代碼並且它工作正常但是當我在 codewars.com 上執行它時它給了我這個錯誤:

main.cpp:29:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^

這是我的代碼:

#include <string>
#include <iostream>

std::string rps(const std::string& p1, const std::string& p2)
{
  if (p1 == "rock" && p2 == "paper") {
    return "Player 2 won!";
  } else if (p1 == "rock" && p2 ==  "scissors") {
    return "Player 1 won!";
  } else if (p1 == "rock" && p2 ==  "rock") {
    return "Draw";
  } else if (p1 == "paper" && p2 == "rock") {
    return "Player 1 won!";
  } else if (p1 == "paper" && p2 == "scissors") {
    return "Player 2 won!";
  } else if (p1 == "paper" && p2 == "paper") {
    return "Draw";
  } else if (p1 == "scissors" && p2 == "rock") {
    return "Player 2 won!";
  } else if (p1 == "scissors" && p2 == "paper") {
    return "Player 1 won!";
  } else if (p1 == "scissors" && p2 == "scissors") {
    return "Draw";
  }
}
int main() {
  std::cout << rps("rock", "scissors") << "\n";
  std::cout << rps("rock", "paper") << "\n";
  std::cout << rps("rock", "rock") << "\n";
  std::cout << rps("scissors", "paper") << "\n";
  std::cout << rps("scissors", "rock") << "\n";
  return 1;
}

我將假設您想問的問題 - 但沒有寫在您的問題中 - 是“為什么我會收到此錯誤消息?”

嗯,有一條通過rps()的路徑返回值。 作為一個人,您可能知道rps()總是只用“rock”、“paper”或“scissors”調用,但編譯器不知道。 在這種情況下,如果將rps()稱為rps(std::string("stone"),std::string("knife"))它應該返回什么? 它必須返回一些東西(或拋出異常),因為你已經承諾它會返回一個 std::string。

您可能會執行多種操作:

  • 如果沒有獲勝者或其他一些特殊值,則返回一個空的 std::string
  • 如果沒有一個條件為真,則引發異常
  • 將您的參數類型更改為枚舉而不是字符串,以便編譯器可以(可能)確定您已經處理了所有 9 種可能的情況

請注意,編譯器正在幫助您。 為什么在不返回值的情況下從非空函數的末尾流出不會產生編譯器錯誤?

正如在另一個答案中已經提到的, std::string rps(const std::string& p1, const std::string& p2)的參數p1p2std::strings並且可以 - 從編譯器的角度來看 - 包含任何值。

鑒於可能存在p1p2的組合,其中沒有一個條件為真。 如果您不從void函數(除了main )返回值,它將導致未定義的行為。

所以你要么需要在那個時候拋出一個異常,要么返回一個空字符串。

但是最好更改代碼,以便參數和返回類型是枚舉,並且該函數首先檢查獲勝情況,並作為默認返回沒有人獲勝。

#include <iostream>
#include <vector>

enum class Winner { kPlayerOne, kPlayerTwo, kNone };
enum class Hand { kRock, kScissors, kPaper };

Winner rps(const Hand &p1, const Hand &p2) {
    
  if (p1 == Hand::kRock && p2 == Hand::kPaper) {
    return Winner::kPlayerTwo;
  } else if (p1 == Hand::kRock && p2 == Hand::kScissors) {
    return Winner::kPlayerOne;
  } else if (p1 == Hand::kPaper && p2 == Hand::kRock) {
    return Winner::kPlayerOne;
  } else if (p1 == Hand::kPaper && p2 == Hand::kScissors) {
    return Winner::kPlayerTwo;
  } else if (p1 == Hand::kScissors && p2 == Hand::kRock) {
    return Winner::kPlayerTwo;
  } else if (p1 == Hand::kScissors && p2 == Hand::kPaper) {
    return Winner::kPlayerOne;
  }
  
  return Winner::kNone;
}

std::string to_string(const Winner &winner) {
  if (winner == Winner::kPlayerOne) {
    return "Player 1 won!";
  } else if (winner == Winner::kPlayerTwo) {
    return "Player 2 won!";
  } else {
    return "Draw";
  }
}

int main() {
  std::cout << to_string(rps(Hand::kRock, Hand::kScissors)) << "\n";
  std::cout << to_string(rps(Hand::kRock, Hand::kPaper)) << "\n";
  std::cout << to_string(rps(Hand::kRock, Hand::kRock)) << "\n";
  std::cout << to_string(rps(Hand::kScissors, Hand::kPaper)) << "\n";
  std::cout << to_string(rps(Hand::kScissors, Hand::kRock)) << "\n";
  return 1;
}

如果你真的需要使用字符串作為輸入,你想在你的rps函數之外使用類似的東西來驗證/轉換它們:

Hand string_to_hand(const std::string &str) {
  if (str == "rock") {
    return Hand::kRock;
  } else if (str == "scissors") {
    return Hand::kScissors;
  } else if (str == "paper") {
    return Hand::kPaper;
  } else {
    throw std::runtime_error("input is not a valid hand");
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM