地方麻将吉林过蛋玩法算法

最近在做地方棋牌游戏,发现有的地方棋牌玩法很独特,比如吉林的过蛋玩法 。先贴出代码,后面在做介绍。算法可鞥不是最优解,欢迎大神拍砖,交流QQ:850912758。

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/// <summary>
/// 判断  过蛋/补蛋  牌逻辑 类
/// 输入:手牌中的蛋牌
/// 输出:可过蛋牌的 所有 排列组合
/// 方法:
///           1. 无 混 :
///                      所有蛋牌排列组合
///           2.有混:
///           2.1.一张混牌所有排列组合
///           2.2 两张混牌所有排列组合
/// </summary>
public class EggCtro
{
    private static EggCtro _instance = null;

    List<int> InputEggCard;//输入的手牌
    private List<List<int>> OutPutEggs = new List<List<int>>();//输出的的过蛋牌 


    private List<List<int>> CurEggCardList ;//当前碰牌区 的蛋牌列表 
    private List<int> AddEggCardList = new List<int>();//补蛋  单张蛋牌集合 (输出的补蛋集合)


     int CardHun = 11;//混牌
    //标准蛋牌 
    int[] Egg1 = { 1, 11, 21 };
    int[] Egg2 = { 9, 19, 29 };
    int[] Egg3 = { 35, 36, 37 };
    int[] Egg4 = { 31, 32, 33, 34 };
    List<int[]> AllEggs = new List<int[]>();
    //标准蛋牌

    public static EggCtro Instance
    {
        get
        {
            if (_instance == null)
                _instance = new EggCtro();
            return _instance;
        }
    }

    #region 过蛋

    void InIt()
    {
        AllEggs.Clear();
        AllEggs.Add(Egg1);
        AllEggs.Add(Egg2);
        AllEggs.Add(Egg3);
        AllEggs.Add(Egg4);
    }

   /// <summary>
   /// 获取可过蛋牌列表
   /// </summary>
   /// <param name="handCards"></param>
   /// <returns></returns>
    public List<List<int>> GetEggCardValues(List<int> handCards)
    {
        OutPutEggs.Clear();
        InputEggCard = handCards;
        InIt();
        NoHunEgg();

        //手牌 中的蛋牌 分类
        List<int> CurYaoEggCard = new List<int>();
        List<int> CurJiuEggCard = new List<int>();
        List<int> CurZFBEggCard = new List<int>();
        List<int> CurFengEggCard = new List<int>();

        if (IsHandHunCard())
        {
            int hunCount = GetHunCount();
            RemoveHunCard();
            DistinctCard();
            //找出当前手牌 每种蛋牌类型的 一张混牌组合
            foreach (int item in InputEggCard)
            {
                if (item == 1||item == 21) { CurYaoEggCard.Add(item); }
                else if (item == 9 || item == 19 || item == 29) { CurJiuEggCard.Add(item); }
                else if (item == 31 || item == 32 || item == 33 || item == 34) { CurZFBEggCard.Add(item); }
                else if (item >= 35 || item == 36 || item == 37) { CurFengEggCard.Add(item); }
            }
            if (hunCount == 1)
            {
                //一个混 
                //蛋牌组 大于两张 ,才可以配合一张混牌组成蛋牌 
                AddOutPutThree(CurYaoEggCard);
                AddOutPutThree(CurJiuEggCard);
                AddOutPutThree(CurZFBEggCard);
                AddOutPutThree(CurFengEggCard); //风牌 四张不同牌 时的多种 排列组合

            }
            else if (hunCount >= 2)
            {
                //一个混 
                //蛋牌组 大于两张 ,才可以配合一张混牌组成蛋牌 
                AddOutPutThree(CurYaoEggCard);
                AddOutPutThree(CurJiuEggCard);
                AddOutPutThree(CurZFBEggCard);
                AddOutPutThree(CurFengEggCard); //风牌 四张不同牌 时的多种 排列组合
                //两个混  
                //可以跟每一张蛋牌组合 成蛋
                AddEggCard(CurYaoEggCard);
                AddEggCard(CurJiuEggCard);
                AddEggCard(CurZFBEggCard);
                AddEggCard(CurFengEggCard);
            }

        }
        return OutPutEggs;
        //ShowLog();
    }
    // 两混 添加提示 蛋牌 列表
    private void AddEggCard(List<int> CurYaoEggCard)
    {
        foreach (int item in CurYaoEggCard)
        {
            if (item == CardHun)//不能三个幺鸡
                continue;
            List<int> tempEgg = new List<int>();
            tempEgg.Add(item);
            tempEgg.Add(CardHun);
            tempEgg.Add(CardHun);
            OutPutEggs.Add(tempEgg);
        }
    }

    //一个混 三张 牌加入
    private void AddOutPutThree(List<int> HandEggCards)
    {
        if (HandEggCards.Count == 2)//两张牌 直接+混
        {
            HandEggCards.Add(CardHun);
            OutPutEggs.Add(HandEggCards);
        }
        else if (HandEggCards.Count >= 3)
        {
            List<int[]> tempEggList = Arrage(HandEggCards, 2); //三选二 排列 / 四选二 排列组合
            foreach (int[] item in tempEggList)
            {
                List<int> egg = item.ToList();
                egg.Add(CardHun);
                OutPutEggs.Add(egg);
            }
        }
    }
    //无混 排列组合
    public void NoHunEgg()
    {

        InputEggCard.Sort();
        //包含标准 蛋牌
        foreach (int[] egg in AllEggs)
        {
            List<int> same = ExistsEggType(egg);
            int sameCount = same.Count;
            if (sameCount == 3)
            {
                OutPutEggs.Add(same);
            }
            else if (sameCount == 4)
            {
                //完整风牌
                List<int[]> fengEgg = Arrage(same.ToList<int>(), 3);//4 选3 排列组合
                foreach (int[] item in fengEgg)
                {
                    OutPutEggs.Add(item.ToList<int>());
                }
            }
        }


    }
    void ShowLog()
    {
        string str = "";
        foreach (List<int> item in OutPutEggs)
        {
            str += " 【";
            foreach (int card in item)
            {
                str += card + " ";
            }
            str += " 】";
        }
        Debug.Log("输出蛋牌为:" + str + "             " + OutPutEggs.Count);
    }
    /// <summary>
    /// 是否包含标准蛋牌(风牌 三张组合例外)
    /// </summary>
    /// <param name="egg">标准蛋牌</param>
    List<int> ExistsEggType(int[] egg)
    {
        int eggCount = 0;
        List<int> tempEgg = new List<int>();
        for (int i = 0; i < egg.Length; i++)
        {
            if (InputEggCard.Exists(o => o == egg[i]))
            {
                eggCount++;
                tempEgg.Add(egg[i]);
            }
        }
        return tempEgg;
    }
    /// <summary>
    /// 手牌中是否包含混牌
    /// </summary>
    /// <returns></returns>
    bool IsHandHunCard()
    {
        return InputEggCard.Exists(o => o == CardHun);
    }
    //混牌数量
    int GetHunCount()
    {
        return InputEggCard.Count(delegate (int item) { return item == CardHun; });
    }
    //移除混牌 的手牌列表
    void RemoveHunCard()
    {
        int count = GetHunCount();
        for (int i = 0; i < count; i++)
        {
            InputEggCard.Remove(CardHun);
        }
    }
    //去除重复牌
    void DistinctCard()
    {
        List<int> result = InputEggCard.Distinct().ToList();//去重复
    }
    //M选N 排列组合
    List<int[]> Arrage(List<int> input, int _n)
    {
        //排列算法
        List<int> inputValue = input;
        int n = _n;
        var result = inputValue.Select(x => new int[] { x });
        for (int i = 0; i < n - 1; i++)
        {
            result = result.SelectMany(x => inputValue.Where(y => y.CompareTo(x.First()) < 0).Select(y => new int[] { y }.Concat(x).ToArray()));
        }
        List<int[]> resultList = new List<int[]>();
        foreach (int[] item in result)
        {
            resultList.Add(item);
        }
        return resultList;
    }

    #endregion





    #region 补蛋

    /// <summary>
    ///  找出手牌中可以补蛋的牌!
    /// </summary>
    /// <param name="curHandCards">当前手中蛋牌</param>
    /// <param name="yetEggs">已过蛋牌</param>
   public List<int> AddEgg(List<int> curHandCards,List<List<int>> yetEggs)
    {
        CurEggCardList = yetEggs;
        InputEggCard = curHandCards;
        if (CurEggCardList.Count == 0)
        {
            return null;
        }
        if (InputEggCard.Count == 0) {
            return null;
        }
        AddEggCardList.Clear();



        ////先判断蛋牌区 无 混牌情况 
        //再判断蛋牌区 有 混牌情况 
        //如果是 替换 幺鸡 的蛋牌 ,需要将幺鸡替换掉 并 加到头像下 +1
        foreach (int handCard in InputEggCard)
        {
            if (handCard == CardHun)
            {
                AddEggCardList.Add(handCard);//幺鸡 直接加入
                continue;
            }
        }
        //无混 蛋牌
        foreach (List<int> egg in CurEggCardList)
        {
            foreach (int card in egg)
            {
                int[] eggValue = GetEggType(card);

                foreach (int handCard in InputEggCard)
                {
                    foreach (int eggCard in eggValue)
                    {
                        if (eggCard == handCard && eggCard != CardHun)
                            AddEggCardList.Add(handCard);//手牌 里有已过蛋牌值 
                    }
                }
                break;
            }
        }

        //有混 蛋牌
        List<int[]> hunEggs = GetHunEggValue();
        foreach (int[] hunEgg in hunEggs)
        {
            List<int> insteadValue = GetHunEggInstead(hunEgg);
            List<int> handEggValue = InputEggCard.Intersect(insteadValue).ToList();//手牌里是否有被混取代的牌值
            if (handEggValue.Count > 0)
                AddEggCardList.AddRange(handEggValue);//得到 被混 取代的蛋牌值
        }


        string eggStr = "";
        foreach (int item in AddEggCardList)
        {
            eggStr += "     " + item.ToString();
        }
        Debug.LogError("可补蛋的牌:" + eggStr);


        return AddEggCardList;
    }


    /// <summary>
    /// 获取牌所属蛋牌型
    /// </summary>
    /// <param name="cardValue">牌值</param>
    /// <returns></returns>
   public int[] GetEggType(int cardValue)
    {
        int[] Eggs = null;
        foreach (int[] eggs in AllEggs)
        {
            foreach (int card in eggs)
            {
                if (cardValue == card)
                {
                    Eggs = eggs;
                }
            }
        }
        return Eggs;
    }
    /// <summary>
    /// //获取hun 蛋牌 中被混牌取代的值
    /// </summary>
    /// <param name="egg">含混蛋</param>
    /// <returns></returns>
    List<int> GetHunEggInstead(int[] egg)
    {
        List<int> tempValues = new List<int>();
        tempValues.Clear();

        List<int> NoHunValue = GetNoHunValue(egg);//获得 含混蛋牌中 不是混的 牌值 
        int cardValue = NoHunValue[0];//根据这个牌值 判断 所属 蛋牌类型 
        int[] typeEgg = GetEggType(cardValue);//获得 该蛋牌的 标准值 
        List<int> typeEggList = typeEgg.ToList();

        //和标准蛋牌比较,得出混牌代替的牌值 
        tempValues = typeEggList.Except(NoHunValue).ToList();//除什么之外?     Except  差集       Intersect交集      Union并集
        return tempValues;
    }

    /// <summary>
    /// 获取含混蛋牌 中的 非混牌值
    /// </summary>
    /// <returns>含混牌的 蛋</returns>
    List<int> GetNoHunValue(int[] hunEgg)
    {
        List<int> values = new List<int>();
        values.Clear();
        foreach (int eggCard in hunEgg)
        {
            if (eggCard != CardHun)
            {
                values.Add(eggCard);
            }
        }
        return values;
    }
    //获取包含 混牌 的蛋
    List<int[]> GetHunEggValue()
    {

        List<int[]> YiTiaoEggs = new List<int[]>();
        YiTiaoEggs.Clear();
        foreach (List<int> egg in CurEggCardList)
        {
            bool isHun = IsHunCard(egg);
            if (isHun)
            {
                int[] HunEgg = egg.ToArray();
                YiTiaoEggs.Add(HunEgg);
            }
        }
        return YiTiaoEggs;
    }
    //是否包含混牌
    bool IsHunCard(List<int> eggs)
    {
        foreach (int card in eggs)
        {
            if (card == CardHun)
            {
                return true;
            }
        }
        return false;
    }




    /// <summary>
    /// //获得 已 过蛋的 牌值
    /// </summary>
    /// <param name="cardValue"></param>
    /// <returns></returns>
    public List<int> GetAsAddEgg(int cardValue)
    {
        int[] eggType = EggCtro.Instance.GetEggType(cardValue);
        foreach (List<int> item in CurEggCardList)
        {
            foreach (int eggCard in item)
            {
                foreach (int typeCard in eggType)
                {
                    if (eggCard != 11 && eggCard == typeCard)
                    {
                        return item;
                    }
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 替换 List <int>
    /// </summary>
    /// <param name="item"></param>
    /// <param name="curValue"></param>
    /// <param name="repValue">被替换的值</param>
    public  void ReplaceListValue(ref List<int> item, int curValue, int repValue)
    {
        int index = item.FindIndex(delegate (int i) { return i == curValue; });
        if (index < item.Count)
            item[index] = repValue;
    }
    /// <summary>
    /// 获得列表中大于1个的 重复组
    /// </summary>
    /// <param name="listValue"></param>
    /// <returns>(Dic<值-个数>)</returns>
    public  Dictionary<int, int> GetListRepitGroup(List<int> listValue)
    {
        //重复组
        Dictionary<int, int> RepetGroup = new Dictionary<int, int>();
        var result = from r in listValue
                     group r by r into g
                     where g.Count() > 1
                     select g;
        //遍历分组结果集
        foreach (var item in result)
        {
            foreach (int u in item)
            {
                RepetGroup.Add(u, item.Count<int>());
                Debug.Log(u + "       " + item.Count<int>());
                break;
            }
        }
        return RepetGroup;
    }
    #endregion


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值