来园子快一年了,从来都是只看看,不说话。一来觉得自己技术太弱,说出来误导别人;二来自己文笔太差,写出来不通就贻笑大方了。

    之前看到园子有人发了一道面试题,觉得蛮有意思的,鼓起勇气写一篇,让大神们扶正一下,也好促进自己进步!

题目描述:

规则一:
四张牌相同。自然数字大的胜出,比如3,3,3,3 < 6,6,6,6
规则二:
四张牌连续。当然序列最大的那个胜出。但是有个小trick,A在这里默认表最大牌,但是如果后接2,3,4,则A表最小牌,为了获得连续序列
比如A,2,3,4 < J,Q,K,A
规则三:
有三张相同。以每个序列相同牌较大的胜出。  
比如3,3,3,2>2,2,2,A  
规则四:  
两个对子。当然以对子较大的胜出,最大的对子相同,则以次大的对子较大者胜出。
比如4,4,3,3 > 4,2,4,2
规则五:
一个对子。对子较大者胜出,如果对子相同,则比较剩下较大牌,如果还相同,比较次大牌
3,3,7,4 < 3,3,7,5
规则六:  
规则序号越小越号,即规则一大于规则二,规则二大于规则三,依次类推;如果以上皆不满足,则按照大牌>小牌比较(即从最大牌开始比较,分出高下为止)

 

    看到这个规则第一印象就是我们四川的斗地主嘛(每年过年,全家必玩的游戏,嘿嘿),不过是四张牌和没有花色而已!

    首先是Card类:

/// <summary>
    ////// </summary>
    public class Card : IComparable
    {
        private string num;
        private int count;
        /// <summary>
        /// 数字
        /// </summary>
        public int Num
        {
            get
            {
                return ConvertStringToNum(num);
            }
            set
            {
                num = value.ToString();
            }
        }
        /// <summary>
        /// 出现次数
        /// </summary>
        public int Count
        {
            get { return count; }
            set { count = value; }
        }
        public Card(string num)
        {
            this.num = num.Trim();
            this.Count = 1;
        }
        public Card()
        { }
        /// <summary>
        /// 实现排序
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            int result;
            try
            {
                Card card = obj as Card;
                result = this.Count.CompareTo(card.Count);
                if (result == 0)
                {
                    result = this.Num.CompareTo(card.Num);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return result;
        }
        /// <summary>
        /// 将JQKA转为数字,方便比较
        /// </summary>
        /// <param name="inputStr"></param>
        /// <returns></returns>
        private int ConvertStringToNum(string inputStr)
        {
            int result = 0;
            if (!Int32.TryParse(inputStr, out result))
            {
                switch (inputStr)
                {
                    case "J":
                        result = 11;
                        break;
                    case "Q":
                        result = 12;
                        break;
                    case "K":
                        result = 13;
                        break;
                    case "A":
                        result = 14;
                        break;

                }
            }
            return result;

        }
    }
View Code

    这个类主要实现了IComparable中的CompareTo方法,方便之后的排序比较。

    然后是四张牌的类型(原谅我取了一个很sao二声,四川人应该懂得起。金花:GlodFlower):

 public enum GlodFlowerType
    {
        /// <summary>
        /// 散牌
        /// </summary>
        Other,
        /// <summary>
        /// 顺子
        /// </summary>
        Progression,
        /// <summary>
        /// 全相同
        /// </summary>
        AllSame,

    }
View Code

    再后是主要的“金花”类(- -!):

  public class GoldFlower
    {
        public static  List<string> cardNumList =new List<string>  { "A","2","3","4","5","6","7",
        "8","9","10","J","Q","K"};

        private List<int> numList = new List<int>();
        public List<Card> cardList = new List<Card>();
        public GlodFlowerType Type
        {
            get
            {
                numList.Sort();
                if (numList[0] == numList[numList.Count - 1])
                    return GlodFlowerType.AllSame;
                else if (IsProgression(numList))
                    return GlodFlowerType.Progression;
                else
                    return GlodFlowerType.Other;

            }
        }
        /// <summary>
        /// 判断是否是连牌
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private bool IsProgression(List<int> list)
        {
            list.Sort();
            for (int i = 0; i < list.Count - 1; i++)
            {
                if (list[i + 1] != list[i] + 1)
                    return false;
            }
            return true;
        }
        public GoldFlower(List<string> list)
        {
            Card card;
            Card cardA = null;
            List<int> tempList = new List<int>();
            foreach (string s in list)
            {
                card = new Card(s);
                numList.Add(card.Num);
                if (card.Num == 14)
                    cardA = card;
                if (!tempList.Contains(card.Num))
                {
                    tempList.Add(card.Num); ;
                    cardList.Add(card);
                }
                else
                {
                    int index = numList.IndexOf(card.Num);
                    cardList[index].Count += 1;
                }
            }
            if (cardA != null)
            {
                int index = cardList.IndexOf(cardA);
                numList.Remove(14);
                if (IsProgression(numList) && numList.Contains(2))
                {
                    cardList[index].Num = 1;
                    numList.Add(1);
                }
                else
                    numList.Add(14);
            }
        }

        public int CompareTo(GoldFlower glodFlower)
        {
            int result = 0;
            this.cardList.Sort();
            glodFlower.cardList.Sort();
            result = this.Type.CompareTo(glodFlower.Type);
            if (result == 0)
                result = ComparenTwoArray(this.cardList, glodFlower.cardList, this.cardList.Count, glodFlower.cardList.Count);

            return result;
        }

        /// <summary>
        /// 字符串比较思想比较两个数组的大小
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="aLen"></param>
        /// <param name="bLen"></param>
        /// <returns></returns>
        private int ComparenTwoArray(List<Card> a, List<Card> b, int aLen, int bLen)
        {
            int i = aLen - 1, j = bLen - 1;
            while (i > 0 && j > 0)
            {
                if (a[i].Count == b[j].Count && a[i].Num == b[j].Num)
                {
                    i--;
                    j--;
                }
                else if (a[i].Count != b[j].Count)
                    return a[i].Count.CompareTo(b[j].Count);
                else if (a[i].Num != b[j].Num)
                    return a[i].Num.CompareTo(b[j].Num);
            }
            if (i == 0 && j == 0)
            {
                return 0;
            }
            else
            {
                return i == 0 ? -1 : 1;
            }
        }
    }
View Code

    比较两个类的时候,先比较类型,类型相同后再比较牌的数字大小。
    测了几组数据,还没有发现误判,但是感觉好慢。不知道是我的机子太烂还是算法不好。希望各位大神帮帮小女子!

    最后,请教一下大家,我看他们的博客都好漂亮,为什么我的不行?排版这些怎么弄的?真的第一次发这种东西,小白一枚!

 

posted on 2014-11-05 11:16  ilyyin  阅读(3598)  评论(16编辑  收藏  举报