Week2:扑克牌发牌与理牌

C-扑克牌发牌

题目内容

四位玩家玩扑克牌,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成(即不包括大小王)。
开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝(无情的洗牌机器 ),你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。
输入格式
输入包含多组数据。
每组数据的第一行包含一个大写字符,表示发牌员是谁。如果该字符为‘#’则表示输入结束。
接下来有两行,每行有52个字符,表示了26张牌,两行加起来一共52张牌。每张牌都由两个字符组成,第一个字符表示花色,第二个字符表示数值。
输出格式
输出多组数据发牌的结果。
每组数据之后需要额外多输出一个空行!
每组数据之后需要额外多输出一个空行!
每组数据之后需要额外多输出一个空行!(重说三)
每组数据应该由24行的组成,输出按照顺时针方向,始终先输出South Player的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。
样例

N
CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9
SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3
#

输出排版过于麻烦所以我选择直接截图

解题思路
看到这一题本人首先想到的是寒假胎死腹中的斗地主小游戏开发计划。
思路很明确:

  • 首先读取牌堆情况,按照一个花色一个值组成一个Card结构体塞进一个队列中。这个队列我们可以起名字叫牌堆。
  • 已知发牌员,所以我们从下家开始,每个玩家都创建一个vector数组表示手牌,然后顺时针依次把牌堆首元素(牌堆顶)出列并塞进当前轮到的这个玩家的手牌里。
  • 按照T=10,J=11,Q=12,K=13,A=14;C=1,D=2,S=3,H=4转化,然后根据这些数字,使用sort按照规则进行排序。
  • 然后就是强行好看的输出环节~

以下是AC代码:

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>using namespace std;struct Card
{int symbol;//C1梅花 D2方片 S3黑桃 H4红桃int count;//2 3 4 5 6 7 8 9 T_10 J_11 Q_12 K_13 A_14char symbol_c;char count_c;Card(int s,int c,char s_c,char c_c){symbol = s;count = c;symbol_c = s_c;count_c = c_c;}
};bool cmp(const Card& a,const Card& b)
{if (a.symbol != b.symbol) return a.symbol < b.symbol;else return a.count < b.count;
}queue<Card>allcards;
vector<Card>playerhand[5];//1南 2西 3北 4东void Input(int &first)
{while (!allcards.empty()) allcards.pop();for (int i = 1; i <= 4; i++){playerhand[i].clear();}string a, b;cin >> a >> b;string all = a + b;for (int i = 0; i < all.length(); i += 2){int s, c;switch (all[i]){case 'C':s = 1;break;case 'D':s = 2;break;case 'S':s = 3;break;case 'H':s = 4;break;}switch (all[i + 1]){case '2':c = 2;break;case '3':c = 3;break;case '4':c = 4;break;case '5':c = 5;break;case '6':c = 6;break;case '7':c = 7;break;case '8':c = 8;break;case '9':c = 9;break;case 'T':c = 10;break;case 'J':c = 11;break;case 'Q':c = 12;break;case 'K':c = 13;break;case 'A':c = 14;break;default:c = 0;break;}allcards.push(Card(s, c, all[i], all[i + 1]));}for (int i = first; i <= 4; i++){if (allcards.empty()) break;playerhand[i].push_back(allcards.front());if (i == 4) i = 0;allcards.pop();}for (int i = 1; i <= 4; i++){sort(playerhand[i].begin(), playerhand[i].end(), cmp);}}void Output(int player)
{if (player == 1) cout << "South player:" << endl;if (player == 2) cout << "West player:" << endl;if (player == 3) cout << "North player:" << endl;if (player == 4) cout << "East player:" << endl;cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;cout << '|';for (int i = 0; i < playerhand[player].size(); i++){cout << playerhand[player][i].count_c << ' ' << playerhand[player][i].count_c << '|';}cout << endl << '|';for (int i = 0; i < playerhand[player].size(); i++){cout << ' ' << playerhand[player][i].symbol_c << ' ' << '|';}cout << endl << '|';for (int i = 0; i < playerhand[player].size(); i++){cout << playerhand[player][i].count_c << ' ' << playerhand[player][i].count_c << '|';}cout << endl << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;}int main()
{char firstPlayer;while (cin >> firstPlayer){if (firstPlayer == '#') break;int first;if (firstPlayer == 'S') first = 2;if (firstPlayer == 'W') first = 3;if (firstPlayer == 'N') first = 4;if (firstPlayer == 'E') first = 1;Input(first);for (int i = 1; i <= 4; i++){Output(i);}cout << endl;}
}

嗯,Input函数里那一大段无情的switch技术水平超级低。