Card tricks with Ruby

First of all I wish to humbly send my thanks everyone taking their time
to
share their pearls of wisdom! You have taught me alot! Hehe my honorable
mention goes to James for the cards.sort_by{ rand } which is nice and
snappy. Also, I thought the ‘deck = deck[x…-1] + deck[0…x]’ was clear
to me, even if I am a ruby newb. Now lets move on…

On Fri, 17 Mar 2006 22:14:47 +0900, dblack wrote:

I have to say, it only dawned on me just now that it’s kind of funny to
cut the deck when the dealer is a computer. The idea of cutting the deck
is to thwart attempts by the dealer to stack the deck. I actually kind of
love the idea that one has to do this in the case of a computer :slight_smile:

Yes, I want the whole deal to be as realistic as possible! Down to
last detail! In real life cards are not really shuffled into random
order!

And thus theres need for realistic Riffle! 8)

Around here, before any card games, after the deck has been
cut into two by the dealer it is of course ‘recombined’ by taking the
two
decks, and mixing them back into one deck, in a manouver called ‘the
riffle’.

“A riffle, in which half of the deck is held in each hand with the
thumbs
inward, then cards are released by the thumbs so that they fall to the
table intertwined.” Thus almost every card other card is from the
other
half of the deck, and vice versa - with the odd double, triple or
quadruple cards sometimes falling on the table from either pack!

You can find a photo and detailed description of the riffle here:

This is done three times, and finally one of the players
gets to cut the deck and the dealer then recombines it and deals out
cards. Ie. dealer does ‘cut + riffle’ three times, then player ‘cuts’,
then dealer riffles, and game can then begin.

How would you code riffle?

How would you code riffle?

Start with a merge sort:

def merge(left, right, &pred)
if right.empty?
left.dup
elsif left.empty?
right.dup
elsif pred.call(left.first, right.first)
[left.first] + merge(left[1…-1], right, &pred)
else
[right.first] + merge(left, right[1…-1], &pred)
end
end

And then riffle!

def riffle(deck)
n = deck.size / 2
left, right = deck[0…n], deck[n…-1]
merge(left, right) { rand < 0.5 }
end

Or, to simulate one side’s cards being more likely given the other
side’s card just went down:

def riffle(deck)
n = deck.size / 2
left, right = deck[0…n], deck[n…-1]
p = 0.5
merge(left, right) do
res = (rand < p)
p = res ? p*p : Math.sqrt§
res
end
end

Yah, [x…y], [x…y), (x…y], (x…y) would be sweetness. It’s slightly less
error-prone IMO since it’s following a common (math) notation. Still, maybe
not perfect.

Can you really stand to look at that? It gives me the same feeling as
putting my shoes on the wrong feet :slight_smile:

As part-mathematician, I whole-heartedly say, “Yes!” It’s a compact,
consistent and clear representation of closed [ and open ( ends of
ranges.

As part-programmer, I recognize that it would be a bitch to parse,
considering how often we make use of braces for all sorts of other
needs (array access, expression grouping, function calls, etc, etc,
etc).

I’m not sure what it is about the range operators that bothers you.
Are you finding it hard to remember which is which? My way of
remembering is: every range is the same width, in relation to the
operators. Since the … operator is wider, the end-point gets pushed
outside the range:

     v  v
     a..b
     a...b
     ^  ^

This is basically how I now remember the difference between the two,
and so having both operators doesn’t bother me as much anymore. But I
will admit that at first I could never remember the difference, and
can see it as confusing to newbs.

On 17 Mar 2006, at 06:11, Stephen W. wrote:

Matthew M. wrote:

deck = deck[x…-1] + deck[0…x] # notice differing amounts of dots

I find myself constantly pointing this out too… is anyone else
bothered by it? Has Matz weighed in on this in the past?

I like being able to express either. I often don’t remember which is
which though. It feels like they’re the wrong way round because three
dots ought to go a little bit further than two :slight_smile:

Hi –

On Sat, 18 Mar 2006, grrr wrote:

love the idea that one has to do this in the case of a computer :slight_smile:
riffle’.
That’s different from the person next to the dealer cutting the deck,
though, which happens after all the shuffling is over.

gets to cut the deck and the dealer then recombines it and deals out
cards. Ie. dealer does ‘cut + riffle’ three times, then player ‘cuts’,
then dealer riffles, and game can then begin.

How would you code riffle?

class Deck
def riffle
sort_by { rand } # just don’t tell anyone :slight_smile:
end
end

But seriously… here’s a first attempt, maybe useful at least as a
starting point for better:

class Deck < Array
def initialize
concat([*1…52])
end

def split # an even cut; you’d want a real cut too
[self[0…26],self[26…52]]
end

def pure_riffle
s = split
s[0].zip(s[1]).flatten
end

def riffle(max_consec = 3)
s,t = split
done = []
until s.empty? || t.empty?
done.push(s.shift,t.shift)
x = if rand(2).zero? then s else t end
if time_for_glitch?
rand(max_consec + 1).times { done.push(x.shift) }
end
end
done + s + t
end

def time_for_glitch?
rand(5).zero?
end
end


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails

Benjohn B. wrote:

I like being able to express either. I often don’t remember which is
which though. It feels like they’re the wrong way round because three
dots ought to go a little bit further than two :slight_smile:

The dots do go a bit further … far enough to push the last value
right out of the range :wink:

– Jim W.

Benjohn B. wrote:

I like being able to express either. I often don’t remember which is
which though. It feels like they’re the wrong way round because three
dots ought to go a little bit further than two :slight_smile:

from _why’s (poignant) guide:

“When you see that third dot, imagine opening the accordion slightly.
Just enough to let one note from its chamber. The note is that end
value. We?ll let the sky eat it.”

On 18/03/06, Tim H. [email protected] wrote:

from _why’s (poignant) guide:

“When you see that third dot, imagine opening the accordion slightly.
Just enough to let one note from its chamber. The note is that end
value. We’ll let the sky eat it.”

“We’ll let the sky eat it.” … is my favourite sentence in the whole
(poignant) guide.


Daniel B.
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog ::
Things
That Suck)
[[My webhost uptime is ~ 92%… if no answer pls call again later!]]

[email protected] wrote:

I’m not sure what it is about the range operators that bothers you.
Are you finding it hard to remember which is which? My way of
remembering is: every range is the same width, in relation to the
operators. Since the … operator is wider, the end-point gets pushed
outside the range:

That you had to invent that mnemonic device just to remember what they
is what I don’t like about them. That they differ by a single ‘.’ is
error-prone. It just one of the few things I’ve run across in Ruby that
doesn’t feel like the rest of Ruby (very straightforward, POLS, etc.).

I don’t want to start a whole thing, though, which is why I inquired as
to whether Matz has discussed this publicly in the past.

Thanks,
Steve

Daniel B. wrote in post #49575:

On 18/03/06, Tim H. [email protected] wrote:

from _why’s (poignant) guide:

“When you see that third dot, imagine opening the accordion slightly.
Just enough to let one note from its chamber. The note is that end
value. We’ll let the sky eat it.”

“We’ll let the sky eat it.” … is my favourite sentence in the whole
(poignant) guide.


Daniel B.
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog ::
Things
That Suck)
[[My webhost uptime is ~ 92%… if no answer pls call again later!]]

I googled “we’ll let the sky eat it” to see where else on the internet
it turns up because it was my favorite sentence in the whole guide as
well. Favorite sentence I’ve seen around for a short while, for that
matter.