C ++剪刀石头布

时间:2020-09-24 09:54:46

标签: c++ conditional-statements fundamentals-ts

我正试图用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;
}

2 个答案:

答案 0 :(得分:1)

我将假设您要提出的问题-但没有在问题中写下-是“为什么我会收到此错误消息?”

好吧,通过rps()的路径不会返回值。作为一个人,您可能知道rps()总是仅用“ rock”,“ paper”或“ scissors”来调用,而编译器却不使用。在这种情况下,如果您将rps()称为rps(std::string("stone"),std::string("knife")),应该返回什么?它必须返回某物(或引发异常),因为您已承诺它将返回std :: string。

您可能会做很多事情:

  • 如果没有获胜者或其他特殊值,请返回一个空的std :: string
  • 如果所有条件都不成立,则引发异常
  • 将您的参数类型更改为枚举而不是字符串,以便编译器可以(可能)确定您已处理所有9种可能的情况

请注意,编译器正在为您提供帮助Why does flowing off the end of a non-void function without returning a value not produce a compiler error?

答案 1 :(得分:0)

正如在其他答案中已经提到的那样,p1的参数p2std::string rps(const std::string& p1, const std::string& p2)std::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");
  }
}