我正在尝试编写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.但是对于我的生活,我想不出办法做到这一点。任何帮助将不胜感激!
答案 0 :(得分: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;
}
}
}
答案 1 :(得分: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)
答案 2 :(得分: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 ++。
答案 3 :(得分: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
}
}
}