Card distribution with constraints

拟墨画扇 提交于 2021-02-10 08:07:00

问题


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:


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


来源:https://stackoverflow.com/questions/47968137/card-distribution-with-constraints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!