wtorek, 23 sierpnia 2022

C - Algorym dla gry Dobble

W tym poście chciałbym opisać zasadę działania argumentu do przygotowania kart do gry w Dobble. 


Aby można było przygotować grę Dobble należy pamiętać o kilku podstawowych zasadach dotyczących tworzenia kart:

  • na każdej karcie musi się znaleźć zestaw unikatowych symboli;
  • każde dwie karty muszą posiadać jeden pasujący do siebie symbol;

Gra składa się z 55 kart. Przestrzegając wszystkich zasad dotyczących gry Dobble może powstać 57 kart. Więc dwie karty zostały usunięte z talii. Może to wynikać ze specyfiki niektórych rodzajów rozgrywek opisanych w instrukcji do gry, gdzie 55 kart sprawdza się lepiej niż 57. Oprócz podstawowego wariantu w sprzedaży jest także wersja tej gry dla dzieci, która oprócz bardziej kontrastujących rysunków posiada też zmniejszoną liczbę symboli (6 symboli na kartach, 30 kart. Maksymalnie można przygotować 31 kart).

Wzór na liczbę kart w zależności od symboli jest następujący [link]:

  1. k=n^2-n+1
  2.  
  3. Gdzie:
  4. n - ilość symboli na kartach

Posłużę się tutaj przykładem w języku Python jaki udało mi się znaleźć w Internecie pod tym linkiem.

Całość wygląda następująco:

  1. #The Dobble Algorithm - www.101computing.net/the-dobble-algorithm/
  2. from random import shuffle
  3.  
  4. #List of symbols used in the game Dobble (Spot It! in the US)
  5. symbols = ["Anchor","Apple","Bomb","Cactus","Candle","Carrot",
  6.   "Cheese","Chess knight","Clock","Clown","Diasy flower","Dinosaur",
  7.   "Dolphin","Dragon","Exclamation mark","Eye","Fire","Four leaf clover",
  8.   "Ghost","Green splats","Hammer","Heart","Ice cube","Igloo","Key",
  9.   "Ladybird","Light bulb","Lightning bolt","Lock","Maple leaf","Milk bottle",
  10.   "Moon","No Entry sign","Orange scarecrow man","Pencil","Purple bird",
  11.   "Purple cat","Purple dobble sign","Question Mark","Red lips","Scissors",
  12.   "Skull and crossbones","Snowflake","Snowman","Spider","Spider’s web",
  13.   "Sun","Sunglasses","Target","Taxi","Tortoise","Treble clef","Tree",
  14.   "Water drop","Dog","Yin and Yang","Zebra"]
  15.  
  16. #The number of symbols on a card has to be a prime number + 1
  17. numberOfSymbolsOnCard = 8   #(7 + 1)
  18. shuffleSymbolsOnCard = False
  19.  
  20. cards = []
  21.  
  22. #Work out the prime number
  23. n = numberOfSymbolsOnCard - 1
  24.  
  25. #Total number of cards that can be generated following the Dobble rules
  26. numberOfCards = n**2 + n + 1  #e.g. 7^2 + 7 + 1 = 57
  27.  
  28.  
  29. #Add first set of n+1 cards (e.g. 8 cards)
  30. for i in range(n+1):  
  31.   #Add new card with first symbol
  32.   cards.append([1])
  33.   #Add n+1 symbols on the card (e.g. 8 symbols)
  34.   for j in range(n):
  35.     cards[i].append((j+1)+(i*n)+1)
  36.  
  37. #Add n sets of n cards
  38. for i in range(0,n):
  39.   for j in range(0,n):
  40.     #Append a new card with 1 symbol
  41.     cards.append([i+2])
  42.      #Add n symbols on the card (e.g. 7 symbols)
  43.     for k in range(0,n):
  44.       val  = (n+1 + n*k + (i*k+j)%n)+1
  45.       cards[len(cards)-1].append(val)
  46.  
  47. #Shuffle symbols on each card
  48. if shuffleSymbolsOnCard :
  49.   for card in cards:
  50.     shuffle(card)
  51.      
  52. #Output all cards  
  53. i = 0
  54. for card in cards:
  55.   i+=1
  56.   line = str(i) + " - ["
  57.   for number in card:
  58.     line = line + symbols[number-1] + ", "
  59.   line = line[:-2] + "]"  
  60.   print(line)

W tablicy znajduje się 57 unikatowych postaci. Każda karta będzie zawierała 8 postaci. Zgodnie ze zmienną numberOfSymbolsOnCard. Maksymalna ilość kart jaka może zostać przygotowana dla tej ilości symboli jest zdeklarowana w zmiennej numberOfCards (7^2 + 7 + 1 = 57). Gdy symboli na karcie miało by być 6, wtedy potrzebne by było 31 osobnych symboli oraz 31 kart.

Po deklaracji podstawowych zmiennych program jest podzielony na kilka części. Pierwsza z nich przygotowuje pierwsze 8 kart. Pierwszym symbolem jest pierwsza pozycja z tablicy dla wszystkich 8 kart. Następnie zostaje ona uzupełniona o pozostałe elementy ze zdeklarowanej tablicy z symbolami, tak aby wspólnym symbolem pomiędzy kartami była tylko pierwsza pozycja.  

Do tablicy wprowadzane są wartości numeryczne następnie na ich podstawie pobierane są wartości dotyczące nazwy symbolu.

Więc po pierwszym przejściu wynik działania programu jest następujący:

  1. 1 - [Anchor, Apple, Bomb, Cactus, Candle, Carrot, Cheese, Chess knight]
  2. 2 - [Anchor, Clock, Clown, Diasy flower, Dinosaur, Dolphin, Dragon, Exclamation mark]
  3. 3 - [Anchor, Eye, Fire, Four leaf clover, Ghost, Green splats, Hammer, Heart]
  4. 4 - [Anchor, Ice cube, Igloo, Key, Ladybird, Light bulb, Lightning bolt, Lock]
  5. 5 - [Anchor, Maple leaf, Milk bottle, Moon, No Entry sign, Orange scarecrow man, Pencil, Purple bird]
  6. 6 - [Anchor, Purple cat, Purple dobble sign, Question Mark, Red lips, Scissors, Skull and crossbones, Snowflake]
  7. 7 - [Anchor, Snowman, Spider, Spider’s web, Sun, Sunglasses, Target, Taxi]
  8. 8 - [Anchor, Tortoise, Treble clef, Tree, Water drop, Dog, Yin and Yang, Zebra]

Wynik działania powyższego programu jest następujący:

  1. 1 - [Anchor, Apple, Bomb, Cactus, Candle, Carrot, Cheese, Chess knight]
  2. 2 - [Anchor, Clock, Clown, Diasy flower, Dinosaur, Dolphin, Dragon, Exclamation mark]
  3. 3 - [Anchor, Eye, Fire, Four leaf clover, Ghost, Green splats, Hammer, Heart]
  4. 4 - [Anchor, Ice cube, Igloo, Key, Ladybird, Light bulb, Lightning bolt, Lock]
  5. 5 - [Anchor, Maple leaf, Milk bottle, Moon, No Entry sign, Orange scarecrow man, Pencil, Purple bird]
  6. 6 - [Anchor, Purple cat, Purple dobble sign, Question Mark, Red lips, Scissors, Skull and crossbones, Snowflake]
  7. 7 - [Anchor, Snowman, Spider, Spider’s web, Sun, Sunglasses, Target, Taxi]
  8. 8 - [Anchor, Tortoise, Treble clef, Tree, Water drop, Dog, Yin and Yang, Zebra]
  9. 9 - [Apple, Clock, Eye, Ice cube, Maple leaf, Purple cat, Snowman, Tortoise]
  10. 10 - [Apple, Clown, Fire, Igloo, Milk bottle, Purple dobble sign, Spider, Treble clef]
  11. 11 - [Apple, Diasy flower, Four leaf clover, Key, Moon, Question Mark, Spider’s web, Tree]
  12. 12 - [Apple, Dinosaur, Ghost, Ladybird, No Entry sign, Red lips, Sun, Water drop]
  13. 13 - [Apple, Dolphin, Green splats, Light bulb, Orange scarecrow man, Scissors, Sunglasses, Dog]
  14. 14 - [Apple, Dragon, Hammer, Lightning bolt, Pencil, Skull and crossbones, Target, Yin and Yang]
  15. 15 - [Apple, Exclamation mark, Heart, Lock, Purple bird, Snowflake, Taxi, Zebra]
  16. 16 - [Bomb, Clock, Fire, Key, No Entry sign, Scissors, Target, Zebra]
  17. 17 - [Bomb, Clown, Four leaf clover, Ladybird, Orange scarecrow man, Skull and crossbones, Taxi, Tortoise]
  18. 18 - [Bomb, Diasy flower, Ghost, Light bulb, Pencil, Snowflake, Snowman, Treble clef]
  19. 19 - [Bomb, Dinosaur, Green splats, Lightning bolt, Purple bird, Purple cat, Spider, Tree]
  20. 20 - [Bomb, Dolphin, Hammer, Lock, Maple leaf, Purple dobble sign, Spider’s web, Water drop]
  21. 21 - [Bomb, Dragon, Heart, Ice cube, Milk bottle, Question Mark, Sun, Dog]
  22. 22 - [Bomb, Exclamation mark, Eye, Igloo, Moon, Red lips, Sunglasses, Yin and Yang]
  23. 23 - [Cactus, Clock, Four leaf clover, Light bulb, Purple bird, Purple dobble sign, Sun, Yin and Yang]
  24. 24 - [Cactus, Clown, Ghost, Lightning bolt, Maple leaf, Question Mark, Sunglasses, Zebra]
  25. 25 - [Cactus, Diasy flower, Green splats, Lock, Milk bottle, Red lips, Target, Tortoise]
  26. 26 - [Cactus, Dinosaur, Hammer, Ice cube, Moon, Scissors, Taxi, Treble clef]
  27. 27 - [Cactus, Dolphin, Heart, Igloo, No Entry sign, Skull and crossbones, Snowman, Tree]
  28. 28 - [Cactus, Dragon, Eye, Key, Orange scarecrow man, Snowflake, Spider, Water drop]
  29. 29 - [Cactus, Exclamation mark, Fire, Ladybird, Pencil, Purple cat, Spider’s web, Dog]
  30. 30 - [Candle, Clock, Ghost, Lock, Moon, Skull and crossbones, Spider, Dog]
  31. 31 - [Candle, Clown, Green splats, Ice cube, No Entry sign, Snowflake, Spider’s web, Yin and Yang]
  32. 32 - [Candle, Diasy flower, Hammer, Igloo, Orange scarecrow man, Purple cat, Sun, Zebra]
  33. 33 - [Candle, Dinosaur, Heart, Key, Pencil, Purple dobble sign, Sunglasses, Tortoise]
  34. 34 - [Candle, Dolphin, Eye, Ladybird, Purple bird, Question Mark, Target, Treble clef]
  35. 35 - [Candle, Dragon, Fire, Light bulb, Maple leaf, Red lips, Taxi, Tree]
  36. 36 - [Candle, Exclamation mark, Four leaf clover, Lightning bolt, Milk bottle, Scissors, Snowman, Water drop]
  37. 37 - [Carrot, Clock, Green splats, Igloo, Pencil, Question Mark, Taxi, Water drop]
  38. 38 - [Carrot, Clown, Hammer, Key, Purple bird, Red lips, Snowman, Dog]
  39. 39 - [Carrot, Diasy flower, Heart, Ladybird, Maple leaf, Scissors, Spider, Yin and Yang]
  40. 40 - [Carrot, Dinosaur, Eye, Light bulb, Milk bottle, Skull and crossbones, Spider’s web, Zebra]
  41. 41 - [Carrot, Dolphin, Fire, Lightning bolt, Moon, Snowflake, Sun, Tortoise]
  42. 42 - [Carrot, Dragon, Four leaf clover, Lock, No Entry sign, Purple cat, Sunglasses, Treble clef]
  43. 43 - [Carrot, Exclamation mark, Ghost, Ice cube, Orange scarecrow man, Purple dobble sign, Target, Tree]
  44. 44 - [Cheese, Clock, Hammer, Ladybird, Milk bottle, Snowflake, Sunglasses, Tree]
  45. 45 - [Cheese, Clown, Heart, Light bulb, Moon, Purple cat, Target, Water drop]
  46. 46 - [Cheese, Diasy flower, Eye, Lightning bolt, No Entry sign, Purple dobble sign, Taxi, Dog]
  47. 47 - [Cheese, Dinosaur, Fire, Lock, Orange scarecrow man, Question Mark, Snowman, Yin and Yang]
  48. 48 - [Cheese, Dolphin, Four leaf clover, Ice cube, Pencil, Red lips, Spider, Zebra]
  49. 49 - [Cheese, Dragon, Ghost, Igloo, Purple bird, Scissors, Spider’s web, Tortoise]
  50. 50 - [Cheese, Exclamation mark, Green splats, Key, Maple leaf, Skull and crossbones, Sun, Treble clef]
  51. 51 - [Chess knight, Clock, Heart, Lightning bolt, Orange scarecrow man, Red lips, Spider’s web, Treble clef]
  52. 52 - [Chess knight, Clown, Eye, Lock, Pencil, Scissors, Sun, Tree]
  53. 53 - [Chess knight, Diasy flower, Fire, Ice cube, Purple bird, Skull and crossbones, Sunglasses, Water drop]
  54. 54 - [Chess knight, Dinosaur, Four leaf clover, Igloo, Maple leaf, Snowflake, Target, Dog]
  55. 55 - [Chess knight, Dolphin, Ghost, Key, Milk bottle, Purple cat, Taxi, Yin and Yang]
  56. 56 - [Chess knight, Dragon, Green splats, Ladybird, Moon, Purple dobble sign, Snowman, Zebra]
  57. 57 - [Chess knight, Exclamation mark, Hammer, Light bulb, No Entry sign, Question Mark, Spider, Tortoise]

Teraz chciałbym przenieść powyższy przykład do języka C, z dodaniem kilku elementów.

Program zamieszczony powyżej w języku Python nie posiada weryfikacji prowadzonych operacji, więc należałoby taką dodać. Głównie po to aby mieć pewność, że każda z przygotowanych kart jest poprawna. Zwłaszcza podczas tworzenia algorytmu.

Poniżej znajduje się cały program w języku C:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4.  
  5. //#define SHUFFLE_SYMBOLS_ON_CARD
  6. #define CHECK_IF_DATA_VALID
  7. #define CHECK_IF_UNIQUE_SYMBOL_ON_CARDS
  8. #define DISPLAY_OUTPUT_NUMERIC_DATA
  9. #define DISPLAY_OUTPUT_TXT_DATA
  10.  
  11. #define NUMBER_SYMBOLS_ON_CARD 8
  12. #define PRIME_NUMBER (NUMBER_SYMBOLS_ON_CARD - 1)
  13. #define NUMBER_OF_CARDS_TO_GENERATE ((PRIME_NUMBER * PRIME_NUMBER) + PRIME_NUMBER + 1)
  14. #define MAX_STRING_SIZE 24
  15.  
  16. char symbols_array[][MAX_STRING_SIZE] = {
  17.   "Anchor", "Apple", "Bomb", "Cactus", "Candle",                           
  18.   "Carrot", "Cheese", "Chess knight", "Clock", "Clown",                    
  19.   "Diasy flower","Dinosaur", "Dolphin", "Dragon", "Exclamation mark",      
  20.   "Eye", "Fire", "Four leaf clover", "Ghost", "Green splats",
  21.   "Hammer", "Heart", "Ice cube", "Igloo", "Key",
  22.   "Ladybird", "Light bulb", "Lightning bolt", "Lock", "Maple leaf",
  23.   "Milk bottle", "Moon", "No Entry sign", "Orange scarecrow man", "Pencil",
  24.   "Purple bird", "Purple cat", "Purple dobble sign", "Question Mark", "Red lips",
  25.   "Scissors", "Skull and crossbones", "Snowflake", "Snowman", "Spider",
  26.   "Spider’s web", "Sun", "Sunglasses", "Target", "Taxi",
  27.   "Tortoise", "Treble clef", "Tree", "Water drop", "Dog",
  28.   "Yin and Yang", "Zebra"
  29. };
  30.  
  31. //Tablica będzie przechowywała tylko wartości numeryczne odpowiadające pozycji
  32. //nazwy podanego obrazu z tablicy symbols_array
  33. uint8_t cards[NUMBER_OF_CARDS_TO_GENERATE][NUMBER_SYMBOLS_ON_CARD];
  34.  
  35. int main(void)
  36. {
  37.     uint8_t cards_tmp[NUMBER_OF_CARDS_TO_GENERATE * NUMBER_SYMBOLS_ON_CARD] = { 0x00 };
  38.     uint16_t pos_in_tmp_buffer = 0;
  39.  
  40.     printf("\r\n#######################################################\r\n\r\n");
  41.     printf("Liczba symboli na karcie - %d\r\n", NUMBER_SYMBOLS_ON_CARD);
  42.     printf("Liczba kart do wygenerowania - %d\r\n", NUMBER_OF_CARDS_TO_GENERATE);
  43.     printf("Prime number - %d\r\n", PRIME_NUMBER);
  44.     printf("\r\n#######################################################\r\n\r\n");
  45.  
  46.     //Przygotowanie pierwszych kart
  47.     for (uint8_t i = 0; i < (PRIME_NUMBER + 1); i++)
  48.     {
  49.         cards[i][0] = 1;
  50.         for (uint8_t j = 1; j < (NUMBER_SYMBOLS_ON_CARD); j++)
  51.         {
  52.             cards[i][j] = ((j) + (i*PRIME_NUMBER) + 1);
  53.         }
  54.     }
  55.  
  56.     //Przygotowanie reszty kart
  57.     for (uint8_t i = 0; i < PRIME_NUMBER; i++) {
  58.         for (uint8_t j = 0; j < PRIME_NUMBER; j++) {
  59.             cards_tmp[pos_in_tmp_buffer++] = i + 2;
  60.             for (uint8_t k = 0; k < PRIME_NUMBER; k++) {
  61.                 cards_tmp[pos_in_tmp_buffer++] = (PRIME_NUMBER + 1 + PRIME_NUMBER * k + (i*k + j) % PRIME_NUMBER) + 1;
  62.             }
  63.         }
  64.     }
  65.  
  66.     //Przepisanie kart z bufora tymczasowego do bufora głównego:
  67.     for (uint16_t i = NUMBER_SYMBOLS_ON_CARD; i < NUMBER_OF_CARDS_TO_GENERATE; i++) {
  68.         for (uint8_t j = 0; j < NUMBER_SYMBOLS_ON_CARD; j++) {
  69.             cards[i][j] = cards_tmp[((i - NUMBER_SYMBOLS_ON_CARD) * NUMBER_SYMBOLS_ON_CARD) + j];
  70.         }
  71.     }
  72.  
  73.  
  74.     #ifdef SHUFFLE_SYMBOLS_ON_CARD
  75.     uint8_t shuffle_tmp_array = 0;
  76.  
  77.     for (uint8_t cardNumber = 0; cardNumber < NUMBER_OF_CARDS_TO_GENERATE; cardNumber++)
  78.     {
  79.         for (uint8_t i = 0; i < NUMBER_SYMBOLS_ON_CARD; i++)
  80.         {
  81.             uint8_t j = i + rand() / (RAND_MAX / (NUMBER_SYMBOLS_ON_CARD - i) + 1);
  82.             uint8_t t = cards[cardNumber][j];
  83.             cards[cardNumber][j] = cards[cardNumber][i];
  84.             cards[cardNumber][i] = t;
  85.         }
  86.     }
  87.     #endif
  88.  
  89.     #ifdef CHECK_IF_UNIQUE_SYMBOL_ON_CARDS
  90.     for (uint8_t cardNumber = 0; (cardNumber < (NUMBER_OF_CARDS_TO_GENERATE)); cardNumber++) {
  91.         for (int i = 0; i < NUMBER_SYMBOLS_ON_CARD - 1; i++) {
  92.             for (int j = i + 1; j < NUMBER_SYMBOLS_ON_CARD; j++) {
  93.                 if (cards[cardNumber][i] == cards[cardNumber][j]) {
  94.                     printf("\r\n#######################################################\r\n\r\n");
  95.                     printf("ERROR Ten sam symbol na karcie %d co %d\r\n", cardNumber, cardNumber);
  96.                     printf("\r\n#######################################################\r\n\r\n");
  97.                     return 0;
  98.                 }
  99.             }
  100.         }
  101.     }
  102.     printf("## Kazda karta zawiera unikalne symbole\r\n\r\n");
  103.     #endif
  104.  
  105.     #ifdef CHECK_IF_DATA_VALID
  106.     //Sprawdzenie poprawności
  107.     uint8_t match_card_status = 0;
  108.     for (uint8_t cardNumber = 0; (cardNumber < (NUMBER_OF_CARDS_TO_GENERATE - 1)); cardNumber++)
  109.     {
  110.         for (uint8_t cardNumber_Second = cardNumber + 1; cardNumber_Second < NUMBER_OF_CARDS_TO_GENERATE; cardNumber_Second++)
  111.         {
  112.             for (uint8_t symbolNumber_1 = 0; symbolNumber_1 < NUMBER_SYMBOLS_ON_CARD; symbolNumber_1++)
  113.             {
  114.                 for (uint8_t symbolNumber_2 = 0; symbolNumber_2 < NUMBER_SYMBOLS_ON_CARD; symbolNumber_2++)
  115.                 {
  116.                     if (cards[cardNumber][symbolNumber_1] == cards[cardNumber_Second][symbolNumber_2])
  117.                     {
  118.                         if (match_card_status == 1) {
  119.                             printf("ERROR karta %d symbol %d z %d %d !!!!\r\n", cardNumber, symbolNumber_1, cardNumber_Second, symbolNumber_2);
  120.                         }
  121.                         match_card_status = 1;
  122.                     }
  123.                 }
  124.             }
  125.             if (match_card_status == 0) {
  126.                 printf("ERROR brak dopasowania symbolu pomiedzy kartami %d z %d!!!!\r\n", cardNumber, cardNumber_Second);
  127.             }
  128.             match_card_status = 0;
  129.         }
  130.     }
  131.     #endif
  132.  
  133.     #ifdef DISPLAY_OUTPUT_NUMERIC_DATA
  134.     //Wyświetlenie wartości numerycznej
  135.     for (uint8_t cardNumber = 0; cardNumber < NUMBER_OF_CARDS_TO_GENERATE; cardNumber++)
  136.     {
  137.         printf("Karta %.2u - ", (cardNumber + 1));
  138.         for (uint8_t symbolNumber = 0; symbolNumber < NUMBER_SYMBOLS_ON_CARD; symbolNumber++)
  139.         {
  140.             printf("%.2u, ", cards[cardNumber][symbolNumber]);
  141.         }
  142.         printf("\r\n");
  143.     }
  144.     #endif
  145.  
  146.     #ifdef DISPLAY_OUTPUT_TXT_DATA
  147.     printf("\r\n#######################################################\r\n\r\n");
  148.     //Wyświetlenie znaku przypisanego do wartości
  149.     for (uint8_t cardNumber = 0; cardNumber < NUMBER_OF_CARDS_TO_GENERATE; cardNumber++)
  150.     {
  151.         printf("Karta %.2u - ", (cardNumber + 1));
  152.         for (uint8_t symbolNumber = 0; symbolNumber < NUMBER_SYMBOLS_ON_CARD; symbolNumber++)
  153.         {
  154.             printf("%s, ", symbols_array[cards[cardNumber][symbolNumber] - 1]);
  155.         }
  156.         printf("\r\n");
  157.     }
  158.     #endif
  159.  
  160.     return 0;
  161. }

Program działa poprawnie dla przygotowania kart składających się z 2, 3, 4, 5, 6, 7, 8, 12, 14 symboli. W tablicy znajdują się 57 symboli. Więc do 8 kart można skorzystać z nazw symboli. Przy większej ilości kart należy albo odpuścić wartości tekstowe albo dołożyć brakujące symbole. W przypadku wykonywania tekstów dla większej ilości symboli na karcie należy pamiętać o konieczności zmiany typu uint8 na uint16, ponieważ może nastąpić ich przepełnienie.

Pierwsza pętla przygotowuje pierwszy zestaw kart:

  1. for (uint8_t i = 0; i < (PRIME_NUMBER + 1); i++) {
  2.     cards[i][0] = 1;
  3.     for (uint8_t j = 1; j < (NUMBER_SYMBOLS_ON_CARD); j++) {
  4.         cards[i][j] = ((j + 1) + (i*PRIME_NUMBER) + 1);
  5.     }
  6. }

Następna pętla przygotowuje pozostałe karty:

  1. for (uint8_t i = 0; i < PRIME_NUMBER; i++) {
  2.     for (uint8_t j = 0; j < PRIME_NUMBER; j++) {
  3.         cards_tmp[pos_in_tmp_buffer++] = i + 2;
  4.         for (uint8_t k = 0; k < PRIME_NUMBER; k++) {
  5.             cards_tmp[pos_in_tmp_buffer++] = (PRIME_NUMBER + 1 + PRIME_NUMBER * k + (i*k + j) % PRIME_NUMBER) + 1;
  6.         }
  7.     }
  8. }

Karty znajdują się teraz w buforze tymczasowym dlatego muszę je teraz przenieść do bufora głównego:

  1. for (uint16_t i = NUMBER_SYMBOLS_ON_CARD; i < NUMBER_OF_CARDS_TO_GENERATE; i++) {
  2.     for (uint8_t j = 0; j < NUMBER_SYMBOLS_ON_CARD; j++) {
  3.         cards[i][j] = cards_tmp[((i - NUMBER_SYMBOLS_ON_CARD) * NUMBER_SYMBOLS_ON_CARD) + j];
  4.     }
  5. }

Opcjonalnym elementem jest mieszanie symboli na karcie. Tutaj wykorzystałem generowanie liczy losowej z zadanego przedziału:

  1. #ifdef SHUFFLE_SYMBOLS_ON_CARD
  2. uint8_t shuffle_tmp_array = 0;
  3.  
  4. for (uint8_t cardNumber = 0; cardNumber < NUMBER_OF_CARDS_TO_GENERATE; cardNumber++)
  5. {
  6.     for (uint8_t i = 0; i < NUMBER_SYMBOLS_ON_CARD; i++)
  7.     {
  8.         uint8_t j = i + rand() / (RAND_MAX / (NUMBER_SYMBOLS_ON_CARD - i) + 1);
  9.         int t = cards[cardNumber][j];
  10.         cards[cardNumber][j] = cards[cardNumber][i];
  11.         cards[cardNumber][i] = t;
  12.     }
  13. }
  14. #endif

Dosyć istotnym elementem jest sprawdzenie czy karty spełniają zadane warunki:

Czy na karcie znajdują się unikatowe symbole:

  1. #ifdef CHECK_IF_UNIQUE_SYMBOL_ON_CARDS
  2. for (uint8_t cardNumber = 0; (cardNumber < (NUMBER_OF_CARDS_TO_GENERATE)); cardNumber++) {
  3.     for (int i = 0; i < NUMBER_SYMBOLS_ON_CARD - 1; i++) {
  4.         for (int j = i + 1; j < NUMBER_SYMBOLS_ON_CARD; j++) {
  5.             if (cards[cardNumber][i] == cards[cardNumber][j]) {
  6.                 printf("\r\n#######################################################\r\n\r\n");
  7.                 printf("ERROR Ten sam symbol na karcie %d co %d\r\n", cardNumber, cardNumber);
  8.                 printf("\r\n#######################################################\r\n\r\n");
  9.                 return 0;
  10.             }
  11.         }
  12.     }
  13. }
  14. printf("## Kazda karta zawiera unikalne symbole\r\n\r\n");
  15. #endif

Czy tylko jeden symbol z karty pasuje z każdą inną kartą z przedziału:

  1. #ifdef CHECK_IF_DATA_VALID
  2. //Sprawdzenie poprawności
  3. uint8_t match_card_status = 0;
  4. for (uint8_t cardNumber = 0, cardNumber_Second = 1; (cardNumber < (NUMBER_OF_CARDS_TO_GENERATE - 1)); cardNumber++)
  5. {
  6.     for (uint8_t cardNumber_Second = cardNumber + 1; cardNumber_Second < NUMBER_OF_CARDS_TO_GENERATE; cardNumber_Second++)
  7.     {
  8.         for (uint8_t symbolNumber_1 = 0; symbolNumber_1 < NUMBER_SYMBOLS_ON_CARD; symbolNumber_1++)
  9.         {
  10.             for (uint8_t symbolNumber_2 = 0; symbolNumber_2 < NUMBER_SYMBOLS_ON_CARD; symbolNumber_2++)
  11.             {
  12.                 if (cards[cardNumber][symbolNumber_1] == cards[cardNumber_Second][symbolNumber_2])
  13.                 {
  14.                     if (match_card_status == 1) {
  15.                         printf("ERROR karta %d symbol %d z %d %d !!!!\r\n", cardNumber, symbolNumber_1, cardNumber_Second, symbolNumber_2);
  16.                     }
  17.                     match_card_status = 1;
  18.                 }
  19.             }
  20.         }
  21.         if (match_card_status == 0) {
  22.             printf("ERROR brak dopasowania symbolu pomiedzy kartami %d z %d!!!!\r\n", cardNumber, cardNumber_Second);
  23.         }
  24.         match_card_status = 0;
  25.     }
  26. }
  27. #endif

Na samym końcu wyświetlany jest wynik operacji w wartości numerycznej oraz tekstowej.

Wynik działania programu jest następujący:

  1. #######################################################
  2.  
  3. Liczba symboli na karcie - 8
  4. Liczba kart do wygenerowania - 57
  5. Prime number - 7
  6.  
  7. #######################################################
  8.  
  9. ## Kazda karta zawiera unikalne symbole
  10.  
  11. Karta 01 - 01, 02, 03, 04, 05, 06, 07, 08,
  12. Karta 02 - 01, 09, 10, 11, 12, 13, 14, 15,
  13. Karta 03 - 01, 16, 17, 18, 19, 20, 21, 22,
  14. Karta 04 - 01, 23, 24, 25, 26, 27, 28, 29,
  15. Karta 05 - 01, 30, 31, 32, 33, 34, 35, 36,
  16. Karta 06 - 01, 37, 38, 39, 40, 41, 42, 43,
  17. Karta 07 - 01, 44, 45, 46, 47, 48, 49, 50,
  18. Karta 08 - 01, 51, 52, 53, 54, 55, 56, 57,
  19. Karta 09 - 02, 09, 16, 23, 30, 37, 44, 51,
  20. Karta 10 - 02, 10, 17, 24, 31, 38, 45, 52,
  21. Karta 11 - 02, 11, 18, 25, 32, 39, 46, 53,
  22. Karta 12 - 02, 12, 19, 26, 33, 40, 47, 54,
  23. Karta 13 - 02, 13, 20, 27, 34, 41, 48, 55,
  24. Karta 14 - 02, 14, 21, 28, 35, 42, 49, 56,
  25. Karta 15 - 02, 15, 22, 29, 36, 43, 50, 57,
  26. Karta 16 - 03, 09, 17, 25, 33, 41, 49, 57,
  27. Karta 17 - 03, 10, 18, 26, 34, 42, 50, 51,
  28. Karta 18 - 03, 11, 19, 27, 35, 43, 44, 52,
  29. Karta 19 - 03, 12, 20, 28, 36, 37, 45, 53,
  30. Karta 20 - 03, 13, 21, 29, 30, 38, 46, 54,
  31. Karta 21 - 03, 14, 22, 23, 31, 39, 47, 55,
  32. Karta 22 - 03, 15, 16, 24, 32, 40, 48, 56,
  33. Karta 23 - 04, 09, 18, 27, 36, 38, 47, 56,
  34. Karta 24 - 04, 10, 19, 28, 30, 39, 48, 57,
  35. Karta 25 - 04, 11, 20, 29, 31, 40, 49, 51,
  36. Karta 26 - 04, 12, 21, 23, 32, 41, 50, 52,
  37. Karta 27 - 04, 13, 22, 24, 33, 42, 44, 53,
  38. Karta 28 - 04, 14, 16, 25, 34, 43, 45, 54,
  39. Karta 29 - 04, 15, 17, 26, 35, 37, 46, 55,
  40. Karta 30 - 05, 09, 19, 29, 32, 42, 45, 55,
  41. Karta 31 - 05, 10, 20, 23, 33, 43, 46, 56,
  42. Karta 32 - 05, 11, 21, 24, 34, 37, 47, 57,
  43. Karta 33 - 05, 12, 22, 25, 35, 38, 48, 51,
  44. Karta 34 - 05, 13, 16, 26, 36, 39, 49, 52,
  45. Karta 35 - 05, 14, 17, 27, 30, 40, 50, 53,
  46. Karta 36 - 05, 15, 18, 28, 31, 41, 44, 54,
  47. Karta 37 - 06, 09, 20, 24, 35, 39, 50, 54,
  48. Karta 38 - 06, 10, 21, 25, 36, 40, 44, 55,
  49. Karta 39 - 06, 11, 22, 26, 30, 41, 45, 56,
  50. Karta 40 - 06, 12, 16, 27, 31, 42, 46, 57,
  51. Karta 41 - 06, 13, 17, 28, 32, 43, 47, 51,
  52. Karta 42 - 06, 14, 18, 29, 33, 37, 48, 52,
  53. Karta 43 - 06, 15, 19, 23, 34, 38, 49, 53,
  54. Karta 44 - 07, 09, 21, 26, 31, 43, 48, 53,
  55. Karta 45 - 07, 10, 22, 27, 32, 37, 49, 54,
  56. Karta 46 - 07, 11, 16, 28, 33, 38, 50, 55,
  57. Karta 47 - 07, 12, 17, 29, 34, 39, 44, 56,
  58. Karta 48 - 07, 13, 18, 23, 35, 40, 45, 57,
  59. Karta 49 - 07, 14, 19, 24, 36, 41, 46, 51,
  60. Karta 50 - 07, 15, 20, 25, 30, 42, 47, 52,
  61. Karta 51 - 08, 09, 22, 28, 34, 40, 46, 52,
  62. Karta 52 - 08, 10, 16, 29, 35, 41, 47, 53,
  63. Karta 53 - 08, 11, 17, 23, 36, 42, 48, 54,
  64. Karta 54 - 08, 12, 18, 24, 30, 43, 49, 55,
  65. Karta 55 - 08, 13, 19, 25, 31, 37, 50, 56,
  66. Karta 56 - 08, 14, 20, 26, 32, 38, 44, 57,
  67. Karta 57 - 08, 15, 21, 27, 33, 39, 45, 51,
  68.  
  69. #######################################################
  70.  
  71. Karta 01 - Anchor, Apple, Bomb, Cactus, Candle, Carrot, Cheese, Chess knight,
  72. Karta 02 - Anchor, Clock, Clown, Diasy flower, Dinosaur, Dolphin, Dragon, Exclamation mark,
  73. Karta 03 - Anchor, Eye, Fire, Four leaf clover, Ghost, Green splats, Hammer, Heart,
  74. Karta 04 - Anchor, Ice cube, Igloo, Key, Ladybird, Light bulb, Lightning bolt, Lock,
  75. Karta 05 - Anchor, Maple leaf, Milk bottle, Moon, No Entry sign, Orange scarecrow man, Pencil, Purple bird,
  76. Karta 06 - Anchor, Purple cat, Purple dobble sign, Question Mark, Red lips, Scissors, Skull and crossbones, Snowflake,
  77. Karta 07 - Anchor, Snowman, Spider, Spiderĺs web, Sun, Sunglasses, Target, Taxi,
  78. Karta 08 - Anchor, Tortoise, Treble clef, Tree, Water drop, Dog, Yin and Yang, Zebra,
  79. Karta 09 - Apple, Clock, Eye, Ice cube, Maple leaf, Purple cat, Snowman, Tortoise,
  80. Karta 10 - Apple, Clown, Fire, Igloo, Milk bottle, Purple dobble sign, Spider, Treble clef,
  81. Karta 11 - Apple, Diasy flower, Four leaf clover, Key, Moon, Question Mark, Spiderĺs web, Tree,
  82. Karta 12 - Apple, Dinosaur, Ghost, Ladybird, No Entry sign, Red lips, Sun, Water drop,
  83. Karta 13 - Apple, Dolphin, Green splats, Light bulb, Orange scarecrow man, Scissors, Sunglasses, Dog,
  84. Karta 14 - Apple, Dragon, Hammer, Lightning bolt, Pencil, Skull and crossbones, Target, Yin and Yang,
  85. Karta 15 - Apple, Exclamation mark, Heart, Lock, Purple bird, Snowflake, Taxi, Zebra,
  86. Karta 16 - Bomb, Clock, Fire, Key, No Entry sign, Scissors, Target, Zebra,
  87. Karta 17 - Bomb, Clown, Four leaf clover, Ladybird, Orange scarecrow man, Skull and crossbones, Taxi, Tortoise,
  88. Karta 18 - Bomb, Diasy flower, Ghost, Light bulb, Pencil, Snowflake, Snowman, Treble clef,
  89. Karta 19 - Bomb, Dinosaur, Green splats, Lightning bolt, Purple bird, Purple cat, Spider, Tree,
  90. Karta 20 - Bomb, Dolphin, Hammer, Lock, Maple leaf, Purple dobble sign, Spiderĺs web, Water drop,
  91. Karta 21 - Bomb, Dragon, Heart, Ice cube, Milk bottle, Question Mark, Sun, Dog,
  92. Karta 22 - Bomb, Exclamation mark, Eye, Igloo, Moon, Red lips, Sunglasses, Yin and Yang,
  93. Karta 23 - Cactus, Clock, Four leaf clover, Light bulb, Purple bird, Purple dobble sign, Sun, Yin and Yang,
  94. Karta 24 - Cactus, Clown, Ghost, Lightning bolt, Maple leaf, Question Mark, Sunglasses, Zebra,
  95. Karta 25 - Cactus, Diasy flower, Green splats, Lock, Milk bottle, Red lips, Target, Tortoise,
  96. Karta 26 - Cactus, Dinosaur, Hammer, Ice cube, Moon, Scissors, Taxi, Treble clef,
  97. Karta 27 - Cactus, Dolphin, Heart, Igloo, No Entry sign, Skull and crossbones, Snowman, Tree,
  98. Karta 28 - Cactus, Dragon, Eye, Key, Orange scarecrow man, Snowflake, Spider, Water drop,
  99. Karta 29 - Cactus, Exclamation mark, Fire, Ladybird, Pencil, Purple cat, Spiderĺs web, Dog,
  100. Karta 30 - Candle, Clock, Ghost, Lock, Moon, Skull and crossbones, Spider, Dog,
  101. Karta 31 - Candle, Clown, Green splats, Ice cube, No Entry sign, Snowflake, Spiderĺs web, Yin and Yang,
  102. Karta 32 - Candle, Diasy flower, Hammer, Igloo, Orange scarecrow man, Purple cat, Sun, Zebra,
  103. Karta 33 - Candle, Dinosaur, Heart, Key, Pencil, Purple dobble sign, Sunglasses, Tortoise,
  104. Karta 34 - Candle, Dolphin, Eye, Ladybird, Purple bird, Question Mark, Target, Treble clef,
  105. Karta 35 - Candle, Dragon, Fire, Light bulb, Maple leaf, Red lips, Taxi, Tree,
  106. Karta 36 - Candle, Exclamation mark, Four leaf clover, Lightning bolt, Milk bottle, Scissors, Snowman, Water drop,
  107. Karta 37 - Carrot, Clock, Green splats, Igloo, Pencil, Question Mark, Taxi, Water drop,
  108. Karta 38 - Carrot, Clown, Hammer, Key, Purple bird, Red lips, Snowman, Dog,
  109. Karta 39 - Carrot, Diasy flower, Heart, Ladybird, Maple leaf, Scissors, Spider, Yin and Yang,
  110. Karta 40 - Carrot, Dinosaur, Eye, Light bulb, Milk bottle, Skull and crossbones, Spiderĺs web, Zebra,
  111. Karta 41 - Carrot, Dolphin, Fire, Lightning bolt, Moon, Snowflake, Sun, Tortoise,
  112. Karta 42 - Carrot, Dragon, Four leaf clover, Lock, No Entry sign, Purple cat, Sunglasses, Treble clef,
  113. Karta 43 - Carrot, Exclamation mark, Ghost, Ice cube, Orange scarecrow man, Purple dobble sign, Target, Tree,
  114. Karta 44 - Cheese, Clock, Hammer, Ladybird, Milk bottle, Snowflake, Sunglasses, Tree,
  115. Karta 45 - Cheese, Clown, Heart, Light bulb, Moon, Purple cat, Target, Water drop,
  116. Karta 46 - Cheese, Diasy flower, Eye, Lightning bolt, No Entry sign, Purple dobble sign, Taxi, Dog,
  117. Karta 47 - Cheese, Dinosaur, Fire, Lock, Orange scarecrow man, Question Mark, Snowman, Yin and Yang,
  118. Karta 48 - Cheese, Dolphin, Four leaf clover, Ice cube, Pencil, Red lips, Spider, Zebra,
  119. Karta 49 - Cheese, Dragon, Ghost, Igloo, Purple bird, Scissors, Spiderĺs web, Tortoise,
  120. Karta 50 - Cheese, Exclamation mark, Green splats, Key, Maple leaf, Skull and crossbones, Sun, Treble clef,
  121. Karta 51 - Chess knight, Clock, Heart, Lightning bolt, Orange scarecrow man, Red lips, Spiderĺs web, Treble clef,
  122. Karta 52 - Chess knight, Clown, Eye, Lock, Pencil, Scissors, Sun, Tree,
  123. Karta 53 - Chess knight, Diasy flower, Fire, Ice cube, Purple bird, Skull and crossbones, Sunglasses, Water drop,
  124. Karta 54 - Chess knight, Dinosaur, Four leaf clover, Igloo, Maple leaf, Snowflake, Target, Dog,
  125. Karta 55 - Chess knight, Dolphin, Ghost, Key, Milk bottle, Purple cat, Taxi, Yin and Yang,
  126. Karta 56 - Chess knight, Dragon, Green splats, Ladybird, Moon, Purple dobble sign, Snowman, Zebra,
  127. Karta 57 - Chess knight, Exclamation mark, Hammer, Light bulb, No Entry sign, Question Mark, Spider, Tortoise,

Wyświetlone są wartości numeryczne oraz ich odpowiedniki jako symbole zdefiniowane w tablicy.

Takie sprawdzenie będę wykonywał przez przejście przez wszystkie elementy