003 代碼開發

代碼已開源,源代碼可從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 , 請看官直言指正,謝謝。

相關文章
相關標籤/搜索