140 lines
3.4 KiB
C
140 lines
3.4 KiB
C
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
typedef enum {
|
|
CARD_ACE, CARD_2, CARD_3, CARD_4, CARD_5, CARD_6, CARD_7, CARD_8, CARD_9, CARD_10, CARD_J, CARD_Q, CARD_K, CARD_COUNT,
|
|
} Card_Type;
|
|
|
|
typedef struct {
|
|
Card_Type cards[16];
|
|
int count;
|
|
} Hand;
|
|
|
|
typedef struct {
|
|
Card_Type cards[64];
|
|
int count;
|
|
} Deck;
|
|
|
|
static void swapCard(Card_Type *a, Card_Type *b) {
|
|
Card_Type tmp = *a;
|
|
*a = *b;
|
|
*b = tmp;
|
|
}
|
|
|
|
void shuffleDeck(Deck *d) {
|
|
if (!d) return;
|
|
int n = d->count;
|
|
if (n <= 1) return;
|
|
for (int i = n - 1; i > 0; --i) {
|
|
int j = rand() % (i + 1); // uniform in [0,i]
|
|
swapCard(&d->cards[i], &d->cards[j]);
|
|
}
|
|
}
|
|
|
|
int cardValue(Card_Type card) {
|
|
return card + 1 <= 10 ? card + 1 : 10;
|
|
}
|
|
|
|
void takeCard(Deck *deck, Hand *hand) {
|
|
hand->cards[hand->count++] = deck->cards[--deck->count];
|
|
};
|
|
|
|
int countScore(Hand hand) {
|
|
int score = 0;
|
|
bool has_ace = false;
|
|
for(int i = 0; i < hand.count; i++){
|
|
if(hand.cards[i] == CARD_ACE) has_ace = true;
|
|
score += cardValue(hand.cards[i]);
|
|
}
|
|
return score + has_ace * 10;
|
|
}
|
|
|
|
void printResult(int player_score, int dealer_score) {
|
|
if(player_score > 21) {
|
|
puts("player lost\n");
|
|
return;
|
|
} else if(player_score == 21 && dealer_score != 21) {
|
|
puts("!!!BLACKJACK!!!\n");
|
|
return;
|
|
} else if(player_score == dealer_score) {
|
|
puts("push\n");
|
|
return;
|
|
} else if(dealer_score > 21 || player_score > dealer_score) {
|
|
puts("player won\n");
|
|
return;
|
|
} else if(dealer_score > player_score) {
|
|
puts("player lost\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
srand((unsigned)time(NULL));
|
|
Deck deck = {0};
|
|
for(int i = 0; i < CARD_COUNT; i++){
|
|
deck.cards[deck.count++] = i;
|
|
deck.cards[deck.count++] = i;
|
|
deck.cards[deck.count++] = i;
|
|
deck.cards[deck.count++] = i;
|
|
}
|
|
|
|
shuffleDeck(&deck);
|
|
shuffleDeck(&deck);
|
|
shuffleDeck(&deck);
|
|
|
|
Hand dealer = {0};
|
|
Hand player = {0};
|
|
takeCard(&deck, &player);
|
|
takeCard(&deck, &player);
|
|
takeCard(&deck, &dealer);
|
|
|
|
char cmd;
|
|
bool ask = true;
|
|
if(countScore(player) == 21) ask = false;
|
|
while(ask){
|
|
printf("player score: %d\n", countScore(player));
|
|
printf("dealer score: %d\n", countScore(dealer));
|
|
puts("[H]it or [S]tand?\n");
|
|
|
|
do {
|
|
cmd = getchar();
|
|
if (cmd == EOF) return 0;
|
|
if (cmd == '\n') break;
|
|
} while (cmd == ' ' || cmd == '\t');
|
|
if (cmd == '\n') continue;
|
|
|
|
int ch;
|
|
while ((ch = getchar()) != EOF && ch != '\n') { /* discard */ }
|
|
|
|
switch (cmd) {
|
|
case 'h':
|
|
case 'H':
|
|
takeCard(&deck, &player);
|
|
if(countScore(player) >= 21) ask = false;
|
|
break;
|
|
case 's':
|
|
case 'S':
|
|
ask = false;
|
|
break;
|
|
case 'q':
|
|
puts("Quitting.");
|
|
return 0;
|
|
default:
|
|
printf("Unknown command: %c\n", cmd);
|
|
}
|
|
}
|
|
|
|
if(countScore(player) >= 21) {
|
|
takeCard(&deck, &dealer);
|
|
} else {
|
|
while(countScore(dealer) < 17) takeCard(&deck, &dealer);
|
|
}
|
|
|
|
printf("player score: %d\n", countScore(player));
|
|
printf("dealer score: %d\n", countScore(dealer));
|
|
printResult(countScore(player), countScore(dealer));
|
|
return 0;
|
|
}
|