0

我正在尝试编写一个 Go Fish 游戏,其中对匹配的卡片给予积分。但是,我似乎无法找到从手上移除匹配对的方法。

我已经实现了一个小循环来删除游戏其他方面使用的单张卡片,如下所示:

for ( i = position - 1 ; i < user_size - 1 ; i++)
    {
        user_hand[i] = user_hand[i+1];
        user_count[i]--;
        user_size--;
    }

其中 user_size 是用户手中的牌张数,user_count 是用户持有的 13 张牌值中每张牌的数量。但是,我找不到删除相同价值卡对的方法。

例如,如果 user_hand 是:2 2 4 5 6 6 6 6 1 2

我想删除除一个 2 (一对)和所有四个 6 (两对)之外的所有。将 user_hand 保留为:4 5 1 2。但是对于我的生活,我想不出办法来做到这一点。任何帮助将不胜感激!

4

4 回答 4

0
void removePairs(int * hand, int size)
{       
    for(int i = 0; i < size; i++)
    {
        for(int j = i+1; j < size; j++)
        {
            if((hand[i] == hand[j]) && hand[i] != -1)
            { 
                hand[i] = -1; // set card "ready to remove"
                hand[j] = -1;
                break;
            }
        }
    }
    for(int k = 0; k < size; k++)
    {
        if(hand[k] != -1)
        {
            printf("%d ", hand[k]); // you can store remaining cards here
        }
    }
}
于 2013-10-29T21:03:45.357 回答
0

首先循环遍历您的user_count数组,然后继续调用 remove_card 两次user_count[rank] >= 2

for(int rank = 1; rank <= 13; rank++)
    while(user_count[rank] >= 2) {
        remove_card(user_hand, user_count, &user_size, rank);
        remove_card(user_hand, user_count, &user_size, rank);
    }

对于remove_card,只需找到第一张匹配的卡片,然后调用您现有的例程:

void remove_card(int *user_hand, int *user_count, int *user_size, int rank) {
    for(int pos = 0; pos < *user_size; pos++)
         if(user_hand[pos] == rank)
            remove_card_at(user_hand, user_count, user_size, pos+1);
}

remove_card_at是您在原始帖子中提供的用于移除特定位置的卡片的例程。请注意,您必须user_size转换为指针并取消引用它才能修改调用函数中的变量。

此外,您应该真正考虑使用结构或类来握住用户的手,具体取决于您使用的是 C 还是 C++。

于 2013-10-29T20:49:34.320 回答
0

通常你会使用 1 个数组来存放卡片,一个变量来保存卡片的数量。然后你可以像这样使用嵌套循环进行迭代:

for (int i = 0; i < user_size; i++){
  for (int j = i+1; j < user_size; j++){
    if(user_hand[i] == user_hand[j]){
      /* remove card at index i */
      for(int z = i; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
      user_size--;
      /* remove card at index j */
      for(int z = j; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
      user_size--;
    }
  }
}

但在你的例子中,你也得到了user_count[]. 如果我理解正确(否则请纠正我) user_count[] 持有用户手上具有多少特定价值的卡片。所以在你的例子中:2 2 4 5 6 6 6 6 1 2

user_count[0] = 0
user_count[1] = 1
user_count[2] = 3
user_count[3] = 0
user_count[4] = 1
user_count[5] = 1
user_count[6] = 4

如果这就是user_count[]目的,那么您可以简单地执行以下操作:

for (int i = 0; i < user_size; i++){
  for (int j = i+1; j < user_size; j++){
    if(user_hand[i] == user_hand[j]){
      int cardNumber = user_hand[i];
      /* remove card at index i */
      for(int z = i; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
      user_size--;
      /* remove card at index j */
      for(int z = j; z < user_size - 1; z++) user_hand[z] = user_hand[z + 1];
      user_size--;
      /* decrement user_count by 2 */
      user_count[cardNumber] = user_count[cardNumber] - 2;
    }
  }
}
于 2013-10-29T20:41:42.440 回答
0

如果重新排序用户手中的卡片不成问题,您可以:

int *hand;
int handSize;
...
sort(hand, handSize);                   // 1. sort

int *newHand = malloc(sizeof(int) * handSize);
int i, newHandSize = 0;
for (i = 1; i < handSize; ++i) {
    if (hand[i - 1] == hand[i]) {
        hand[i] = -1;                   // 2. "flag" last value of a pair
        continue;
    }
    newHand[newHandSize] = hand[i - 1]; // 3. copy last examined card to new hand
    newHandSize++;
}
if (hand[handSize - 1] != -1) {         // 4. copy last element if needed
    newHand[newHandSize] = hand[handSize - 1];
    newHandSize++;
}
int* handToFree = hand;
hand = newHand;                         // 5. replace users hand with new hand
free(handToFree);                       // 6. clean up

但我认为它不能低于O( n*log(n) + n )

于 2013-10-29T20:42:11.620 回答