【问题标题】:Shuffling a meteor collection洗牌流星集合
【发布时间】:2013-11-30 23:40:01
【问题描述】:

我正在构建一个纸牌游戏,需要在游戏开始前洗牌玩家的牌组。通过在将数组插入数据库之前对其进行改组,可以毫无问题地完成此操作。然而,在游戏开始后,有些情况下玩家需要洗牌。我想到的唯一方法是在再次洗牌后重新插入甲板,但这肯定是无效的。 这是插入前洗牌的代码。

deck = _.shuffle (Card_Reference.find deck_id: hoster.deck).fetch()


    _.each deck, (card) ->
        Deck.insert
            userId: opponent._id
            game_id: id
            card: card.card

插入后

deck = Deck.find().fetch()
ids = _.pluck deck, "_id"
shuffled = _.shuffle deck
Deck.remove {_id: $in: ids}

_.each shuffled, (card) ->
    Deck.insert
       userId: opponent._id
       game_id: id
       card: card.card

这当然是无效和不必要的。 那么,如何洗牌一个集合呢? 谢谢。

【问题讨论】:

  • 您是想为所有玩家设置相同的随机播放,还是为每个播放器设置不同的随机播放?
  • @AndrewMao 我想要的是当玩家点击洗牌按钮时,玩家的牌组再次洗牌。

标签: javascript arrays collections coffeescript meteor


【解决方案1】:

是的,移除和重新插入是一种低效的洗牌方式,尤其是在渲染卡片是一项耗时的操作时。我建议使用以下方法,如果Deck{{#each}} 中呈现,则仅生成moved 操作,例如:

无论您在何处使用需要洗牌的牌组,请使用按洗牌顺序排序的光标:

deck = Deck.find({}, {sort: {order: 1}}).fetch()

现在,在需要洗牌时更改顺序:

newOrder = _.shuffle [1..52] # or whatever Deck.find().count() is
Deck.find({}).forEach (card, idx) -> 
  Deck.update(card._id, $set: {order: newOrder[idx]})

这种洗牌方法不会导致任何内容被删除并重新出现在集合中。只要您为玩家和游戏正确地确定查找操作的范围,以便其他牌组在不知不觉中被洗牌,您就应该开始做生意了。

【讨论】:

  • 所以,按照这种方式,如果我想在卡组底部插入一张卡片,我只需给它一个卡组大小+1的顺序,负值添加一张卡片甲板顶部,对吧?
  • 是的,但在这种情况下,您可能需要做一些更聪明的事情来跟踪正在使用的索引,因为它们不会是连续的。
猜你喜欢
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多