2
votes

Suppose I would like to distribute a deck of 52 cards unto N players, not necessarily equally so each player Pi would get a number of cards Ci. Suppose that each of these players might have constraints that dictate what cards (s)he can receive, for example Player P2 cannot get any cards in the Hearts color and P5 cannot get any cards above 10. All these constraints are guaranteed to have at least one distribution/solution.

My main question is how would one go about this programmatically? Does this require the use of some rule engine? and if possible, what name would this distribution have in mathematics or what field in mathematics would handle this kind of problem?

Example in Javascript:

var cards = [
   {n: 1, c: 'd'},
   {n: 3, c: 'h'},
   {n: 12, c: 's'}
   //...
];

n being the number of the card (J converted to 11, Q to 12 and K to 13) and c its color (d for diamonds, h for hearts...)

var players = [
   { id: 1, cards: [], topPossibleCardPerColor: {'d': 12, 'h': 1, 's': 0, 'c': 1 }},
   { id: 2, cards: [], topPossibleCardPerColor: {'d': 6, 'h': 0, 's': 10, 'c': 1 }}
   //...
];

The topPossibleCardPerColor is what defines the constraints. For the player 1 for example, (s)he cannot have above the Q in the diamond color so no K nor 1, (s)he can have any card in the hearts or clubs color and absolutely no card in the spades color.

EDIT: bump! Anyone has any suggestions?

1
Your problem is not well-defined yet. However it should be something equivalent to splitting a set into several disjoint subsets with constraints. And the latter is possibly an equivalent to a problem on a graph of some kind. programmatically, regardless of language? Turing machine? ;-)) - Matt
I reformulated the question with more details. Sorry! I'm doing this in Javascript and just looking for the best way to go about this! - younesouhbi
But what is the problem exactly? Just to generate a random distribution fitting constraints, or is it something else? - Matt
Basically, I'm working on an AI that plays a game similar to Bridge. Once the AI receives its hand, it deduces the remaining cards and it needs to distributes them (for simulation sake) among the other players while taking into account the constraints that are deduced from bidding/play. The distributions (if many) need to be as close to the reality as possible in order for the simulation to yield interesting results. - younesouhbi

1 Answers

0
votes

We could firstly map all cards to the players who may receive them:

 const left = [];
 for(const card of cards){
   const players = card.players = players.filter(p => (p.topPossibleCardPerColor[card.c] || 20) <= card.n);

If a card can only be received by one player, its very likely that he will get it:

   if(!players.length) throw `Card ${card.n} cant be distributed to a player`;
   if(players.length === 1){
     players.cards.push(card);
   }else{
     left.push(card);
     players.forEach(p => (p.possible || p.possible = []).push(card));
   }
 }

Now we can distribute the cards, and always handing them to a certain user if mandatory:

 for(const player of players){
   if(!player.cards.length && player.possible.length === 1){
      player.cards.push(...player.possible);
   }
 }