如何给所有人分配目标,但目标不能是自己或彼此互相选择

在 Roblox 上创建一个游戏,但我遇到了一个问题,那就是要确保每个人都有一个目标,而这个目标不是他们自己或已经选择了他们的人。

比如说,如果有 4 个玩家被随机分配目标。我想防止出现以下结果。

Player1 选择 Player2

Player2 选择 Player3

Player3 选择 Player1

Player4 选择 Player4

或者 Player3 选择 Player4

Player4 选择 Player3


function aFunctionfdfsd()
local targetList = {} -- 尚未被选择的三个或以上人员名单

while myTarget == Me or myTarget == targetsMe do  -- 不能选择自己或交换目标
    ranPlayer = math.random(1, #targetList)
    myTarget = targetList[ranPlayer]

    -- 在这里需要帮助 ?

end

table.remove(targetList, targetList[ranPlayer])

end
点赞
用户2858170
用户2858170

Option 1)

创建目标列表的本地副本,并从目标列表中删除被定位玩家。 然后从减少了的目标列表中选择一个目标。

local myTargetList = {}
for i,v in ipairs(targetList) do
  if v != Me then
    table.insert(myTargetList, v)
  end
end
-- 从 myTargetList 而不是 targetList 中选择目标

Option 2)

随机选择目标,直到目标不是被定位玩家。

2019-10-23 07:38:01
用户2860267
用户2860267

一种可靠的方法可能是通过固定量来偏移每个玩家,从而得到他们的目标。

回合1) 偏移量 = 1

  • 玩家1的目标为玩家2

  • 玩家2的目标为玩家3

  • 玩家3的目标为玩家4

  • 玩家4的目标为玩家1

回合2) 偏移量=2

  • 玩家1的目标为玩家3

  • 玩家2的目标为玩家4

  • 玩家3的目标为玩家1

  • 玩家4的目标为玩家2

等等。

一旦偏移量等于玩家人数,就将其重置为1。如果有玩家加入和离开,玩家很难看出这种模式。或者你可以每轮都打乱玩家列表。

-- 记录当前的偏移量
local offset = 1

-- 获取每轮的玩家与目标的对应关系
local function getTargetsForRound()
    local targets = {}

    local playerList = game.Players:GetPlayers()
    for i, player in ipairs(playerList) do
        -- 计算目标索引并纠正为基于1的数组
        local targetIndex
        if i + offset > #playerlist then
            targetIndex = (i + offset) % #playerList
        else
            targetIndex = i + offset
        end
        targets[ player.Name ] = playList[ targetIndex ].Name
    end

     -- 为下一轮增加偏移量
     offset = offset + 1
     if offset == #playersList then
         offset = 1
     end
end

-- 在每轮开始时,获取下一轮的目标
local t = getTargetsForRound()

for playerName, targetName in pairs(t) do
    print( string.format("%s的目标是%s", playerName, targetName )
end
2019-10-23 07:44:21
用户5373986
用户5373986

我决定在我的解决方案中使用一点递归和随机。

在下面的代码中,你传入球员名称列表 (即 game.Players:getChildren()),代码将随机匹配它们与其他球员。它有检查来确保它们不能匹配自己或已经被选中的目标,如果最后一个人没有目标可以选择,它将调用自身来获取一个新的列表。

由于我使用的种子是真正的随机数,因此你不会因为这个陷入递归循环的危险,因为下一个循环始终不同。

function stayOnTarget(players)
    math.randomseed(tonumber(tostring({}):sub(8))) --非常可靠的随机种子
    local availableTargets = {}
    local choosenTargets = {}

    --不链接球员数组的复制
    for _, player in pairs(players) do
        table.insert(availableTargets, player)
    end

    for i, player in pairs(players) do
        --如果最后一个球员被留下自己,再试一次
        if i == #players and availableTargets[1] == player then
            return stayOnTarget(players)
        end

        --选择一个不是自己的目标
        local targetIndex = math.random(1, #availableTargets)
        local target = availableTargets[targetIndex]
        while target == player do
            targetIndex = math.random(1, #availableTargets)
            target = availableTargets[targetIndex]
        end

        --存储目标并将其从可用目标中移除
        choosenTargets[player] = target
        table.remove(availableTargets, targetIndex)
    end
    return choosenTargets
end
local results = stayOnTarget({"User1", "User2", "User3", "User4"})

--打印目标匹配
for i, v in pairs(results) do
    print(i .. " = " .. v)
end

最后返回一个字典,并设置了一个循环来打印结果,如果你想看到它们的话。如果你有任何问题,请留言评论。

2019-10-23 14:05:43