洗牌流星系列

时间:2013-11-17 22:59:03

标签: javascript arrays collections coffeescript meteor

我正在建立一个纸牌游戏,需要在游戏开始前洗牌玩家的套牌。通过在将数组插入数据库之前对数组进行混洗,没有任何问题。但是,在游戏开始后,有些情况下玩家需要洗牌。我想到的唯一方法是在再次洗牌后重新插入牌组,但这肯定是无效的。 这是插入之前的洗牌代码。

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

这当然是无效的,也是不必要的。 那么,如何改变一个集合呢? 感谢。

1 个答案:

答案 0 :(得分:2)

是的,删除和重新插入是一种低效的混乱方式,特别是在渲染卡片是一项耗时的操作时。我建议使用以下方法,只有在moved中呈现Deck时才生成{{#each}}个操作,例如:

无论您何时使用需要改组的牌组,请使用按顺序排序的游标:

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

这种改组方法不会导致任何东西被移除并重新出现在集合中。只要您为玩家和游戏正确确定查找操作的范围,以便其他套牌无意中洗牌,您就应该开展业务。