Выбрать 10 случайных неповторяющихся карт из колоды - C (СИ)
Формулировка задачи:
Добрый день, подскажите пожалуйста, где ошибка: у меня колода из 52 карт, где value - это числа от 1 до 13, suit - ч, б, к , п ( черви, буби, крести, пики)
я хочу выбрать 10 неповторяющихся карт, но не всегда они выходят правильно, что-то неверное в else -if
спасибо!
struct card{
int value;
char suit;
};
struct board{
struct card deck[52];
}; for(i=0; i<10; i++){
temp = rand()%52+1;
if(b.deck[temp].value != 0){
a.deck[i].value = b.deck[temp].value;
a.deck[i].suit = b.deck[temp].suit;
b.deck[temp].value = 0;
b.deck[temp].suit = 'X';
}
else
break;
}
иногда верно выходит, а иногда нет
Card Value: 6 Suit: c
Card Value: 10 Suit: d
Card Value: 2 Suit: s
Card Value: 1 Suit: s
Card Value: 11 Suit: d
Card Value: 2664756 Suit: 6
Card Value: 2665094 Suit: ▒
Card Value: 8662208 Suit: P
Card Value: 2665094 Suit: .
Card Value: 2665159 Suit:
Решение задачи: «Выбрать 10 случайных неповторяющихся карт из колоды»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define SUITS_COUNT 4
#define VALUES_COUNT 13
#define CARDS_IN_DECK (SUITS_COUNT * VALUES_COUNT)
#define CARDS_PER_PLAYER 5
#define NUMBER_OF_PLAYERS 4
typedef struct CARD {
const char * value;
const char * suit;
} card_t;
/*S - Spades, C - Clubs, D - Diamonds, H - Hearts*/
card_t deck[CARDS_IN_DECK] = {
{"2", "S"}, {"3", "S"}, {"4", "S"}, {"5", "S"}, {"6", "S"}, {"7", "S"}, {"8", "S"}, {"9", "S"}, {"10", "S"}, {"J", "S"}, {"Q", "S"}, {"K", "S"}, {"A", "S"},
{"2", "C"}, {"3", "C"}, {"4", "C"}, {"5", "C"}, {"6", "C"}, {"7", "C"}, {"8", "C"}, {"9", "C"}, {"10", "C"}, {"J", "C"}, {"Q", "C"}, {"K", "C"}, {"A", "C"},
{"2", "D"}, {"3", "D"}, {"4", "D"}, {"5", "D"}, {"6", "D"}, {"7", "D"}, {"8", "D"}, {"9", "D"}, {"10", "D"}, {"J", "D"}, {"Q", "D"}, {"K", "D"}, {"A", "D"},
{"2", "H"}, {"3", "H"}, {"4", "H"}, {"5", "H"}, {"6", "H"}, {"7", "H"}, {"8", "H"}, {"9", "H"}, {"10", "H"}, {"J", "H"}, {"Q", "H"}, {"K", "H"}, {"A", "H"}
};
int top;
/* бестолковая функция для перемешивания карт */
int rndcmp(const void * a, const void * b) {
return rand() - rand();
}
/* перемешивание колоды + установка на первую карту значения вершины */
void shuffle_deck(void) {
top = 0;
qsort(deck, CARDS_IN_DECK, sizeof(card_t), rndcmp);
}
/* выдача карты из колоды */
card_t * get_card(void) {
return ( top < 0 || top >= CARDS_IN_DECK ) ? NULL : &deck[top++];
}
/* печать карты */
void print_card(const card_t * card) {
printf("|%2s %s| ", card->value, card->suit);
}
/* функции для сравнения карт */
/* по значению */
int compare_by_value(const card_t * a, const card_t * b) {
static const char values[] = "2345678910JQKA";
return strstr(values, a->value) - strstr(values, b->value);
}
/* по масти (в покере вещь ненужная, только для красивости вывода) */
int compare_by_suit(const card_t * a, const card_t * b) {
static const char suits[] = "SCDH";
return strstr(suits, a->suit) - strstr(suits, b->suit);
}
/* по значению, за тем по масти, подходит для qsort */
int compare_cards(const void * a, const void * b) {
card_t * ca = *(card_t**)a;
card_t * cb = *(card_t**)b;
int diff = compare_by_value(ca, cb);
return ( diff ) ? diff : compare_by_suit(ca, cb);
}
#define PLAYER_NAME_LENGTH 64
typedef struct PLAYER {
char name[PLAYER_NAME_LENGTH];
card_t * cards[CARDS_PER_PLAYER];
} player_t;
int main(void) {
player_t players[NUMBER_OF_PLAYERS];
int nPlayer, nCard;
srand(time(NULL));
/* Имена для наглядности */
for ( nPlayer = 0; nPlayer < NUMBER_OF_PLAYERS; ++nPlayer )
sprintf(players[nPlayer].name, "Player #%d", nPlayer + 1);
/* Раздача карт */
shuffle_deck();
for ( nCard = 0; nCard < CARDS_PER_PLAYER; ++nCard ) {
for ( nPlayer = 0; nPlayer < NUMBER_OF_PLAYERS; ++nPlayer ) {
if ( ! ( players[nPlayer].cards[nCard] = get_card() ) ) {
fprintf(stderr, "ERROR! No more cards in deck!\n");
exit(1);
}
}
}
/* Сортировка и вывод карт у игроков до обмена + обмен */
printf("\nEnter string in form 00101 where 0 to keep card, 1 to change.\n\n");
for ( nPlayer = 0; nPlayer < NUMBER_OF_PLAYERS; ++nPlayer ) {
int cardsToChange;
printf("%s\n", players[nPlayer].name);
qsort(players[nPlayer].cards, CARDS_PER_PLAYER, sizeof(card_t*), compare_cards);
for ( nCard = 0; nCard < CARDS_PER_PLAYER; ++nCard )
print_card(players[nPlayer].cards[nCard]);
printf("\n> ");
scanf("%d", &cardsToChange);
for ( nCard = CARDS_PER_PLAYER - 1; nCard >= 0; --nCard, cardsToChange /= 10 ) {
if ( cardsToChange % 10 ) {
if ( ! ( players[nPlayer].cards[nCard] = get_card() ) ) {
fprintf(stderr, "ERROR! No more cards in deck!\n");
exit(1);
}
}
}
printf("\n");
}
printf("\n\nAfter exchange:\n");
for ( nPlayer = 0; nPlayer < NUMBER_OF_PLAYERS; ++nPlayer ) {
int cardsToChange;
printf("%s\n", players[nPlayer].name);
qsort(players[nPlayer].cards, CARDS_PER_PLAYER, sizeof(card_t*), compare_cards);
for ( nCard = 0; nCard < CARDS_PER_PLAYER; ++nCard )
print_card(players[nPlayer].cards[nCard]);
printf("\n\n");
}
exit(0);
}
Объяснение кода листинга программы
В данном коде реализована игра в покер. Изначально задаются параметры: количество игроков (не более 4), количество карт на каждого игрока (не более 5), количество карт в колоде (не более 52). Далее идет работа с картами. Код содержит функции для перемешивания колоды, получения карты из колоды, печати карты, а также функции для сравнения карт по значению и по масти. Затем идет работа с игроками. Каждый игрок имеет имя и массив карт. Карты раздаются игрокам случайным образом. После этого идет обмен карт между игроками. В конце программы происходит вывод карт каждого игрока и сообщение об успешном завершении игры.