`
墙头上一根草
  • 浏览: 149238 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

麻将胡牌逻辑 java

阅读更多

      最近写了一个麻将的胡牌逻辑,这个麻将是没有万字牌 和 东西南北风牌,以前也写过麻将胡牌逻辑,都没有记录,这次记录一下,方便以后查阅

 

   

/**
	 * 胡牌
	 * @param isZiMo  是否自摸
	 * @param roleId  胡牌玩家
	 * @param pcc     麻将场
	 */
	public static boolean huCard(boolean isZiMo,int roleId,PlayCardContext pcc){
		PlayCardUnit pcu = pcc.getCardUnitByRoleId(roleId);
		
		List<Byte> handCards = pcu.getCards();
		List<OperateCardData> chiPengGangCard = pcu.getChiPengGangCard();
		
		int cardSize = handCards.size();
		//1-9的索引为筒子 11-19为条子 21-23为中发白
		byte[] cards = new byte[24];
		byte[] color = new byte[3];
		
		for (int i = 0; i < cardSize; i++) {
			byte cardId = handCards.get(i);
			SCard card = (SCard) StaticData.getStaticModel(EStaticData.CARD, cardId);
			int index = 0;
			
			if(card.type == EColorType.TONG_ZI.getType()){
				index = card.value;
				color[0]++;
			}else if (card.type == EColorType.TIAO_ZI.getType()) {
				index = 10+card.value;
				color[1]++;
			}else  {
				index = 20+card.value;
				color[2]++;
			}
			cards[index]++;
		}
		int colorCount = (color[0]!=0?1:0)+(color[1]!=0?1:0)+(color[2]!=0?1:0);
		boolean isSameColor = colorCount==1;
		
		if(isSameColor){
			int size = chiPengGangCard==null?0:chiPengGangCard.size();
			
			if(size>0){
				for (int i = 0; i < size; i++) {//计算吃碰杠的牌是否清一色
					OperateCardData ocd = chiPengGangCard.get(i);
					SCard card = (SCard) StaticData.getStaticModel(EStaticData.CARD, ocd.getCards().get(0));
					
					if(card.type == EColorType.TONG_ZI.getType()){
						color[0]++;
					}else if (card.type == EColorType.TIAO_ZI.getType()) {
						color[1]++;
					}else  {
						color[2]++;
					}
				}
				colorCount = (color[0]!=0?1:0)+(color[1]!=0?1:0)+(color[2]!=0?1:0);
				isSameColor = colorCount==1;
			}
			
		}
		List<String> huCardPatterns = new ArrayList<>();//胡牌牌型
		int fanCount =isHu(cards, cardSize, chiPengGangCard,isSameColor,huCardPatterns);
		boolean isHuCard = fanCount !=-1;
		
		if(isHuCard){
			pcc.setStart(false);
			pcc.setReadyRoleIds(null);
			pcc.calHuScore(roleId, isZiMo, fanCount);
			pcc.setWinUnit(pcu);
		}
		return isHuCard;
	}
	
	
	
	/**
	 * 是否胡牌
	 * @param cards                具有的手牌信息
	 * @param cardSize             手牌数量
	 * @param chiPengGangCard      所有吃碰杠的牌
	 * @param isSameColor          是否清一色
	 * @return                     -1-没有胡牌 其他-为胡牌的翻数
	 */
	public static int isHu(byte[] cards,int cardSize,List<OperateCardData> 
					chiPengGangCard,boolean isSameColor,List<String> huCardPatterns){
		if(cardSize<2||((cardSize-2)%3)!=0) return -1;//查看牌型是否满足3n+2
		Map<Byte,Byte> cardTypeCounts = new HashMap<>(3);
		Map<Byte,Byte> chiPengGang = new HashMap<>(3);
		
		for (int i = 0; i < CARD_COUNT; i++) {//计算手牌 每种牌 的数量(0 1 2 3 4)
			byte count = cards[i];
			if(count<=1) continue;
			Byte inCount = cardTypeCounts.get(count);
			cardTypeCounts.put(count, (byte)(1+(inCount==null?0:inCount)));
		}
		int size = chiPengGangCard==null?0:chiPengGangCard.size();
		
		for (int i = 0; i < size; i++) {//计算吃碰杠的牌
			OperateCardData ocd = chiPengGangCard.get(i);
			
			if(ocd.getCardType() == EOperateCardType.CHI_TYPE){
				Byte inCount = cardTypeCounts.get((byte)1);
				cardTypeCounts.put((byte)1, (byte)(1+(inCount==null?0:inCount)));
			}else if(ocd.getCardType() == EOperateCardType.PENG_TYPE){
				Byte inCount = cardTypeCounts.get((byte)2);
				cardTypeCounts.put((byte)2, (byte)(1+(inCount==null?0:inCount)));
			}else if(ocd.getCardType() == EOperateCardType.AN_GANG_TYPE
					||ocd.getCardType() == EOperateCardType.MING_GANG_TYPE){
				Byte inCount = cardTypeCounts.get((byte)3);
				cardTypeCounts.put((byte)3, (byte)(1+(inCount==null?0:inCount)));
			}
		}
		Byte qiDuiZiCount = cardTypeCounts.get((byte)2);//对子的数量
		Byte anGangCount = cardTypeCounts.get((byte)4);//四个的数量
		Byte anKeCount = cardTypeCounts.get((byte)3);//三个的数量
		
		Byte chiCardCount = chiPengGang.get((byte)1);//吃的数量
		Byte mingKeCount = chiPengGang.get((byte)2);//碰的数量
		Byte mingGangCount = chiPengGang.get((byte)3);//杠的数量(包括明杠 暗杠)
		
		//七对子的数量
		int qdzCount = (qiDuiZiCount==null?0:qiDuiZiCount)+(anGangCount==null?0:(anGangCount*2));
		//刻和杠的数量
		int keZiAndGangCount = (anGangCount==null?0:anGangCount)+(mingGangCount==null?0:mingGangCount)
				+(anKeCount==null?0:anKeCount)+(mingKeCount==null?0:mingKeCount);
		//吃碰杠的数量
		int chiPengGangCount = (mingGangCount==null?0:mingGangCount)
				+(chiCardCount==null?0:chiCardCount)+(mingKeCount==null?0:mingKeCount);
		
		int hongZhongCount = cards[21];
		int faCaiCount = cards[22];
		int baiBanCount = cards[23];
		//红中 发财 白板的数量
		int totalCount = hongZhongCount+faCaiCount+baiBanCount;
		
		if(qdzCount==7){//七对子
			if(isSameColor){//清一色七对子
				huCardPatterns.add(Hu_card_type_1);
				return 8;
			}else if (anGangCount!=null) {//豪华七对子
				huCardPatterns.add(Hu_card_type_3);
				return 8;
			}else if (totalCount>=8){//三元七对
				huCardPatterns.add(Hu_card_type_4);
				return 8;
			}
			huCardPatterns.add(Hu_card_type_2);
			return 4;
		}else if(chiCardCount==null&&(qiDuiZiCount==null?
				0:qiDuiZiCount)==1&&keZiAndGangCount>=4){//碰碰胡
			huCardPatterns.add(Hu_card_type_5);
			
			if(isSameColor){
				huCardPatterns.add(Hu_card_type_1);
				return 8;
			}
			return 4;
		}else if((qiDuiZiCount==null?0:qiDuiZiCount)==1&&chiPengGangCount>=4){//手抓一
			huCardPatterns.add(Hu_card_type_6);
			
			if(isSameColor){
				huCardPatterns.add(Hu_card_type_1);
				return 8;
			}
			return 4;
		}else {//普通胡牌
			List<List<CardTypeData>> cardTypeDatas = new ArrayList<>();
			
			for (int i = 0; i < CARD_COUNT; i++) {
	            int count = cards[i];
	            
				if(count>=2){
					byte[] data = new byte[CARD_COUNT];
					System.arraycopy(cards, 0, data, 0, CARD_COUNT);
					data[i] -=2 ;
					List<CardTypeData> currData = new ArrayList<>();
					currData.add(new CardTypeData(ECardType.JIANG, data[i]));
					
					if (isHuCurrCardType(data, currData)) {
						cardTypeDatas.add(currData);
					}
				}
			}
			if(cardTypeDatas.size()<=0) return -1;//不胡牌

			if(totalCount==8){//小三元
				huCardPatterns.add(Hu_card_type_7);
				return 4;
			}else if(totalCount==9){//大三元
				huCardPatterns.add(Hu_card_type_8);
				return 8;
			}
			huCardPatterns.add(Hu_card_type_9);
			return 1;
		}
	}
	
	
	/**
	 * 当前牌型是否能胡牌
	 * @param cards  胡牌信息
	 * @param result 胡牌牌型
	 * @return
	 */
	private static boolean isHuCurrCardType(byte[] cards,List<CardTypeData> result){
		for (int i = 0; i < CARD_COUNT; i++) {
			int value = cards[i];
			if(value == 0) continue;
			
			if(value ==1||value ==4){
				if(i>20||cards[i+1]<1||cards[i+2]<1) return false;
				result.add(new CardTypeData(ECardType.SHUN_ZI, (byte)cards[i+2]));
				cards[i]--;
				cards[i+1]--;
				cards[i+2]--;
				
				if(value ==4){
					result.add(new CardTypeData(ECardType.AN_KE_ZI, (byte)value));
					cards[i]=0;
				}
			}else if (value ==2) {
				if(i>20||cards[i+1]<2||cards[i+2]<2) return false;
				cards[i]-=2;
				cards[i+1]-=2;
				cards[i+2]-=2;
				CardTypeData ctd = new CardTypeData(ECardType.SHUN_ZI, (byte)cards[i+2]);
				result.add(ctd);
				result.add(ctd);
			}else if (value ==3) {
				result.add(new CardTypeData(ECardType.AN_KE_ZI, (byte)value));
				cards[i]=0;
			}
			isHuCurrCardType(cards, result);
		}
		return true;
	}

 

0
0
分享到:
评论
1 楼 oyhuang 2019-08-17  
看不懂啊,这么多行

相关推荐

Global site tag (gtag.js) - Google Analytics