首页 > 解决方案 > 未定义的行为(程序突然停止)。我究竟做错了什么?

问题描述

好的,所以我在尝试制作的游戏中遇到了一个主要问题,那就是战争游戏(纸牌游戏)。现在,我接近程序的结尾,我正在尝试设计一种解决方案,用于从两个不同的向量(玩家的牌组和计算机的牌组)中添加和删除牌。我省略了这个程序的其余部分,因为我知道(我想我知道?)故障代码在这三个函数中的某个地方。

基本上,程序的这一部分现在是如何工作的,它将一个充满 Card 对象的洗牌数组拆分为两个向量,然后这些向量成为实际的牌组。然后程序要求玩家抽出玩家牌组的最上面的牌,然后抽出那张牌(随机选择)并与计算机的牌进行比较,该牌也是随机选择的。“更强大”的牌获胜,它会向玩家打印一条消息,指出谁赢得了这一轮。然后,打出的牌应该被添加到赢得回合的牌组中(如果我链接那些 push_back 和 insert 语句,因为前面提到的未定义行为或我不知道如何的 bad_alloc 错误,这不会发生修复。请记住,如果我使用单个 push_back,当我调用此处代码中未列出的 printDeck 函数时,我没有收到 bad_alloc 错误,并且明显添加了一张卡片。仅当我尝试添加两张卡而不是一张卡时才会出现该特定错误)。“战争”功能(两张相同值的卡)还没有完成,我还没有完成它,因为我需要先弄清楚为什么我的程序不能正常运行。

另外,我知道有很多不必要/冗余的代码和我犯的一些新手错误(这是一个废话,因为我什至找不到该程序的修复程序并且我对标签的使用被看不起)但我'如果有任何答案首先更适合于解决方案,然后是有用的提示(如果有的话),我将不胜感激。

现在,最大的问题是,如果我在没有“cardBattle”函数中的“注释掉的代码”的情况下运行我的程序,程序将按预期循环,然后它将在完全随机的时间终止。我有一种感觉,我在 getRandomComputerCard 函数(它有一个我省略的双 getRandomPlayerCard 函数)中做错了,但我不知道那可能是什么。也许这是我删除矢量元素然后尝试稍后添加它的事实?我不知道。

请帮忙。

void playGame(Card (&mainDeck)[52])
        {
            std::vector<Card> playerDeck;
            playerDeck.resize(26);

            std::vector<Card> computerDeck;
            computerDeck.resize(26);

            int i = 0;

            for (auto card : mainDeck)
                {
                playerDeck[i] = mainDeck[i];
                computerDeck[i] = mainDeck[i+26];
                i++;
                }

            square2:

            std::cout <<
            "The rules of War are simple. If your card is more powerful (higher value) than your opponent's, then you win their card and it is shuffled into your deck. This can also be said for your opponent. \n\n"
            "If two cards are played which are the same value, then you enter into 'War.' Here, two cards are 'placed face down' by both players and a third is drawn and played normally, dictating who wins all three cards. \n\n"
            "Easy enough? Alright --- \n\n"
            "Decks have been randomized and cut in half. There are no jokers so the high card is the Ace. . . Ready? (y/n) \n\n";
            char userInput;
            std::cin >> userInput;

            if(userInput == 'y' || userInput == 'Y')
            {
                char playerChoice;

                while (playerDeck.empty() != true || computerDeck.empty() != true)
                {
                    resumePlay:

                    std::cout << "Play the top card in your deck: (p) ";
                    std::cin >> playerChoice;
                        if (playerChoice == 'p')
                        {
                            cardBattle(playerDeck, computerDeck);
                        }

                        else
                        {
                            std::cout << "Invalid Input.";
                            goto resumePlay;
                        }
                }
            }

            else if (userInput == 'n' || userInput == 'N')
            {
                std::cout << "Sorry that you weren't ready. Goodbye!";
            }

            else
            {
                std::cout << "Invalid input.";
                goto square2;
            }
        }






Card getRandomComputerCard(std::vector<Card> &computerDeck)
    {
        srand(time(0));
        std::mt19937 mersenne(static_cast<std::mt19937::result_type>(std::time(nullptr)));
        std::uniform_int_distribution<> card(0, 25);

        int randomNum = card(mersenne);
        Card computerCard = computerDeck[randomNum];
        computerDeck.erase(computerDeck.begin() + randomNum);

        std::cout << "The computer has played a ";
        cardToString(computerCard);
        std::cout << std::endl;

        return computerCard;
    }




void cardBattle(std::vector<Card> &playerDeck, std::vector<Card> &computerDeck)
{
    Card playerCard = getRandomPlayerCard(playerDeck);
    Card computerCard = getRandomComputerCard(computerDeck);

    if(playerCard.cr > computerCard.cr)
        {
        std::cout << "The player's card is higher. The player wins the round! \n";
            /*if(playerDeck.size() == 26)
                {
                playerDeck.push_back(playerCard);
                playerDeck.insert(playerDeck.begin(), computerCard);
                }
            else
                {
                playerDeck.insert(playerDeck.begin() + 2, playerCard);
                playerDeck.insert(playerDeck.begin() + 3, computerCard);
                }*/
        }
    else if (computerCard.cr > playerCard.cr)
        {
        std::cout << "The computer's card is higher. The computer wins the round! \n";
          /*  if (computerDeck.size() == 26)
                {
                computerDeck.push_back(playerCard);
                computerDeck.insert(computerDeck.begin() + 2, computerCard);
                }
            else
            {
                computerDeck.insert(computerDeck.begin() + 2, computerCard);
                computerDeck.insert(computerDeck.begin() + 3, playerCard);
            }*/
        }
    else if (computerCard.cr == playerCard.cr)
        {
        std::cout << "The player's card and the computer's card are the same strength! War! \n";
        War();
        }

        std::cout << std::endl;
        printSideDeck(playerDeck);
        printSideDeck(computerDeck);
        std::cout << std::endl;
}

标签: c++c++17

解决方案


错误在这里:

int i = 0;
for (auto card : mainDeck)
{
    playerDeck[i] = mainDeck[i];
    computerDeck[i] = mainDeck[i+26];
    i++;
}

因为 mainDeck 包含 52 张卡片,所以在循环过程中i,值的范围是从051,因此您尝试访问mainDeck[51 + 26]不存在的 。

我们可以很容易地重写函数:

int i = 0; 
for(auto& card : playerDeck) {
    card = mainDeck[i++]; 
}
for(auto& card : computerDeck) {
    card = mainDeck[i++]; 
}

或者我们也可以通过在声明这些向量时进行复制来进一步简化事情:

// This is actually the most efficent solution
// because we don't have to default-construct any of the cards
using std::begin;
using std::end; 
// Get the first 26 elements of mainDeck
std::vector<Card> playerDeck(begin(mainDeck), begin(mainDeck) + 26);
// Get the second 26 elements of mainDeck 
std::vector<Card> computerDeck(begin(mainDeck) + 26, end(mainDeck)); 

推荐阅读