Tasowanie kart(liczb)

0
 void tasowanie(int tab[2][52])
{
    int i,x,y,z,v;
    srand(time(NULL));
    int sprtab[52];
    for (i=0;i<52;i++)
    sprtab[i]=1;
    for (i=0;i<26;i++)
        z=rand()%52;
        v=rand()%52;
        while(sprtab[z]==0)
            z=rand()%52;
        while(sprtab[v]==0)
            v=rand()%52;
        sprtab[z]=0;
        x=tab[0][z];
        tab[0][z]=tab[0][z];
        tab[0][z]=x;
        y=tab[1][v];
        tab[1][v]=tab[1][v];
        tab[1][v]=y;
}

Napisałem taka funkcje do tasowania kart w C. Są one w tablicy dwuwymiarowej. W tab[0][x] przechowywane są wartości kart do gry w oczko. W tab[1][x] przechowywane sa indeksy, ktore maja byc tasowane razem z wartościami, aby później dało się wypisać odpowiednie figury oraz kolory. Ale coś nie działa. Jakby ktoś mi wyjaśnił jak poprawić byłbym wdzięczny.

0

Po co pisać własne sortowanie skoro

  • ktoś już to zrobił
  • gotowe rozwiązanie jest szybsze w użyciu
  • gotowe rozwiązanie jest pewniejsze w działaniu
  • gotowe rozwiązanie jest ładniejsze
  • itd

Proponowałbym stworzyć strukturę 'karty' i posortować tak:
(napisane w C99, żeby zadziałało na starszych (hmm) kompilatorach musisz zmienić sposób tworzenia tablicy. Oczywiście zadziała dla dowolnej ilości kard, trzy to tylko przykład.)

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

struct card {
    int value;
    int ndx;
};

int compareCards(const void *a, const void *b) {
    return ((struct card*)a)->value - ((struct card*)b)->value;
}

void sortCards(struct card *cards, int count) {
    qsort(cards, count, sizeof(struct card), compareCards);
}

int main() {
    struct card c[3] = {
        { .value = 0, .ndx = 1 },
        { .value = 2, .ndx = 0 },
        { .value = 1, .ndx = 2 }
    };

    sortCards(c, 3);

    for (int i = 0; i < 3; i++) {
        printf("%d - %d\n", c[i].value, c[i].ndx);
    }
}
0

Dzięki!

Ps. nie wiem czy mogę używać gotowych rozwiązań.

0

Jeśli nauczycielowi będą przeszkadzało używanie biblioteki standardowej to cóż, dziwne podejście, ale niech będzie - możesz zamienić funkcję tasującą na np (klasyczne sortowanie 'bąbelkowe')

int compareCards(struct card a, struct card b) {
    return a.value > b.value;
}

void sortCards2(struct card *cards, int count)
{
     for (int i = 0; i < count; i++) {
          for (int j = 0; j < count - i - 1; j++) {
               if (compareCards(cards[j], cards[j + 1])) {
                    struct card tmp = cards[j];
                    cards[j] = cards[j + 1];
                    cards[j + 1] = tmp;
               }
          }
     }
}
1

Coś tu nie kumam, pytający pyta o tasowanie, odpowiadają mu o sortowaniu, on dziękuje za podane rozwiązania. Albo ja zgłupiałem albo @pele12 oraz @msm.

0

Ehh sorry, mój błąd. Nie zauważyłem, kod miałem analizować dopiero dziś. Z sortowaniem nie mam problemu. W takim razie jak poprawić moj kod aby dobrze tasował karty. Ma być oparty na generatorze liczb pseudolosowych(srand, rand). Dodam tylko, ze zamiast tablicy do kart planuje zrobić strukturę, ale myślę, że to będzie się dało analogicznie zmienić.

0

Hmm, czyli to ja nie zrozumiałem o co chodzi z tasowaniem (jakoś skojarzyło mi się tasowanie kart z sortowaniem...)

No dobra, to kolejne podejście do odpowiedzi:
Prosty algorytm na to to http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Czyli w tym przypadku coś w rodzaju:

void shuffle(struct card *cards, int count) {
    for (int i = count - 1; i > 0; i--) {
        int j = rand() % (i + 1); // wybierz element 0 <= j <= i
        struct card tmp = cards[j]; // zamień cards[i] z cards[j]
        cards[j] = cards[i];
        cards[i] = tmp;
    }
}

Czyli po prostu idziesz od końca i zamieniasz element z jakimś losowo wybranym.

Na jakimś prostym przykładzie:
Mamy 'talię':
[1, 2, 3, 4]

Bierzemy czwarty (ostatni) element i zamieniamy z losowo wybranym (powiedzmy z drugim - to co nam wyjdzie w losowaniu)
[1, 4, 3, 2]

Teraz bierzemy trzeci element i zamieniamy z jakimś wcześniejszym (czyli drugim albo pierwszym - losujemy):
[1, 3, 4, 2]

Teraz bierzemy drugi i robimy ostatnią podmianę - została tylko jedna opcja czyli zamiana z pierwszym:
[3, 1, 4, 2]

I na tym kończymy 'tasowanie'.

0

Pytanie (do tego co jest w nawiasach w funcji --> void shuffle(*)) jak wczytywac strukture? Załóżmy, że mam struct talia{char nazwa[3];int wartosc;}.

Drugie pytanie, czy ta funkcja nie będzie zawsze tasowała w ten sam sposób, to znaczy czy nie zawsze będzie ustawiac w ten sam ciąg. Chodzi mi o to czy nie trzeba użyć srand(time(NULL))?

0

srand(time(NULL)) trzeba użyć ale nie w tej funkcji, tylko na przykład na początku main'a.
Poco ci pakowanie nazwy i wartości do struktury, użyj liczby do identyfikacji karty:
const char *kolor[]={"piki","trefle","karo","kier"};
const char *nazwa[]={"2","3","4", ... ,"Q","K","A"};
unsigned wartosc[]={2,3,4, ... ,10,10,11};
z liczby X = 0..51
for(X=0;X<52;++X) cout<<nazwa[X>>2]<<kolor[X&3]<<" - "<<wartosc[X>>2]<<endl;

0

Ewentualnie mogę zrobić, że mam tablice dwuelementowa z indeksami i wartosciami. Indeksy tasują się tak jak wartości(przechodzą jakby na to samo miejsce). i potem do identyfikacji koloru biorę modulo 4 i na podobnej zasadzie figury.

0
_13th_Dragon napisał(a):

...Poco ci pakowanie nazwy i wartości do struktury, użyj liczby do identyfikacji karty...
Jeżeli już to to i to, proponuję mniej więcej taki interfejs:

typedef unsigned CardID; // 0 .. 23

enum CardColour {
    CARD_COLOUR_SPADE  = 0,
    CARD_COLOUR_CLUB   = 1, 
    CARD_COLOUR_HEART  = 2,
    CARD_COLOUR_DIMOND = 3
};

struct CardSpec {
    unsigned value;
    CardColour colour;
};

struct CardColourSpec {
    const char *name;
};

CardSpec GetCardSpec(CardID card_id);
/* lub */
CardSpec *GetCardSpec(CardID card_id);

CardColourSpec GetCardColourSpec(CardColour colour);
/* lub */
CardColourSpec *GetCardColourSpec(CardColour colour);

1 użytkowników online, w tym zalogowanych: 0, gości: 1