This prints to a compiler just fine, but how can I get these cards randomized ? I think I could put a table.insert and a math.random somewhere.....
~~~
suit={"♠️","♣️","♥️","♦️"}
val={"2","3","4","5","6","7","8","9","10","J","Q","K","A"}
cards={}
for x=1,4 do
for y=1,13 do
str=string.format(" %s\n%s",val[y],suit[x])
table.insert(cards,str)
print(val[y],suit[x])
end
end
~~~

P.S. : This is just a study along with a Lua book....

@kendog400 There are a lot of card programs already written in this forum. Try doing a search for them and you’ll find code to randomize a deck of cards.

@kendog400 I don’t know what you’re doing, but in one of your other card game programs that you posted, you have a very nice shuffle function that shuffles a deck of cards.

Here’s something I came up with that you can look thru.

displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)
function setup()
s={" ♥️"," ♠️"," ♦️"," ♣️"}
v={" 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10"," J"," Q"," K"," A"}
deck={}
for z=0,51 do
table.insert(deck,v[z%13+1]..s[z//13+1])
end
end
function draw()
background(151, 223, 223, 255)
fontSize(40)
fill(255)
text("Tap screen to shuffle",WIDTH/2,HEIGHT-50)
for z=0,51 do
text(deck[z+1],275+(z//13)*150,50+(z%13)*50)
end
end
function shuffle()
for q=1,100 do
a,b=math.random(52),math.random(52)
deck[a],deck[b]=deck[b],deck[a]
end
end
function touched(t)
if t.state==BEGAN then
shuffle()
end
end

I would like to know why when i touch the screen the PGM deals cards, when it should only deal when i touch the Deal button...Can someone help ?

-- Shuffle
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)
function setup()
suit={"♠️","♣️","♥️","♦️"}
value={"2","3","4","5","6","7","8","9","10","J","Q","K","A"}
Shuffled=shuffleCards(5)
r=0
end
function draw()
background(230, 228, 219, 255)
fill(45, 127, 37, 255)
font("Copperplate-Bold")
fontSize(50)
card=0
fill(0, 5, 255, 255)
text("Player 1",WIDTH/2,HEIGHT-40)
text("Player 2",WIDTH-150,500)
text("Player 3",WIDTH/2,280)
text("Player 4",130,500)
font("AmericanTypewriter-Bold")
fontSize(50)
for round=1,r do
for player=1,4 do
card=card+1
s=math.ceil(Shuffled[card]/13) -- get suit value
v=Shuffled[card]%13+1 -- get card value
str=value[v].." of "..suit[s] -- print card
fill(0)
if s>2 then
fill(255,0,0)
end
if player==1 then
text(str,WIDTH/2,HEIGHT-30-60*round)
end
if player==2 then
text(str,WIDTH-150,480-55*round)
end
if player==3 then
text(str,WIDTH/2,275-50*round)
end
if player==4 then
text(str,120,490-50*round)
end
end
end
fill(0)
rect(0,0,WIDTH,50)
-- This is the Reset button
fill(255, 255, 255, 255)
stroke(255, 0, 8, 255)
strokeWidth(4)
ellipse(865, 650,150)
fill(0, 0, 0, 255)
font("Copperplate-Bold")
fontSize(40)
text("Reset",WIDTH/2+350,HEIGHT-120)
-- This is the Deal button
fill(255, 255, 255, 255)
stroke(255, 0, 8, 255)
strokeWidth(4)
ellipse(150, 650,150)
fill(0, 0, 0, 255)
font("Copperplate-Bold")
fontSize(50)
text("Deal",WIDTH/2-365,HEIGHT-120)
end
function touched(t)
if t.state==BEGAN then
if t.x>765 and t.x<915 and t.y>550 and t.y<700 then
sound("Game Sounds One:1-2 Go")
Shuffled=shuffleCards(5)
r=0
return
end
r=r+1
if r>5 then
r=5
end
end
if t.state==BEGAN then
if t.x>50 and t.x<200 and t.y>550 and t.y<700 then
sound("Game Sounds One:Bell 2")
draw()
end
end
end
function shuffleCards(x)
local d1, d2, s, y, z = {}, {}
for z=1,52 do
d2[z]=z -- fill table with numbers 1 to 52
end
for y=1,x do -- shuffle x number of times
d1,d2=d2,{}
for z=1,52 do
s=math.random(1,#d1) -- get a random number from table d1
table.insert(d2,d1[s]) -- insert it in table d2
table.remove(d1,s) -- remove it from table d1
end
end
return d2 -- return shuffled deck
end

In the touched() function your adding 1 to r when you don’t touch a button. In the draw() function you’re displaying more cards because r was increased.

Just by-the-by, the standard algorithm for shuffling a table is the Fisher-Yates-Knuth algorithm. In lua, it looks like this:

function Shuffle(n)
local l
local p = {}
for k = 1,n do
p[k] = k
end
for k = 1,n-1 do
l = math.random(k,n)
if l ~= k then
p[k],p[l] = p[l],p[k]
end
end
return p
end

This creates a table with 1,...,n in a shuffled order, which can then be used as indices to another table to extract them in the given order. Eg:

cards = { ... }
order = Shuffle(52)
for i=1,52 do
print (cards[order[i]])
end

@kendog400 Press the shuffle button to shuffle the cards. Press the deal button to deal a card. Make whatever changes you need.

-- Shuffle
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)
function setup()
suit={"♠️","♣️","♥️","♦️"}
value={"2","3","4","5","6","7","8","9","10","J","Q","K","A"}
Shuffled=shuffleCards(5)
end
function draw()
background(230, 228, 219, 255)
fill(45, 127, 37, 255)
font("Copperplate-Bold")
fontSize(50)
card=0
fill(0, 5, 255, 255)
text("Player 1",WIDTH/2,HEIGHT-40)
text("Player 2",WIDTH-150,500)
text("Player 3",WIDTH/2,350)
text("Player 4",130,500)
font("AmericanTypewriter-Bold")
fontSize(50)
for round=1,r do
for player=1,4 do
card=card+1
s=math.ceil(Shuffled[card]/13) -- get suit value
v=Shuffled[card]%13+1 -- get card value
str=value[v].." of "..suit[s] -- print card
fill(0)
if s>2 then
fill(255,0,0)
end
if player==1 then
text(str,WIDTH/2,HEIGHT-30-60*round)
end
if player==2 then
text(str,WIDTH-150,480-55*round)
end
if player==3 then
text(str,WIDTH/2,350-50*round)
end
if player==4 then
text(str,120,490-50*round)
end
end
end
fill(0)
rect(0,0,WIDTH,50)
-- This is the Shuffle button
fill(255, 255, 255, 255)
stroke(255, 0, 8, 255)
strokeWidth(4)
ellipse(865, 650,150)
fill(0, 0, 0, 255)
font("Copperplate-Bold")
fontSize(40)
text("Shuffle",WIDTH/2+350,HEIGHT-120)
-- This is the Deal button
fill(255, 255, 255, 255)
stroke(255, 0, 8, 255)
strokeWidth(4)
ellipse(150, 650,150)
fill(0, 0, 0, 255)
font("Copperplate-Bold")
fontSize(50)
text("Deal",WIDTH/2-365,HEIGHT-120)
end
function touched(t)
if t.state==BEGAN then
if t.x>75 and t.x<225 and t.y>575 and t.y<725 then
sound("Game Sounds One:1-2 Go")
r=r+1
if r>5 then
r=5
end
elseif t.x>790 and t.x<940 and t.y>575 and t.y<725 then
sound("Game Sounds One:Bell 2")
Shuffled=shuffleCards(5)
r=0
end
end
end
function shuffleCards(x)
r=0
local d1, d2, s, y, z = {}, {}
for z=1,52 do
d2[z]=z -- fill table with numbers 1 to 52
end
for y=1,x do -- shuffle x number of times
d1,d2=d2,{}
for z=1,52 do
s=math.random(1,#d1) -- get a random number from table d1
table.insert(d2,d1[s]) -- insert it in table d2
table.remove(d1,s) -- remove it from table d1
end
end
return d2 -- return shuffled deck
end

@LoopSpace Here’s a shuffle routine I wrote that seems to work OK. The deck is created 1 time and the shuffle routine will shuffle the previously shuffled deck. Tap the screen to shuffle and print deck sequence.

function setup()
-- create the deck 1 time
deck={}
for z=1,52 do
table.insert(deck,z)
end
end
function touched(t) -- touch screen to shuffle deck and display numbers
if t.state==BEGAN then
shuffle()
print(table.concat(deck," "))
end
end
function shuffle() -- shuffle the shuffled deck
for z=1,200 do -- swap random positions 200 times
r1,r2=math.random(52),math.random(52) -- create 2 random positions
deck[r1],deck[r2]=deck[r2],deck[r1] -- swap numbers at 2 positions
end
end

@LoopSpace Thanks for the link, I was looking for something like that but never found one. I’m not saying that routine is perfect, but it gets the job done. Each shuffle will take the previously shuffled deck and shuffle it again. I don’t think you can say that one sequence of numbers is more random than any other. Every sequence of numbers has the same chance of occurring as any other sequence. Even if the same sequence occurs twice in a row doesn’t mean it’s not random. Now to get back to that link and read more.

@LoopSpace Looking at the explanation of a 3 card deck at the link you provided, they say the 6 combinations of sequences should be about equal. Random sequences don’t happen equally. If I flip a coin 1000 times, does that mean I should have 500 heads and 500 tails. 990 heads and 10 tails has the same chance of happening as any other combination, but that doesn’t mean it’s not random. So far I’m not agreeing to much with that link, but I’ll keep on reading.

@dave1707 Not time for a long reply, but you're wrong in what you say:

If I flip a coin 1000 times, does that mean I should have 500 heads and 500 tails. 990 heads and 10 tails has the same chance of happening as any other combination

If you prescribe the order of the 500 heads and tails, and of the 990 heads and tails then yes, each is as likely to occur as the other. However, when we say "500 heads and tails" then we (usually) mean without taking order into account. In that case, there are far, far more ways of getting 500 heads and tails than 990 heads and 10 tails.

Extremes are helpful: there is precisely one way to get 1000 heads. But there are 1000 ways to get 999 heads and 1 tail. So 999 heads is 1000 times more likely that 1000 heads.

@LoopSpace I agree with you on the coin toss, that was a bad choice on my part. Right now I’m writing code to check my shuffle using a 3 card deck to see how the counts come up for the six different combinations.

@LoopSpace Here’s the results of a 3 card shuffle after 3 1,000,000 count runs. The top is using my shuffle and the bottom is using the shuffle from the link. I think my shuffle comes close to the results they want.

@dave1707 You're right, in a sense, but wrong in another. Your algorithm is different to the one that Jeff Attwood uses but I wasn't critiquing the specific algorithm but rather saying that shuffling algorithms are subtle.

Your algorithm is a random walk on the graph of arrangements connected by transpositions. This converges to a uniform distribution, which is why you're seeing the roughly even distribution. However, your algorithm is expensive. You need to do a lot of transpositions relative to the number of objects to get it to be uniform. Your original code used 200 swaps and I don't think that would be enough for 52 cards. It is enough for 3 cards, as shown in your tests, but it is 100 more swaps than necessary. When shuffling 3 cards, only two swaps are necessary.

(Though in actual fact, shuffling 52 cards reaches the limit of the pseudo-random generator - it won't reach all possible shuffles of 52 cards simply because there are too many of them. But that's a different aspect.)

@LoopSpace I was trying to find something that would say how well a random sequence was random, but didn’t find anything. But one thing I tried on my shuffle was to see how many numbers (1-52) when shuffled ended up in their numerical position, ie 5 in position 5, 25 in position 25, etc. When I kept shuffling and checking, a lot of times 1 number was in its numerical position. Sometimes I had 0 and sometimes I had 2. I didn’t have more than 2, but I didn’t check on the order of thousands of runs. I don’t know how well that checks anything, but for a shuffle for a simple card game, I think it works OK. I don’t know if there’s an optimal number of swaps, but I picked 200 for no reason.

-- shuffle
function setup()
deck = {}
for i=1,10 do
deck[i] = i
end
print(table.concat(deck,"-"))
deck = shuffle(deck)
print(table.concat(deck,"-"))
end
function shuffle(t)
temp = {}
for i,v in pairs(t) do
temp[i] = {v, math.random()}
end
table.sort(temp, function(a,b) return a[2]<b[2] end)
for i,v in pairs(temp) do
t[i] = temp[i][1]
end
return t
end

On line 53, is there a way that the card value could be printed upside down like a real card ? Take a peek anyone...

--- Random Card
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)
function setup()
rectMode(CENTER)
suit={{" ♥️",” ♦️"," ♠️"," ♣️ "}
u={" 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10"," J"," Q"," K"," A"}
deck={} -- Table for the cards
createDeck() -- Goto createDeck
getCard=true -- Show the first card
cc = 52 -- Keep count of the Cards
end
function draw()
-- Background color
background(31, 34, 97, 255)
if getCard then --if a card is showing
getCard=false --Dont get another until the button is touched
randomCard() --Goto the random card fx
c=v%13+1 --The card value
s=math.ceil(v/13)
end
-- This is the white card background
fill(255)
rect(WIDTH/2,HEIGHT/2,350,500) --This is the WHT rectangle, location & Size
-- Font & font size of the suit & value
font("AmericanTypewriter-Bold")
fontSize(160) --size of suit font
--This is the card suit being printed to the screen
text(suit[s],WIDTH/2,HEIGHT/2)
-- This is the different colors of the suits
if s==1 then --hearts
fill(255,0,0)
elseif
s==2 then --dimonds
fill(31, 0, 255, 255)
elseif
s==3 then --spades
fill(0, 0, 0, 255)
elseif
s==4 then --clubs
fill(31, 109, 53, 255)
end
-- This is the card value
text(u[c],WIDTH/2-90,HEIGHT/2+170)
text(u[c],WIDTH/2+80,HEIGHT/2-170) -- This is line 53,,,,,,
--End of deck suit
font("Baskerville-BoldItalic")
fontSize(60)
fill(255, 255, 255, 255)
text(str, WIDTH/2,HEIGHT-60)
-- Card count, this is being constantly updated
font("Baskerville-BoldItalic")
fontSize(50)
fill(255, 255, 255, 255)
text(cc, WIDTH-875,HEIGHT/2)
-- Plain text
font("Copperplate-Bold")
fontSize(50)
fill(255, 255, 255, 255)
text("Cards left\n in Deck :", WIDTH-855,HEIGHT/2+80)
-- This is the button
fill(255, 255, 255, 255)
stroke(255, 0, 8, 255)
strokeWidth(4)
ellipse(865, 420,150)
fill(0, 0, 0, 255)
font("Copperplate-Bold")
fontSize(50)
text("Next",WIDTH/2+350,HEIGHT-345)
end
--This is the touch area location
-- The 'x', subtract 100 from 865 = 765
-- The 'y', subtract 100 from 420 = 320
-- Stretch this 150 pixels
function touched(t)
if t.state==BEGAN then
if t.x>765 and t.x<915 and t.y>320 and t.y<470 then
sound("Game Sounds One:Bell 2")
getCard=true
end
end
end
function createDeck()
str = "Tap button for next card"
for z=1,52 do
deck[z]=z
end
end
function randomCard()
-- This plucks a random card then subtracts it from the Main deck
if #deck>0 then --if there are any cards left in the deck, then pluck
d=math.random(#deck) --pluck at random
v=deck[d]
table.remove(deck,d) --after being plucked, remove it from the deck
else
str = "End of Deck"
end
-- This keeps track of the amount of cards left in the deck
if cc <= 52 then --cc means card-count
cc = cc - 1
end
end

It can be done but it’s more work. Here's an example for 1 card. You use the translate and rotate commands.

function setup()
end
function draw()
background(40, 40, 50)
stroke(255, 164, 0, 255)
strokeWidth(5)
fill(255)
rect(200,300,130,200)
fill(255,0,0)
text("2",220,480)
text("♥️",220,460)
scale(2,2)
text("♥️",133,220)
scale(.5,.5)
-- show things upside down
translate(300,300)
rotate(180)
text("2",-10,-20)
text("♥️",-10,-40)
scale(2,2)
text("♥️",18,-30)
translate(-300,-300)
end

@Jmv38 Your sort does produce shuffles with the correct distribution, but it you do more steps than necessary. As you're using a sort (I can't recall which sort table.sort uses off the top of my head), you are typically doing n log(n) swaps, whereas the optimal algorithm uses n-1 swaps.

So your algorithm is less efficient than the Knuth-Fisher-Yates one.

(The actual multiplier is trickier since one measures complexity of algorithms in "big-O" notation, which ignores certain factors.)

I would say as long as people arent winning or losing tens of thousands of dollars based on the above sort routines, then whichever one is used doesn’t really matter that much. As long as it appears to be random and doesn’t take a long time, then that’s good enough. But it’s still interesting to see all the different routines and comments about them.

## Comments

Do a search for

`Ignatz tutorials`

. I don't know it he did anything for card games. Do a forum search for what you want, you'll find some info there.This prints to a compiler just fine, but how can I get these cards randomized ? I think I could put a table.insert and a math.random somewhere.....

~~~

suit={"♠️","♣️","♥️","♦️"}

val={"2","3","4","5","6","7","8","9","10","J","Q","K","A"}

cards={}

for x=1,4 do

for y=1,13 do

str=string.format(" %s\n%s",val[y],suit[x])

table.insert(cards,str)

print(val[y],suit[x])

end

end

~~~

P.S. : This is just a study along with a Lua book....

@kendog400 There are a lot of card programs already written in this forum. Try doing a search for them and you’ll find code to randomize a deck of cards.

@kendog400 I don’t know what you’re doing, but in one of your other card game programs that you posted, you have a very nice shuffle function that shuffles a deck of cards.

Here’s something I came up with that you can look thru.

Thanks !...I'm just reading a book on Lua and trying to get a good comprehension...If I can understand whats going on I can tackle it !..

I would like to know why when i touch the screen the PGM deals cards, when it should only deal when i touch the Deal button...Can someone help ?

In the touched() function your adding 1 to r when you don’t touch a button. In the draw() function you’re displaying more cards because r was increased.

I tried a few steps, but i’m baffled as to what to do ?

In the draw function i changed the

for round=1,r do to for found=1,4 and it automatically spits out 4 cards a player...

Just by-the-by, the standard algorithm for shuffling a table is the

Fisher-Yates-Knuthalgorithm. In lua, it looks like this:This creates a table with

`1,...,n`

in a shuffled order, which can then be used as indices to another table to extract them in the given order. Eg:@kendog400 Press the shuffle button to shuffle the cards. Press the deal button to deal a card. Make whatever changes you need.

@LoopSpace Here’s a shuffle routine I wrote that seems to work OK. The deck is created 1 time and the shuffle routine will shuffle the previously shuffled deck. Tap the screen to shuffle and print deck sequence.

@dave1707 Not all algorithms are equal, see this post for a discussion of shuffling algorithms in particular.

@LoopSpace Thanks for the link, I was looking for something like that but never found one. I’m not saying that routine is perfect, but it gets the job done. Each shuffle will take the previously shuffled deck and shuffle it again. I don’t think you can say that one sequence of numbers is more random than any other. Every sequence of numbers has the same chance of occurring as any other sequence. Even if the same sequence occurs twice in a row doesn’t mean it’s not random. Now to get back to that link and read more.

@LoopSpace Looking at the explanation of a 3 card deck at the link you provided, they say the 6 combinations of sequences should be about equal. Random sequences don’t happen equally. If I flip a coin 1000 times, does that mean I should have 500 heads and 500 tails. 990 heads and 10 tails has the same chance of happening as any other combination, but that doesn’t mean it’s not random. So far I’m not agreeing to much with that link, but I’ll keep on reading.

@dave1707 Not time for a long reply, but you're wrong in what you say:

If you prescribe the

orderof the 500 heads and tails, and of the 990 heads and tails then yes, each is as likely to occur as the other. However, when we say "500 heads and tails" then we (usually) mean without taking order into account. In that case, there are far, far more ways of getting 500 heads and tails than 990 heads and 10 tails.Extremes are helpful: there is precisely one way to get 1000 heads. But there are 1000 ways to get 999 heads and 1 tail. So 999 heads is 1000 times more likely that 1000 heads.

@LoopSpace I agree with you on the coin toss, that was a bad choice on my part. Right now I’m writing code to check my shuffle using a 3 card deck to see how the counts come up for the six different combinations.

@LoopSpace Here’s the results of a 3 card shuffle after 3 1,000,000 count runs. The top is using my shuffle and the bottom is using the shuffle from the link. I think my shuffle comes close to the results they want.

Ps. I should have used 600,000 instead of 1,000,000 to match their results.

@dave1707 You're right, in a sense, but wrong in another. Your algorithm is different to the one that Jeff Attwood uses but I wasn't critiquing the specific algorithm but rather saying that shuffling algorithms are subtle.

Your algorithm is a random walk on the graph of arrangements connected by transpositions. This

convergesto a uniform distribution, which is why you're seeing the roughly even distribution. However, your algorithm is expensive. You need to do a lot of transpositions relative to the number of objects to get it to be uniform. Your original code used 200 swaps and I don't think that would be enough for 52 cards. It is enough for 3 cards, as shown in your tests, but it is 100 more swaps than necessary. When shuffling 3 cards, only two swaps are necessary.(Though in actual fact, shuffling 52 cards reaches the limit of the pseudo-random generator - it won't reach all possible shuffles of 52 cards simply because there are too many of them. But that's a different aspect.)

@LoopSpace I was trying to find something that would say how well a random sequence was random, but didn’t find anything. But one thing I tried on my shuffle was to see how many numbers (1-52) when shuffled ended up in their numerical position, ie 5 in position 5, 25 in position 25, etc. When I kept shuffling and checking, a lot of times 1 number was in its numerical position. Sometimes I had 0 and sometimes I had 2. I didn’t have more than 2, but I didn’t check on the order of thousands of runs. I don’t know how well that checks anything, but for a shuffle for a simple card game, I think it works OK. I don’t know if there’s an optimal number of swaps, but I picked 200 for no reason.

to shuffle i like to use this

I assume this method has no caveats?

On line 53, is there a way that the card value could be printed upside down like a real card ? Take a peek anyone...

It can be done but it’s more work. Here's an example for 1 card. You use the translate and rotate commands.

Thanks...

It worked...

@Jmv38 Your sort does produce shuffles with the correct distribution, but it you do more steps than necessary. As you're using a sort (I can't recall which sort

`table.sort`

uses off the top of my head), you are typically doing`n log(n)`

swaps, whereas the optimal algorithm uses`n-1`

swaps.So your algorithm is less efficient than the Knuth-Fisher-Yates one.

(The actual multiplier is trickier since one measures complexity of algorithms in "big-O" notation, which ignores certain factors.)

@LoopSpace thanks for this analysis.

I would say as long as people arent winning or losing tens of thousands of dollars based on the above sort routines, then whichever one is used doesn’t really matter that much. As long as it appears to be random and doesn’t take a long time, then that’s good enough. But it’s still interesting to see all the different routines and comments about them.