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