C++自学求助:石头剪刀布游戏switch表达式能否更简化?
石头剪刀布游戏的高效实现方案
你的现有switch实现已经相当简洁高效了,把9种对局情况压缩到3个分支的思路很聪明。不过我们可以从可读性、扩展性或者代码紧凑性的角度,提供几种更优化的实现方式:
1. 模运算+数组映射(最紧凑的实现)
利用数学运算把结果映射到固定索引,完全替代switch,代码更简洁,效率和switch相当:
// 先定义结果字符串(和你原代码的tie、win、lose对应) const char* tie = "It's a tie!"; const char* win = "You win!"; const char* lose = "You lose!"; int match = guess - botGuess; // 通过模运算把match的可能值(-2,-1,0,1,2)转成0-2的索引 int idx = (match + 3) % 3; // 索引对应关系:0→平局,1→赢,2→输 const char* outcomes[] = {tie, win, lose}; cout << outcomes[idx];
原理:(match + 3)把负数转为正数,再对3取模,刚好把所有可能的差值映射到0、1、2三个索引,直接通过数组访问结果。
2. 枚举+查找表(可读性优先)
用枚举类型替代魔法数字,再用二维数组直接存储所有对局结果,逻辑一目了然,后期维护和扩展更方便:
// 用枚举明确选择和结果的含义,避免1/2/3的魔法数字 enum class Choice { Rock = 1, Paper = 2, Scissors = 3 }; enum class Result { Tie, Win, Lose }; // 定义结果字符串 const char* resultStr[] = {"It's a tie!", "You win!", "You lose!"}; // 二维查找表:行=用户选择,列=机器人选择,值=对应结果 Result resultTable[4][4] = { {Result::Tie, Result::Tie, Result::Tie, Result::Tie}, // 索引0不用 {Result::Tie, Result::Lose, Result::Win}, // 用户选Rock(1) {Result::Win, Result::Tie, Result::Lose}, // 用户选Paper(2) {Result::Lose, Result::Win, Result::Tie} // 用户选Scissors(3) }; // 使用时直接查表 Choice userChoice = static_cast<Choice>(guess); Choice botChoice = static_cast<Choice>(botGuess); Result res = resultTable[static_cast<int>(userChoice)][static_cast<int>(botChoice)]; cout << resultStr[static_cast<int>(res)];
这种方式完全不需要复杂计算,直接通过索引访问结果,效率极高,而且代码语义清晰,新手也能快速理解每个对局的结果逻辑。
3. 简化switch的写法(保留分支逻辑)
如果想保留switch的分支思路,还可以进一步简化代码,让逻辑更紧凑:
switch (guess - botGuess) { case 0: cout << tie; break; case -1: case 2: cout << lose; break; default: cout << win; // 剩下的情况只有-2和1,直接用default }
去掉冗余的case判断,用default覆盖剩下的赢的情况,代码更简洁。
内容的提问来源于stack exchange,提问作者Jacob Huber
相关产品推荐
相关产品推荐

