未定义的行为(程序突然停止)。我在做什么错了?

时间:2019-04-01 03:13:24

标签: c++ c++17

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

基本上,程序的这一部分现在是如何工作的,它是将装满Card对象的重组数组分成两个向量,然后这些向量成为实际的卡片组。然后,程序要求玩家抽出玩家卡组的顶层纸牌,然后抽出该纸牌(随机选择)并将其与随机选择的计算机纸牌进行比较。 “功能更强大”的卡获胜,并向玩家显示一条消息,指示谁赢得了本轮比赛。然后,应该将打出的纸牌添加到赢得回合的套牌中(如果由于先前提到的未定义行为或不知道如何发生bad_alloc错误而将这些push_back和insert语句链接在一起,则不会发生这种情况请记住,如果使用单个push_back,则不会出现bad_alloc错误,并且在调用我的printDeck函数时会明显添加卡,该函数未在此处的代码中列出。添加两张卡片,而不是一张)。 “战争”功能(两张同等价值的卡)尚未完成,我还没有完成它,因为我需要弄清楚为什么我的程序首先无法正确运行。

此外,我知道我犯了很多不必要的/多余的代码和一些菜鸟错误(这是一个傻瓜,因为我什至找不到该程序的修补程序,而且我对标签的使用也视而不见)但是如果您首先将更多答案用于解决方案,然后再提供有用的提示,我将不胜感激。

现在,最大的问题是,如果我在“ 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;
}

2 个答案:

答案 0 :(得分:3)

错误在这里:

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

由于mainDeck包含52张卡片,因此在循环过程中i的值范围将从051,因此您尝试访问{{1} }(不存在)。

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

mainDeck[51 + 26]

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

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

答案 1 :(得分:0)

我知道了。

发生了什么事,我将随机数(在getRandomComputerCard / getRandomPlayerCard函数内部)设置为0到25之间的值,并且当其中一个向量浸入该范围以下并且该函数返回的值超出范围时这些向量中,程序不知道该怎么办。