在几个玩家之间获得所有可能的卡片排列

问题描述

我正在尝试在 3 个玩家之间获得所有可能的 n 卡交易,其中每个玩家 i 需要正好 n_i 卡,而一些玩家无法获得一些卡片。

例如,假设有4张牌:Ac,Jh,9d,2s和玩家N,E,S分别需要1,1,2张牌,但是N不能得到Ac,并且 S 无法获得 Jh

输入是n卡片的列表,以及每个位置和每张卡片的限制:

List<Card> unplayedCards
Map<Position,Integer> numberOfCardsEachPlayerNeeds
Map<Card,List<Position>> possiblePositionsForCard

输出应该是可能的交易列表

List<Map<Position,List<Card>>>

我用 Java 编写,但答案是哪种语言并不重要。

解决方法

使用递归算法最容易做到这一点。类似Python的伪代码:

function possible_deals(players,cards):
  output := []
  generate_deals(players,cards,{},output)
  return output

function generate_deals(players,index,assignment,output):
  if index >= len(cards):
    output.append(assignment)
  else:
    card := cards[index]
    for player in players:
      if player doesn't have enough cards yet and player can have card:
        assignment[card] = player
        generate_deals(players,index + 1,output)
        del assignment[card]

我们为 assignmentoutput 假设传递引用语义,以便递归函数调用可以修改它们。

output 列表中的每个条目都包含一张从卡片到玩家的地图。由此,很容易重建手部。

,

根据@Thomas 的回答制作了一个 Java 版本。

static List<Map<Position,CardsList>> getAllPossibleDeals(CardsList cards,Map<Position,Integer> cardsPerPosition,Map<Card,List<Position>> positionsPerCard,List<Card> unplayedCardsOrderedByPossibilities) {

    List<Map<Position,CardsList>> possibleDeals = new ArrayList(); // all the deals
    Map<Position,CardsList> assignment = new HashMap<>(); // a single deal.
    generateDeals(cards,cardsPerPosition,positionsPerCard,possibleDeals,assignment); 
    return possibleDeals;
}


private static void generateDeals(CardsList cards,List<Map<Position,CardsList>> possibleDeals,int i,CardsList> assignment) {

    if (i >= cards.size()){
        Map<Position,CardsList> assignmentCopy = deepCopyMap(assignment);
        possibleDeals.add(assignmentCopy);
    }
    else {
        Card card = cards.get(i);
        for (Position pos : positionsPerCard.get(card)) {
            if (assignment.get(pos) == null || cardsPerPosition.get(pos) > assignment.get(pos).size()){
                // position can have the card
                assignment.computeIfAbsent(pos,k -> new CardsList()).add(card);
                generateDeals(cards,i+1,assignment);
                assignment.get(pos).remove(card);
            }
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...