如果您在 0 和 xMax 之间随机放置一个“主要”对象,并且必须将 1 个或多个“次要”对象放置在同一范围内,但距离 mainX 的主要对象至少 D,和次要对象可以尽可能靠近,如果有多个,那么试试这个:
function getRandPosNotTooCloseToMain(xMax, mainX, D)
assert(2*D < xMax) -- if false then main too "fat"
local leftLen = mainX - D
local rightLen = xMax - (mainX + D)
local leftSideWins = true -- need some default
if leftLen < 0 then -- can only place it right side of main
assert(rightLen > 0)
leftSideWins = false
elseif rightLen < 0 then -- can only place it on left side of main
-- nothing to do, because leftSideWins already true
else -- there is space on either side of main (both leftLen and rightLen > 0),
-- so randomly select one side then return random # on that side
local ratio = leftLen / (leftLen + rightLen)
if math.random() > ratio then -- right half wins
leftSideWins = false
else -- left side wins, this is the default
end
end
if leftSideWins then
return math.random(0, leftLen)
else
return mainX + D + math.random(0, rightLen)
end
end
这可以通过以下方式进行测试:
-- test
math.randomseed(os.time())
local numTests = 100000
-- generate a bunch of values for right side always wins:
for x=1,numTests do
local x = getRandPosNotTooCloseToMain(60, 15, 20)
assert( x >= 15+20, x )
end
-- generate a bunch of values for left side always wins:
for x=1,numTests do
local x = getRandPosNotTooCloseToMain(60, 45, 20)
assert( x <= 45-20, x )
end
-- generate a bunch of values for left side always wins:
for x=1,numTests do
local x = getRandPosNotTooCloseToMain(60, 30, 20)
assert( x <= 10 or x>= 50, x )
end
-- if get this far then all tests passed!
print("Passed!")
所有测试都通过。在您的情况下,您将通过math.random(0,xMax) 随机设置mainX。