2016-11-28 104 views
1

我有一个相当昂贵的计算(每个30分钟)。其实169是一样的。我想只运行一次并加载它们。创建并加载数据(对象)

private List<Hands> Hands = new List<Hand>() {new Hand(...), new Hand(...)}; 

我的计划是只运行程序,并打印出所有新的手(...),然后我将它复制粘贴到程序中。

有没有更好的方法来解决这个问题?

我宁可不使用数据库或外部XML。

Debug.WriteLine("HoleCards holeCards = new HoleCards(new Card({0}), new Card({1}), {2}, {3}, {4}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20});", 
          holecards.Card1.CardInt, holecards.Card2.CardInt, holecards.Wins, holecards.Loses, holecards.Ties 
          , holecards.StrFlush, holecards.Quads, holecards.Boat, holecards.Flush, holecards.Straight, holecards.Trips, holecards.TwoPair, holecards.OnePair, holecards.High 
          , holecards.StrFlushLose, holecards.QuadsLose, holecards.BoatLose, holecards.FlushLose, holecards.StraightLose, holecards.TripsLose, holecards.TwoPairLose, holecards.OnePairLose, holecards.HighLose); 
+3

为什么不把它们序列化(对于某些二进制格式不需要xml)? – Evk

+0

@Evk这不是一个坏主意。我会仔细看看的。 – Paparazzi

+0

一个不错的选择是protobuf(https://github.com/mgravell/protobuf-net)。相当快,二进制,占用空间小(如果你的类包含两个int属性 - 基本上是以序列化的形式,它将只是这两个int)。 – Evk

回答

1

这不回答问题,但在评论OP要求在C#中快速查找评估。你可以使用所谓的“两加二评估”。这是一个预先计算好的查找表,您可以使用它来查找给定手的强度值。

这是C#中的一些代码。

public static class Card { 
    private static readonly Dictionary<char, int> _suites = new Dictionary<char, int> { 
     {'c', 0}, {'d', 1}, {'h', 2}, {'s', 3} 
    }; 

    private static readonly Dictionary<char, int> _ranks = new Dictionary<char, int> { 
     {'2', 1}, {'3', 2}, {'4', 3}, {'5', 4}, {'6', 5}, {'7', 6}, {'8', 7}, {'9', 8}, {'T', 9}, {'J', 10}, {'Q', 11}, {'K', 12}, {'A', 13} 
    }; 

    public static Dictionary<char, int> Ranks => _ranks; 

    public static int FromString(string c) { 
     if (c.Length != 2) throw new ArgumentException("c"); 
     char rank = Char.ToUpperInvariant(c[0]); 
     char suit = Char.ToLowerInvariant(c[1]); 
     return (_ranks[rank] - 1)*4 + _suites[suit] + 1; 
    } 
} 

卡只是将卡从字符串表示形式(“作为”为黑桃等)转换为我们使用的评估器预期的int表示形式。

public class RankEvaluator 
{ 
    readonly string[] _handTypes = new[] { 
     "invalid hand", 
     "high card", 
     "one pair", 
     "two pairs", 
     "three of a kind", 
     "straight", 
     "flush", 
     "full house", 
     "four of a kind", 
     "straight flush" 
    }; 
    private RankEvaluator() 
    { 

    } 
    private int[] _lut; 
    private void Init() 
    { 
     _lut = InitIntl(); 
    } 

    private static readonly Lazy<RankEvaluator> _instance = new Lazy<RankEvaluator>(() => { 
     var r = new RankEvaluator(); 
     r.Init(); 
     return r; 
    }, true); 

    public static RankEvaluator Instance => _instance.Value; 

    private int[] InitIntl() 
    { 
     var lut = new int[32487834]; 
     if (!File.Exists("HandRanks.dat")) throw new InvalidOperationException("HandRanks.dat not found"); 
     using (var reader = new BinaryReader(File.Open("HandRanks.dat", FileMode.Open, FileAccess.Read, FileShare.Read))) 
     { 
      var tempBuffer = reader.ReadBytes(32487834 * 4); 
      Buffer.BlockCopy(tempBuffer, 0, lut, 0, 32487834 * 4); 
     } 
     return lut; 
    } 

    public int LookupHand(params int[] cards) 
    { 
     unchecked 
     { 
      int p = _lut[53 + cards[0]]; 
      p = _lut[p + cards[1]]; 
      p = _lut[p + cards[2]]; 
      p = _lut[p + cards[3]]; 
      p = _lut[p + cards[4]]; 
      p = _lut[p + cards[5]]; 
      return _lut[p + cards[6]]; 
     } 
    } 

    public string GetType(int value) { 
     return _handTypes[value >> 12]; 
    } 

    public int GetRank(int value) { 
     return value & 0x00000fff; 
    } 
} 

该类将带有巨大查找表的HandRanks.dat文件加载到内存中,并实现查找手强度所需的简单算法。你可以得到dat文件here

使用这样的:

var hand1 = "As Ah"; 
var hand2 = "2s 2c"; 
var board = "5s 2d 8h 8s Ks"; 
var fullHand1 = (hand1 + " " + board).Split(' ').Select(Card.FromString).ToArray(); 
var fullHand2 = (hand2 + " " + board).Split(' ').Select(Card.FromString).ToArray(); 
var r1 = RankEvaluator.Instance.LookupHand(fullHand1); 
var r2 = RankEvaluator.Instance.LookupHand(fullHand2); 
var type1 = RankEvaluator.Instance.GetType(r1); // two pairs 
var rank1 = RankEvaluator.Instance.GetRank(r1); 
var type2 = RankEvaluator.Instance.GetType(r2); // full house 
var rank2 = RankEvaluator.Instance.GetRank(r2); 
Debug.Assert(r2 > r1); // full house wins 

这只是基本实现,但起这个,你可以做很多事情(评估对翻牌前一方面的获奖VS其他的变化,翻牌,转,比较手VS范围其他手等)。

+0

我想出了一个评估器,它在一秒钟内运行并且不使用表或数据库。 – Paparazzi

+0

@Paparazzi很棒,但“一秒之内”似乎不是太快,因为这个人可以每秒执行数百万次评估:) – Evk

+0

我可能需要回到这个。我将在1秒内评估260万起手牌。但我会来看看这个。 – Paparazzi