C++ 剪刀石头布游戏

2025 年 2 月 11 日 | 阅读 10 分钟

C++ 石头剪刀布游戏简介

石头剪刀布 是一款经典的纸牌游戏,通常用作简单的决策工具。该游戏通常在两人之间进行,每位玩家同时伸出一只手,做出三种形状之一:石头、剪刀或布。规则很简单:石头赢剪刀,剪刀赢布,布赢石头。

在 C++ 中创建一个石头剪刀布游戏是初学者学习基本编程概念(如条件语句、循环和输入/输出操作)的绝佳项目。通过开发这个游戏,您将获得 C++ 基本语法和结构的实践经验,同时也能获得一些乐趣。

图像

Rock-paper-scissor game in C++

要遵循的游戏规则

我们需要考虑三种情况

  1. 石头 vs 布 -> 布获胜。
  2. 布 vs 剪刀 -> 剪刀获胜。
  3. 剪刀 vs 石头 -> 石头获胜。

方法 1:简单方法

实施

输出

 
Enter your choice (0 = Rock, 1 = Paper, 2 = Scissors): Rock
You chose: Rock
Computer chose: Paper
You lose!   

说明

  • 步骤 1:导入库
    首先,程序包含必要的库
    1. 流库用于输入和输出操作,允许我们通过控制台与用户进行交互。
    2. cstdlib 库用于生成随机数,这将帮助计算机做出选择。
    3. ctime 库用于使用当前时间为随机数生成器播种,以确保每次运行程序时随机选择都不同。
  • 步骤 2:定义选择
    定义了一个枚举(enumeration)来表示游戏中的三种可能选择:石头、布和剪刀。通过使用有意义的名称而不是任意数字,这使得代码更具可读性和可管理性。
  • 步骤 3:生成计算机的选择
    创建了一个函数来生成计算机的选择。该函数使用 rand() 函数生成 0 到 2 之间的随机数,每个数字代表三种选择之一(石头、布或剪刀)。之后,将随机数转换为 Choice 枚举。
  • 步骤 4:获取用户选择
    定义了另一个函数来获取用户选择。程序提示用户输入一个数字(0 表示石头,1 表示布,2 表示剪刀)。之后,将此数字转换为相应的 Choice 枚举。
  • 步骤 5:打印选择
    使用一个函数以可读的格式打印所选选项(石头、布或剪刀)。根据 Choice 枚举的值;函数输出相应的字符串。
  • 步骤 6:确定赢家
    定义了一个函数,根据石头剪刀布的游戏规则确定赢家
    1. 如果用户和计算机都选择了相同的选项,则结果是平局。
    2. 如果根据游戏规则用户的选择胜过计算机的选择(石头赢剪刀,布赢石头,剪刀赢布),则用户获胜。
    3. 否则,计算机获胜。
  • 步骤 7:主函数操作
    在主函数中,程序首先使用 srand() 函数使用当前时间为随机数生成器播种。这确保了每次运行程序时随机选择都不同。

复杂度分析

时间复杂度

  1. 生成计算机选择:这涉及生成随机数,这是一个常数时间操作,O(1)。
  2. 获取用户选择:从用户那里读取输入也是一个常数时间操作,O(1)。
  3. 打印选择:打印两个选择(用户和计算机)是另一个常数时间操作,O(1)。
  4. 确定赢家:通过几个条件检查来确定赢家,这些检查再次以常数时间 O(1) 运行。

总的来说,程序的时间复杂度为 O(1),因为所有操作都是常数时间。

空间复杂度

变量存储

  • 用户的选择存储在一个变量中。
  • 计算机的选择存储在另一个变量中。
  • 函数和枚举还使用了额外的内存,但它们的固定大小。

枚举和常量

  • 石头、布和剪刀的枚举定义是固定大小的,不会随着输入而增长。

输入/输出操作

  • 输入和输出操作所需的空间最小且恒定。
  • 总的来说,程序空间复杂度为 O(1),因为它使用的内存量是固定的,与输入大小无关。

方法 2:使用类和对象

在此方法中,我们使用面向对象编程 (OOP) 原则来实现石头剪刀布游戏。通过将游戏逻辑封装在类中,我们创建了一个模块化且可重用的设计。这种方法提供了更好的代码组织,并促进了封装和抽象等概念。

类和对象的实现

输出

 
Enter your choice (0 = Rock, 1 = Paper, 2 = Scissors): Rock
You chose: Rock
Computer chose: Rock
It's a tie!   

说明

  • 步骤 1:定义类
    我们首先定义一个名为 RockPaperScissorsGame 的类。类在 C++ 中是创建对象的蓝图。它封装了数据以及对这些数据进行操作的函数。
  • 步骤 2:枚举选择
    在类中,我们定义了一个枚举 Choice,它表示游戏中的三种可能选择:石头、布和剪刀。通过使用有意义的名称而不是任意数字,这使得代码更具可读性且易于管理。
  • 步骤 3:生成计算机的选择
    我们在类中创建了一个私有方法 getComputerChoice()。该方法使用 rand() 函数生成 0 到 2 之间的随机数,每个数字对应石头、布或剪刀。之后,将随机数转换为 Choice 枚举。
  • 步骤 4:获取用户选择
    另一个私有方法 getUserChoice() 提示用户输入一个数字(0 表示石头,1 表示布,2 表示剪刀)。之后,将用户输入转换为相应的 Choice 枚举。
  • 步骤 5:打印选择
    我们定义了一个私有方法 printChoice(Choice choice),该方法接受一个 Choice 作为参数并打印相应的名称(石头、布或剪刀)。该方法使用 switch 语句来处理从枚举到字符串表示的转换。
  • 步骤 6:确定赢家
    私有方法 determineWinner(Choice userChoice, Choice computerChoice) 根据游戏规则确定赢家
    s
    1. 如果两个选择相同,则打印“平局!”。
    2. 如果根据游戏规则用户的选择胜过计算机的选择(石头赢剪刀,布赢石头,剪刀赢布),则打印“你赢了!”。
    3. 否则,打印“你输了!”。
  • 步骤 7:玩游戏
    play() 方法是协调游戏的公共方法。
    1. 调用 getUserChoice() 获取用户选择。
    2. 调用 getComputerChoice() 生成计算机选择。
    3. 使用 printChoice() 打印两个选择。
    4. 使用 determineWinner() 确定并打印赢家。
  • 步骤 8:主函数操作
    在 main() 函数中,我们使用 srand(time(0)) 使用当前时间为随机数生成器播种,以确保每次运行程序时随机选择都不同。然后,我们创建一个 RockPaperScissorsGame 类的对象并调用其 play() 方法来开始游戏。

复杂度分析

时间复杂度

生成计算机选择

getComputerChoice 函数生成随机数,这是一个常数时间操作,O(1)。

获取用户选择

getUserChoice 函数提示用户输入并读取它,这也是一个常数时间操作,O(1)。

打印选择

print choice 函数根据枚举值打印字符串,这是一个常数时间操作,O(1)。

确定赢家

determine winner 函数使用几个条件检查来确定赢家,这是一个常数时间操作,O(1)。

玩游戏

play 函数按顺序调用上述函数,每个函数都以常数时间运行,从而得出整体常数时间复杂度 O(1)。

空间复杂度

变量存储

游戏使用几个变量来存储用户的选择、计算机的选择以及方法中的任何临时变量。这些变量的数量是固定的,不依赖于任何输入大小,因此它们贡献固定的空间量,O(1)。

枚举和常量

类中定义的 Choice 枚举和任何常量的大小是固定的,并且不随输入大小而改变,贡献固定的空间量,O(1)。

输入/输出操作

输入和输出操作(例如,存储用户输入、打印到控制台)所需的空间最小且恒定,O(1)。

类开销

定义类及其方法的开销也是恒定的,不依赖于输入大小,贡献固定的空间量,O(1)。

方法 3:使用数组处理选择和结果

这种方法利用数组来处理选择和结果,使代码更简洁、更具可伸缩性。

使用数组处理选择和结果的实现

输出

 
Enter your choice (0 = Rock, 1 = Paper, 2 = Scissors): Rock
You chose: Rock
Computer chose: Paper
You lose!   

说明

  • 步骤 1:导入库
    我们首先包含必要的库
    1. 流用于输入和输出操作。
    2. cstdlib 用于随机数生成函数。
    3. ctime 用于使用当前时间为随机数生成器播种。
  • 步骤 2:使用数组定义选择
    我们定义一个字符串数组 choices,其中包含三种可能的选择:“石头”、“布”和“剪刀”。此数组允许我们根据其索引轻松访问和打印选择。
  • 步骤 3:生成计算机的选择
    我们定义 getComputerChoice 函数来为计算机生成随机选择。它使用 rand() 函数生成 0 到 2 之间的随机数,该数字对应于 choices 数组的索引。
  • 步骤 4:获取用户选择
    getUserChoice 函数提示用户输入他们的选择(0 表示石头,1 表示布,2 表示剪刀)。之后,返回用户输入的整数。
  • 步骤 5:确定赢家
    determineWinner 函数将用户的选择和计算机的选择作为参数。然后,它将这些选择进行比较以确定赢家
    1. 如果选择相同,则为平局。
    2. 如果根据游戏规则用户的选择胜过计算机的选择,则用户获胜。
    3. 否则,计算机获胜。
  • 步骤 6:主函数操作
    在主函数中,我们使用 srand(time(0)) 使用当前时间为随机数生成器播种,以确保每次运行程序时随机选择都不同。

复杂度分析

时间复杂度

生成计算机选择

getComputerChoice 函数使用 rand() % 3 生成随机数,这是一个常数时间操作,O(1)。

获取用户选择

getUserChoice 函数提示用户输入并读取它,这也是一个常数时间操作,O(1)。

打印选择

打印用户和计算机的选择涉及从 choices 数组中访问元素并打印它们,这两个操作都是常数时间操作,O(1)。

确定赢家

determine winner 函数执行几次比较并根据游戏规则打印消息,所有这些都是常数时间操作,O(1)。

主函数操作

主函数中的操作,例如调用函数和打印结果,都以常数时间 O(1) 执行。

因此,程序的整体时间复杂度为 O(1),因为所有操作都以常数时间执行,与输入大小无关。

空间复杂度

变量存储

程序使用几个变量来存储用户选择、计算机选择以及比较结果。这些变量需要恒定的空间量,O(1)。

数组

choices 数组存储三个常量字符串(“石头”、“布”、“剪刀”),贡献固定的空间量,O(1)。

枚举和常量

此实现中除了 choices 数组外,没有使用枚举或常量,所有这些都占用固定的空间量,O(1)。

输入/输出操作

输入(用户选择)和输出(打印消息)操作所需的空间最小且恒定,O(1)。

因此,程序的整体空间复杂度为 O(1),因为它使用的内存量是固定的,并且不依赖于输入大小。


下一个主题C++ 中的笛卡尔树