Sorting 防止玩家获得同一张牌的算法

Sorting 防止玩家获得同一张牌的算法,sorting,lua,tabletop-simulator,Sorting,Lua,Tabletop Simulator,我在桌面模拟器中编写了一个游戏,所有玩家(p)都得到一张牌(C)。一旦记住所有玩家将牌放回牌组(D),洗牌,然后所有玩家从同一牌组(D)中获得一张牌。我正在尝试编写最简单的算法,以防止玩家获得自己的卡。现在,当谈到编码时,我认为这应该很简单,而不是创建模拟来运行直到成功。假设您有以下几点: 牌组,包含所有牌(包括玩家看到的牌)的随机牌组 玩家所看到的卡的id,一个查找表,提供玩家所看到的卡的guid 那么解决办法就简单了 localcard_id={} 对于i,ipair(deck.getO

我在桌面模拟器中编写了一个游戏,所有玩家(p)都得到一张牌(C)。一旦记住所有玩家将牌放回牌组(D),洗牌,然后所有玩家从同一牌组(D)中获得一张牌。我正在尝试编写最简单的算法,以防止玩家获得自己的卡。现在,当谈到编码时,我认为这应该很简单,而不是创建模拟来运行直到成功。

假设您有以下几点:

  • 牌组
    ,包含所有牌(包括玩家看到的牌)的随机牌组
  • 玩家所看到的卡的id
    ,一个查找表,提供玩家所看到的卡的guid
那么解决办法就简单了

localcard_id={}
对于i,ipair(deck.getObjects())中的card_数据
表.insert(卡ID、卡数据.guid)
结束
对于玩家,两人一组看牌(玩家看牌)
本地卡标识=表。删除(卡标识)
如果card\U id==已查看的\U card\U id,则
本地i=math.random(1,#卡ID)
卡识别码[i],卡识别码=卡识别码,卡识别码[i]
结束
--处理特定的卡。
deck.takeObject({
guid=卡\u ID[i],
position=player.getHandTransform().position,
翻转=正确,
})
结束
当我们挑选玩家已经看到的牌时,它会被放回剩余牌中的一个随机位置。这样可以确保每张牌被下一位玩家抽到的机会均等。这是该计划的基本原则


充分展示

功能广播错误(msg)
广播全部(msg,{r=1,g=0,b=0})
结束
函数获取玩家看到的卡片()
本地玩家\u id=player.getAvailableColors()
本地错误=错误
本地玩家看到的牌{}
对于i,ipair中的player_id(player_id)do
本地玩家=玩家[玩家id]
本地hand_objs=player.getHandObjects()
本地玩家_错误=错误
如果#hand_objs>1,则
player_error=true
elseif#hand#u objs==1那么
本地卡=手持卡[1]
如果card.tag~=“card”,则
player_error=true
其他的
被玩家[玩家]看到的牌=牌
结束
结束
如果玩家出现错误,那么
广播错误(玩家id.“没有有效的牌。”)
错误=真
结束
结束
如果有错误,那么
归零
结束
返回被玩家看到的卡
结束
函数运行()
本地数据组=getObjectFromGUID(“…”)
本地被玩家看到的卡=获得被玩家看到的卡()
如果玩家看到的卡=零或下一张(玩家看到的卡=零),则
返回
结束
本地玩家看到的卡片id={}
对于玩家,成对的牌(见玩家的牌)可以
本地卡\u id=card.guid
被玩家[玩家]看到的卡片id=卡片id
卡片。putObject(卡片组)
结束
deck.randomize()
本地卡\u ID={}
对于i,ipair(deck.getObjects())中的card_数据
表.insert(卡ID、卡数据.guid)
结束
对于玩家,两人一组看牌(玩家看牌)
本地卡标识=表。删除(卡标识)
如果card\U id==已查看的\U card\U id,则
本地i=math.random(1,#卡ID)
卡识别码[i],卡识别码=卡识别码,卡识别码[i]
结束
deck.takeObject({
guid=卡\u ID[i],
position=player.getHandTransform().position,
翻转=正确,
})
结束
结束

用一副牌创建一个游戏。将上述代码放在全局中,用组的GUID替换
。要运行演示,请将一张卡发给任意数量的玩家,然后在聊天窗口中使用
/execute Global.call(“run”)

多少玩家,多少张卡?只画第二张牌,如果和第一张牌一样,再画一次有什么不对?这很简单。同样简单的是复制牌组,每个玩家一次,在第二张牌被抽出来之前不要替换第一张牌。我知道我可以这样做,但这是通过代码完成的,所以我想让它尽可能简单。如果有一个简单的方法,如果可能的话,我希望这样做。你会如何用一副真正的牌来做到这一点?谢谢你的详细回答。我稍后会试试这个。现在我做一个简单的Fisher-Yates洗牌,检查确保每张牌与玩家现有的牌不匹配,如果失败,则进行另一张Fisher-Yates洗牌,同时循环,直到洗牌中没有一张与原始牌匹配。我希望我可以不用一个while循环,只运行一次,就可以得到一个确定的大O,而不是随机性。如果您有每张卡的ID列表,并且如果
deck.takeObject
为O(1),则可以使用O(1)解决方案。(而不是
deck.randomize()
,根据每个玩家是否看到自己的牌,你可以做一次或两次FY传球。)但我怀疑
deck.takeObject
是O(1),但即使是蛮力,在一切正常之前重新洗牌的方法在统计上也是O(N)。当你增加牌数时,需要洗牌的几率变得非常接近于零。对于大牌组(和少量玩家),永远不需要3次洗牌,所以我们可以说它受O(3N)的约束,也就是O(N)。我接受了你的答案,但我使用了另一种更简单的方法。当我做这个的时候,我意识到我只想要一条链子。这样我们就可以制作一个单链卡片,而不是让两个玩家交换卡片并创建一个单独的链。所以我所做的就是在一张桌子上刷上球员的颜色,在ipair foreach里我做了球员卡[I][“SecondCard”]=球员卡[I+1][“FirstCard”]。当然,如果我做了一个模数检查,如果它大于玩家的尺寸,它会回到1。