/*背景:两个人每人发3张牌(各从一副牌中),
每张牌包括花色(红桃(Heart)>黑桃(Spade)>方块(Diamond)>梅花(Club))和大小(从小到大依次是:2-10、J、Q、K、A),谁
手上有最大的一张或多张(如果有相同的牌)牌谁获胜。
输入:A的3张牌(未排序)和B的3张牌(未排序)。
(参见用例)
DA H2 C3
H4 H3 DJ
输出:A的3张牌的排序后的输出和B的3张牌的排序后的输出,以及A和B谁获胜。
(参见用例)
Winner is B!
A: H2 DA C3
B: H4 H3 DJ
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct card_structure{
int type;
int number;
int abs;
};
/**
* 牌的数据结构。
* type对应花色,值为1到4。
* number对应大小,值为1到13。
* 2的值为1,3的值为2……10的值为9,J的值为10,Q的值为11,K的值为12,A的值为13。
* abs为“数值绝对大小”,由number + (4- type) * 13算出。用来给牌排序。
*/
typedef struct card_structure card;
void my_input(char *c1, char *c2);
int my_analyze(char *c, card * cards);
int my_get_type_value(char type);
int my_get_number_value(char number);
void my_get_string(card * cards, char * buffer);
int my_compare (const void *a ,const void *b);
void my_tidy_cards(card * cards);
void my_get_winner(card * player1, card * player2);
/**
* 花色字典:1代表H,2代表S,3代表D,4代表C
*/
char g_types[5] = {' ', 'H', 'S', 'D', 'C'};
/**
* 牌的大小字典:2的值为1,3的值为2……10的值为9,J的值为10,Q的值为11,K的值为12,A的值为13。
* 注意!10由于是两个字符,所以用T代替。
*/
char g_numbers[14] = {' ', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};
/**
* 让用户用键盘输入两个字符串到c1和c2两个字符数组。
* 作为玩家1和玩家2的牌。
* @param c1 char *
* @param c2 char *
*/
void my_input(char *c1, char * c2){
gets(c1);
gets(c2);
}
/**
* 将牌的字符串分析成数据结构
* @param c char * 牌的字符串
* @param cards card * 分析后的牌的数据结构地址
* @return int 1表示分析成功,0表示输入有误,分析失败。
*/
int my_analyze(char *c, card * cards){
int len = strlen(c);
int pos = 0;
int count = 0;
while(1){
if(pos + 1 > len - 1){
return 0;
}
char type_name = c[pos];
char number_name = c[pos + 1];
char number_name2 = c[pos + 2];/*这个可能是空格,也可能是大小为10的牌的号码10的那个0。*/
int type_value = my_get_type_value(type_name);
if(!type_value){
return 0;
}
int number_value = 0;
if('0' != number_name2){
number_value = my_get_number_value(number_name);
if(!number_value){
return 0;
}
pos += 3;
}
else if('0' == number_name2 && '1' == number_name){
number_value = my_get_number_value('T');
pos += 4;
}
else{
return 0;
}
cards[count].type = type_value;
cards[count].number = number_value;
cards[count].abs = number_value + (4 - type_value) * 13;
int j = 0;
for(;j < count; j ++){ /* 不允许有重复的牌 */
if(cards[j].abs == cards[count].abs){
return 0;
}
}
count ++;
if(count >= 3){
return 1;
}
}
}
/**
* 按花色获取值
* @param type char 花色字符。H、S、D或C。
* @return int 0到4。0代表错误,1代表H,2代表S,3代表D,4代表C。
*/
int my_get_type_value(char type){
type = toupper(type);
int len = sizeof(g_types) / sizeof(char);
int i;
for(i = 1; i < len; i ++){
if(g_types[i] == type){
return i;
}
}
return 0;
}
/**
* 按牌的大小获取值
* @param number char 牌的大小字符。2、3、4、……10、J、Q、K或A。注意!10由于是两个字符,所以用T代替。
* @return int 0到13。0代表错误。2的值为1,3的值为2……10的值为9,J的值为10,Q的值为11,K的值为12,A的值为13。
*/
int my_get_number_value(char number){
number = toupper(number);
int len = sizeof(g_numbers) / sizeof(char);
int i;
for(i = 1; i < len; i ++){
if(g_numbers[i] == number){
return i;
}
}
return 0;
}
/**
* 将牌的数据结构变为字符串。
* @param cards card * 牌的数据结构。
* @param buffer char * 字符输出缓存。
*/
void my_get_string(card * cards, char * buffer){
int i = 0;
int pos = 0;
for(;i < 3; i ++){
card cd = cards[i];
int type = cd.type;
int number = cd.number;
char type_name = g_types[type];
char number_name = g_numbers[number];
buffer[pos] = type_name;
if('T' == number_name){
buffer[pos + 1] = '1';
buffer[pos + 2] = '0';
buffer[pos + 3] = ' ';
pos += 4;
}
else{
buffer[pos + 1] = number_name;
buffer[pos + 2] = ' ';
pos += 3;
}
}
buffer[pos] = 0;
}
/**
* 给牌做排序时要用到的比较函数。
* @param a const void *
* @param b const void *
* @return int
*/
int my_compare (const void *a ,const void *b) {
card *ca=(card * ) a,*cb = (card * )b;
int aa = ca->abs, bb = cb->abs;
if(aa > bb) return -1;/*倒序排列*/
else if(aa == bb) return 0;
else return 1;
}
/**
* 将牌的数组按牌的花色和大小排序。
* @param cards card * 牌的数组首地址
*/
void my_tidy_cards(card * cards){
qsort(cards, 3, sizeof(card), my_compare);
}
/**
* 判断赢家,并做显示输出。
* @param player1 card * 玩家1的牌的数组的首地址
* @param palyer2 card * 玩家2的牌的数组的首地址
*/
void my_get_winner(card * player1, card * player2){
int i = 0;
int v1, v2;
for(;i < 3; i ++){
v1 = player1[i].abs;
v2 = player2[i].abs;
if(v1 > v2){
printf("Winner is A!\n");
return;
}
else if(v1 == v2){
continue;
}
else{
printf("Winner is B!\n");
return;
}
}
printf("Winner is X!\n");
return;
}
int main(int argc, char** argv) {
char c1[20];/*字符数组1,存放玩家1的牌的字符串*/
char c2[20];/*字符数组2,存放玩家2的牌的字符串*/
my_input(c1, c2);/*输入牌*/
card player1[3];/*玩家1的牌的数组*/
card player2[3];/*玩家2的牌的数组*/
int result;
result = my_analyze(c1, player1);/*分析玩家1的牌的字符串,放入玩家1的牌的数组*/
if(!result){
printf("Input Error!");
return -1;
}
result = my_analyze(c2, player2);/*分析玩家2的牌的字符串,放入玩家2的牌的数组*/
if(!result){
printf("Input Error!");
return -1;
}
my_tidy_cards(player1);/*玩家1的牌按花色和大小排序*/
my_tidy_cards(player2);/*玩家2的牌按花色和大小排序*/
my_get_winner(player1, player2);/*判断赢家,并显示输出。*/
char s1[20];/*整理后的牌的字符串表示*/
char s2[20];
my_get_string(player1, s1);/*将玩家牌的数组转换为字符串。*/
my_get_string(player2, s2);
printf("A: %s\nB: %s\n", s1, s2);/*输出排序后的牌*/
return 0;
}
评论0