Shuffling Tables Using the Fisher-Yates Algorithm
Introduction
Lua does not provide a built-in method for shuffling tables, so I wanted to share an efficient and fair way to shuffle tables using the Fisher-Yates algorithm.
Why Use Fisher-Yates?
Efficient – Runs in O(n)
time, making it fast even for large tables.
Fair – Ensures every possible permutation has an equal chance.
No Duplicates – Cards are properly shuffled without repetition.
Now, let’s see how we can apply this algorithm in a game that uses playing cards.
Step 1: Creating a Deck of Cards
We first define the suits and ranks for our deck:
local suits = {"Hearts", "Diamonds", "Clubs", "Spades"} -- Create the table of available suits
local ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"} -- Create the table of available ranks
Now, let’s create an empty table to store the deck:
local deck = {} -- Create an empty table to store the deck
We populate the deck by combining each rank with each suit:
for _, suit in ipairs(suits) do -- Loop through each suit
for _, rank in ipairs(ranks) do -- Loop through each rank
table.insert(deck, rank .. " of " .. suit) -- Insert the card into the deck
end
end
Step 2: Shuffling the Deck Using Fisher-Yates Algorithm
We use the Fisher-Yates shuffle to randomize the deck:
for i = #deck, 2, -1 do -- Start from the last card down to the second card
local j = math.random(1, i) -- Select a random index between 1 and i
deck[i], deck[j] = deck[j], deck[i] -- Swap the randomly selected card with the current card
end
To verify the shuffle, we print the deck:
for i, v in ipairs(deck) do
print(v) -- Print each shuffled card
end
Note: The output will differ each time you run it since the shuffle is random.
Step 3: Distributing Cards to Players
Now that we have a shuffled deck, let’s distribute cards to players.
First, define our players:
local players = {"Player1", "Player2", "Player3", "Player4"} -- List of players
local hands = {} -- Table to store each player's hand
Initialize empty hands for each player:
for _, player in ipairs(players) do
hands[player] = {} -- Create an empty table for each player's hand
end
Dealing 4 Cards per Player
local cardsPerPlayer = 4 -- Number of cards each player gets
for i = 1, cardsPerPlayer do -- Loop to distribute the set number of cards per player
for _, player in ipairs(players) do -- Loop through each player
if #deck > 0 then -- Ensure there are still cards left in the deck
local card = table.remove(deck, 1) -- Remove the top card from the deck
table.insert(hands[player], card) -- Assign the removed card to the player
end
end
end
Printing Each Player’s Hand
for player, hand in pairs(hands) do
print(player .. "'s hand:") -- Print player's name
for _, card in ipairs(hand) do
print(" - " .. card) -- Print each card in the player's hand
end
end
Note: The card distribution will vary each time due to randomness.
Example Output:
Player1’s hand:
- 4 of Hearts
- 6 of Spades
- 7 of Clubs
- 6 of Clubs
Player2’s hand:- 8 of Spades
- A of Diamonds
- 4 of Diamonds
- 5 of Spades
Player4’s hand:- 2 of Diamonds
- A of Spades
- 9 of Spades
- 10 of Diamonds
Player3’s hand:- 10 of Clubs
- Q of Hearts
- 4 of Clubs
- 8 of Clubs
Conclusion
With this method, we’ve successfully:
Shuffled a deck of cards using Fisher-Yates.
Ensured randomness for fair gameplay.
Distributed cards evenly among players.
I hope this tutorial was helpful! Let me know if you have any questions.