保皇这种桌游做完这个题之后的未来一大段时间内小白可能都不会再碰了,此题可说是融汇了大部分Java的基础知识了。
游戏规则:
①4副扑克,5个玩家,有一个大王标记为皇上。每次发牌时,所发牌中有该大王的玩家是皇上。
②皇帝选择侍卫(也叫保儿、腿子,游戏过程中与皇帝一伙):作为皇上的玩家从自己的牌中选择一张拥有相同三张(点数和花色都相同)的一张牌(不能是2、3、大小王),其他四个玩家中有这张牌的就是侍卫。
③皇上可自保(即皇上有一套四张牌相同的点数的牌)
④皇帝没有满足要求的牌,无法获得侍卫,但游戏继续(即皇上一打四)
要求:程序启动后生成5个玩家,并自动给他们发牌。然后输出:1)皇帝和侍卫的名字及其手里的牌(每张牌输出为“花色”+“点数”,如红桃5,牌之间用“,”分割),并按照大王、小王、2、A、K、Q、J、10、9、8、7、6、5、4、3的顺序排列,相同点数但不同花色的牌要把相同花色的牌放在一起;2)那张作为侍卫所特有的牌(“花色”+“点数”)。如果无法得到侍卫,则程序输出相应的提示。例如,程序运行后输出如下的结果:
皇帝是:玩家1
皇帝的牌是:[皇上, 小王, 小王, 小王, 小王, 方片2, 黑桃2, 黑桃A, 黑桃A, 红桃A, 方片K, 梅花K, 黑桃K, 红桃K, 梅花Q, 梅花Q, 黑桃Q, 方片J, 方片J, 方片J, 红桃J, 梅花9, 黑桃9, 黑桃9, 方片8, 梅花8, 红桃8, 梅花7, 黑桃7, 黑桃7, 红桃7, 梅花6, 梅花6, 黑桃6, 黑桃6, 方片5, 梅花5, 黑桃5, 黑桃5, 梅花4, 梅花4, 梅花4, 方片3, 红桃3]
侍卫对应的牌是:方片J
侍卫是:玩家2
侍卫的牌是:[方片2, 黑桃2, 红桃2, 方片A, 方片K, 梅花K, 梅花K, 黑桃K, 红桃K, 红桃K, 黑桃Q, 红桃Q, 方片J, 方片10, 黑桃10, 红桃10, 红桃10, 红桃10, 方片9, 红桃9, 方片8, 梅花8, 梅花8, 黑桃8, 黑桃8, 黑桃8, 红桃8, 红桃8, 方片7, 黑桃7, 黑桃7, 方片6, 黑桃6, 黑桃5, 梅花4, 黑桃4, 红桃4, 红桃4, 方片3, 梅花3, 黑桃3, 红桃3, 红桃3]
思路:读完题可发现,需要构建两个基本类:扑克牌类和玩家类,用来描述单张扑克牌和一个玩家的属性;一张扑克牌的基本属性有花色和点数,一个玩家基本属性有手中的牌和自己的身份(是皇上还是保子还是平民),由于有4副扑克,相同花色相同点数的牌可能有多张,还需要通过牌数判断玩家是否是保子,故可用map存储。根据题目描述可知需要实现的功能有:随机给每个玩家发牌、比较两张牌的大小、判断两张牌是否相等、判断玩家的身份、皇上找出保儿牌、打印自己手中的牌。
实现:
/*默认皇上首选其他玩家为保子,要不起时能自保则自保,不能自保则本局不设置保子;
* 若有多个保儿牌则选点数最大的*/
class OnePoker implements Comparable<OnePoker>{//单张扑克牌
private String color;//花色
private String figure;//点数
private String onepoker;//花色+点数
private int colorint,figureint;//用于比较大小的花色、点数
public OnePoker(int color,int figure) {
colorint = color;
switch (color) {
case 1:
this.color = "红桃";
break;
case 2:
this.color = "黑桃";
break;
case 3:
this.color = "梅花";
break;
case 4:
this.color = "方片";
break;
default:
break;
}
switch (figure) {
case 11:
this.figure = "J";
figureint = 11;
break;
case 12:
this.figure = "Q";
figureint = 12;
break;
case 13:
this.figure = "K";
figureint = 13;
break;
case 1:
this.figure = "A";
figureint = 14;
break;
case 2:
this.figure = "2";
figureint = 15;
break;
default:
figureint = figure;
this.figure = String.valueOf(figure);
break;
}
onepoker = this.color + this.figure;
}
public OnePoker(String king) {
if(king.equals("小王")) {
this.figureint = 16;
}
else if(king.equals("大王")) {
this.figureint = 17;
}
else if(king.equals("皇上")) {
this.figureint = 18;
}
this.figure = null;
this.color = null;
this.onepoker = king;
}
public String getOnepoker() {
return onepoker;
}
public int getColorint() {
return colorint;
}
public int getFigureint() {
return figureint;
}
@Override
public int compareTo(OnePoker o) {
// TODO Auto-generated method stub
if(this.figureint>o.getFigureint()) {
return -1;
}
else if(this.figureint<o.getFigureint()) {
return 1;
}
else {
if(this.colorint>o.getColorint()) {
return -1;
}
else if(this.colorint<o.getColorint()) {
return 1;
}
else {
return 0;
}
}
}
@Override
public boolean equals(Object obj) {//点数和花色相同的两张牌即为相等,为后面map的排序做准备
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
OnePoker other = (OnePoker) obj;
if (colorint != other.colorint)
return false;
if (figureint != other.figureint)
return false;
if (onepoker == null) {
if (other.onepoker != null)
return false;
} else if (!onepoker.equals(other.onepoker))
return false;
return true;
}
}
class Player{
private Map<OnePoker, Integer> ownpokers=new TreeMap<OnePoker,Integer>(//指定TreeMap的排序方式
new Comparator<OnePoker>() {
@Override
public int compare(OnePoker o1, OnePoker o2) {
// TODO Auto-generated method stub
return o1.compareTo(o2);
}
});;
private int identity;//用于判断身份(是皇上还是平民),皇上为1,平民为0
private int guards;//用于判断是否是保子,因为皇上可自保,是保子则为1,否则为0
public int getIdentity() {
return identity;
}
public void setIdentity(int identity) {
this.identity = identity;
}
public int getGuards() {
return guards;
}
public void setGuards(int guards) {
this.guards = guards;
}
public void AddPoker(OnePoker p) {//玩家摸牌
if(ownpokers.containsKey(p)){//如果map中已存在摸到的牌,牌数+1
int num = ownpokers.get(p);
ownpokers.replace(p,num+1);
}
else {
ownpokers.put(p, 1);
}
}
public OnePoker ConfirmGuard() {//查询本玩家是否是皇上并找保儿牌,成功找到返回保儿牌
if(identity==1) {
for(Map.Entry<OnePoker, Integer> entry:ownpokers.entrySet()) {
if(entry.getValue()==3&&entry.getKey().getFigureint()!=15) {//选点数大的为保儿牌,且保儿牌不能是2
return entry.getKey();
}
}
for(Map.Entry<OnePoker, Integer> entry:ownpokers.entrySet()) {
if(entry.getValue()==4) {//皇上自保
return entry.getKey();
}
}
System.out.println("The emperor has no right to choose his guards.");
}
return null;
}
public boolean judgeGuards(OnePoker p) {//玩家判断自己是否是保子
for(Map.Entry<OnePoker, Integer> entry:ownpokers.entrySet()) {
if(entry.equals(p)) {
return true;
}
}
return false;
}
public void print() {//打印自己的牌
//遍历map
int flag = 0;
for(Map.Entry<OnePoker, Integer> entry:ownpokers.entrySet()) {
if(flag==0) {
for(int i=0;i<entry.getValue();i++) {
if(i==0)
System.out.print(entry.getKey().getOnepoker());
else {
System.out.print(", "+entry.getKey().getOnepoker());
}
}
}
else {
for(int i=0;i<entry.getValue();i++)
System.out.print(", "+entry.getKey().getOnepoker());
}
flag++;
}
}
}
public class ProEmp {
public static void main(String[] args) {
List<OnePoker> pockers = new LinkedList<OnePoker>();//列表存储四副扑克牌,共216张
Player[] players;//共五个玩家
players = new Player[5];
boolean[] judge = new boolean[216];
Arrays.fill(judge, false);
Random random = new Random();
for(int i=0;i<5;i++) {//创建player对象!
players[i] = new Player();
}
//向扑克列表pockers中加除王之外的牌
for(int i=0;i<4;i++) {//共四副扑克,循环四次
for(int j=1;j<=4;j++) {//每副扑克四种花色
for(int k=1;k<=13;k++) {
OnePoker tmp = new OnePoker(j,k);
pockers.add(tmp);
}
}
}
//向扑克列表中加四张小王,三张大王,一张皇上
for(int i=0;i<3;i++) {
pockers.add(new OnePoker("大王"));
pockers.add(new OnePoker("小王"));
}
pockers.add(new OnePoker("小王"));
pockers.add(new OnePoker("皇上"));
//给玩家发牌,1号玩家有44张牌,2、3、4、5号玩家各43张牌
for(int i=0;i<5;i++) {
int pockernum;//记录每个玩家的牌数
int playerpocker = 0;//每个玩家现在已经分到的牌数
if(i==0)
pockernum = 44;
else
pockernum = 43;
while(playerpocker<pockernum) {
int k=random.nextInt(216);//随机获取List的下标(0~215之间)
if(judge[k]==false) {
judge[k] = true;
if(pockers.get(k).getOnepoker().equals("皇上")) {
players[i].setIdentity(1);
}
players[i].AddPoker(pockers.get(k));
playerpocker++;
}
}
}
//找皇上
int keyemp=0;
OnePoker tmp = null;//保儿牌
for(int i=0;i<5;i++) {
if(players[i].getIdentity()==1) {
keyemp = i;
tmp = players[i].ConfirmGuard();
break;
}
}
//找保子
int keyguard=0;
int guardflag = 1;//标记是否有保子,没有为0,有为1
for(int i=0;i<5;i++) {
if(tmp==null) {//没有保子
guardflag = 0;
break;
}
if(players[i].judgeGuards(tmp)) {
keyguard = i;
break;
}
}
System.out.println("皇帝是:玩家"+(keyemp+1));
System.out.print("皇帝的牌是:[");
players[keyemp].print();
System.out.println("]");
if(guardflag==0) {
System.out.println("There is no guards!");
}
else {
System.out.println("侍卫对应的牌是:"+tmp.getOnepoker());
System.out.println("侍卫是:玩家"+(keyguard+1));
System.out.print("侍卫的牌是:[");
players[keyguard].print();
System.out.println("]");
}
}
}