首页 > 解决方案 > C++ D&D 点购买 - 点跟踪?

问题描述

我正在通过编写 D&D 5E 角色创建器来自学 C++。我知道这将至少是一个三步过程,我 (1) 学习语言,(2) 实施数据验证,然后 (3) 学习和实施适当的约定。

我试图只使用标准库。现在我正在研究能力得分点购买系统。可能是我筋疲力尽了,但我不确定如何正确跟踪积分支出。

看,在积分购买系统中,你可以在你的六个能力分数中分配 27 分。它们每个从 8 开始。每次增加花费 1 点,最多 13,然后每次增加 2 点,最多 15。超过 15 和低于 8 的值是不允许的。

我已经得到了要跟踪的点,并且识别了上限和下限。我只是想不出任何方法(更不用说像我喜欢的简单而优雅的方法)来调整分数进入或离开 14 或 15 的积分成本。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    const string abilities[6] = { "STR", "DEX", "CON", "INT", "WIS", "DEX" };

    bool editing = 1;

    int stats[6] = { 8, 8, 8, 8, 8, 8 };
    int points = 27;

    while (editing == 1)
    {
        int select = 0;
        int adjust = 0;
        int result = 0;
        int remainder = 0;

        cout << "You have " << points << " points to spend on your ability scores." << endl;
        cout << "Select a number to adjust that ability's score:\n1) STR = " << stats[0] << "\n2) DEX = " << stats[1] << "\n3) CON = " << stats[2] << "\n4) INT = " << stats[3] << "\n5) WIS = " << stats[4] << "\n6) CHA = " << stats[5] << endl;
        cout << "Select a number outside the above range to finalize your ability scores.\n";
        cin >> select;

        while (cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid entry; try again: ";
            cin >> select;
        }

        select -= 1;

        if (select < 0 || select > 5)
        {
            editing = 0;
            break;
        }

        cout << "Adjust " << stats[select] << " " << abilities[select] << " by how much? ";
        cin >> adjust;

        result = (stats[select] + adjust);

        if (result < 8)
        {
            cout << "Ability scores cannot be lower than 8 in the point buy system.\n";
        }
        else if (result > 15)
        {
            cout << "Ability scores cannot be higher than 15 in the point buy system.\n";
        }
        else
        {
            remainder = stats[select] - result;
            points += remainder;
            if (points < 1)
            {
                cout << "You do not have the points for that operation.";
                break;
            }
            else if (points > 27)
            {
                cout << "You cannot accrue more than 27 points.";
                break;
            }
            stats[select] = result;
        }
    }
}

有没有人有任何建议或例子我可以撕开?

编辑:

...替换上面代码中的第 4 行到最后一行,以对我的查询制定一个乏味且不优雅的解决方案:

            if (stats[select] == 15 && result == 14)
            {
                points += remainder + 1;
            }
            else if (stats[select] == 15 && result < 14)
            {
                points += remainder + 2;
            }
            else if (stats[select] == 14 && result < 14)
            {
                points += remainder + 1;
            }
            else if (result == 15 && stats[select] == 14)
            {
                points += remainder - 1;
            }
            else if (result == 15 && stats[select] < 14)
            {
                points += remainder - 2;
            }
            else if (result == 14 && stats[select] < 14)
            {
                points += remainder - 1;
            }
            else
            {
                points += remainder;
            }
            stats[select] = result;

这仍然不完美。条件句的额外分数独立于检查是否还有足够的分数来执行操作。

标签: c++

解决方案


与其对调整进行算术运算,不如直接查看统计数据到积分成本?

// outside main()
int stat_cost(int stat) {
    switch (stat){
        case 8: return 0;
        case 9: return 1;
        case 10: return 2;
        case 11: return 3;
        case 12: return 4;
        case 13: return 5;
        case 14: return 7;
        case 15: return 9;
        default: throw std::out_of_range("stat must be between 8 and 15 (inclusive)");
    }
}

// after checking result is in range
int points_result = points - stat_cost(result) + stat_cost(stats[select]);
if (points_result < 0)
{
    std::cout << "You do not have the points for that operation.";
    break;
}
else if (points_result > 27) // N.b. This condition can never be true
{
    std::cout << "You cannot accrue more than 27 points.";
    break;
}
points = points_result;
stats[select] = result;

推荐阅读