void Calculate() { foreach (Pocket p in _pockets) { _mPocket = new CardSet( StdDeck.Descriptor.CardSets[(int)p._c1], StdDeck.Descriptor.CardSets[(int)p._c2]); List <double> evList = new List <double>(1225); for (int c1 = StdDeck.Descriptor.Size - 1; c1 >= 0; --c1) { CardSet m1 = StdDeck.Descriptor.CardSets[c1]; if (m1.IsIntersectingWith(_mPocket)) { continue; } for (int c2 = c1 - 1; c2 >= 0; --c2) { CardSet m2 = new CardSet(m1, StdDeck.Descriptor.CardSets[c2]); if (m2.IsIntersectingWith(_mPocket)) { continue; } _evCount = 0; _mOther = m2; CardEnum.Combin(StdDeck.Descriptor, 5, CardSet.Empty, _mPocket | m2, Evaluate); double ev = 0.5 * _evCount / _boardsCount; p._evDict.Add(m2, ev); } } } }
public void Test_Random() { int REPETITIONS = 100; #if DEBUG REPETITIONS = 8; #endif int seed = (int)DateTime.Now.Ticks; Console.WriteLine("Random seed {0}", seed); Random rand = new Random(seed); _cardRng = new SequenceRng(seed); _cardRng.SetSequence(StdDeck.Descriptor.FullDeckIndexes); for (int r = 0; r < REPETITIONS; ++r) { _enumCount = r % 7; int sharedCount = rand.Next(0, StdDeck.Descriptor.Size + 1 - _enumCount); int deadCount = rand.Next(0, StdDeck.Descriptor.Size + 1 - sharedCount - _enumCount); _cardRng.Shuffle(sharedCount + deadCount); int rc = 0; _shared = new CardSet(); for (int i = 0; i < sharedCount; ++i) { _shared |= StdDeck.Descriptor.CardSets[_cardRng.Sequence[rc++]]; } _dead = new CardSet(); for (int i = 0; i < deadCount; ++i) { _dead |= StdDeck.Descriptor.CardSets[_cardRng.Sequence[rc++]]; } Debug.Assert(rc == sharedCount + deadCount); Debug.Assert(!_shared.IsIntersectingWith(_dead)); //Console.WriteLine("B: {0:x16} D:{1:x16}", board, dead); _combinationsCount = 0; _lastCs = 0; CardEnum.Combin(StdDeck.Descriptor, _enumCount, _shared, _dead, VerifyCombination); Assert.AreEqual(EnumAlgos.CountCombin(StdDeck.Descriptor.Size - sharedCount - deadCount, _enumCount), _combinationsCount); _combinationsCount1 = 0; _lastCs1 = 0; CardEnum.Combin(StdDeck.Descriptor, _enumCount, _shared, _dead, VerifyCombinationParam, _combinationsCount); Assert.AreEqual(EnumAlgos.CountCombin(StdDeck.Descriptor.Size - sharedCount - deadCount, _enumCount), _combinationsCount1); _combinationsCount1 = 0; _lastCs1 = 0; int[] cards = new int[_enumCount + sharedCount].Fill(-1); StdDeck.Descriptor.GetIndexesAscending(_shared).ToArray().CopyTo(cards, 0); int[] deadIdx = StdDeck.Descriptor.GetIndexesAscending(_shared | _dead).ToArray(); CardEnum.Combin(StdDeck.Descriptor, _enumCount, cards, sharedCount, deadIdx, deadIdx.Length, VerifyCombinationParam, _combinationsCount); Assert.AreEqual(EnumAlgos.CountCombin(StdDeck.Descriptor.Size - sharedCount - deadCount, _enumCount), _combinationsCount1); } Console.WriteLine("{0} repetitions done.", REPETITIONS); }
public void SetMask(int cardCount) { CardSet.Clear(); for (int i = 0; i < cardCount; ++i) { Debug.Assert(!CardSet.IsIntersectingWith(StdDeck.Descriptor.CardSets[Cards[i]])); CardSet.UnionWith(StdDeck.Descriptor.CardSets[Cards[i]]); } }
static int Showdown(CardSet ourPocket, CardSet oppPocket, CardSet board, int handSize) { Debug.Assert(!ourPocket.IsIntersectingWith(oppPocket)); Debug.Assert(!ourPocket.IsIntersectingWith(board)); Debug.Assert(!ourPocket.IsIntersectingWith(board)); CardSet ourHand = new CardSet(ourPocket, board); CardSet oppHand = new CardSet(oppPocket, board); UInt32 ourRank = CardSetEvaluator.Evaluate(ref ourHand); UInt32 oppRank = CardSetEvaluator.Evaluate(ref oppHand); if (ourRank > oppRank) { return(1); } else if (ourRank < oppRank) { return(-1); } return(0); }
void CombinRecursive( // Deck parameters CardSet[] deck, int suitCount, int deckSize, // Initial call parameters int n, // Algorithm parameters int depth, CardSet result1, int r1, int s1, int maxSuit, // Debug and test parameters ref int counter ) { if (depth == n) { Debug.Assert(result1.CountCards() == n); counter++; _list.Add(result1); if (Verbose) { Console.WriteLine("{0,6}: {1}", counter, result1); } return; } int r2 = r1; int s2 = s1 + 1; if (s2 >= suitCount) { s2 = 0; r2++; } for (; (r2 + s2) < deckSize + 1 - (n - depth);) { int maxSuit2 = r2 == r1 ? maxSuit : Math.Max(maxSuit, s2); //int maxSuit2 = Math.Max(maxSuit, s2); CardSet result2 = deck[r2 + s2]; Debug.Assert(!result2.IsIntersectingWith(result1)); result2.UnionWith(result1); CombinRecursive(deck, suitCount, deckSize, n, depth + 1, result2, r2, s2, maxSuit2, ref counter); s2++; if (s2 > Math.Min(maxSuit + 1, suitCount - 1)) { s2 = 0; r2 += suitCount; } } }
private void VerifyCombination(ref CardSet cs) { _combinationsCount++; Assert.IsFalse(cs.IsIntersectingWith(_dead)); Assert.IsTrue(cs.Contains(_shared)); CardSet uniqueMask = new CardSet { bits = cs.bits & (~_shared.bits) }; Assert.AreEqual(_enumCount, uniqueMask.CountCards()); // Use the fact that CardEnum generate masks in ascending order to check uniqueness if (_enumCount > 0) { Assert.Greater(uniqueMask.bits, _lastCs); } _lastCs = uniqueMask.bits; }
void OnCombinLinkStates(CardSet srcCards, int count) { // Find the state for theses cards. No search is necessary here, // as the cards are dealt in the same order as in creation, we can use _combinCount. int srcMapIdx = _combinCount; Debug.Assert(_cardsToState[count][srcMapIdx].Cards == srcCards); State srcState = _states[_cardsToState[count][srcMapIdx].StateId]; // Deal next cards. for (int c = 0; c < 52; ++c) { if (srcState.Table[c] != 0) { // Already linked continue; } CardSet newCard = StdDeck.Descriptor.CardSets[c]; if (newCard.IsIntersectingWith(srcCards)) { // Impossible card. continue; } CardSet dstCards = newCard | srcCards; int linkValue; if (count + 1 < _maxHandSize) { // Link to state int dstMapIdx = Array.BinarySearch(_cardsToState[count + 1], new CardsToState { Cards = dstCards }); Debug.Assert(_cardsToState[count + 1][dstMapIdx].Cards == dstCards); State dstState = _states[_cardsToState[count + 1][dstMapIdx].StateId]; linkValue = dstState.Id; } else { // Link to hand value. linkValue = (int)CardSetEvaluator.Evaluate(ref dstCards); } srcState.Table[c] = linkValue; } _combinCount++; }
private void FillFinalHands(State state, CardSet cards) { for (int c = 0; c < 52; ++c) { if (state.Table[c] != 0) { // Already done. continue; } CardSet nextCard = StdDeck.Descriptor.CardSets[c]; if (nextCard.IsIntersectingWith(cards)) { continue; } CardSet finalHand = cards | nextCard; Debug.Assert(finalHand.CountCards() == _maxHandSize); UInt32 handRank = CardSetEvaluator.Evaluate(ref finalHand); state.Table[c] = (Int32)handRank; } }
private void VerifyCombinationParam(int [] cards, int param) { CardSet cs = StdDeck.Descriptor.GetCardSet(cards); Assert.AreEqual(_combinationsCount, param); _combinationsCount1++; Assert.IsFalse(cs.IsIntersectingWith(_dead)); Assert.IsTrue(cs.Contains(_shared)); CardSet uniqueCs = new CardSet { bits = cs.bits & (~_shared.bits) }; Assert.AreEqual(_enumCount, uniqueCs.CountCards()); // Use the fact that CardEnum generate masks in ascending order to check uniqueness if (_enumCount > 0) { Assert.Greater(uniqueCs.bits, _lastCs1); } _lastCs1 = uniqueCs.bits; }
public GameRecord Generate(int repetition) { string[][] enumNames = new string[_enumCounts.Count][]; int[] enumIndexes = new int[_enumCounts.Count]; CardSet deadCards = _fixedCards; if (_enumCounts.Count != 0) { int r = repetition; for (int d = _enumCounts.Count - 1; d >= 0; --d) { enumIndexes[d] = r % (int)_enumCombosCounts[d]; r /= (int)_enumCombosCounts[d]; } int redealFrom = _enumCombos.Count; for (int d = _enumCounts.Count - 1; d >= 0; --d) { if (enumIndexes[d] != 0) { break; } redealFrom = d; } for (int d = 0; d < redealFrom; ++d) { deadCards.UnionWith(_enumCombos[d][enumIndexes[d]]); } for (int d = redealFrom; d < _enumCombos.Count; ++d) { _enumCombos[d].Clear(); CardEnum.Combin(_deckDescr, _enumCounts[d], CardSet.Empty, deadCards, OnCombin, d); Debug.Assert(_enumCombosCounts[d] == _enumCombos[d].Count); deadCards.UnionWith(_enumCombos[d][enumIndexes[d]]); } for (int d = 0; d < _enumCombos.Count; ++d) { string enumCards = _deckDescr.GetCardNames(_enumCombos[d][enumIndexes[d]]); enumNames[d] = enumCards.Split(_separator, StringSplitOptions.RemoveEmptyEntries); } } GameRecord result = new GameRecord(_cfg.ToString()); result.Actions.Clear(); // Shuffle the rest of the deck. CardSet deckRest = _deckDescr.FullDeck; deckRest.Remove(deadCards); _randomDealer.SetSequence(_deckDescr.GetIndexesAscending(deckRest).ToArray()); _randomDealer.Shuffle(_randomCount); int randomDealt = 0; int[] enumDealt = new int[_enumCounts.Count]; // Deal the cards. for (int a = 0; a < _cfg.Actions.Count; ++a) { PokerAction action = _cfg.Actions[a]; if (!action.IsDealerAction()) { continue; } string[] cards = action.Cards.Split(_separator, StringSplitOptions.RemoveEmptyEntries); CardSet resultCards = new CardSet(); foreach (string card in cards) { CardSet nextCard = new CardSet(); if (card == "?") { nextCard = _deckDescr.GetCardSet(_randomDealer.Sequence, randomDealt++, 1); } else if (card.Length > 0 && card.Substring(0, 1) == "#") { int d = int.Parse(card.Substring(1)); string enumName = enumNames[d][enumDealt[d]++]; nextCard = _deckDescr.GetCardSet(enumName); } else { nextCard = _deckDescr.GetCardSet(card); } Debug.Assert(!resultCards.IsIntersectingWith(nextCard)); resultCards.UnionWith(nextCard); } PokerAction resultAction = new PokerAction(action.Kind, action.Position, action.Amount, _deckDescr.GetCardNames(resultCards)); result.Actions.Add(resultAction); } Debug.Assert(_randomCount == randomDealt); return(result); }
bool FinalizeDeal(ref string currentDeal) { if (currentDeal == "") { return true; } if (_gameState.IsPlayerActing(_position)) { ShowMessage("Is's agents turn"); return false; } List<Ak> allowedActions = _gameState.GetAllowedActions(GameDef); if (!allowedActions.Contains(Ak.d)) { ShowMessage(string.Format("Wrong action: 'd', expected: '{0}'", ActionKindListToString(allowedActions))); return false; } CardSet cs = StdDeck.Descriptor.GetCardSet(currentDeal); int dealRound = _gameState.Round +1; int expectedCardsCount = dealRound == 0 ? GameDef.PrivateCardsCount[dealRound] : GameDef.SharedCardsCount[dealRound]; if (cs.CountCards() != expectedCardsCount) { ShowMessage(string.Format("Wrong cards count: {0}, expected: {1}", cs.CountCards(), expectedCardsCount)); return false; } if(cs.IsIntersectingWith(_dealtCards)) { ShowMessage(string.Format("Some of cards {0} are already dealt", currentDeal)); return false; } _dealtCards |= cs; PokerAction pa = new PokerAction {Kind = Ak.d, Cards = currentDeal}; currentDeal = ""; if (_gameState.Round == -1) { PokerAction oppPrivateDeal = new PokerAction { Kind = Ak.d, Cards = "" }; if (_position == 0) { pa.Position = 0; oppPrivateDeal.Position = 1; _gameRecord.Actions.Add(pa); _gameRecord.Actions.Add(oppPrivateDeal); } else { pa.Position = 1; oppPrivateDeal.Position = 0; _gameRecord.Actions.Add(oppPrivateDeal); _gameState.UpdateByAction(oppPrivateDeal, GameDef); _gameRecord.Actions.Add(pa); } _gameState.UpdateByAction(_gameRecord.Actions[_gameRecord.Actions.Count - 2], GameDef); _gameState.UpdateByAction(_gameRecord.Actions[_gameRecord.Actions.Count - 1], GameDef); } else { pa.Position = -1; _gameRecord.Actions.Add(pa); _gameState.UpdateByAction(pa, GameDef); } return true; }