经过长时间的奋战之后,终于将双飞及相关牌型功能实现。这些都得功于之前的优先排序算法,在这里列一下优先排序算法,
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的倍数的,代码实现如下:
@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;
}
其中主要是要注意一下对最后一个三个的判断。
轻松搞定双飞之后,双飞带单及双飞带对还不是手到擒来!简单列一下双飞带单的实现吧。
/**
* <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的实现
/**
* 在进行了一次排序后,组中全是单牌
* @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;
}
这些简单的判断我放在了牌组内,是符合职责内聚原则的。
非常希望大家能给点建议,这样我会更加有动力写下去,谢谢。