代碼已開源,源代碼可從github下獲得,地址爲 https://github.com/Juneve/DouDiZhu.git 。java
主要說一下兩個地方的設計思路,他們都採用了策略模式。git
一個是CardGroup中內置的排序規則,目前實現了從大到小,從小到大,對子優先大到小三種排序算法。他們都實現了接口ICardGroupSort,代碼以下:github
/** * <p>Title: ICardGroupSort.java</p> * <p>Description:排序策略接口 </p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月15日 * @version 1.0 */ public interface ICardGroupSort { void sort(List<Card> list); }
從大到小,從小到大排序算法都很簡單,都是採用了簡單排序中的插入排序,下面列出DecreaseSort類代碼:算法
/** * <p>Title: DecreaseSort.java</p> * <p>Description: 遞減排序</p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月15日 * @version 1.0 */ public class DecreaseSort implements ICardGroupSort { public void sort(List<Card> list) { int inner; for(int i=1; i<list.size(); i ++ ) { inner = i; Card temp = list.get(inner); while(inner > 0 && list.get(inner - 1).compareTo(temp) < 0 ){ list.set(inner, list.get(inner - 1)); --inner; } list.set(inner, temp); } } }
對子優先算法略微有點複雜,先貼出代碼:ide
/** * <p>Title: PairPrecedenceSort.java</p> * <p>Description:對子優先排序 </p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月15日 * @version 1.0 */ public class PairPrecedenceSort implements ICardGroupSort { public void sort(List<Card> list) { //從大到小排序 CardGroup cardGroup = new CardGroup(); cardGroup.addAll(list); cardGroup.doSort(CardGroupSortType.DECREASE); //優化算法 if(cardGroup.size() < 3 ) return; // 從列表中取出對子,三個及炸彈牌形 List<CardGroup> cardGroups = new ArrayList<CardGroup>(); int index = 0; if (cardGroup.getCardList().get(index).isBigKing() && cardGroup.getCardList().get(index + 1).isSmallKing()) { cardGroups.add(cardGroup.removeRange(0, 2)); } while(index < cardGroup.size() - 1) { if(cardGroup.subCardGroup(index, index + 2).isSame()) { if((index + 3 <= cardGroup.size()) && cardGroup.subCardGroup(index, index + 3).isSame()) { if((index + 4 <= cardGroup.size()) && cardGroup.subCardGroup(index, index + 4).isSame()) { cardGroups.add(cardGroup.removeRange(index, index + 4)); continue; } cardGroups.add(cardGroup.removeRange(index, index + 3)); continue; } cardGroups.add(cardGroup.removeRange(index, index + 2)); continue; } ++index; } // 列表合併 List<Card> tempList = new ArrayList<Card>(); for(int i = 0 ; i < cardGroups.size() ; i++) { tempList.addAll(cardGroups.get(i).getCardList()); } if(!tempList.isEmpty()) { cardGroup.getCardList().addAll(0, tempList); list.clear(); list.addAll(cardGroup.getCardList()); } } }
主要分三步走,首先對列表進行遞減排序;而後將列表中的對子,三個,炸彈牌型選出來;最後,將列表合併。測試
另外一個就是牌型的實現,全部的牌型都繼承了HandCard抽象類,該類代碼以下:
優化
package org.tunie.game.doudizhu.card; /** * <p>Title: HandCard.java</p> * <p>Description:一手牌 </p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月13日 * @version 1.0 */ public abstract class HandCard { private int type; private int score; private CardGroup cardGroup; public HandCard() { } public int getType() { return type; } protected void setType(int type) { this.type = type; } public int getScore() { return score; } protected void setScore(int score) { this.score = score; } public CardGroup getCardGroup() { return cardGroup; } protected void setCardGroup(CardGroup cardGroup) { this.cardGroup = cardGroup; setScore(cardGroup.getCard(0).getType()); } /** * 判斷牌型 */ public abstract boolean judge(CardGroup cardGroup); /** * 判斷指定size長度的cardGroup的牌同樣 * @param cardGroup * @param size * @return */ protected boolean judge(CardGroup cardGroup , int size) { boolean result = false; if(cardGroup.size() == size) { result = cardGroup.isSame(); if(result) { setCardGroup(cardGroup); } } return result; } }
這個類很早就寫說了,不過斷斷續續的添加了多個方法。一個是judge方法的一個重載實現,這個方法會被多個牌型子類使用,例如Bomb代碼以下:this
/** * <p>Title: Bomb.java</p> * <p>Description:炸彈 </p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月15日 * @version 1.0 */ public class Bomb extends HandCard { public Bomb() { setType(HandCardType.BOMB); } @Override public boolean judge(CardGroup cardGroup) { return judge(cardGroup , 4); } }
還有如對子、三個等牌型,與炸彈的實現是大同小異的,就是將Bomb中的4分別換爲二、3。spa
再囉嗦兩句,留意下ThreeA類的實現,列表代碼:設計
/** * <p>Title: ThreeA.java</p> * <p>Description: 三帶單牌型</p> * <p>Copyright: Copyright (c) 2007</p> * @author Tunie * @date 2014年9月15日 * @version 1.0 */ public class ThreeA extends HandCard{ public ThreeA() { setType(HandCardType.THREE); } @Override public boolean judge(CardGroup cardGroup) { boolean result = false; if(cardGroup.size() == 4) { cardGroup.doSort(CardGroupSortType.PAIR_PRECEDENCE); result = cardGroup.subCardGroup(0, 3).isSame() && !cardGroup.isSame(); if(result) { setCardGroup(cardGroup); } } return result; } }
這裏用到了對子優先排序算法,雖然這個類目前尚未獲得測試,不過,離真相應該也不遠了。
因爲本人能力有限,代碼及文中不免會出現這樣那樣的bug , 請看官直言指正,謝謝。