2010-08-15 3 views
0

Эта программа должна сортировать карты, группировать их и в 5 групп, называемых руками, по порядку код делает именно это, однако по какой-то причине я не уверен в этом, я не могу определить winer. Победителем считается значение, показанное как самое высокое среди пар. если рука имеет королю как самую высокую пару, а рука 3 имеет 7 как самую высокую пару, тогда рука должна быть объявлена ​​победителем.с помощью qsort для сортировки массива

#include<stdio.h> 
#include<stdlib.h> 
#include<time.h> 
#include <windows.h> 


typedef unsigned char card; 
typedef unsigned char pairs; 

static char *suits[] = {"Hearts","Diamonds","Clubs","Spades"}; 
static char *values[]= {"Ace","Two","Three","Four","Five","Six",\ 
        "Seven","Eight","Nine","Ten","Jack",\ 
        "Queen","King"}; 
static char *colour[]= {"Black","Red"}; 

void printcard(card c); /* Displays the value of a card*/ 
void printdeck(card deck[52]); /* prints an entire deck of cards*/ 
void filldeck(card deck[52]); /* Populates a deck of cards */ 
void shuffle(card deck[52]); /* Randomizes the order of cards */ 
int compareface(const void* c1,const void *c2); 

pairs findpairs(card *hand); /* finds any pairs in a hand */ 
int findwinner(card *hand); 


int main() 
{ 

card deck[52],*deckp,*temp3,max; 
card hands[5][5],handssorted[5][5]; 
pairs numpairs[5],highest; 
int hand,cd,winner=0,temp2; 
char loop; 

{ 
printf("\n(__)(__)(__)(__) CARD GAME(__)(__)(__)(__)(__)\n\n"); 
printf("\n(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)\n\n"); 
printf("\n\t ====== Before Shuffling =====\n\n"); 
srand(time(NULL)); /* seed the random number generator */ 

    filldeck(deck);//printdeck(deck); 
    printdeck(deck); 
    printf("\n\t ========== Shuffled Cards ========\n\n"); 
    shuffle(deck);//printdeck(deck); 
    printdeck(deck); 

int i=0; 
for(cd=0;cd<5;cd++) 
{ 
    for(hand=0;hand<5;hand++){ 
     hands[hand][cd]=deck[i]; 
     i++; 
    } 
    } 

printf("\n\t ============= Hands ===========\n\n"); 
for(hand=0;hand<5;hand++) 
{ 
    qsort(hands[hand],5,sizeof(card),compareface);; 

    int kok=0; 

    printf("\tHand %i:\n",hand+1); 

    for(cd=0;cd<5;cd++) 
    {    
     printcard(hands[hand][cd]); 
    } 

    numpairs[hand]=findpairs(hands[hand]); 
    printf("\n\tNumber of pairs:%i\n\n",numpairs[hand]); 
    temp2=0; 
    if(numpairs!=0) 
     temp2=findwinner(hands[cd]); 
} 
pairs findpairs(card *hand) 
{  int cd=0,dd=0; 

    card temp; 
    pairs numpairs=0; 

    for (cd=0;cd<4;cd++) 
    { 
    if (values[(hand[cd]&0x3c)>>2] == values[(hand[cd+1]&0x3c)>>2]) 
    { 
     dd++; 
     temp=hand[cd]; 
    } 

    switch (dd) 
    { 
     case 0:numpairs=0; 
     break; 
     case 1:numpairs=1; 
     break; 
     case 2: 
       if ((values[(hand[1]&0x3c)>>2] !=values[(hand[3]&0x3c)>>2])&& 
       (values [(hand[0]&0x3c)>>2]\ 
        !=values[(hand[2]&0x3c)>>2])&&(values[(hand[2]&0x3c)>>2] !=values 
       [(hand[4]&0x3c)>>2]))numpairs=2; 

       else 
        numpairs=1; 
        break; 
     case 3:numpairs=2; 
     break; 
     case 4:numpairs=2; 
     break; 
     }} 
     printf("\tHighest pair is:"); 
     if (numpairs!=0) 
     printf("\t%s",values[(temp&0x3c)>>2]);   
    return numpairs; 
} 

int findwinner(card *hand){  
int cd=0,temp2=0,winner=0; 
for (cd=0;cd<4;cd++) 
    { 
    if (values[(hand[cd]&0x3c)>>2] == values[(hand[cd+1]&0x3c)>>2]) 
    { 
    // temp2=cd; 
    winner=cd; 
    }} 

    return winner; 
} 


void filldeck(card deck[52]) 
{ 
card suit,value; 
int i=0; 

for(suit=0;suit<4;suit++) 
{ 
    for(value=0;value<13;value++) 
    { 
     deck[i]=suit|(value<<2);      
     if(suit<2) 

      deck[i]|=0x40; /*card is red, so do red stuff */       
     i++; 
    } 
} 

return; 
} 
void printdeck(card deck[52]) 
{ 
    int i; 
    for(i=0;i<52;i++) 
    printcard(deck[i]); 
    return; 
} 

void printcard(card c) 
{ 
    printf("\t%s\t of %-8s is %s\n",values[(c&0x3c)>>2],suits[c&0x3], 
    colour[(c&0x40) >>6]); 
    return; 
} 

void shuffle(card deck[52]) 
{ 
    int i,rnd; 
    card c; 
    for(i=0;i<52;i++) 
{ 
    rnd=rand() * 52.0/RAND_MAX; 
    c=deck[rnd]; 
    deck[rnd]=deck[i]; 
    deck[i]=c; 
} 
    return; 
} 


int compareface(const void* c1, const void *c2) 
    { 

    card cd1,cd2; 
    cd1=*((card*) c1); 
    cd2=*((card*) c2); 

    cd1= (cd1&0x3c)>>2; 
    cd2= (cd2&0x3c)>>2; 

    if(cd1>cd2) 
     return 1; 

    if(cd1==cd2) 
     return 0; 

    return -1; 
} 
+2

- это то, как вы обычно форматируете свой C-код? –

+1

Возможно, вы могли бы добавить код, объявляющий «руки», «колоду», а также «карточку»? –

ответ

1

Одна из возможных проблем находится в конце «сравнить» цикла:

if(numpairs!=0) 
    temp2=findwinner(hands[cd]); 

С «CD» находится вне диапазона в то время, вы получите странные результаты. Вы должны объяснить нам больше, чтобы быть уверенными в правильности.

Необходимо выполнить проверку вашего кода сортировки. Сдвиг на самом деле не нужен; бит-маскирование гарантирует, что значения монотонно возрастают, игнорируя костюм, который, по-видимому, сдвигается.


Я принял взглянуть на полный код (который отсутствует пара близких скобок перед функцией findpairs() определяется). Для компиляции не нужен заголовок <windows.h>, что хорошо. Основной код - то, что перетасовывает карты и т. Д. - кажется достаточно прочным. Есть много ничтожных изменений, которые я бы сделал, но все в порядке.

Одна тонкая деталь: процедура сравнения карт не сортирует массив «2H 2C 2S 2D 3S» так, чтобы двое были в любом конкретном порядке. Это может иметь значение позже; человек с «2C 2S» может победить человека с «2D 2H», потому что 2S находится выше, чем любой другой дядя. И если это не так, вам все равно нужно прибивать правила. Вам также нужно учитывать, сколько пар в руке «2H 2C 2S 2D 3S» - 6 было бы разумным ответом.

Код findpairs() имеет интересную деталь посередине; Я думаю, вы должны использовать двойной цикл, с внутренним циклом, который находит конец диапазона карт с равными значениями.

Линии, которые я изначально выделял, - вот где ваши проблемы начинаются - я не думаю, что вы правильно сформулировали, как вы определяете победителя, потому что вы не храните необходимую информацию. Условие «numpairs!=0» всегда верно, потому что numpairs - это массив, и указатель никогда не является нулевым указателем.

Также, когда вызывается функция findwinner(), cd равно 6, и поэтому поведение не определено. Поскольку вы сразу бросаете возвращаемое значение, некоторые из них не имеют значения.

Очевидно, что вы должны упорно работать на:

  • Как обрабатывать тройки и четверки
  • Как определить Победители

Но ваш первоначальный вопрос об использовании qsort() можно ответить «вам используют его ОК ".

Я отмечаю мимоходом, что есть места, где вы сравниваете значение карт для равенства с выражениями типа:

if (values[(hands[hand][cd]&0x3C)>>2] == values[(hands[hand][cd]&0x3C)>>2]) 

Там нет необходимости ссылаться на values массиве в этом. Он работает нормально, но это не нужно.


Пересмотренный код - определение победителя, но немного опрятное в других отношениях. Может быть скомпилирован с '-DVERBOSE_NAMES', чтобы распечатать карты с длинными именами. В противном случае он использует короткие имена: «AC» для туза клубов, «2H» для двойки сердец, «TD» для десяти бриллиантов и «KS» для короля пик. Он требует компилятора C99 (или C++) из-за того, как он объявляет переменные в циклах и использует встроенные функции и т. Д. (Проверено: GCC 4.5.1 и G ++ 4.5.1 на MacOS X 10.6.4.)

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

enum { NUM_HANDS  = 5 }; 
enum { CARDS_PER_HAND = 7 }; 
enum { CARDS_PER_DECK = 52 }; 

typedef unsigned char card; 
typedef unsigned char pairs; 

static const char *values[]= 
{ 
    "Ace", "Two", "Three", "Four", "Five", "Six", 
    "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" 
}; 
#ifdef VERBOSE_NAMES 
static const char *suits[] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 
static const char *colour[]= { "Black", "Red" }; 
#endif /* VERBOSE_NAMES */ 

static void printcard(card c); /* Displays the value of a card*/ 
static void printdeck(card deck[CARDS_PER_DECK]); /* prints an entire deck of cards*/ 
static void filldeck(card deck[CARDS_PER_DECK]); /* Populates a deck of cards */ 
static void shuffle(card deck[CARDS_PER_DECK]); /* Randomizes the order of cards */ 
static int compareface(const void* c1, const void *c2); 
static pairs findpairs(card *hand); /* finds any pairs in a hand */ 

static inline int card_value(card c) { return((c & 0x3C) >> 2); } 
static inline int card_suit(card c) { return((c & 0x03)); } 
static inline int card_colour(card c) { return((c & 0x40) ? 1 : 0); } 

static void deal(card deck[CARDS_PER_DECK], card hands[NUM_HANDS][CARDS_PER_HAND]) 
{ 
    int i = 0; 
    for (int cd = 0; cd < CARDS_PER_HAND; cd++) 
    { 
     for (int hand = 0; hand < NUM_HANDS; hand++) 
      hands[hand][cd] = deck[i++]; 
    } 
} 

static void printhand(int num, card hand[CARDS_PER_HAND]) 
{ 
#ifdef VERBOSE_NAMES 
    printf("\tHand %i:\n", num); 
#else 
    printf("\tHand %i:", num); 
#endif /* VERBOSE_NAMES */ 
    for (int cd = 0; cd < CARDS_PER_HAND; cd++) 
    { 
     printcard(hand[cd]); 
    } 
} 

static void printhands(card hands[NUM_HANDS][CARDS_PER_HAND]) 
{ 
    int i; 
    for (i = 0; i < NUM_HANDS; i++) 
    { 
     printhand(i+1, hands[i]); 
     putchar('\n'); 
    } 
} 

int main() 
{ 
    card deck[CARDS_PER_DECK]; 
    card hands[NUM_HANDS][CARDS_PER_HAND]; 
    pairs numpairs[NUM_HANDS]; 

    printf("(__)(__)(__)(__) CARD GAME (__)(__)(__)(__)(__)\n"); 
    printf("(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)(__)\n\n"); 
    printf("\t====== Before Shuffling =====\n\n"); 
    srand(time(NULL)); /* seed the random number generator */ 

    filldeck(deck); 
    printdeck(deck); 
    printf("\t========== Shuffled Cards ========\n\n"); 
    shuffle(deck); 
    printdeck(deck); 
    deal(deck, hands); 
    printf("\t============= Hands ===========\n\n"); 
    printhands(hands); 
    putchar('\n'); 

    printf("\t============= Analysis ===========\n\n"); 
    for (int hand = 0; hand < NUM_HANDS; hand++) 
    { 
     qsort(hands[hand], CARDS_PER_HAND, sizeof(card), compareface);; 
     printhand(hand+1, hands[hand]); 
     numpairs[hand] = findpairs(hands[hand]); 
    } 

    return 0; 
} 

static pairs findpairs(card *hand) 
{ 
    card pair = 0; 
    pairs numpairs = 0; 

    for (int cd1 = 0; cd1 < CARDS_PER_HAND; cd1++) 
    { 
     for (int cd2 = cd1 + 1; cd2 < CARDS_PER_HAND; cd2++) 
     { 
      if (card_value(hand[cd1]) == card_value(hand[cd2])) 
      { 
       numpairs++; 
       pair = hand[cd1]; 
      } 
     } 
    } 

    if (numpairs > 0) 
     printf(" %d pairs - highest pair is: %s\n", numpairs, 
       values[card_value(pair)]); 
    else 
     printf(" 0 pairs\n"); 
    return numpairs; 
} 

void filldeck(card deck[CARDS_PER_DECK]) 
{ 
    int i = 0; 
    for (int suit = 0; suit < 4; suit++) 
    { 
     for (int value = 0; value < 13; value++) 
     { 
      deck[i] = suit | (value<<2); 
      if (suit < 2) 
       deck[i] |= 0x40; /*card is red, so do red stuff */ 
      i++; 
     } 
    } 
} 

void printdeck(card deck[CARDS_PER_DECK]) 
{ 
    for (int i = 0; i < CARDS_PER_DECK; i++) 
    { 
     printcard(deck[i]); 
     if ((i % 13) == 12) 
      putchar('\n'); 
    } 
    putchar('\n'); 
} 

#ifndef VERBOSE_NAMES 
static char abbr_card_value(card c) 
{ 
    static const char abbr_values[] = "A23456789TJQK"; 
    return abbr_values[card_value(c)]; 
} 
static char abbr_card_suit(card c) 
{ 
    static const char abbr_suits[] = "CDHS"; 
    return abbr_suits[card_suit(c)]; 
} 
#endif /* VERBOSE_NAMES */ 

void printcard(card c) 
{ 
#ifdef VERBOSE_NAMES 
    printf("\t%s\t of %-8s is %s\n", values[card_value(c)], suits[card_suit(c)], 
      colour[card_colour(c)]); 
#else 
    printf(" %c%c", abbr_card_value(c), abbr_card_suit(c)); 
#endif /* VERBOSE_NAMES */ 
} 

void shuffle(card deck[CARDS_PER_DECK]) 
{ 
    for (int i = 0; i < CARDS_PER_DECK; i++) 
    { 
     int rnd = rand() * 52.0/RAND_MAX; 
     card c = deck[rnd]; 
     deck[rnd] = deck[i]; 
     deck[i] = c; 
    } 
} 

int compareface(const void* c1, const void *c2) 
{ 
    card cd1 = *((card*) c1); 
    card cd2 = *((card*) c2); 

    cd1 = card_value(cd1); 
    cd2 = card_value(cd2); 

    if (cd1 > cd2) 
     return +1; 
    else if (cd1 < cd2) 
     return -1; 
    else 
     return 0; 
} 
+0

Мне действительно было сложно объяснить без кода, я опубликовал весь код. Простите его довольно долго. Тем не менее, вы можете просто выполнить его, и вы сразу увидите, о чем идет речь !! Я не могу объявить победителя, это должно было произойти из отсортированных пар. –

0
  1. Если вам действительно нужно только это, чтобы получить максимальную пару, это действительно неправильная стратегия слишком сложна и излишне медленно. Просто используйте цикл for , чтобы пройти через вашу колоду, и выберите самую большую пару, которую вы видите .
  2. Ваш сравнивающий код для карточек показывает, что у вас недостаточно модульная ваша программа. Если вы настаиваете на том, чтобы ввести свои карты в целое число , как кажется, не используйте смены и аналогичные для доступа к разные части, но битподы.
Смежные вопросы