package taurus.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import com.game.Util;



public class WinCard {
	public int					pair_count;
	public Stack<List<Integer>>	stack;
	public List<Integer>		cardList;
	public boolean				jiang	= true;
	public int					zhong_count;
	public int					zhongid	= 0;

	private void push(List<Integer> cardGroup) {
		this.stack.push(cardGroup);
	}

	private void rollBack() {
		List<Integer> cardGroup = this.stack.pop();
		for (Integer card : cardGroup) {
			if (card == zhongid) {
				this.zhong_count += 1;
			} else {
				this.cardList.add(card);
			}
		}
		Collections.sort(this.cardList);
	}

	private boolean tryShunzi(int card) {
		if (card % 100 > 7) {
			return false;
		}

		if (Util.checkCard(card + 1, this.cardList) && Util.checkCard(card + 2, this.cardList)) {
			Util.removeCard(this.cardList, card, 1);
			Util.removeCard(this.cardList, card + 1, 1);
			Util.removeCard(this.cardList, card + 2, 1);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card + 1);
			cardGroup.add(card + 2);
			this.push(cardGroup);
			return true;
		}
		return false;
	}

	private boolean tryKezi(int card) {
		if (Util.checkCardAndRomve(card, this.cardList, 3)) {
//			CardUtil.removeCard(this.cardList, card, 3);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			return true;
		}
		return false;
	}

	private boolean tryPair(int card) {
		if (this.pair_count > 0) {
			return false;
		}
		if (jiang) {
			if (!(card % 100 == 2 || card % 100 == 5 || card % 100 == 8)) {
				return false;
			}
		}
		if (Util.checkCardAndRomve(card, this.cardList, 2)) {
//			CardUtil.removeCard(this.cardList, card, 2);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			this.pair_count = 1;
			return true;
		}
		return false;
	}

	private boolean tryKezi1Zhong(int card) {
		if (this.zhong_count >= 1 && Util.checkCardAndRomve(card, this.cardList, 2)) {
//			CardUtil.removeCard(this.cardList, card, 2);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			cardGroup.add(this.zhongid);
			this.zhong_count -= 1;
			this.push(cardGroup);
			return true;
		}
		return false;
	}

	private boolean tryShunzi1Zhong(int card) {
		if (card % 100 > 8) {
			return false;
		}

		if (this.zhong_count < 1) {
			return false;
		}

		if (Util.checkCard(card + 1, this.cardList)) {
			Util.removeCard(cardList, card, 1);
			Util.removeCard(cardList, card + 1, 1);
			this.zhong_count -= 1;
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card + 1);
			cardGroup.add(this.zhongid);
			this.push(cardGroup);
			return true;
		}

		if (Util.checkCard(card + 2, this.cardList) && ((card + 1) % 100 != 0)) {
			Util.removeCard(cardList, card, 1);
			Util.removeCard(cardList, card + 2, 1);
			this.zhong_count -= 1;
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(this.zhongid);
			cardGroup.add(card + 2);
			this.push(cardGroup);
			return true;
		}
		return false;
	}

	private boolean tryPair1Zhong(int card) {
		if (this.pair_count > 0) {
			return false;
		}
		if (jiang) {
			if (!(card % 100 == 2 || card % 100 == 5 || card % 100 == 8)) {
				return false;
			}
		}
		if (this.zhong_count < 1) {
			return false;
		}

		Util.removeCard(cardList, card, 1);
		List<Integer> cardGroup = new ArrayList<Integer>();
		cardGroup.add(card);
		cardGroup.add(this.zhongid);
		this.push(cardGroup);
		this.zhong_count -= 1;
		this.pair_count = 1;
		return true;
	}

	public boolean tryWin() {
		if (this.cardList.size() == 0 && this.pair_count == 1) {
			return true;
		}

		if (this.cardList.size() == 0) {
			return false;
		}
		int activeCard = this.cardList.get(0);

		if (tryPair(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.pair_count = 0;
			this.rollBack();
		}

		if (tryKezi(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.rollBack();

		}
		if (tryShunzi(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.rollBack();
		}

		if (tryKezi1Zhong(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.rollBack();

		}
		if (tryShunzi1Zhong(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.rollBack();
		}
		if (tryPair1Zhong(activeCard)) {
			if (tryWin()) {
				return true;
			}
			this.pair_count = 0;
			this.rollBack();
		}

		return false;
	}

	public WinCard(List<Integer> cardInhand, int addCard) {
		this.stack = new Stack<List<Integer>>();
		this.cardList = new ArrayList<Integer>();
		this.cardList.addAll(cardInhand);
		if (addCard == 0) {
			this.zhongid = 0;
			this.zhong_count = 1;
		} else {
			this.cardList.add(addCard);
		}

		Collections.sort(this.cardList);
	}

	public static void main(String[] args) {

		long time = System.currentTimeMillis();
//		for (int i = 0; i < 1000000; ++i) {
		ArrayList<Integer> cardInhand = new ArrayList<Integer>();
		cardInhand.add(207);
		cardInhand.add(207);
		cardInhand.add(202);
		cardInhand.add(202);
		cardInhand.add(202);
		cardInhand.add(109);

		cardInhand.add(109);
		cardInhand.add(109);
		cardInhand.add(104);
		cardInhand.add(104);
		cardInhand.add(102);
		cardInhand.add(102);

		cardInhand.add(102);
//			cardInhand.add(301);
//			cardInhand.add(301);
//			cardInhand.add(108);

//			cardInhand.contains(204);
//			Util.checkCard(204, cardInhand);
//			CardUtil.checkCardAndRomve(204, cardInhand, 2);

//			if(Util.checkCard(204, cardInhand)) {
//				CardUtil.removeCard(cardInhand, 204, 2);
//			}
			WinCard win = new WinCard(cardInhand, 104);
			boolean c = win.tryWin();
			System.out.println(c);
//			Paixing.tingKongCheck(new ArrayList<>(), cardInhand, 301);
//		}
		//Map<Integer, WinCardType> map = new HashMap<Integer, WinCardType>();
		//Paixing.checkWin(map, new ArrayList<>(), cardInhand, 305, room.difen_score);

		System.out.println(System.currentTimeMillis() - time);

	}

}
