一张扑克牌有两个属性,一个是花色(suit),一个是点数(rank),下面写一个简单的类
Card
package com.syz.card; import java.io.Serializable; public class Card implements Serializable{ private static final long serialVersionUID = -4279016186402068401L; private int suit; private int rank; public static final int SPADE = 0; public static final int HEART = 1; public static final int CLUB = 2; public static final int DIAMOND = 3; public static final int BLACK = 4; public static final int RED = 5; private static final String[] suits = new String[] { "黑桃", "红桃", "梅花", "方块", "小", "大" }; public static final int ACE = 1000; public static final int TWO = 1001; public static final int THREE = 1002; public static final int FOUR = 1003; public static final int FIVE = 1004; public static final int SIX = 1005; public static final int SEVEN = 1006; public static final int EIGHT = 1007; public static final int NINE = 1008; public static final int TEN = 1009; public static final int JACK = 1010; public static final int QUEEN = 1011; public static final int KING = 1012; public static final int JOKER = 1013; private static final String[] ranks = new String[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "王" }; public Card(int suit, int rank) { if (suit > -1 && suit < 6) { if (suit < 4) { if (rank < 1000 || rank > 1012) { throw new IllegalArgumentException("花色或点数参数错误!"); } } else { if (rank != 1013) { throw new IllegalArgumentException("花色或点数参数错误!"); } } } else { throw new IllegalArgumentException("花色参数错误!"); } this.suit = suit; this.rank = rank; } public int getSuit() { return suit; } public int getRank() { return rank; } @Override public String toString() { return suits[suit] + ranks[rank - 1000]; } }
写完之后,要new一张扑克牌,需要两个参数,suit和rank,而且suit和rank是有关系的黑红梅方可以对应A2345678910JQK,然后黑色小王,红色大王。这个在构造器里做了校验,如果不符合,则抛出参数错误异常。
下面是测试类
CardClient
package com.syz.card; import java.util.ArrayList; import java.util.List; public class CardClient { public static void main(String[] args) { test2(); } private static void test1() { Card c = new Card(Card.BLACK, Card.JOKER); System.out.println(c); } private static void test2() { int[] suits = new int[] { Card.SPADE, Card.HEART, Card.CLUB, Card.DIAMOND }; int[] ranks = new int[] { Card.ACE, Card.TWO, Card.THREE, Card.FOUR, Card.FIVE, Card.SIX, Card.SEVEN, Card.EIGHT, Card.NINE, Card.TEN, Card.JACK, Card.QUEEN, Card.KING }; List<Card> cards = new ArrayList<Card>(); for (int i = 0; i < suits.length; i++) { for (int j = 0; j < ranks.length; j++) { cards.add(new Card(suits[i], ranks[j])); } } cards.add(new Card(Card.BLACK, Card.JOKER)); cards.add(new Card(Card.RED, Card.JOKER)); System.out.println(cards); } }
测试结果:
[黑桃A, 黑桃2, 黑桃3, 黑桃4, 黑桃5, 黑桃6, 黑桃7, 黑桃8, 黑桃9, 黑桃10, 黑桃J, 黑桃Q, 黑桃K, 红桃A, 红桃2, 红桃3, 红桃4, 红桃5, 红桃6, 红桃7, 红桃8, 红桃9, 红桃10, 红桃J, 红桃Q, 红桃K, 梅花A, 梅花2, 梅花3, 梅花4, 梅花5, 梅花6, 梅花7, 梅花8, 梅花9, 梅花10, 梅花J, 梅花Q, 梅花K, 方块A, 方块2, 方块3, 方块4, 方块5, 方块6, 方块7, 方块8, 方块9, 方块10, 方块J,
方块Q, 方块K, 小王, 大王]
这样一副扑克就创建成功了。
扑克原来有52张,没有大小王,后来才加上了大小王。现在有些扑克会带一张白板牌里面是一些广告什么的,如果把这张牌加入的话,就得改改这个Card类了。
下面我们来看看第二种方式创建一副扑克牌,不过这儿的类有些多,好处就是可以扩展。看代码:
1.Suit
package com.syz.pattern.bridge;
public abstract class Suit {
private Face face;
public Suit(Face face) {
this.face = face;
}
public void show() {
face.show(this);
}
protected abstract String getName();
}
2.Face
package com.syz.pattern.bridge;
public abstract class Face {
protected abstract String getName();
public void show(Suit suit) {
System.out.println(suit.getName() + this.getName());
}
}
以上两个抽象类,相互引用。是花色和点数的父类。
Suit的几个子类:
package com.syz.pattern.bridge; public class Spade extends Suit { public Spade(Face face) { super(face); } @Override public String getName() { return "黑桃"; } }
package com.syz.pattern.bridge; public class Heart extends Suit { public Heart(Face face) { super(face); } @Override protected String getName() { return "红桃"; } }
package com.syz.pattern.bridge; public class Club extends Suit { public Club(Face face) { super(face); } @Override protected String getName() { return "梅花"; } }
package com.syz.pattern.bridge; public class Diamond extends Suit { public Diamond(Face face) { super(face); } @Override protected String getName() { return "方块"; } }
package com.syz.pattern.bridge; public class Black extends Suit { public Black(Face face) { super(face); } @Override protected String getName() { return "小"; } }
package com.syz.pattern.bridge; public class Red extends Suit { public Red(Face face) { super(face); } @Override protected String getName() { return "大"; } }
Face的几个子类
package com.syz.pattern.bridge; public class Ace extends Face { @Override protected String getName() { return "A"; } }
package com.syz.pattern.bridge; public class Two extends Face { @Override protected String getName() { return "2"; } }
package com.syz.pattern.bridge; public class Three extends Face { @Override protected String getName() { return "3"; } }
package com.syz.pattern.bridge; public class Four extends Face { @Override protected String getName() { return "4"; } }
package com.syz.pattern.bridge; public class Five extends Face { @Override protected String getName() { return "5"; } }
package com.syz.pattern.bridge; public class Six extends Face { @Override protected String getName() { return "6"; } }
package com.syz.pattern.bridge; public class Seven extends Face { @Override protected String getName() { return "7"; } }
package com.syz.pattern.bridge; public class Eight extends Face { @Override protected String getName() { return "8"; } }
package com.syz.pattern.bridge; public class Nine extends Face { @Override protected String getName() { return "9"; } }
package com.syz.pattern.bridge; public class Ten extends Face { @Override protected String getName() { return "10"; } }
package com.syz.pattern.bridge; public class Jack extends Face { @Override protected String getName() { return "J"; } }
package com.syz.pattern.bridge; public class Queen extends Face { @Override protected String getName() { return "Q"; } }
package com.syz.pattern.bridge; public class King extends Face { @Override protected String getName() { return "K"; } }
package com.syz.pattern.bridge; public class Joker extends Face { @Override protected String getName() { return "王"; } }
接下来看一些测试:
Suit c1 = new Spade(new Ace());
c1.show();
c1 = new Heart(new Jack());
c1.show();
c1 = new Club(new Queen());
c1.show();
c1 = new Diamond(new King());
c1.show();
c1 = new Spade(new Joker());
c1.show();
测试结果:
黑桃A
红桃J
梅花Q
方块K
黑桃王
花色和点数组合,可以看出,这里没有规则,“黑桃王”这样的都可以拼出来,我就呵呵了。
那么怎么组合成一副54张的扑克呢,这里可以用反射来做,看代码:
package com.syz.pattern.bridge; import java.util.ArrayList; import java.util.List; public class CardClient { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) throws Exception { // reflect String[] suitNames = { "com.syz.pattern.bridge.Spade", "com.syz.pattern.bridge.Heart", "com.syz.pattern.bridge.Club", "com.syz.pattern.bridge.Diamond" }; String[] rankNames = { "com.syz.pattern.bridge.Ace", "com.syz.pattern.bridge.Two", "com.syz.pattern.bridge.Three", "com.syz.pattern.bridge.Four", "com.syz.pattern.bridge.Five", "com.syz.pattern.bridge.Six", "com.syz.pattern.bridge.Seven", "com.syz.pattern.bridge.Eight", "com.syz.pattern.bridge.Nine", "com.syz.pattern.bridge.Ten", "com.syz.pattern.bridge.Jack", "com.syz.pattern.bridge.Queen", "com.syz.pattern.bridge.King" }; List<Suit> cards = new ArrayList<>(); for (int i = 0; i < suitNames.length; i++) { Class suitClazz = Class.forName(suitNames[i]); for (int j = 0; j < rankNames.length; j++) { Class rankClazz = Class.forName(rankNames[j]); cards.add((Suit) suitClazz .getConstructor(new Class[] { Face.class }) .newInstance(new Object[] { rankClazz.newInstance() })); } } cards.add(new Black(new Joker())); cards.add(new Red(new Joker())); for (int i = 0; i < cards.size(); i++) { Suit card = cards.get(i); card.show(); } } }
结果:
黑桃A
黑桃2
黑桃3
黑桃4
黑桃5
黑桃6
黑桃7
黑桃8
黑桃9
黑桃10
黑桃J
黑桃Q
黑桃K
红桃A
红桃2
红桃3
红桃4
红桃5
红桃6
红桃7
红桃8
红桃9
红桃10
红桃J
红桃Q
红桃K
梅花A
梅花2
梅花3
梅花4
梅花5
梅花6
梅花7
梅花8
梅花9
梅花10
梅花J
梅花Q
梅花K
方块A
方块2
方块3
方块4
方块5
方块6
方块7
方块8
方块9
方块10
方块J
方块Q
方块K
小王
大王