You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

新手友好提示

  1. 成员函数的作用:类的成员函数默认可以访问当前对象的所有成员,不需要把对象自己传进去,传进去反而会创建副本白忙活。
  2. 赋值 vs 比较:写代码时要注意=(赋值,给变量设值)和==(比较,判断是否相等)的区别,这是新手常犯的语法错误。
  3. 字符串比较:C中直接用==比较字符串指针,比较的是内存地址不是内容,一定要用strcmp或者C的std::string来比较字符串内容。

内容的提问来源于stack exchange,提问作者nbslay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 17:24:27