Like a turned card

Hey guys, i am looking for a script.
i need a random spawn. just like blackjack.
when you hit a button you will get a random card.
i hope somebody over here can help me :slight_smile:

You could use card = math.random(13) to determine whether it is an ace through king then do suit = math.random(4) to determine suit, then store both into a table of usedCards.



table.insert(usedCards, { card, suit })



Then when adding the next random card, make sure to check the table to see if that card was already used.

Better to shuffle the deck first and then deal out the randomised cards.

A straightforward algorithm for this is the Fischer-Yates-Knuth shuffle:

function KnuthShuffle(n,odd)
    local l
    local o = 0
    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]
            o = 1 - o
        end
    end
    if not odd and o == 1 then
        p[1],p[2] = p[2],p[1]
    end
    return p
end

This will shuffle the integers from 1 to n. Modulo the usual remarks about math.random not being truly random, this gives the correct distribution on shuffles. The optional flag odd is because I wanted a way to ensure that the resulting shuffle was an even permutation (it was for a picture-sliding puzzle).

Yeah thats more like it, i Need it for all THE 52 cards.

@Andrew_stacey when i need a random order for a deck i do like this:

  • 1/ get a random number Ri for each card i of the deck.
  • 2/ sort the cards wrt the numbers Ri.
    It is quick and simple. What do you think of this algorithm? How would you compare it to FYK shuffle?

@Jmv38 Apparently, table.sort uses quick sort which is O(n log n). Fisher-Yates-Knuth (and, according to Wikipedia, Durstenfeld) is O(n). So FYDK is quicker.

It would be easier to see the comparison if we replaced the quicksort by a bubble sort.

Your algorithm:

  1. Generate n random numbers
  2. Perform 1/2 n(n-1) comparisons (A bubble sort does n-1 + n-2 + n-3 + n-4 + … + 1 comparisons).
  3. Perform a bubble sort which on average performs 1/4 n(n-1) swaps (we expect half of the comparisons to result in a swap). If n is bigger than 4, this is bigger than n-1, and it grows with the square of n.

FYDK algorithm:

  1. Generate n-1 random numbers.
  2. Perform at most n-1 swaps.

So I’d say that the Fisher-Yates-Knuth-Durstensfeld algorithm is quicker.

Of course, the fact that the quicksort is internal might have an impact, but other than that I’d go for the other.

Incidentally, I discovered this algorithm not all that long ago and was so taken with it that I wrote a blog post about it: http://tex.blogoverflow.com/2011/08/do-the-knuth-shuffle/ I find it actually a very intuitive algorithm.

Thanks for the detailed argumentation.

Here’s a routine that I used. You can setup a table of 52 cards instead of using 2 tables like I have here.


function setup()
    suit={"Diamonds","Hearts","Spades","Clubs"}
    value={"2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace"}
    
    cards={}
    
    for z=1,52 do    -- clear selected cards
        cards[z]=0
    end
    
    for z=1,52 do    -- 52 cards
        selectedCard=math.random(1,52)    -- random card
        if cards[selectedCard]~=0 then    -- card already selected
            while cards[selectedCard]~=0 do    -- look for next card not selected
                selectedCard = selectedCard + 1    -- try next card
                if selectedCard>52 then    -- end of deck
                    selectedCard=1    -- start over
                end
            end
        end
        cards[selectedCard]=1    -- set card as selected
        s=math.ceil(selectedCard/13)   -- get suit 
        v=selectedCard%13+1    -- get value
        print(value[v].." of "..suit[s])
    end       
end

Verry nice dave but how do i link Some sprites to the numbers.
And how do i get text with every card?

@dave1707 That’s pretty close to the original FY algorithm. The one I describe is meant to be an improvement on that.

@Draakk - perhaps I can save you some trouble. In the posts 39 & 40 of the link below is code to draw your own cards (without any sprites), shuffle and deal them, etc

http://coolcodea.wordpress.com/2013/04/

@Draakk I’m not sure how you’re creating your sprites, but if you have 1 sprite per card then you would use a table for the sprites. In my code above, selectedCard would be an offset into that table. My code would also have to be modified a little depending on how you want it to work with your code. It could be changed to return a table containing 52 random cards or changed to a function to return a random card for each call for the 52 cards.

@Andrew_Stacey That’s a routine that I used probably 25+ years ago when I was messing around with card programs on my Apple II.

What is the best way to animate a turning over card given a front and back png? Maybe with a slight bend in the card as it turns using a swipe of the finger. Maybe even with some thickness to the card. Maybe with both sides of the card visible at the same time during part of the turn.

I dont want THE script draw THE cards, ive created 52 awsome .png’s
How Will it end up with png’s

@Draakk - that is a very broad request - do you have a specific question?

I just want 2 stacks of cards 1 stack with the backside up you must hit it and the other stack is the random turned cards when you hit the first stack.
Ive created my own playing cards in illustrator and exported the 52 images to png files.

@Draakk suggestion: post your own script, and if it doesnt work well some great folk on this forum will correct it or improve it. No one is going to code your game for you, if this is what you are looking for? >:D<
(with the exception of Dave, maybe, who is a really really nice guy and a coding machine!)

This is my current main script
But the problem is the cards are repeating… It doesnt stop at the end of the stack.
And when i hit the stack it draws almost 3 cards in 1 time.
And how do i get text drawn in the screen?
Thnq

-- Use this function to perform your initial setup
function setup()
    --b=Backup("Cards v105")
    img=readImage("Documents:cb") --image for back of card
    deal()
    print("Turn the card!")
end

function touched(touched)
-- this examines if the touch is within the rectangle's boundraries:
if CurrentTouch.x > 308 and CurrentTouch.x < 494 and CurrentTouch.y > 317 and CurrentTouch.y < 602 then
    deal() --redeal if we touch the screen
    end
end

function deal()
    c=Card(250,img)  --big cards 
    p=Pack(1)
    cards={}
    for i=1,1 do
        cards[i]=p:nextCard() 
    end 
end

-- This function gets called once every frame
function draw()
    -- This sets a background
    -- ipad size:2048,1536
    sprite("Documents:bg1", 512, 384, 1024, 768)
   -- sprite("Documents:cb", 401, 462, 186, 290)
    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    --draw our hand of cards
    --spread out cards to look nice
    for i,card in ipairs(cards) do
       c:draw(523+i*18,555,card.cardIndex,true)
    end
    --draw a pack face down
    for i=1,4 do
       c:draw(312+i*2,590-i*2,1,false) 
    end
    end

The reason it is dealing more than one card is that the touched function gets called at least twice for a touch - once at the beginning and once at the end. Try this, to only deal when the touch ends.

function touched(touch)
    if touch.state==ENDED then
        if touch.x>308 and touch.x<494 and .....  --your code goes here
    end
end