一張撲克牌有兩個屬性,一個是花色(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 cards = new ArrayList();
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 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
小王
大王