2016-11-28 1 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#에서 빠른 조회 평가자를 요청했습니다. 소위 "two plus two evaluator"를 사용할 수 있습니다. 그것은 당신이 주어진 손의 힘의 가치를 찾기 위해 사용할 수있는 큰 precomputed lookup table입니다.

다음은 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로. 필요한 간단한 알고리즘을 구현 메모리에 거대한 조회 테이블 HandRanks.dat 파일

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; 
    } 
} 

이 클래스로드는 손 힘을 조회합니다. 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 

당신이 (플롭, 프리 플랍에 또 다른 대 한 손으로 승리의 변화를 평가 켜 많은 일을 할 수있는이에서 불과 기본 구현하지만 시작이다, 범위 대 손을 비교 다른 손등).

+0

나는 초 안에 실행되는 평가자를 알아 냈고 테이블이나 데이터베이스를 사용하지 않았다. – Paparazzi

+0

@Paparazzi 위대하지만 "초 미만"은 초당 수백만 번의 평가를 수행 할 수 있기 때문에 너무 빠르지는 않습니다. – Evk

+0

나는이 문제에 다시 돌아올 필요가 있습니다. Mine은 1 초에 260 만 건의 시동 손을 평가할 것입니다. 그러나 나는이 하나를 다른 모습으로 보여주기 위해 올 것이다. – Paparazzi

관련 문제