007 實現雙飛及相關牌型

    通過長時間的奮戰以後,終於將雙飛及相關牌型功能實現。這些都得功於以前的優先排序算法,在這裏列一下優先排序算法,
java

        public void sort(List<Card> list) {
		//從大到小排序
		CardGroup cardGroup = new CardGroup();
		cardGroup.addAll(list);
		cardGroup.doSort(CardGroupSortType.DECREASE);
		//優化算法
		if(cardGroup.size() < 3 ) return;
		// 從列表中取出對子,三個及炸彈牌形
		List<CardGroup> bombCardGroups = new ArrayList<CardGroup>();
		List<CardGroup> threeCardGroups = new ArrayList<CardGroup>();
		List<CardGroup> pairCardGroups = new ArrayList<CardGroup>();
		int index = 0;
		if (cardGroup.getCardList().get(index).isBigKing() && cardGroup.getCardList().get(index + 1).isSmallKing()) {
			bombCardGroups.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()) {
						bombCardGroups.add(cardGroup.removeRange(index, index + 4));
						continue;
					}
					threeCardGroups.add(cardGroup.removeRange(index, index + 3));
					continue;
				}
				pairCardGroups.add(cardGroup.removeRange(index, index + 2));
				continue;
			} 
			++index;
		}
		// 對牌形大小進行比較,與以前的列表合併
		List<Card> tempList = new ArrayList<Card>();
		for(int i = 0 ; i < bombCardGroups.size() ; i++) {
			tempList.addAll(bombCardGroups.get(i).getCardList());
		}
		for(int i = 0 ; i < threeCardGroups.size() ; i++) {
			tempList.addAll(threeCardGroups.get(i).getCardList());
		}
		for(int i = 0 ; i < pairCardGroups.size() ; i++) {
			tempList.addAll(pairCardGroups.get(i).getCardList());
		}
		if(!tempList.isEmpty()) {
			cardGroup.getCardList().addAll(0, tempList);
			list.clear();
			list.addAll(cardGroup.getCardList());
		}
	}

若是這個算法可以優化的話就更好了,但願你們能給我點意見。算法

    如今切入正題,關於雙飛算法的實現。雙飛其實很簡單,不過這個是雙飛帶單,雙飛帶對的基石,仍是有必要說一下的。雙飛的牌數確定是不小於6且爲3的倍數的,代碼實現以下:
ide

        @Override
	protected boolean determineConditions(CardGroup cardGroup) {
		return cardGroup.size() >= 6 && cardGroup.size()%3 == 0;
	}

    而後就是判斷牌是否符合三個及遞減規則了,代碼實現以下:
優化

@Override
	protected boolean judgeResult(CardGroup cardGroup) {
		cardGroup.doSort(CardGroupSortType.DECREASE);
		boolean result = true;
		int score = cardGroup.getCard(0).getType();
		for(int i = 0; i <cardGroup.size()-2 ; i += 3 , score --) {
			if( !cardGroup.subCardGroup(i, i + 3).isSame() || ((i + 3)<cardGroup.size() &&  score != cardGroup.getCard(i+3).getType() + 1)){
				result = false;
				break;
			}
		}
		return result;
	}

其中主要是要注意一下對最後一個三個的判斷。
code

    輕鬆搞定雙飛以後,雙飛帶單及雙飛帶對還不是手到擒來!簡單列一下雙飛帶單的實現吧。
排序

/**
 * <p>Title: FlyingA.java</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2007</p>
 * @author Tunie 
 * @date 2014年9月16日
 * @version 1.0
 */
public class FlyingA extends HandCard {
	
	public FlyingA() {
		setType(HandCardType.FLYING_A);
	}

	private int getCount(CardGroup cardGroup) {
		return cardGroup.size()/4;
	}
	
	@Override
	protected void setCardGroup(CardGroup cardGroup) {
		super.setCardGroup(cardGroup);
		setCount(getCount(cardGroup));
	}
	
	@Override
	protected boolean determineConditions(CardGroup cardGroup) {
		return cardGroup.size() >= 8 && cardGroup.size()%4 == 0;
	}

	@Override
	protected boolean judgeResult(CardGroup cardGroup) {
		cardGroup.doSort(CardGroupSortType.PAIR_PRECEDENCE);
		HandCard fly = new Flying();
		int count = getCount(cardGroup);
		boolean result = fly.judge(cardGroup.subCardGroup(0, count * 3)) && cardGroup.subCardGroup(count * 3, cardGroup.size()).isDiff();
		return result;
	}
}

簡單說下條件判斷,由於是三帶單的話,牌數起碼爲8張且爲4的整數倍,而後就裏就用了下CardGroup的isDiff方法,列一下isDiff的實現three

/**
	 * 在進行了一次排序後,組中全是單牌
	 * @return
	 */
	public boolean isDiff() {
		Card card = cardList.get(0);
		boolean result = true;
		int count = 1;
		while(count < size()) {
			if(cardList.get(count).equalType(card)) {
				result = false;
				break;
			}
			card = cardList.get(count);
			count++;
		}
		return result;
	}

這些簡單的判斷我放在了牌組內,是符合職責內聚原則的。ip

很是但願你們能給點建議,這樣我會更加有動力寫下去,謝謝。rem

相關文章
相關標籤/搜索