石头剪刀布(C++)

Rock Paper Scissors (C++)

本文关键字:C++ 石头剪刀布      更新时间:2023-10-16

我在C++大学里有一个作业,它要求我为剪刀石头布制作一个程序,它有非常具体的说明。我必须创建一个具有这些变量的结构(播放器) a) 字符数组(名称[41]) b)命名为 points 的整数变量 c)名为 master 的布尔变量 d)一个字符数组(武器[8]),只能取石头、纸、剪刀的值。

  1. 我必须创建一个 void 函数(checkMastery),它将 Player 结构的指针作为参数。在函数中,如果玩家的点数小于 100,则 player.master 必须设置为 false,如果点数等于或大于 100,则必须设置为 true。
  2. 我必须创建另一个 void 函数 letsFight,它将两个 Player 结构的指针作为参数。在函数中,如果玩家用石头剪刀布赢得了战斗,则该玩家的积分增加 1 分,如果玩家输了,积分减少 1,如果是平局,则两个玩家的积分增加 1。如果任何玩家有其他东西作为武器,则该玩家的积分设置为 0,游戏结束。
  3. 我必须创建一个字符串函数showBestPlayer,它将Player结构的指针作为参数。它通过比较玩家的积分来检查谁赢了,并打印它的名字,如果我们有平局,它会打印平局。

好吧,我在下面创建了程序并编译。但是,无论它作为输入,输出都是"平局"。我能做什么?

//7540
#include <iostream>
#include <string>
#include <cstdlib>
#include <locale>
using namespace std;
struct Player {
char name[41];
int points;
bool master;
char weapon[9];
}players[2], *pointer1, *pointer2;
void checkMastery(Player *pointer);
void letsFight(Player *pointer1,Player *pointer2);
string showBestPlayer(Player* pointer1, Player* pointer2);
int main(){
pointer1 = players;
pointer2 = &players[1];
cout<<"Enter the player's name:n";
cin>>players[0].name;
fflush(stdin);
cout<<"Enter the player's weapon:n";
cin>>players[0].weapon;
fflush(stdin);
cout<<"Enter the player's name:n";
cin>>players[1].name;
cout<<"Enter the player's weapon:n";
cin>>players[1].weapon;
fflush(stdin);
checkMastery(pointer1);
checkMastery(pointer2);
letsFight(pointer1, pointer2);
showBestPlayer(pointer1, pointer2);
}
void checkMastery(Player* pointer){
pointer->master=((pointer->points<100) ? false : true); 
}
void letsFight(Player* pointer1, Player* pointer2){
if (((*pointer2).weapon !="rock")&&((*pointer2).weapon != "paper")&&((*pointer2).weapon!= "scissors")) {
(*pointer2).points = 0 ;
if (((*pointer1).weapon !="rock")&&((*pointer1).weapon != "paper")&&((*pointer1).weapon!= "scissors")){
(*pointer1).points = 0;
}
}
if ((*pointer1).weapon == "rock"){
if ((*pointer2).weapon == "rock"){
(*pointer1).points+=1;
(*pointer2).points+=1;
}else if((*pointer2).weapon == "paper"){
(*pointer1).points-=1;
(*pointer2).points+=1;
}else if((*pointer2).weapon == "scissors"){
(*pointer1).points+=1;
(*pointer2).points-=1;
}else if ((*pointer1).weapon == "paper"){
if ((*pointer2).weapon == "rock"){
(*pointer1).points+=1;
(*pointer2).points-=1;
}else if ((*pointer2).weapon == "paper"){
(*pointer1).points+=1;
(*pointer2).points-=1;
}else if ((*pointer2).weapon == "scissors"){
(*pointer1).points-=1;
(*pointer2).points+=1;
}
}else if((*pointer1).weapon == "scissors"){
if((*pointer2).weapon == "rock"){
(*pointer1).points+=1;
(*pointer2).points-=1;
}else if((*pointer2).weapon == "paper"){
(*pointer1).points-=1;
(*pointer2).points+=1;
}else if ((*pointer2).weapon == "scissors"){
(*pointer1).points+=1;
(*pointer2).points+=1;
}
}
}   
}
string showBestPlayer(Player* pointer1, Player* pointer2){
if ((*pointer1).points > (*pointer2).points) {
char bestPlayer[41];
memcpy(bestPlayer,(*pointer1).name,40);
cout << (*bestPlayer);
}
else if ((*pointer2).points > (*pointer1).points) {
char bestPlayer[41];
memcpy(bestPlayer, (*pointer2).name,40);
cout << (*bestPlayer);
}
else if((*pointer1).points == (*pointer2).points) {
cout << "tie";
}
}

有很多编译错误:

main.cpp:17:1: error: 'pointer' does not name a type
pointer = players[2];
^~~~~~~

那是因为你有

struct Player *pointer;
pointer = players[2];

这是全局范围的;你不能把这样的赋值放在函数(松散的扬声器)之外。 你可以改为写:

struct Player *pointer = players[2];

但请注意,players[2]已经过了players数组的末尾 - 可以安全地与另一个通过players递增的指针进行比较,以确定您是否在数组的末尾,但不能安全地取消引用。 您可能想分配给&players[0](或 - 相同但更简单的符号 -players- 我还没有看过你以后如何使用pointer来了解什么是有意义的。

main.cpp:19:26: error: variable or field 'checkMastery' declared void
void checkMastery(pointer) {
^

在那里说"指针"是没有意义的。pointer是一个全局变量,但您将其放入函数签名中,其中需要参数类型和标识符的列表。 查看您的函数体,参数没有明显的用途,因为该函数会修改全局变量。

然后继续...

main.cpp:25:16: error: variable or field 'letsFight' declared void
void letsFight(struct* players[0], struct* players[1]) {
^~~~~~
main.cpp:25:16: error: expected primary-expression before 'struct'
main.cpp:25:36: error: expected primary-expression before 'struct'
void letsFight(struct* players[0], struct* players[1]) {
^~~~~~
main.cpp:83:23: error: expected primary-expression before 'struct'
string showBestPlayer(struct* players[0], struct* players[1]) {
^~~~~~
main.cpp:83:43: error: expected primary-expression before 'struct'
string showBestPlayer(struct* players[0], struct* players[1]) {
^~~~~~
main.cpp:83:63: error: expected ',' or ';' before '{' token
string showBestPlayer(struct* players[0], struct* players[1]) {
^
main.cpp: In function 'int main()':
main.cpp:98:20: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
for (int i = 0; i = 1; ++i) {
~~^~~
main.cpp:101:4: error: expected ';' before 'cout'
cout << "Input a weapon:";
^~~~
main.cpp:104:12: error: no match for 'operator*' (operand type is 'Player')
letsFight(*players[0], *players[1]);
^~~~~~~~~~~
main.cpp:104:25: error: no match for 'operator*' (operand type is 'Player')
letsFight(*players[0], *players[1]);
^~~~~~~~~~~
main.cpp:104:2: error: 'letsFight' was not declared in this scope
letsFight(*players[0], *players[1]);
^~~~~~~~~
main.cpp:105:17: error: no match for 'operator*' (operand type is 'Player')
showBestPlayer(*players[0], *players[1]);
^~~~~~~~~~~
main.cpp:105:30: error: no match for 'operator*' (operand type is 'Player')
showBestPlayer(*players[0], *players[1]);
^~~~~~~~~~~

你基本上需要系统地解决每个编译错误 - 如果你把它归结为一两个你无法理解,然后寻求帮助。 如果你完全不知所措,从问题的一小部分开始,为此编写代码,确保它能够编译和工作,并逐步构建东西,以便你随时控制。


更新

好吧,所以你还在挣扎。 下面是一些不会崩溃的代码。 请注意,对于您不知道用户可能键入多少数据name之类的事情,我已经避免了固定长度的数组,并且我使用了引用而不是指针 - 很难弄错它们! 我没有仔细研究该程序正在做什么,但它不应该再崩溃了,你可以破解它,直到你对它感到满意。

#include <iostream>
#include <string>
#include <cstdlib>
#include <locale>
#include <cstring>
using namespace std;
struct Player {
std::string name;  // use std::string not char arrays
int points;        // (much safer and easier)
bool master;
std::string weapon;
};
void checkMastery(Player& pointer);
void letsFight(Player& pointer1, Player& pointer2);
void showBestPlayer(Player& pointer1, Player& pointer2);
int main(){
Player players[2]{};
cout<<"Enter the player's name:n";
getline(cin, players[0].name);
cout<<"Enter the player's weapon:n";
getline(cin, players[0].weapon);
cout<<"Enter the player's name:n";
getline(cin, players[1].name);
cout<<"Enter the player's weapon:n";
getline(cin, players[1].weapon);
checkMastery(players[0]);
checkMastery(players[1]);
letsFight(players[0], players[1]);
showBestPlayer(players[0], players[1]);
}
void checkMastery(Player& player){
player.master = player.points >= 100;
}
void letsFight(Player& player1, Player& player2){
if (player2.weapon != "rock" && player2.weapon != "paper" && player2.weapon != "scissors") {
player2.points = 0;
if (player1.weapon != "rock" && player1.weapon != "paper" && player1.weapon != "scissors") {
player1.points = 0;
}
}
if (player1.weapon == "rock"){
if (player2.weapon == "rock"){
player1.points+=1;
player2.points+=1;
}else if(player2.weapon == "paper"){
player1.points-=1;
player2.points+=1;
}else if(player2.weapon == "scissors"){
player1.points+=1;
player2.points-=1;
}else if (player1.weapon == "paper"){
if (player2.weapon == "rock"){
player1.points+=1;
player2.points-=1;
}else if (player2.weapon == "paper"){
player1.points+=1;
player2.points-=1;
}else if (player2.weapon == "scissors"){
player1.points-=1;
player2.points+=1;
}
}else if(player1.weapon == "scissors"){
if(player2.weapon == "rock"){
player1.points+=1;
player2.points-=1;
}else if(player2.weapon == "paper"){
player1.points-=1;
player2.points+=1;
}else if (player2.weapon == "scissors"){
player1.points+=1;
player2.points+=1;
}
}
}   
}
void showBestPlayer(Player& player1, Player& player2){
if (player1.points > player2.points) {
cout << "best player: " << player1.name << 'n';
}
else if (player2.points > player1.points) {
cout << "best player: " << player2.name << 'n';
}
else if(player1.points == player2.points) {
cout << "tien";
}
}

您的代码遇到的具体问题:

(*pointer1).weapon == "rock"

您不能只将字符箭头与字符串文本进行比较,例如"rock"- C++将查看字符数组是否位于同一地址,而且永远不会。 通过使用std::string,您可以使用==它将按预期工作。 对于字符数组,您需要使用 C 库函数strcmp(pointer1->weapon, "rock") == 0来测试相等性。

string showBestPlayer(Player* pointer1, Player* pointer2);

这承诺showBestPlayer将返回一个string,但您的函数只是在cout上打印了最好的播放器,并且没有返回任何内容。 这很可能导致您的崩溃。

cin >> player1.name

当您使用>>流式传输文本时,它会在找到空格时停止,无论是来自键入 ENTER 的用户还是名称中的空格,例如"Jane Smith"。 那么"史密斯"就会被意外解读为简的武器。

最好使用getline(std::cin, my_string_variable),因为这会将所有内容读取到 ENTER 生成的换行符,包括空格。

fflush(stdin);

永远不需要冲洗stdin。 任何写入标准输出(通过std::cout发送)的提示都应在从标准输入读取之前刷新,以便用户可以看到提示,但C++会自动执行此操作:std::cin流和std::cout流以这种方式绑定

语句

pointer = players[2];

仅在函数中允许。 您可以在文件范围(函数外部)使用它。 这会在您的程序中给出第一个错误(尽管您没有提到它)。

由于pointer是一个变量,在函数外部声明,因此函数定义

void checkMastery(pointer)   // rest of definition omitted

无效,因为(在此上下文中)指针必须是类型,而不是变量。 快速修复:删除pointer

第三个问题是

void letsFight(struct* players[0], struct* players[1]) {

它尝试声明两个具有相同名称的参数(players)。 由于函数体尝试使用players,快速解决方法是将上述内容更改为

void letsFight(struct* players[]) {

这可能会触发编译器的其他诊断 - 因为您的代码更早地将players声明为变量。

而不是为所有问题提供修复,

1)当查看来自编译器的错误消息时,FIRST是最重要的(您正在查看LAST)。

2)阅读有关C++的基本教科书,并了解变量和类型。 完成基本练习。 试图通过猜测来构建代码,就像你一样,浪费你和其他人的时间。 而且,是的,很明显你在猜测,考虑到你编写代码的方式,并发布了问题。