How can I prevent getting the same number twice?

Hi, I am trying to make a boss fight system and I wonder how to prevent it taking 2 numbers twice. Here´s the script. Does anybody know how I can prevent that?

...
 local Attacks = {"RingAttack","WallAttack"}
print(Attacks)
local randomAttacks = "RingAttack" -- First attack boss does

local function randomizeAttacks()
randomAttacks = Attacks[math.random(1,#Attacks)] -- this is the part of the code which picks the attacks 
-- (I want to prevent that it takes the same attack twice)
end


									
local Attackvalue = 0
local function attack()
										
randomizeAttacks()
										
if randomAttacks == "WallAttack" and debounce == true then
debounce = false
WallAttack()
if Attackvalue == 6 then
debounce = false
else
debounce = true
end
end
										
if randomAttacks == "RingAttack" and debounce == true then
...
1 Like

Have a variable previousAttack. At the end of the function, set previousAttack as randomAttacks. And then check if they are the same:

repeat
    randomAttacks = Attacks[math.random(1,#Attacks)] -- this is the part of the code which picks the attacks 
    -- (I want to prevent that it takes the same attack twice)
until randomAttacks ~= previousAttack
previousAttack = randomAttacks
1 Like

A common way to do this would be to make a copy of your “attacks” array, and when you get a selection you remove it from the copied array. It works like a deck of cards, where each attack draws a card. If you had four attacks it would have to go through all four before using an attack again, like 1-3-2-4 shuffles 4-3-1-2 but at the shuffle point it could repeat attacks.

I’d recommend a slightly different version so that it never plays the same card twice in a row but could repeat patterns like 1-2-1-2

local deck: {string} = {unpack(Attacks)}
local function randomizeAttacks(): string
    local card = deck[math.random(1, #deck)]
    
    -- reset the deck, but remove our last used card
    deck = {unpack(Attacks)}
    table.remove(deck, table.find(deck, card))

    return card
end
2 Likes

I am getting this error message:
ServerScriptService.MainScript:582: invalid argument #1 to ‘find’ (table expected, got string)

I did it like this: (this is a little part of the boss script)

...
local Attacks = {"RingAttack","WallAttack"}
print(Attacks)
local randomAttacks = "RingAttack" -- First attack boss does

local deck: {string} = {unpack(Attacks)}
local function randomizeAttacks(): string
local card = deck[math.random(1, #deck)]

-- reset the deck, but remove our last used card
deck = {unpack(Attacks)}
table.remove(deck, table.find(card))

return card
end


																		
local Attackvalue = 0
local function attack()
										
randomizeAttacks()
										
if randomAttacks == "WallAttack" and debounce == true then
...

the error seems to be in this line:
table.remove(deck, table.find(card))

U actually use math.random?
Use random.new.

local rndm = Random.new(tick())
rndm:NextInteger(1,3) -- random number which never repeats.
2 Likes

sorry it’s supposed to be
table.remove(deck, table.find(deck, card))
I forgot to include 2 arguments in table.find

1 Like

Random.new is uniformly distributed, which does not mean it won’t repeat. It still can and will repeat values, uniform distribution means is it will give an even amount of 1s, 2s, and 3s in your example; math.random might give slightly more 1s than 2s or 3s it’s a very technical difference, but it will repeat numbers.

2 Likes

it seems like it would work but the attacks wont happen anymore and it printed something like: table: 0x82109a0478e7a838

local Attacks = {"RingAttack","WallAttack"}
									print(Attacks)
									local randomAttacks = "" -- First attack boss does

									local deck: {string} = {unpack(Attacks)}
									local function randomizeAttacks(): string
										local card = deck[math.random(1, #deck)]

										-- reset the deck, but remove our last used card
										deck = {unpack(Attacks)}
										table.remove(deck, table.find(deck, card))

										return card
									end


									-- here it will check which attack it selected and then it will start it										
									local Attackvalue = 0
									local function attack()
										
										randomizeAttacks()
										
										if randomAttacks == "WallAttack" and debounce == true then

ah I’m not sure where you’re printing that should return table : 0x82... but I understand where the error is.
since the randomizeAttacks function returns a string (card) you have to call it like this:

local function attack()
    randomAttacks = randomizeAttacks() -- how to call our function with return
    if randomAttack == "WallAttack" and debounce then
        -- rest of the script ...
1 Like

Oh. Then do this

local rndm = Random.new(tick())
local randompickednumber = rndm:NextInteger(1,3)
local beforepick = nil
 local function ran()
if randompickednumber == beforepick then
return ran()
else
return randompickednumber
end
end


if beforepick ~= nil then
print(ran())
else
beforepick = randompickednumber
end
1 Like

it worked, looks like the attacks arent repeating anymore. Thanks for the help