卡片分配有限制

时间:2017-12-25 11:23:08

标签: javascript constraints distribution playing-cards

假设我想将 52张卡分发给 N个玩家,不一定相同,所以每个玩家 Pi 会得到一个数字卡 Ci 。假设这些玩家中的每一个可能都有约束来决定他可以接收哪些牌,例如玩家P2无法获得任何卡牌的心脏颜色而P5无法获得任何超过10张牌。所有这些约束保证至少有一个分配/解决方案。

我的主要问题是如何以编程方式进行此操作?这是否需要使用某些规则引擎?如果可能的话,这个分布在数学中会有什么名称,或者数学领域会处理这类问题?

Javascript中的示例:

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

n 是卡片的编号(J转换为11,Q为12,K为13), c 为其颜色(d为钻石,h为心脏) ...)

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 }}
   //...
];

topPossibleCardPerColor定义了约束。例如,对于玩家1,他不能在钻石颜色的Q之上,所以没有K或1,他可以在心脏或俱乐部颜色中有任何卡,并且绝对没有黑桃卡。< / p> 编辑:碰撞!有人有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我们首先可以将所有牌都映射到可能接收它们的玩家:

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

如果一张牌只能由一名牌手接收,很可能他会得到它:

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

现在我们可以分发这些卡片,并且如果必须的话,总是将它们交给某个用户:

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