用C语言写一个斗地主游戏
时间: 2023-07-01 18:05:18 浏览: 504
python写的斗地主游戏,有mysql数据库,可做毕业设计,下载即可运行
以下是一个简单的斗地主游戏的C语言实现,只包括基本的发牌、出牌和比较大小的功能,没有考虑AI出牌策略和游戏规则等更复杂的部分。代码注释中有详细的说明。
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define CARD_NUM 54 // 扑克牌数量
// 扑克牌结构体
typedef struct {
int num; // 牌面大小,1-13表示A、2、3...K,0表示小王,1表示大王
int suit; // 花色,0表示黑桃,1表示红桃,2表示梅花,3表示方块
} Card;
// 初始化扑克牌,将54张牌按顺序放入cards数组中
void init_cards(Card *cards) {
for (int i = 0; i < CARD_NUM; i++) {
if (i < 52) {
cards[i].num = i % 13 + 1;
cards[i].suit = i / 13;
} else if (i == 52) {
cards[i].num = 0;
cards[i].suit = 4;
} else {
cards[i].num = 1;
cards[i].suit = 4;
}
}
}
// 洗牌,将cards数组中的牌随机打乱
void shuffle(Card *cards) {
srand(time(NULL));
for (int i = 0; i < CARD_NUM; i++) {
int j = rand() % CARD_NUM;
Card tmp = cards[i];
cards[i] = cards[j];
cards[j] = tmp;
}
}
// 打印牌面,将num和suit转换为字符串打印
void print_card(Card card) {
char *num_str, *suit_str;
switch (card.num) {
case 1: num_str = "A"; break;
case 2: num_str = "2"; break;
case 3: num_str = "3"; break;
case 4: num_str = "4"; break;
case 5: num_str = "5"; break;
case 6: num_str = "6"; break;
case 7: num_str = "7"; break;
case 8: num_str = "8"; break;
case 9: num_str = "9"; break;
case 10: num_str = "10"; break;
case 11: num_str = "J"; break;
case 12: num_str = "Q"; break;
case 13: num_str = "K"; break;
case 0: num_str = "W"; break;
default: num_str = ""; break;
}
switch (card.suit) {
case 0: suit_str = "\u2660"; break;
case 1: suit_str = "\u2665"; break;
case 2: suit_str = "\u2663"; break;
case 3: suit_str = "\u2666"; break;
case 4: suit_str = "J"; break;
default: suit_str = ""; break;
}
printf("%s%s ", num_str, suit_str);
}
// 打印一组牌面
void print_cards(Card *cards, int n) {
for (int i = 0; i < n; i++) {
print_card(cards[i]);
}
printf("\n");
}
// 比较两张牌的大小,返回1表示card1大,返回-1表示card2大,返回0表示相同大小
int compare_cards(Card card1, Card card2) {
if (card1.num == card2.num) {
if (card1.suit > card2.suit) {
return 1;
} else if (card1.suit < card2.suit) {
return -1;
} else {
return 0;
}
} else if (card1.num == 1) {
return 1;
} else if (card2.num == 1) {
return -1;
} else if (card1.num > card2.num) {
return 1;
} else {
return -1;
}
}
// 判断一组牌是否为顺子,返回1表示是,返回0表示不是
int is_straight(Card *cards, int n) {
if (n < 5) {
return 0;
}
for (int i = 0; i < n - 1; i++) {
if (cards[i].num != cards[i+1].num - 1) {
return 0;
}
}
return 1;
}
int main() {
Card cards[CARD_NUM];
init_cards(cards);
shuffle(cards);
// 发牌
Card player1[17], player2[17], player3[17], public_cards[3];
for (int i = 0; i < 17; i++) {
player1[i] = cards[i*3];
player2[i] = cards[i*3+1];
player3[i] = cards[i*3+2];
}
for (int i = 0; i < 3; i++) {
public_cards[i] = cards[51+i];
}
printf("Player 1: ");
print_cards(player1, 17);
printf("Player 2: ");
print_cards(player2, 17);
printf("Player 3: ");
print_cards(player3, 17);
printf("Public cards: ");
print_cards(public_cards, 3);
// 出牌
int player = 1;
Card last_cards[20];
int last_num = 0;
while (1) {
printf("Player %d's turn: ", player);
Card played_cards[20];
int played_num = 0;
char input_str[100];
fgets(input_str, 100, stdin);
if (input_str[0] == '\n') {
printf("Pass.\n");
player = player % 3 + 1;
continue;
}
char *token = strtok(input_str, " \n");
while (token != NULL) {
int num, suit;
switch (token[0]) {
case 'A': num = 1; break;
case '2': num = 2; break;
case '3': num = 3; break;
case '4': num = 4; break;
case '5': num = 5; break;
case '6': num = 6; break;
case '7': num = 7; break;
case '8': num = 8; break;
case '9': num = 9; break;
case '1': num = 10; break;
case 'J': num = 11; break;
case 'Q': num = 12; break;
case 'K': num = 13; break;
case 'W': num = 0; break;
default: num = -1; break;
}
switch (token[1]) {
case '\u2660': suit = 0; break;
case '\u2665': suit = 1; break;
case '\u2663': suit = 2; break;
case '\u2666': suit = 3; break;
case 'J': suit = 4; break;
default: suit = -1; break;
}
if (num == -1 || suit == -1) {
printf("Invalid input: %s\n", token);
break;
}
Card card = {num, suit};
played_cards[played_num++] = card;
token = strtok(NULL, " \n");
}
// 检查出牌是否合法
if (played_num == 0) {
printf("Invalid input: no cards played.\n");
continue;
}
if (player == 1 && played_num != 1) {
printf("Invalid input: must play one card.\n");
continue;
}
if (played_num != last_num && last_num != 0) {
printf("Invalid input: number of cards does not match.\n");
continue;
}
if (played_num == 1 && played_cards[0].num == 0) {
printf("Invalid input: cannot play joker.\n");
continue;
}
for (int i = 0; i < played_num; i++) {
int found = 0;
for (int j = 0; j < 17; j++) {
if (compare_cards(played_cards[i], player1[j]) == 0) {
found = 1;
break;
}
}
if (!found) {
printf("Invalid input: card not in hand.\n");
break;
}
}
if (played_num == 1 && last_num != 0 && compare_cards(played_cards[0], last_cards[0]) <= 0) {
printf("Invalid input: card not larger than last played card.\n");
continue;
}
if (played_num > 1 && !is_straight(played_cards, played_num)) {
printf("Invalid input: not a straight.\n");
continue;
}
if (played_num > 1 && played_num != last_num && last_num != 0) {
printf("Invalid input: number of cards does not match.\n");
continue;
}
// 更新出牌记录和玩家手牌
for (int i = 0; i < played_num; i++) {
last_cards[i] = played_cards[i];
for (int j = 0; j < 17; j++) {
if (compare_cards(played_cards[i], player1[j]) == 0) {
player1[j] = (Card){-1, -1};
break;
}
}
}
last_num = played_num;
printf("Played cards: ");
print_cards(played_cards, played_num);
// 判断游戏是否结束
int end = 0;
for (int i = 0; i < 17; i++) {
if (player1[i].num != -1) {
end = 1;
break;
}
}
if (!end) {
printf("Game over! Player 1 wins.\n");
break;
}
player = player % 3 + 1;
}
return 0;
}
```
该代码实现的斗地主游戏只能在命令行中运行,并且没有图形界面等交互体验,但可以作为一个基础的斗地主游戏框架,在此基础上可以扩展出更多的游戏规则和功能。
阅读全文