題目描述
一副撲克有52張牌,打橋牌時應將牌分給4個人。請設計一個程序完成自動發牌的工作。要求:黑桃用S (Spaces)表示,紅桃用H (Hearts)表示,方塊用D (Diamonds)表示,梅花用C (Clubs)表示。
問題分析
個人思路:
這題實現起來還是比較簡單的,只需定義兩個多維的字符數組,第一個用來存放撲克的編號,第二個用來存放4個玩家的手牌。
52張牌發給4個人,需要發13輪,每輪按玩家的編號順序給他們發牌,發牌時,用隨機函數生成要發牌的編號(隨機函數的介紹可以參考我第61天的練習),如果該牌之前沒被發放(已發放的牌用'\0'標記),則將牌的編號存放到玩家的手牌數組中,同時將該牌的編號賦值為'\0'。如果生成的隨機數對應的牌已經被發過了,則繼續生成新的隨機數。當52張牌全部發放完畢,打印發牌的結果。
撲克數組char poker[4][13];中的4表示花色種類有四種,13表示每種有13張(13個編號),撲克牌的編號(名字)用字符表示,分別為:{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'}('0'表示10)
玩家的手牌數組是一個三維字符數組,char players[PLAYER_NUMBER][4][13] = {0}; (PLAYER_NUMBER是玩家數量,4表示牌的花色種類有4種,13為某種花色的牌最多13張)
初始化時,手牌數組的所有值設置為'\0',表示手上無牌。
代碼實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include <stdio.h> #include <stdlib.h> //srand()/rand() #include <time.h> //time() #define CARD_NUMBER 52 //總牌數(目前僅支持52) #define PLAYER_NUMBER 4 //玩家數量 /****************************************************************************** * @brief 給某個玩家發牌 * @param player_id 玩家編號 * @param players 玩家手牌數組 * @param left_num 剩余可發放牌數 * @param poker 撲克牌數組 * @return 返回0表示發牌成功,返回-1表示無牌可發 ******************************************************************************/ int Distribute_Card( int player_id, char players[][4][13], int *left_num, char poker[][13]) { if (*left_num <= 0) return -1; //無牌可發 int card_id = 0; //撲克牌編號 int card_index = 0; //手牌數組下標 do { /* 隨機獲取一個撲克牌的編號(0~52) */ card_id = rand () % CARD_NUMBER; } while (poker[card_id / 13][card_id % 13] == '\0' ); //如果該牌已經發放,繼續獲取編號 (*left_num)--; //剩余可發牌數減1 while (players[player_id][card_id / 13][card_index] != '\0' ) { card_index++; //到達該玩家的手牌數組有效值的下一個下標('\0'表示無效值) } /* 給玩家手牌數組賦值(加一張牌) */ players[player_id][card_id / 13][card_index] = poker[card_id / 13][card_id % 13]; /* 將該牌標記為無效牌(已發放) */ poker[card_id / 13][card_id % 13] = '\0' ; return 0; } /****************************************************************************** * @brief 打印發牌結果 * @param players 玩家手牌數組 ******************************************************************************/ void Print_Result( char players[][4][13]) { int i = 0, j = 0, k = 0; /* 牌的類別 */ char card_name[][8] = { "黑桃" , "紅桃" , "方塊" , "梅花" }; for (i = 0; i < PLAYER_NUMBER; i++) { printf ( "\n玩家%d:\n" , i + 1); for (j = 0; j < 4; j++) { printf ( "%s: " , card_name[j]); //打印卡牌類型 //依次打印某玩家該類型的手牌 for (k = 0; players[i][j][k]!= '\0' && k < 13; k++) { if (players[i][j][k] == '0' ) printf ( "10 " ); //'0'對應10 else printf ( "%c " , players[i][j][k]); } printf ( "\n" ); } } } int main() { /* 撲克牌數組 */ char poker[4][13] = {{ '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , 'J' , 'Q' , 'K' , 'A' },\ { '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , 'J' , 'Q' , 'K' , 'A' },\ { '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , 'J' , 'Q' , 'K' , 'A' },\ { '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , 'J' , 'Q' , 'K' , 'A' }}; int left_num = sizeof (poker); //剩余可發放牌數(應該等于CARD_NUMBER) char players[PLAYER_NUMBER][4][13] = {0}; //玩家手牌數組 int i = 0, j = 0, k = 0; //用系統秒數初始化隨機數種子 srand ((unsigned) time (NULL)); /* 給每個玩家發牌 */ for (i = 0; i < CARD_NUMBER/PLAYER_NUMBER + 1; i++) //當玩家是奇數時,需要+1(這個值只能多不能少) { for (j = 0; j < PLAYER_NUMBER; j++) { //給某一個玩家發牌 if (!Distribute_Card(j, players, &left_num, poker)) k++; //發牌成功次數+1 } } printf ( "\n成功發牌%d次!\n" , k); //總發牌次數 Print_Result(players); //打印結果 return 0; } |
運行結果
網上參考
這份代碼的實現思路和我差不多,但是還是存在許多細節上的差異,同時他還在發牌結束后給每個人的手牌進行了排序(從大到?。!静贿^他的隨機函數的隨機數種子是固定的,這樣會導致每次運行的結果都相同】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#include<stdlib.h> #include<stdio.h> int comp( const void *j, const void *i); void p( int b[], char n[]); int main( void ) { static char n[]={ '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'T' , 'J' , 'Q' , 'K' , 'A' }; int a[53], b1[13], b2[13], b3[13], b4[13]; int b11=0, b22=0, b33=0, b44=0, t=1, m, flag, i; while ( t<=52 ) /*控制發52張牌*/ { m= rand ()%52; /*產生0到51之間的隨機數*/ for (flag=1,i=1; i<=t&&flag; i++) /*查找新產生的隨機數是否已經存在*/ if (m==a[i]) flag=0; /*flag=1表示產生的是新的隨機數,flag=0表示新產 生的隨機數已經存在*/ if (flag) { a[t++]=m; /*如果產生了新的隨機數,則存入數組*/ /*根據t的模值,判斷當前的牌應存入哪個數組中*/ if (t%4==0) b1[b11++]=a[t-1]; else if (t%4==1) b2[b22++]=a[t-1]; else if (t%4==2) b3[b33++]=a[t-1]; else if (t%4==3) b4[b44++]=a[t-1]; } } qsort (b1, 13, sizeof ( int ), comp); /*將每個人的牌進行排序*/ qsort (b2, 13, sizeof ( int ), comp); qsort (b3, 13, sizeof ( int ), comp); qsort (b4, 13, sizeof ( int ), comp); p(b1, n); /*分別打印每個人的牌*/ p(b2, n); p(b3, n); p(b4, n); return 0; } void p( int b[], char n[]) { int i; printf ( "\n\006 " ); /*打印黑桃標記*/ for (i=0; i<13; i++) /*將數組中的值轉換為相應的花色*/ if (b[i]/13==0) /*找到該花色對應的牌*/ printf ( "%c " , n[b[i]%13]); printf ( "\n\003 " ); /*打印紅桃標記*/ for (i=0; i<13; i++) if ((b[i]/13)==1) printf ( "%c " , n[b[i]%13]); printf ( "\n\004 " ); /*打印方塊標記*/ for (i=0; i<13; i++) if (b[i]/13==2) printf ( "%c " , n[b[i]%13]); printf ( "\n\005 " ); /*打印梅花標記*/ for (i=0; i<13; i++) if (b[i]/13==3 || b[i]/13==4) printf ( "%c " , n[b[i]%13]); printf ( "\n" ); } int comp( const void *j, const void *i) /*qsort調用的排序函數*/ { return (*( int *)i-*( int *)j); }<font face= "Arial, Verdana, sans-serif" ><span style= "white-space: normal;" > </span></font> |
以上就是C語言實現自動發牌程序的詳細內容,更多關于C語言自動發牌程序的資料請關注服務器之家其它相關文章!
原文鏈接:https://blog.csdn.net/weixin_43772810/article/details/121771299