Week 3 & 4 - Bigger Challenge and A First Look at Object-Oriented Programming

题目 1 - 扑克牌出牌

题目要求

设想你在打扑克牌“斗地主”。现在,上家刚刚出完牌。给定你当前手中的牌和上家刚刚出的牌,请尝试判断能否用手中的牌压过对方的牌。如果可以,输出最小的能压过对方牌型的一组牌。为了简化问题,本题不考虑花色。

“最小的能压过对方牌型”即优先使用与对手相同的牌型,且牌面数字尽量小。如果无法压过对方,再依次考虑炸弹、王炸。

斗地主游戏中牌的顺序是:3、4、5、6、7、8、9、10、J、Q、K、A、2、小王、大王,有以下牌型:

更详细的牌形和规则解释,请参阅这里。这道题目只考虑上面提到的规则,其他附加规则请忽略。

实现要求

请自己设计程序,将不同功能拆分成不同函数。

输入输出格式及样例

输入的第一行包含两个数字n和m;第二行包含n张牌的牌面,表示你手头有的牌,空格隔开;第三行包含m张牌的牌面,表示对手打出的牌,空格隔开。3~2的牌用数字或大写字母表示,小王用joker(小写)表示,大王用JOKER(大写)表示。输入的牌面不一定按顺序排列。

如果手头的牌能压过对手的牌,请输出最小的组合,将牌面从大到小按顺序输出。如果无法压过对手的牌,输出YAO BU QI

输入1:

16 6
JOKER 2 2 A Q Q Q J J 10 10 9 8 8 4 4
5 5 4 4 3 3

输出1:

Q Q J J 10 10

输入2:

8 2
JOKER 2 2 A Q 9 8 8
A A

输出2:

2 2

输入3:

19 4
JOKER joker 2 2 K K K K J 10 9 9 9 9 8 7 7 4 4
5 5 5 3

输出3:

9 9 9 4

题目 2 - 模拟牌局

题目要求

你已经实现了一个最简单的出牌策略,稍加改动,就可以模拟一个真实的牌局了!这是通往一个完整纸牌游戏的一小步。

尝试对于一个给定的起始牌局,模拟每一轮每个玩家的操作,及每一个玩家操作之后的手牌。当轮到一个人任意出牌时(即地主第一轮首先出牌,或某个玩家出的牌另外两个人要不起时),你可以打出任意合法的牌型,但是如有非单张牌型,不允许打单张。

本周的练习中,我们提供一个程序shuffle_and_deal.cpp点击这里下载)用于生成初始的手牌。程序读入一个unsigned int类型的随机种子,输出三行手牌。其中,第一行有20张牌,为地主的手牌;第二三行分别有17张牌,为地主下家和上家的手牌。一个确定的随机种子可以输出确定的洗牌和分牌,变换不同的随机种子则会生成不同的洗牌。这个程序的输出应该作为你程序的输入。

输入输出方式

编译并运行shuffle_and_deal.cpp,输入一个随机种子以生成测试数据。例如,输入某个随机种子,程序会输出:

10 A A J 5 Q 2 K A 6 Q 4 3 joker 2 K 4 3 5 K
5 7 8 2 Q 5 4 K J 4 7 9 6 8 8 6 9
7 8 J 10 3 A Q 2 7 9 10 6 9 10 JOKER 3 J

你的程序应该以此作为输入,并输出三个玩家打牌的过程。例如:

Player 1 plays: 3 3
Player 1 holds: joker 2 2 A A A K K K Q Q J 10 6 5 5 4 4
Player 2 plays: 4 4
Player 2 holds: 2 K Q J 9 9 8 8 8 7 7 6 6 5 5
Player 3 plays: 7 7
Player 3 holds: JOKER 2 A Q J J 10 10 10 9 9 8 6 3 3
Player 1 plays: Q Q
Player 1 holds: joker 2 2 A A A K K K J 10 6 5 5 4 4
Player 2 pass.
Player 2 holds: 2 K Q J 9 9 8 8 8 7 7 6 6 5 5
Player 3 pass.
Player 3 holds: JOKER 2 A Q J J 10 10 10 9 9 8 6 3 3
Player 1 plays: 4 4
Player 1 holds: joker 2 2 A A A K K K J 10 6 5 5
Player 2 plays: 5 5
Player 2 holds: 2 K Q J 9 9 8 8 8 7 7 6 6
......

这道题不使用脚本评测,你可以对输出的形式进行改动,但是请保证输出的清晰易读。输出的牌型和手牌请按从大到小的顺序输出。

题目 3 - ???

待续……