C++终端对战游戏武器无法切换问题求助(附代码)
问题定位与修复方案
你的代码里有三个核心错误直接导致武器切换失败,还有一个潜在的字符串比较风险,下面逐个说明并修复:
1. nextWeapon函数传参错误(值传递导致原对象无变化)
你的nextWeapon函数参数是Player plr,这是值传递——函数内部会创建传入Player的副本,你修改的只是这个副本的current_weapon,原对象(比如p1、p2)完全没被改动。
修复方式:
这是Player类的成员函数,直接操作当前对象即可,不需要传参。改成无参函数,直接访问类成员即可(成员函数默认指向当前对象)。
2. 赋值运算符写成了比较运算符
nextWeapon函数里的plr.current_weapon == (char*)weapons[1]用了双等号==,这是比较运算符,不是赋值的单等号=。这行代码只是判断两个地址是否相等,完全没有给current_weapon赋值。
修复方式:
把所有的==改成=。
3. Player2切换武器时调用了错误的对象
在Main.cpp的Player2回合里,按下N键时你写的是p1.nextWeapon(p1),这会去修改p1的武器,而不是p2的,完全搞反了操作对象。
修复方式:
改成p2.nextWeapon()(修复后的函数无参)。
4. 潜在问题:字符串地址比较的风险
你现在用current_weapon == (char*)weapons[0]比较字符串,本质是比较两个指针的地址。因为weapons里的是字符串常量,地址固定,所以暂时能工作,但如果以后用动态分配的字符串(比如new char[]),这种比较会彻底失效。
优化方式:
用C标准库的strcmp函数比较字符串内容,需要包含<cstring>头文件。当strcmp返回0时,表示两个字符串内容完全相同。
修复后的完整代码
Classes.h
#pragma once #include <cstring> // 用于strcmp函数 namespace Game { class Player { public: int health = 10; int max_health = 10; int medkit_count = 3; int medkit_heal_amount = 4; const char* weapons[3] = {"Pistol", "Rifle", "Shovel"}; int weapon_dmg[3] = {1, 3, 5}; const char* default_weapon = weapons[0]; const char* current_weapon = default_weapon; // 去掉不必要的强制类型转换,保持const属性 void nextWeapon() { // 用strcmp比较字符串内容,更安全 if (strcmp(current_weapon, weapons[0]) == 0) { current_weapon = weapons[1]; } else if (strcmp(current_weapon, weapons[1]) == 0) { current_weapon = weapons[2]; } else if (strcmp(current_weapon, weapons[2]) == 0) { current_weapon = weapons[0]; } } bool changing_weapon = false; }; }
Main.cpp
#include <iostream> #include "Classes.h" #include <cstring> // 用于strcmp函数 int main() { using Game::Player; using std::cout; using std::cin; using std::endl; Player p1; Player p2; int turn = 1; while (p1.health > 0 && p2.health > 0) { system("cls"); cout << "Player1 HP: " << p1.health << endl; cout << "Player2 HP: " << p2.health << endl; // p1's turn if (turn == 1) { cout << endl << "Player1's turn" << endl; cout << "Current weapon: " << p1.current_weapon << endl; cout << "Medkit count: " << p1.medkit_count << endl; cout << endl << "Enter A for ATTACK, H to HEAL, N for NEXT WEAPON: "; int dmg{}; // 用strcmp比较字符串内容 if (strcmp(p1.current_weapon, p1.weapons[0]) == 0) { dmg = p1.weapon_dmg[0]; } else if (strcmp(p1.current_weapon, p1.weapons[1]) == 0) { dmg = p1.weapon_dmg[1]; } else if (strcmp(p1.current_weapon, p1.weapons[2]) == 0) { dmg = p1.weapon_dmg[2]; } char p1_Move; cin >> p1_Move; //Player 1 Attacks if (p1_Move == 'A') { p2.health -= dmg; if (p2.health <= 0) { p2.health = 0; } turn = 2; } //Player 1 Uses Potion else if (p1_Move == 'H') { if (p1.medkit_count > 0) { p1.health += p1.medkit_heal_amount; p1.medkit_count--; if (p1.health > p1.max_health) { p1.health = p1.max_health; } turn = 2; } } //Player 1 Switches weapon else if (p1_Move == 'N') { p1.nextWeapon(); // 调用无参成员函数 } //Player 1 Skips else { turn = 2; } } else if (turn == 2) { cout << endl << "Player2's turn" << endl; cout << "Current weapon: " << p2.current_weapon << endl; cout << "Medkit count: " << p2.medkit_count << endl; cout << endl << "Enter A for ATTACK, H to HEAL, N for NEXT WEAPON: "; int dmg{}; // 用strcmp比较字符串内容 if (strcmp(p2.current_weapon, p2.weapons[0]) == 0) { dmg = p2.weapon_dmg[0]; } else if (strcmp(p2.current_weapon, p2.weapons[1]) == 0) { dmg = p2.weapon_dmg[1]; } else if (strcmp(p2.current_weapon, p2.weapons[2]) == 0) { dmg = p2.weapon_dmg[2]; } char p2_Move; cin >> p2_Move; if (p2_Move == 'A') { p1.health -= dmg; if (p1.health <= 0) { p1.health = 0; } turn = 1; } else if (p2_Move == 'H') { if (p2.medkit_count > 0) { p2.health += p2.medkit_heal_amount; p2.medkit_count--; if (p2.health > p2.max_health) { p2.health = p2.max_health; } turn = 1; } } //Player 2 Switches weapon - 修复对象错误 else if (p2_Move == 'N') { p2.nextWeapon(); } else { turn = 1; } } } if (p1.health <= 0 && p2.health > 0) { system("cls"); cout << "PLAYER 2 WINS" << endl; system("pause"); } else if (p2.health <= 0 && p1.health > 0) { system("cls"); cout << "PLAYER 1 WINS" << endl; system("pause"); } return 0; }
新手友好提示
- 成员函数的作用:类的成员函数默认可以访问当前对象的所有成员,不需要把对象自己传进去,传进去反而会创建副本白忙活。
- 赋值 vs 比较:写代码时要注意
=(赋值,给变量设值)和==(比较,判断是否相等)的区别,这是新手常犯的语法错误。 - 字符串比较:C中直接用
==比较字符串指针,比较的是内存地址不是内容,一定要用strcmp或者C的std::string来比较字符串内容。
内容的提问来源于stack exchange,提问作者nbslay
相关产品推荐
相关产品推荐

