下面我将详细解析如何使用C语言实现扑克牌游戏的核心功能,包括牌组表示、洗牌、发牌等操作。
#include
#include
#include
#include
// 定义扑克牌花色
typedef enum {
HEARTS, // 红心
DIAMONDS, // 方块
CLUBS, // 梅花
SPADES // 黑桃
} Suit;
// 定义扑克牌点数
typedef enum {
ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING
} Rank;
// 定义单张扑克牌结构
typedef struct {
Suit suit;
Rank rank;
int isFaceUp; // 是否正面朝上
} Card;
// 定义牌堆结构
typedef struct {
Card* cards;
int size;
int capacity;
} Deck;
// 函数声明
Deck* createDeck;
void initStandardDeck(Deck* deck);
void shuffleDeck(Deck* deck);
void printCard(const Card* card);
void printDeck(const Deck* deck);
Card drawCard(Deck* deck);
void addCardToDeck(Deck* deck, Card card);
void freeDeck(Deck* deck);
int main {
srand(time(NULL)); // 初始化随机数种子
// 创建并初始化标准扑克牌
Deck* deck = createDeck;
printf("初始牌组:\
);
printDeck(deck);
// 洗牌
shuffleDeck(deck);
printf("\
洗牌后:\
);
printDeck(deck);
// 模拟发牌
printf("\
模拟发5张牌:\
);
for (int i = 0; i
Card drawn = drawCard(deck);
printf("第%d张: ", i + 1);
printCard(&drawn);
printf("\
剩余牌数: %d\
, deck->size);
freeDeck(deck);
return 0;
// 创建空牌堆
Deck* createDeck {
Deck* deck = (Deck*)malloc(sizeof(Deck));
deck->capacity = 52;
deck->size = 0;
deck->cards = (Card*)malloc(deck->capacity * sizeof(Card));
initStandardDeck(deck);
return deck;
// 初始化标准52张扑克牌
void initStandardDeck(Deck* deck) {
deck->size = 0;
for (int suit = HEARTS; suit
for (int rank = ACE; rank
Card card;
card.suit = (Suit)suit;
card.rank = (Rank)rank;
card.isFaceUp = 1; // 默认正面朝上
addCardToDeck(deck, card);
// Fisher-Yates洗牌算法
void shuffleDeck(Deck* deck) {
for (int i = deck->size
int j = rand % (i + 1);
// 交换牌
Card temp = deck->cards[i];
deck->cards[i] = deck->cards[j];
deck->cards[j] = temp;
// 打印单张牌
void printCard(const Card* card) {
const char* suitNames[] = {"♥", "♦", "♣", "♠"};
const char* rankNames[] = {
, "A", "2", "3", "4", "5", "6",
7", "8", "9", "10", "J", "Q", "K
};
printf("%s%s ", rankNames[card->rank], suitNames[card->suit]);
// 打印整副牌
void printDeck(const Deck* deck) {
for (int i = 0; i size; i++) {
printCard(&deck->cards[i]);
if ((i + 1) % 13 == 0) printf("\
); // 每行13张牌
// 从牌堆顶部抽一张牌
Card drawCard(Deck* deck) {
if (deck->size == 0) {
fprintf(stderr, "错误: 牌堆已空!\
);
exit(1);
return deck->cards[--deck->size];
// 向牌堆添加一张牌
void addCardToDeck(Deck* deck, Card card) {
if (deck->size >= deck->capacity) {
// 动态扩容
deck->capacity *= 2;
deck->cards = realloc(deck->cards, deck->capacity * sizeof(Card));
deck->cards[deck->size++] = card;
// 释放牌堆内存
void freeDeck(Deck* deck) {
free(deck->cards);
free(deck);
枚举类型定义:
结构体设计:
Fisher-Yates洗牌算法:
for (int i = deck->size
int j = rand % (i + 1);
// 交换牌
Card temp = deck->cards[i];
deck->cards[i] = deck->cards[j];
deck->cards[j] = temp;
这是一种高效且公平的随机洗牌算法,时间复杂度O(n)。
typedef struct {
Card* hand;
int handSize;
char name[50];
} Player;
Player* createPlayer(const char* name) {
Player* player = (Player*)Player*)malloc(sizeof(Player));
strcpy(player->name, name);
player->handSize = 0;
player->hand = NULL;
return player;
void addCardToHand(Player* player, Card card) {
player->hand = realloc(player->hand, (player->handSize + 1) * sizeof(Card));
player->hand[player->handSize++] = card;
int calculateHandValue(const Player* player) {
int value = 0;
int aces = 0;
for (int i = 0; i handSize; i++) {
Rank rank = player->hand[i].rank;
if (rank >= JACK && rank
value += 10;
} else if (rank == ACE) {
aces++;
value += 11;
} else {
value += rank;
// 处理A的软硬值
while (value > 21 && aces > 0) {
value -= 10;
aces--;
return value;
bash
gcc -o poker poker.c
./poker
初始牌组:
A♥ 2♥ 3♥ 4♥ 5♥ 6♥ 7♥ 8♥ 9♥ 10♥ J♥ Q♥ K♥
A♦ 2♦ 3♦ 4♦ 5♦ 6♦ 7♦ 8♦ 9♦ 10♦ J♦ Q♦ K♦
...
洗牌后:
8♠ K♦ 2♥ Q♣ 7♥ 10♠ A♣ 5♦ ...
悟空黑桃a官网这个实现展示了C语言在游戏开发中的强大能力,特别是对内存管理和数据结构的精细控制。可以根据具体游戏规则在此基础上继续扩展功能。