来园子快一年了,从来都是只看看,不说话。一来觉得自己技术太弱,说出来误导别人;二来自己文笔太差,写出来不通就贻笑大方了。
之前看到园子有人发了一道面试题,觉得蛮有意思的,鼓起勇气写一篇,让大神们扶正一下,也好促进自己进步!
题目描述:
规则一:
四张牌相同。自然数字大的胜出,比如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; } }
这个类主要实现了IComparable中的CompareTo方法,方便之后的排序比较。
然后是四张牌的类型(原谅我取了一个很sao二声,四川人应该懂得起。金花:GlodFlower):
public enum GlodFlowerType { /// <summary> /// 散牌 /// </summary> Other, /// <summary> /// 顺子 /// </summary> Progression, /// <summary> /// 全相同 /// </summary> AllSame, }
再后是主要的“金花”类(- -!):
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; } } }
比较两个类的时候,先比较类型,类型相同后再比较牌的数字大小。
测了几组数据,还没有发现误判,但是感觉好慢。不知道是我的机子太烂还是算法不好。希望各位大神帮帮小女子!
最后,请教一下大家,我看他们的博客都好漂亮,为什么我的不行?排版这些怎么弄的?真的第一次发这种东西,小白一枚!