package com.backfire.arithmetic;

import java.util.ArrayList;
import java.util.Collections;

public class CardJudge3_Laizi {

	public enum CardType_Laizi {
		NONE, 
		SOLO, // 单牌
		PAIR, // 对子
		TRIO, // 三不带
		CHAIN, // 顺子
		TRIO_X, // 三带一 , 三带二
		PAIR_CHAIN, // 连对
		PLANE, // 飞机不带
		PLANE_1, // 飞机三带一 ,
		PLANE_2, // 飞机三带二
		FOUR_WITH_X, // 四带一 ， 四带二
		MIX_BOMB, // 混搭炸弹
		BOMB, // 原生炸弹
		LAIZHI_BOMB, // 纯癞子炸
		ROCKET, // 王炸
		CardEnd // 结尾符号，用于做错误处理
	};

	// void ChangeColorSame();
	/** 含有癞子牌的集合 **/
	public ArrayList<Card> mCardVec_Laizi;
	public ArrayList<Card> mCardVec_LaiziForChange;
	public int mCardNum;
	
	public CardJudge3_Laizi(){
		mCardVec_Laizi=new ArrayList<Card>();
		mCardVec_LaiziForChange=new ArrayList<Card>();
		mCardNum=0;
	}

	public CardReturn_Laizi judgeCardType(final ArrayList<Card> myCard) {
		CardReturn_Laizi pCardReturn_Laizi = new CardReturn_Laizi();
		ArrayList<Card> pCardWithNoLaizi = new ArrayList<Card>(); // 没有癞子的牌，用于拆分
		ArrayList<Card> pCardIsLaizi = new ArrayList<Card>(); // 有癞子的牌，用于拆分
		Collections.sort(myCard,new CardAssist.Desc());
		do {
			if (myCard.isEmpty())// 判空处理;
				break;

			mCardNum = myCard.size();// 获得卡片量
			mCardVec_Laizi = myCard;

			// ----------判断其内有没有癞子牌型
			boolean bIsHaveLaiZi = false;
			for (int i = 0; i < myCard.size(); ++i) {
				if (mCardVec_Laizi.get(i).isLaiZi()) {
					bIsHaveLaiZi = true;
					pCardIsLaizi.add(myCard.get(i));
					continue;
				}
				pCardWithNoLaizi.add(myCard.get(i));
			}

			// 如果没有癞子牌 按照普通牌分析并且返回判断结果
			if (!bIsHaveLaiZi) {
				CardJudge3 cardJundge3 = new CardJudge3();
				CardReturn myReturn = cardJundge3.judgeCardType(myCard);
				pCardReturn_Laizi.copy(myReturn.mCardType, myReturn.mCardHead,
						myReturn.mCardNum);
				return pCardReturn_Laizi;
			} else {
				// 如果有癞子，先拆分癞子
				pCardReturn_Laizi = judgeCardForLaiZi(pCardWithNoLaizi,
						pCardIsLaizi);
				// 写出13种有癞子情况的变牌算法
			}
		} while (false);
		return pCardReturn_Laizi;
	}

	public CardReturn_Laizi judgeCardForLaiZi(
			final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi) {
		int iSize = pCardWithNoLaizi.size() + pCardIsLaizi.size();
		CardReturn_Laizi pCardReturn_Laizi = new CardReturn_Laizi();
		pCardReturn_Laizi.mCardType = CardType_Laizi.CardEnd;

		switch (iSize) {
		case CardJudge.N_1:
			judgeSOLO(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _单牌
			break;
		case CardJudge.N_2:
			judgePAIR(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _对子
			break;
		case CardJudge.N_3:
			judgeTRIO(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _三不带
			break;
		case CardJudge.N_4:
			judgeTRIO_WITH_1(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _三带一
			judgeBOMB(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _炸弹
			break;
		case CardJudge.N_5:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _5个顺
			judgeTRIO_WITH_2(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _三带二
			break;
		case CardJudge.N_6:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _6个顺
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _连对
																				
			judgeTRIO_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _2个飞机不带
			judgeFOUR_WITH_2(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _四带二
			break;
		case CardJudge.N_7:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _7个顺
			break;
		case CardJudge.N_8:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _8顺
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _4连对
			judgePLANE_1(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 2个飞机三带一
			judgeFOUR_WITH_4(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi);//4带2对
			break;
		case CardJudge.N_9:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _9顺
			judgeTRIO_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _3个飞机不带
			break;
		case CardJudge.N_10:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _10顺，
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _5连对
			JudgePLANE_2(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 2个飞机飞机三带二
			break;
		case CardJudge.N_11:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _11顺
																			// ，
			break;
		case CardJudge.N_12:
			judgeCHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 12顺
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _6对
			judgeTRIO_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 4个飞机不带
			judgePLANE_1(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // ，3个飞机三带一
			break;
		case CardJudge.N_14:
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // _7对
			break;
		case CardJudge.N_15:
			judgeTRIO_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 5个飞机不带
			JudgePLANE_2(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 3个飞机飞机三带二
			break;
		case CardJudge.N_16:
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 8对
			judgePLANE_1(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 4个飞机三带一
			break;
		case CardJudge.N_18:
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 9对
			judgeTRIO_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 6个飞机三不带，
			break;
		case CardJudge.N_20:
			judgePAIR_CHAIN(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 10对
			judgePLANE_1(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // 5个飞机三带一
			JudgePLANE_2(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi); // ，4个飞机三带二，
			break;
		}
		// ChangeColorSame();
		return pCardReturn_Laizi;
	}

	public ArrayList<Card> getChangeLaiZi() {
		return mCardVec_LaiziForChange;
	}

	/** 判断单牌 **/
	public boolean judgeSOLO(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		pCardReturn_Laizi.copy(CardType_Laizi.SOLO, pCardIsLaizi.get(0),
				CardJudge.N_1);
		return true;
	}

	/** 判断_对子 **/
	public boolean judgePAIR(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		do {
			if (!pCardWithNoLaizi.isEmpty()) {
				if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
						|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
					return false;
			}

			// 两张癞子
			if (pCardIsLaizi.size() == CardJudge.N_2) {
				// 取大的一张看做非癞子与癞子组成对子
				pCardReturn_Laizi.copy(CardType_Laizi.PAIR,
						pCardIsLaizi.get(0), CardJudge.N_2);
				break;
			} else {// 癞子和非癞子一样一张
				if (pCardWithNoLaizi.isEmpty())
					return false;
				// 取非癞子与癞子组成对子
				pCardReturn_Laizi.copy(CardType_Laizi.PAIR,
						pCardWithNoLaizi.get(0), CardJudge.N_2);
				break;
			}
		} while (false);

		return true;
	}

	/** 判断3不带 **/
	public boolean judgeTRIO(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		do {
			if (!pCardWithNoLaizi.isEmpty()) {
				if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
						|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
					return false;
			}

			if (pCardIsLaizi.size() == CardJudge.N_3) { // 三张全癞子
				pCardReturn_Laizi.copy(CardType_Laizi.TRIO,
						pCardIsLaizi.get(0), CardJudge.N_3);
				break;
			} else if (pCardIsLaizi.size() == 2 && pCardWithNoLaizi.size() == 1) {// 两张癞子与一张非癞子
				pCardReturn_Laizi.copy(CardType_Laizi.TRIO,
						pCardWithNoLaizi.get(0), CardJudge.N_3);
				break;
			} else if (pCardIsLaizi.size() == 1 && pCardWithNoLaizi.size() == 2) {// 一张癞子与两张非癞子
				// 两张非癞子牌必须一样
				if (judgeSame(pCardWithNoLaizi)) {
					pCardReturn_Laizi.copy(CardType_Laizi.TRIO,
							pCardWithNoLaizi.get(0), CardJudge.N_3);
					break;
				} else {
					return false;
				}
			}
		} while (false);

		return false;
	}

	/** 判断3带1 **/
	public boolean judgeTRIO_WITH_1(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		int iNum = pCardWithNoLaizi.size();
		Card myCard = pCardIsLaizi.get(0);
		switch (iNum) {
		case CardJudge.N_0:
		case CardJudge.N_1:
			break;// 会判定为炸弹，所以返回
		case CardJudge.N_2:
			pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
			pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
			break;
		case CardJudge.N_3:
			if (judgeDifference(pCardWithNoLaizi) < 3) {
				pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(2);
				if (pCardWithNoLaizi.get(0).getPoint() == pCardWithNoLaizi.get(1).getPoint())
					pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
			}
			break;
		}

		if (pCardReturn_Laizi.mCardType != CardType_Laizi.TRIO_X)
			return false;

		pCardReturn_Laizi.mCardNum = 4;

		return true;
	}

	/** 判断炸弹 **/
	public boolean judgeBOMB(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;
		}

		if (pCardWithNoLaizi.isEmpty()) {
			pCardReturn_Laizi.mCardType = CardType_Laizi.LAIZHI_BOMB;
			pCardReturn_Laizi.mCardNum = 4;
			pCardReturn_Laizi.mCardHead = pCardIsLaizi.get(0);
		} else if (pCardWithNoLaizi.size() == 1) {
			pCardReturn_Laizi.mCardType = CardType_Laizi.MIX_BOMB;
			pCardReturn_Laizi.mCardNum = 4;
			pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
		} else {
			if (judgeSame(pCardWithNoLaizi)) {
				pCardReturn_Laizi.mCardType = CardType_Laizi.MIX_BOMB;
				pCardReturn_Laizi.mCardNum = 4;
				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
			}else{
				return false;
			}
		}
		return true;
	}
	
	/** 判断顺子 **/
	public boolean judgeCHAIN(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker)) {
				return false;
			}
			// 如果出现2则不能组成顺子
			if (pCardWithNoLaizi.get(0).getPoint() == Card.Point2) {
				return false;
			}
		}

		Card card_A = new Card(Card.Club, Card.PointA); // 构造一个A
		Card card_3 = new Card(Card.Club, Card.Point3); // 构造一个3
		int iNoLaziNum = pCardWithNoLaizi.size();
		int iLaziNum = pCardIsLaizi.size();// 癞子个数
		int chainSize = iNoLaziNum + iLaziNum;

		// 排除张数小于5和大于12的情况
		if (iNoLaziNum + iLaziNum < 5 || iNoLaziNum + iLaziNum > 12) {
			return false;
		}

		// 如果全部是癞子
		if (iNoLaziNum == 0) {
			int PointAddHead = pCardIsLaizi.get(0).getPoint() + chainSize- 1;

			if (PointAddHead >= Card.PointA)// 如果大于A 则取A
			{
				pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, card_A, chainSize);
			} else {
				Card cardHead = new Card(Card.Club,
						Card.changePoint(PointAddHead)); // 构造牌头
				pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, cardHead,
						chainSize);
			}

			return true;
		}else {// 癞子和非癞子牌都有的情况  
			// 非癞子牌中原本就是顺子
			if (judgeIsCHAIN(pCardWithNoLaizi)) {
				// 在尾部加入癞子牌
				if (pCardWithNoLaizi.get(0).getPoint() == Card.PointA) {
					pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, card_A,
							chainSize);
				} else// 在头部加入癞子牌
				{
					// 取得现在的牌头加上后的点数
					int PointAddHead = pCardWithNoLaizi.get(0).getPoint()
							+ iLaziNum;

					if (PointAddHead >= Card.PointA)// 如果大于A 则取A
					{
						pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, card_A,
								chainSize);
					} else {
						Card cardHead = new Card(Card.Club,
								Card.changePoint(PointAddHead)); // 构造牌头
						pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, cardHead,
								chainSize);
					}
				}

				return true;
			} else // 非癞子牌中不是顺子
			{
				for (int iX = 0; iX < iNoLaziNum - 1; ++iX) {
					// 得到相邻两张的差值
					int iDValue = pCardWithNoLaizi.get(iX).getPoint()
							- pCardWithNoLaizi.get(iX + 1).getPoint();

					// 如果两张相同则一定不是顺子
					if (iDValue == 0) {
						return false;
					}

					iLaziNum = iLaziNum - (iDValue - 1);// 减去癞子牌的张数

					if (iLaziNum < 0)// 没有癞子牌了则判定不能成为顺子
					{
						return false;
					}
				}

				if (iLaziNum == 0)// 癞子牌刚好用完
				{
					pCardReturn_Laizi.copy(CardType_Laizi.CHAIN,
							pCardWithNoLaizi.get(0), chainSize);
				} else {
					int PointAddHead = pCardWithNoLaizi.get(0).getPoint()
							+ iLaziNum;

					if (PointAddHead > Card.PointA)// 如果大于A 则取A
					{
						pCardReturn_Laizi.copy(CardType_Laizi.CHAIN, card_A,
								chainSize);
					} else {
						Card cardHead = new Card(Card.Club,
								Card.changePoint(PointAddHead)); // 构造牌头
						pCardReturn_Laizi.copy(CardType_Laizi.CHAIN,
								cardHead, chainSize);
					}
				}
				return true;
			}
		}
	}

	/** 判断3带2 **/
	public boolean judgeTRIO_WITH_2(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;
		}

		int iNum = pCardWithNoLaizi.size();
		Card myCard = pCardIsLaizi.get(0);
		// Card myCardEnd = pCardIsLaizi.get(0);
		switch (iNum) {
		case CardJudge.N_0:
			pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
			pCardReturn_Laizi.mCardHead = pCardIsLaizi.get(0);
			break;
		case CardJudge.N_1:
			pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
			// 说明：3 癞/癞/癞/癞 --->变成AAA 33的情况 或者 AAAA 3
			pCardReturn_Laizi.mCardHead = pCardIsLaizi.get(0);
			// myCardEnd = pCardWithNoLaizi.get(0);
			if (pCardWithNoLaizi.get(0).getPoint() > pCardIsLaizi.get(0)
					.getPoint()) {
				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
				// myCardEnd = pCardIsLaizi.get(0);
			}
			break;
		case CardJudge.N_2:
			pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
			if (judgeSame(pCardWithNoLaizi)) {
				pCardReturn_Laizi.mCardHead = pCardIsLaizi.get(0);
				// myCardEnd = pCardWithNoLaizi.get(0);
				if (pCardWithNoLaizi.get(0).getPoint() > pCardIsLaizi.get(0)
						.getPoint()) {
					pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
					// myCardEnd = pCardWithNoLaizi.get(0);
				}
			} else{
				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
			}
			break;
		case CardJudge.N_3:
			if (judgeDifference(pCardWithNoLaizi) < 3) {
				pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;
				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
			}else{
				return false;
			}
			break;
		case CardJudge.N_4:
			if (judgeDifference(pCardWithNoLaizi) < 3) {
				pCardReturn_Laizi.mCardType = CardType_Laizi.TRIO_X;

				pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(0);
				if (pCardWithNoLaizi.get(1).getPoint() == pCardWithNoLaizi.get(
						3).getPoint())
					pCardReturn_Laizi.mCardHead = pCardWithNoLaizi.get(1);
			}else{
				return false;
			}
			break;
		}
		if (pCardReturn_Laizi.mCardType != CardType_Laizi.TRIO_X)
			return false;

		pCardReturn_Laizi.mCardNum = 5;

		return true;
	}

	/** 判断4带2：考虑带王的问题 **/
	public boolean judgeFOUR_WITH_2(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		int iNum = pCardWithNoLaizi.size();

		if (judgeDifference(pCardWithNoLaizi) > 3)
			return false;

		switch (iNum) {
		case CardJudge.N_0:
			pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
					(pCardIsLaizi.get(0)), 6);
			break;

		case CardJudge.N_1:
		case CardJudge.N_2:
			if (pCardWithNoLaizi.get(0).getPoint() > pCardIsLaizi.get(0)
					.getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						pCardWithNoLaizi.get(0), 6);
			else
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						pCardIsLaizi.get(0), 6);
			break;

		case CardJudge.N_3:
			pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
					(pCardWithNoLaizi.get(0)), 6);
			break;

		case CardJudge.N_4:
			if (pCardWithNoLaizi.get(1).getPoint() == pCardWithNoLaizi.get(3)
					.getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(1)), 6);
			else if (pCardWithNoLaizi.get(0).getPoint() == pCardWithNoLaizi
					.get(2).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(0)), 6);
			else if (pCardWithNoLaizi.get(2).getPoint() == pCardWithNoLaizi
					.get(3).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(2)), 6);
			else if (pCardWithNoLaizi.get(1).getPoint() == pCardWithNoLaizi
					.get(2).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(1)), 6);
			else if (pCardWithNoLaizi.get(0).getPoint() == pCardWithNoLaizi
					.get(1).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(0)), 6);
			break;

		case CardJudge.N_5:
			if (pCardWithNoLaizi.get(1).getPoint() == pCardWithNoLaizi.get(4)
					.getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(1)), 6);
			else if (pCardWithNoLaizi.get(0).getPoint() == pCardWithNoLaizi
					.get(3).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(0)), 6);
			else if (pCardWithNoLaizi.get(2).getPoint() == pCardWithNoLaizi
					.get(4).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(2)), 6);
			else if (pCardWithNoLaizi.get(1).getPoint() == pCardWithNoLaizi
					.get(3).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(1)), 6);
			else if (pCardWithNoLaizi.get(0).getPoint() == pCardWithNoLaizi
					.get(2).getPoint())
				pCardReturn_Laizi.copy(CardType_Laizi.FOUR_WITH_X,
						(pCardWithNoLaizi.get(0)), 6);
			break;
		}
		return true;
	}

	/** 判断4带2对 **/
	public boolean judgeFOUR_WITH_4(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		int iSize=pCardWithNoLaizi.size()+pCardIsLaizi.size();
		
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;
		}
		if (judgeDifference(pCardWithNoLaizi) > 3)
			return false;
		//88 666 33 癞 --->测试出错：
		for(int i=0;i<pCardWithNoLaizi.size();i++){
			ArrayList<Card> tmpCardWithNoLaizi=CardAssist.copyList(pCardWithNoLaizi);
			boolean tmpGatherFour=unitsParts(tmpCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi, CardType_Laizi.FOUR_WITH_X, 1, 4);
			if(tmpGatherFour){
				Card head=pCardReturn_Laizi.mCardHead;
				removeCard(head, tmpCardWithNoLaizi);//移除头牌
				if(judgeDifference(tmpCardWithNoLaizi)<=2){
					pCardReturn_Laizi.setmCardNum(iSize);
					return true;
				}else{
					return false;
				}
			}
		}
		
		return false;
	}
	
	public void removeCard(Card card,ArrayList<Card> cards){
		for(int i=0;i<cards.size();){
			if(cards.get(i).getPoint()==card.getPoint()){
				cards.remove(i);
			}else{
				i++;
			}
		}
	}
	
	/** 判断连队 **/
	public boolean judgePAIR_CHAIN(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;

			if (pCardWithNoLaizi.get(0).getPoint() == Card.Point2)// 判断头部是否含有2
				return false;
		}

		float iNum = pCardWithNoLaizi.size() + pCardIsLaizi.size();

		if ((iNum / 2) != ((int) iNum / 2))
			return false;

		if (judgeDifference(pCardWithNoLaizi) > iNum / 2) // 判断不同的个数是否大于运行出现数
			return false;

		return judgeTRIOandPAIR(pCardWithNoLaizi, pCardIsLaizi,
				pCardReturn_Laizi, 2);
	}

	/** 飞机不带 **/
	public boolean judgeTRIO_CHAIN(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		float iNum = pCardWithNoLaizi.size() + pCardIsLaizi.size();

		if ((iNum / 3) != ((int) iNum / 3))
			return false;

		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;

			if (pCardWithNoLaizi.get(0).getPoint() == Card.Point2)// 判断头部是否含有2
				return false;
		}

		if (judgeDifference(pCardWithNoLaizi) > iNum / 3) // 判断不同的个数是否大于运行出现数
			return false;

		if (pCardWithNoLaizi.size() > 3) {
			for (int i = 0; i < ((int) pCardWithNoLaizi.size()) - 3; ++i) {
				if (pCardWithNoLaizi.get(i).getPoint() == pCardWithNoLaizi.get(
						i + 3).getPoint()) // 判断是否有4个出现的
					return false;
			}
		}

		int iCardWithNoLaiziNum = pCardWithNoLaizi.size();
		int iPoint;
		Card myCard_LaiZi = new Card(Card.Club, Card.Point3);
		switch (iCardWithNoLaiziNum) {
		case CardJudge.N_0:
			for (int i = 0; i < pCardIsLaizi.size(); ++i) {
				if (pCardIsLaizi.get(i).getPoint() != Card.Point2) {
					iPoint = pCardIsLaizi.get(i).getPoint() + 1;
					if (pCardIsLaizi.get(i).getPoint() == Card.PointA)
						iPoint--;
					myCard_LaiZi.setColor(pCardIsLaizi.get(i).getColor());
					myCard_LaiZi.setPoint(Card.changePoint(iPoint));
					pCardReturn_Laizi.copy(CardType_Laizi.PLANE, myCard_LaiZi,
							6); // 只可能为6个癞子
				}
			}
			break;
		case CardJudge.N_1:
			iPoint = pCardWithNoLaizi.get(0).getPoint() + 1;
			if (pCardWithNoLaizi.get(0).getPoint() == Card.PointA)
				iPoint--;
			myCard_LaiZi.setColor(pCardWithNoLaizi.get(0).getColor());
			myCard_LaiZi.setPoint(Card.changePoint(iPoint));
			pCardReturn_Laizi.copy(CardType_Laizi.PLANE, myCard_LaiZi,
					(int) iNum); // 只可能为6个癞子
		default:
			judgeTRIOandPAIR(pCardWithNoLaizi, pCardIsLaizi,
					pCardReturn_Laizi, 3);
			break;
		}

		return true;
	}

	class SRange {
		public int hight;
		public int low;
		
		@Override
		public String toString() {
			return "SRange [hight=" + hight + ", low=" + low + "]";
		}
	}

	/** 判断飞机(3带1) **/
	public boolean judgePLANE_1(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		
		int iPlAneLong = (pCardWithNoLaizi.size() + pCardIsLaizi.size()) / 4;
		CardType_Laizi type=CardType_Laizi.PLANE_1;
		
		boolean result=unitsParts(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi, type, iPlAneLong, 3);
		if(result){
			pCardReturn_Laizi.setmCardNum(pCardWithNoLaizi.size()+pCardIsLaizi.size());
		}
		
		return result;
	}
	
	/** 判断飞机(3带2)**/
	public boolean JudgePLANE_2(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi) {
		if (!pCardWithNoLaizi.isEmpty()) {
			if ((pCardWithNoLaizi.get(0).getPoint() == Card.PointBigJoker)
					|| (pCardWithNoLaizi.get(0).getPoint() == Card.PointSmallJoker))
				return false;
		}
		// 飞机的长度
		float iPlAneLong = (pCardWithNoLaizi.size() + pCardIsLaizi.size()) / 5;

		if (iPlAneLong != (int) iPlAneLong)
			return false;

		ArrayList<SRange> myRangeVec = new ArrayList<SRange>();

		int iMax = Card.Point2;
		// 搜索所有普通牌,组成的飞机带连对的可能
		for (int i = 0; i < pCardWithNoLaizi.size(); ++i) {
			int iHead = pCardWithNoLaizi.get(i).getPoint();
			for (int j = 0; j <= iPlAneLong; ++j) {
				SRange myRange = new SRange();
				myRange.hight = (int) (iHead + iPlAneLong - j);
				myRange.low = iHead - j + 1;

				if ((myRange.hight < Card.Point2)
						&& (myRange.low >= Card.Point3))
					myRangeVec.add(myRange);
			}
		}

		for (int i = 0; i < myRangeVec.size(); ++i) {
			int iHave = 0;
			ArrayList<Card> surplusVec = new ArrayList<Card>();
			int wwhight = myRangeVec.get(i).hight;
			int wwlow = myRangeVec.get(i).low;
			for (int j = 0; j < pCardWithNoLaizi.size(); ++j) {
				if ((pCardWithNoLaizi.get(j).getPoint() <= myRangeVec.get(i).hight)
						&& (pCardWithNoLaizi.get(j).getPoint() >= myRangeVec
								.get(i).low)) {
					++iHave;
				} else {
					surplusVec.add(pCardWithNoLaizi.get(j));
				}
			}

			int iSurplus = (int) (pCardIsLaizi.size() - (iPlAneLong * 3 - iHave));

			if (iSurplus < 0)// 错误条件一
				continue;

			// -----------------------------分离剩余Vec

			int iDifference = judgeDifference(surplusVec);
			for (int j = 0; j < ((int) surplusVec.size()) - 2; ++j) {
				if (surplusVec.get(j).getPoint() == surplusVec.get(j + 2)
						.getPoint()) {
					iDifference++;
					j = j + 2;
				}
			}

			if (iDifference > iPlAneLong)// 错误条件二
				continue;

			for (int j = 0; j < pCardWithNoLaizi.size(); ++j) {
				if (pCardWithNoLaizi.get(j).getPoint() == myRangeVec.get(i).hight)
					pCardReturn_Laizi.copy(CardType_Laizi.PLANE_2,
							pCardWithNoLaizi.get(j), (int) iPlAneLong * 5);
			}
			Card myTestCard = new Card(Card.Dimond, myRangeVec.get(i).hight);
			pCardReturn_Laizi.copy(CardType_Laizi.PLANE_2, myTestCard,
					(int) iPlAneLong * 5);
			return true;
		}

		return false;
	}

	/** 判断ArrayList中元素是相同 **/
	public boolean judgeSame(final ArrayList<Card> myCard) {
		if (myCard.isEmpty())
			return false;
		int size = myCard.size();

		if (myCard.get(0).getPoint() == myCard.get(size - 1).getPoint()) // 相邻两个是否相同
		{
			return true;
		} else {
			return false;
		}
	}

	/** p判断ArrayList中不同的元素 **/
	public int judgeDifference(final ArrayList<Card> myCard) {
		if (myCard.size() <= 1)
			return myCard.size();

		int iNum = 1;

		for (int i = 0; i < ((int) myCard.size()) - 1; ++i) {
			if (myCard.get(i).getPoint() != myCard.get(i + 1).getPoint())
				iNum++;
		}
		return iNum;
	}

	/** 判断ArrayList中是否为顺子 **/
	public boolean judgeIsCHAIN(final ArrayList<Card> myCard) {
		for (int i = 0; i < ((int) myCard.size()) - 1; ++i) {
			if (myCard.get(i).getPoint() - myCard.get(i + 1).getPoint() != 1) {
				return false;
			}
		}

		return true;
	}

	public boolean judgeTRIOandPAIR(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi, int iSize) {
		int iCHAINNum = (pCardWithNoLaizi.size() + pCardIsLaizi.size()) / iSize;
		int iA = Card.PointA;
		CardType_Laizi myType = CardType_Laizi.CardEnd;
		if (iSize == 2)
			myType = CardType_Laizi.PAIR_CHAIN;
		else if (iSize == 3)
			myType = CardType_Laizi.PLANE;

		//原代码:Card myCard = new Card(pCardIsLaizi.get(0));8、癞、7、7、6、6不通过
		Card myCard = new Card(pCardWithNoLaizi.get(0));// 随便搞一个

		if (!pCardWithNoLaizi.isEmpty()) {
			if (pCardIsLaizi.size() == iCHAINNum * iSize) {
				int iHead = pCardIsLaizi.get(0).getPoint() + (iCHAINNum - 1);

				if ((iHead > iA)) {
					iHead = iA;
				}

				myCard.setPoint(Card.changePoint(iHead));
				pCardReturn_Laizi.copy(myType, myCard, iSize * iCHAINNum);
				return true;
			} else// 有非癞子牌情况
			{
				boolean result=unitsParts(pCardWithNoLaizi, pCardIsLaizi, pCardReturn_Laizi, myType, iCHAINNum,iSize);
				if(result){
					pCardReturn_Laizi.setmCardNum(pCardWithNoLaizi.size() + pCardIsLaizi.size());
				}
				return result;
			}
		}
		return true;
	}
	
	/**
	 * 收集单位组件（对，三同，四同）
	 * @param pCardWithNoLaizi  无癞子牌集合
	 * @param pCardIsLaizi  癞子牌集合
	 * @param pCardReturn_Laizi
	 * @param myType 牌型
	 * @param iChainNum 连续组件数量
	 * @param iSize  组件单位长度
	 * @return
	 */
	public boolean unitsParts(final ArrayList<Card> pCardWithNoLaizi,
			final ArrayList<Card> pCardIsLaizi,
			CardReturn_Laizi pCardReturn_Laizi,CardType_Laizi myType,int iChainNum ,int iSize){
			//添加点数连续性
			int head=pCardWithNoLaizi.get(0).getPoint();
			int next=0;
			int laiziCnt = pCardIsLaizi.size();
			int continuCnt = iSize;// 此点连续数
			int saveHead=0;
			int partCnt=0;
			
			Card myCard = new Card(Card.Dimond,head);// 随便搞一个
			
			for (int headPos=0,offsetPos = 0; offsetPos< pCardWithNoLaizi.size();) {
				next=pCardWithNoLaizi.get(offsetPos).getPoint();
				if(next==head){
					offsetPos++;
				}else{//加癞子
					laiziCnt--;
					if(laiziCnt<0){
						headPos=headPos+1;
						offsetPos=headPos+1;
						saveHead=head=pCardWithNoLaizi.get(headPos).getPoint();
						laiziCnt=pCardIsLaizi.size();
						continuCnt=iSize;
						partCnt=0;
					}
				}
				continuCnt--;
				if(0==continuCnt){//找到或凑成iSize个
					if(0==saveHead){
						saveHead=head;
					}
					head=head-1;
					continuCnt=iSize;
					partCnt++;
					if(partCnt>=iChainNum){
						break;
					}
				}
			}
			
			//补齐
			if(partCnt<iChainNum){
				int brankPart=(int) (iChainNum-partCnt-1);
				if(laiziCnt>=continuCnt+brankPart*iSize){
					if(continuCnt!=iSize){//节点完整,不需补部分了
						laiziCnt-=continuCnt;
					}
					partCnt+=1+brankPart;
				}else{
					return false;
				}
			}
			
			if(partCnt==iChainNum){
				myCard.setPoint(saveHead);
				if (laiziCnt > 0) {// 剩下癞子牌，往head牌上加点
					//可能会问题:目前未测试出问题
					head = saveHead + laiziCnt / iSize;
					if (head >Card.PointA) {
						myCard.setPoint(Card.changePoint(Card.PointA));
					}else{
						myCard.setPoint(head);
					}
				}
				pCardReturn_Laizi.copy(myType, myCard);
			}else{
				return false;
			}
			return true;
	}
}
