C語言每日一練
2021年12月7日
文章目錄
- 題目描述
- 問題分析
- 代碼實作
- 運行結果
- 網上參考
題目描述
一副撲克有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',表示手上無牌,
代碼實作
#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;
}
運行結果

網上參考
原文鏈接:http://c.biancheng.net/cpp/html/3363.html
這份代碼的實作思路和我差不多,但是還是存在許多細節上的差異,同時他還在發牌結束后給每個人的手牌進行了排序(從大到小),【不過他的隨機函式的亂數種子是固定的,這樣會導致每次運行的結果都相同】
#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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/377161.html
標籤:其他
