瑞典卡牌游戏开发难题:无法获取最后一张牌的花色
问题排查与修复方案
核心错误:数组越界访问
你当前调用teste(hands[HAND_COUNT][j]);存在两个致命的数组越界问题:
- 玩家索引越界:
hands是维度为[HAND_COUNT][HAND_SIZE]的二维数组,玩家的合法索引范围是0到HAND_COUNT-1(即0~3),直接使用HAND_COUNT(值为4)作为索引会访问数组外的非法内存。 - 手牌索引越界:变量
j在最后一次循环for(j=0;j<HAND_SIZE;j++)结束后,值会等于HAND_SIZE(即10),而手牌的合法索引范围是0到HAND_SIZE-1(即0~9),同样会导致非法访问。
规则匹配:正确获取王牌花色
根据游戏规则,最后发的牌花色为王牌花色,而最后发的牌是发牌者自己手牌的最后一张(对应牌堆的最后一张牌)。我们需要先确定发牌者的索引,再获取其最后一张手牌:
步骤1:确定发牌者的数组索引
你的代码中已经计算出发牌者的编号(playerX),需要将其转换为数组索引(数组从0开始,player1对应索引0):
int dealer_idx; if(num + 1 == 4){ dealer_idx = 0; // player1对应索引0 }else if(num + 1 == 5){ dealer_idx = 1; // player2对应索引1 }else{ dealer_idx = (num + 2) - 1; // playerX对应索引X-1 }
步骤2:正确调用teste函数
替换原来的错误调用,改为访问发牌者手牌的最后一张:
teste(hands[dealer_idx][HAND_SIZE - 1]);
额外问题修复:切牌逻辑错误
你的代码中切牌部分只是输出hands[i][j+1],完全不符合“将牌堆随机分两部分,下半部分放于上半部分之上”的规则,补充正确的切牌函数:
void deck_cut(short *deck) { // 随机选择切牌位置,至少保留1张牌在上半部分 int split_pos = rand() % (DECK_SIZE - 1) + 1; short temp[DECK_SIZE]; // 先复制下半部分到临时数组 memcpy(temp, &deck[split_pos], (DECK_SIZE - split_pos) * sizeof(short)); // 再复制上半部分到临时数组的后半段 memcpy(&temp[DECK_SIZE - split_pos], deck, split_pos * sizeof(short)); // 将临时数组内容复制回原牌堆 memcpy(deck, temp, DECK_SIZE * sizeof(short)); }
然后在洗牌后调用切牌函数:
/* deck shuffle */ deck_shuffle(deck); /* 切牌 */ deck_cut(deck);
修正后的main函数末尾代码示例
printf("\n\n"); /* 确定发牌者索引 */ int dealer_idx; if(num + 1 == 4){ dealer_idx = 0; }else if(num + 1 == 5){ dealer_idx = 1; }else{ dealer_idx = (num + 2) - 1; } /* 获取王牌花色(最后发的牌) */ printf("王牌花色检测:"); teste(hands[dealer_idx][HAND_SIZE - 1]); return 0; }
内容的提问来源于stack exchange,提问作者Filipe Martins
相关产品推荐
相关产品推荐

