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

C++实现扑克牌洗牌时如何正确设置cardInDeck标记为true

问题排查与修正方案

1. 初始化阶段的致命错误

你在初始化卡牌的嵌套循环中写的越界赋值代码是第一个核心问题:

int index = (13 * numberOfSuits) + cardRank - 1;
stackOfCards[index].cardInDeck = false;

这段代码计算出来的index值固定为13*4+13-1=64,已经超出了stackOfCards数组52个元素的合法下标范围(0~51),属于数组越界访问,根本没有给每个卡牌的cardInDeck属性正确赋值,导致初始状态下大部分卡牌的cardInDeck值是不确定的,不是你预期的全为false。
修正方法:在初始化每个卡牌的时候直接给cardInDeck赋值:

stackOfCards[k].cardSuit = cardSuit[suit];
stackOfCards[k].cardFace = cardFace[rank];
stackOfCards[k].cardValue = cardValue[rank];
stackOfCards[k].cardInDeck = false; // 新增这行,删掉之前的越界赋值代码
k++;

2. 洗牌逻辑完全不符合需求

你现有的交换逻辑和你预期的「抽未使用的卡牌放到洗好的牌堆」逻辑完全不匹配,才会出现只有部分卡牌被标记为true的问题。按照你的预期目标,洗牌逻辑应该改成如下流程:

  • 遍历shuffledDeck的每个位置
  • 每次生成一个随机下标,检查该下标对应stackOfCards的cardInDeck是否为false
  • 如果是未使用状态,就把该卡牌复制到shuffledDeck的当前位置,同时把该卡牌的cardInDeck设为true
  • 如果是已使用状态,就重新生成随机下标,直到抽到未使用的卡牌为止

3. 修正后的完整代码

#include <iostream>
#include <cstdlib>
#include <ctime>

struct CARD
{
    char cardSuit {};
    char cardFace {};
    int cardValue {};
    bool cardInDeck {};
    
    void printCard(){
        std::cout << cardFace << cardSuit << "\n";
    }
};

int main()
{
    const int numberOfCards {52};
    const int cardRank {13};
    const int numberOfSuits {4};
    
    CARD stackOfCards[numberOfCards];
    
    char cardSuit [] = {'H','S','C','D'};
    char cardFace [] = {'A', '2','3','4','5','6','7','8','9','T','J','Q','K'};
    int cardValue [] = {11,2,3,4,5,6,7,8,9,10,10,10,10};
   
    int k = 0;
    for(int suit = 0; suit < numberOfSuits; suit++)
    {
        for(int rank = 0; rank < cardRank; rank++)
        {
            stackOfCards[k].cardSuit = cardSuit[suit];
            stackOfCards[k].cardFace = cardFace[rank];
            stackOfCards[k].cardValue = cardValue[rank];
            stackOfCards[k].cardInDeck = false; // 正确初始化每张卡的使用状态
            k++;
        }
    } // end of card stack initializer
    
    srand(time(0));
    CARD shuffledDeck [numberOfCards];
    
    for (int cardCounter = 0; cardCounter < numberOfCards; cardCounter++)
    {
        int randomNum;
        // 循环直到抽到未使用的卡牌
        do {
            randomNum = rand() % 52;
        } while (stackOfCards[randomNum].cardInDeck == true);
        
        // 复制到洗好的牌堆
        shuffledDeck[cardCounter] = stackOfCards[randomNum];
        // 标记为已使用
        stackOfCards[randomNum].cardInDeck = true;
    }

    // 测试输出洗好的牌
    for(int i=0; i<numberOfCards; i++){
        shuffledDeck[i].printCard();
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:27:03