How to implement a dealer class without storing a deck of cards?

前端 未结 8 1269
长发绾君心
长发绾君心 2021-02-09 19:07
  • Question

    Even only 52 cards, the permutationIndex where I describe in Explanations section, would be a huge number; it is

相关标签:
8条回答
  • 2021-02-09 19:13

    While I have a bit of a problem understanding what you are really trying to accomplish here, I suppose a coprime will generate a bunch of permutation numbers; that is: if you don't care too much about the distribution. You can use the Euclidian algorithm for that.

    Algebra (set theory) states that you can simply use x = (x + coprime) % set.Length to get all elements in the set. I suppose each coprime is a permutation number as you describe it.

    That said I'm not sure what distribution you get when using a generated coprime as 'random number generator'; I suppose certain distributions will occur more frequently than others and that a lot of distributions will be excluded from the generated numbers, for the simple reason that the generator will pick numbers in a ring. I'm being a bit creative here so perhaps it fits your needs, although it probably won't be the answer you're looking for.

    0 讨论(0)
  • 2021-02-09 19:16

    If I've understood you right, the following code implements this:

    public class Dealer {
        public int Dealing() {
            var number=
                _freeCards.Count>0
                    ?_freeCards.Dequeue()
                    :_lastNumber++;
    
            _dealtCards.Add(number);
            return number;
        }
    
        public void Collect(int number) {
            if(!_dealtCards.Remove(number))
                throw new ArgumentException("Card is not in use", "number");
    
            _freeCards.Enqueue(number);
        }
    
        readonly HashSet<int> _dealtCards=new HashSet<int>();
        readonly Queue<int> _freeCards=new Queue<int>(); // "Pool" of free cards.
        int _lastNumber;
    }
    
    0 讨论(0)
  • 2021-02-09 19:18

    I am also struggling to see the whole picture here, but you could convert each permutation to base(52) with a single character representing each card and have a string representing each permutation.

    So Spades could be 1-9 (ace - 9), 0ABC (10, J Q K), then DEFG... starting the hearts and so on.

    So a deck of 3 cards, 2 Spade (2), 3 Heart (F) and 2 Diamond (say e), would have these permutation numbers:

    2Fe
    2eF
    F2e
    Fe2
    eF2
    e2F
    

    You could convert these back and forth to a int/long/bigint by doing base 52 to base 10 conversions.

    Here's an introduction to converting between bases.

    So e2F would be F + 2*52 + e * 52^2 which would be 16 + 2*52 + 43*52*52 = 116392

    So 116392 would be your permutation number.

    (btw. I'm guessing about it 2 diamond being 'e' and 43, you can count it up and see exact what it would be)

    0 讨论(0)
  • 2021-02-09 19:19

    Like the others I am not sure what you want to do but if you want to save as much space a possible on the communication/storage of the dealt cards I would do the following:

    I would store the cards dealt on a single Long using a enum with the flag attribute so I could use bitwise comparisons to see which card has been dealt.

    Because each card is a separate "flag" with a unique number which is set to the exponent of 2 so they will never clash.

    In total even if you deal all the cards the storage will still be 8 bytes. any extra data you need you can bolt on the end.

    Please see the working example below.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication12
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Because each card is unique you could use Flag attributed Enum see the enum below and set each item a unique value I used 2 to the power of 52
                Cards cardsdealt = Cards.Clubs_10 | Cards.Clubs_2 | Cards.Diamonds_3;
    
                if ((cardsdealt & Cards.Clubs_10) == Cards.Clubs_10)
                {
                    Console.WriteLine("Card.Clubs_10 was dealt");
                }
    
                // Storage would always be 8 bytes for the long data type
            }
    
            [Flags]
            public enum Cards : long
            {
                Spades_Ace = 1,
                Spades_2 = 2,
                Spades_3 = 4,
                Spades_4 = 8,
                Spades_5 = 16,
                Spades_6 = 32,
                Spades_7 = 64,
                Spades_8 = 128,
                Spades_9 = 256,
                Spades_10 = 512,
                Spades_Jack = 1024,
                Spades_Queen = 2048,
                Spades_King = 4096,
                Hearts_Ace = 8192,
                Hearts_2 = 16384,
                Hearts_3 = 32768,
                Hearts_4 = 65536,
                Hearts_5 = 131072,
                Hearts_6 = 262144,
                Hearts_7 = 524288,
                Hearts_8 = 1048576,
                Hearts_9 = 2097152,
                Hearts_10 = 4194304,
                Hearts_Jack = 8388608,
                Hearts_Queen = 16777216,
                Hearts_King = 33554432,
                Diamonds_Ace = 67108864,
                Diamonds_2 = 134217728,
                Diamonds_3 = 268435456,
                Diamonds_4 = 536870912,
                Diamonds_5 = 1073741824,
                Diamonds_6 = 2147483648,
                Diamonds_7 = 4294967296,
                Diamonds_8 = 8589934592,
                Diamonds_9 = 17179869184,
                Diamonds_10 = 34359738368,
                Diamonds_Jack = 68719476736,
                Diamonds_Queen = 137438953472,
                Diamonds_King = 274877906944,
                Clubs_Ace = 549755813888,
                Clubs_2 = 1099511627776,
                Clubs_3 = 2199023255552,
                Clubs_4 = 4398046511104,
                Clubs_5 = 8796093022208,
                Clubs_6 = 17592186044416,
                Clubs_7 = 35184372088832,
                Clubs_8 = 70368744177664,
                Clubs_9 = 140737488355328,
                Clubs_10 = 281474976710656,
                Clubs_Jack = 562949953421312,
                Clubs_Queen = 1125899906842620,
                Clubs_King = 2251799813685250,
    
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-09 19:22

    Not exactly what you are trying to accomplish here, but if you want to deal from a random ordering of a deck of cards, you use a shuffle algorithm. The typical shuffle algorithm is Fisher-Yates. The shuffle algorithm will create an array listing the card numbers in random order ( 13,5,7,18,22,... etc ). To deal you start at the first element in the array and continue forward.

    0 讨论(0)
  • 2021-02-09 19:25

    You have working - and extremely efficient c# example for The kth Permutation of Order n (aka PermutationIndex) at this very old post:

    • http://msdn.microsoft.com/en-us/library/Aa302371.aspx#permutat_topic3

    For those interested in Combinations topic:

    • http://msdn.microsoft.com/en-us/magazine/cc163957.aspx
    • http://msdn.microsoft.com/en-us/library/Aa289166(VS.71).aspx

    I suggest that you read through, before going into specific implementation.

    0 讨论(0)
提交回复
热议问题