洗牌流星集合
Posted
技术标签:
【中文标题】洗牌流星集合【英文标题】: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 我想要的是当玩家点击洗牌按钮时,玩家的牌组再次洗牌。 【参考方案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的顺序,负值添加一张卡片甲板顶部,对吧? 是的,但在这种情况下,您可能需要做一些更聪明的事情来跟踪正在使用的索引,因为它们不会是连续的。以上是关于洗牌流星集合的主要内容,如果未能解决你的问题,请参考以下文章
java斗地主扑克 扑克牌 洗牌 发牌 Collection 集合练习
Java学习笔记34(集合框架八:综合案例:模拟斗地主的洗牌发牌)
Map集合HashMap集合LinkedHashMap集合Hashtable集合Collections工具类和模拟斗地主洗牌和发牌