You might do better to abstract some of this away from your mind. You might just be getting hung up on the details because you're keeping too much in your head.
First, abstract your thought process to create card "zones" instead of decks and hands. A card "zone" holds list of cards that are in a specific order (note that this order can be randomized, but it is fixed).
Then try writing these functions:
function CreateNewDeck() return <a sorted deck of 40 cards>
function Shuffle(zone) -- to shuffle the cards in a zone
function DrawFirst(zone) -- remove and return the first card in this zone
function ContainsCard(zone, card) -- return true if the zone contains that card, nil otherwise
function RemoveCard(zone, card) -- remove the specific card that you pass as the second variable from the specified zone; you probably for your own convenience want to return the removed card as a result of this function
function Size(zone) -- return the number of cards in this zone
function InsertInFront(zone, card) -- put the given card into the front of this zone
function Clear(zone) -- basically, set this zone to an empty array
Once you do that, the mechanics should be easy.
local deck, discard, p1, p2, p3 = {}, {}, {}, {}, {}
deck = CreateNewDeck()
Shuffle(deck)
-- pass out cards
InsertInFront(p1, DrawFirst(deck))
InsertInFront(p2, DrawFirst(deck))
InsertInFront(p3, DrawFirst(deck))
InsertInFront(p1, DrawFirst(deck))
InsertInFront(p2, DrawFirst(deck))
InsertInFront(p3, DrawFirst(deck))
InsertInFront(p1, DrawFirst(deck))
InsertInFront(p2, DrawFirst(deck))
InsertInFront(p3, DrawFirst(deck))
InsertInFront(p1, DrawFirst(deck))
InsertInFront(p2, DrawFirst(deck))
InsertInFront(p3, DrawFirst(deck))
InsertInFront(p1, DrawFirst(deck))
InsertInFront(p2, DrawFirst(deck))
InsertInFront(p3, DrawFirst(deck))
-- allow player one to choose the cards he discards using some method,
-- let's assume he loads the array "p1discardlist" with the cards he doesn't want
for each _, c in ipairs(p1discardlist) do
if ContainsCard(p1, c) then
InsertInFront(discard, RemoveCard(p1, c))
InsertInFront(p1, DrawFirst(deck))
end end
--repeat for each other player
--determine winner, pay money
--Let's mimick a real game for some random reason
--collect all the cards
while #p1 > 0 do
InsertInFront(discard, DrawFirst(p1))
end
--repeat for all
--load the shoe
while #discard > 0 do
InsertInFront(deck, DrawFirst(discard))
end
Shuffle(deck)
Of course, the end could easily be:
ClearZone(p1)
ClearZone(p2)
ClearZone(p3)
ClearZone(discard)
deck = Shuffle(CreateNewDeck())
Like Nick said, just make sure to balance each Draw/Remove with an InsertInFront and you'll never lose track of a card.
Write functions like "PrintZoneToScreen" and you'll easy be able to send the hands to each player as they're updated.
They key concept to take away is that all the real memory work is now being done by storing all of your state information in the "zone" variables, NOT in the actual logic of your code. You'd be surprised at how much this simplifies your tasks once you get used to the idea. |