Author Topic: 27 Cards Trick  (Read 3674 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
27 Cards Trick
« on: November 07, 2019, 03:41:28 pm »
Hi all,

I saw this trick come up after Steve's "Flip It" link and was amazed!

Finding a persons card out of 27 with 3 clues, not bad.

But putting that card anywhere in the deck to be drawn at number n with just 3 re-stacks, Fantastic!
(Of course, you will have to trust that it is just 3 restacks or read the code.)

Like this (mod2 Update):
Code: QB64: [Select]
  1.  
  2. _TITLE "27 Cards Trick" ' B+ started 2019-11-06
  3. ' Saw this on Internet after Steve's Flip It link   [youtube]https://www.youtube.com/watch?v=l7lP9y7Bb5g[/youtube]
  4. ' Cool! I wonder if it works half as well as computer program? Let's see!
  5. ' So I barrowed Steve's Cards and some code for the presentation.
  6. ' 2019-11-08 some changes in wording per jack's suggestion and added do again option.
  7. ' 2019-11-10 27 Cards Trick mod 2 attempt a more elegant stacking sub, good success!
  8. ' eliminated several variables and arrays.
  9.  
  10. DEFINT A-Z
  11. CONST cardW = 72, cardH = 96, marg = 50, mint = &HFF88DDAA
  12.  
  13. DIM SHARED Deck(51)
  14. DIM SHARED CardImage AS LONG: CardImage = _LOADIMAGE("Cards.bmp", 32)
  15. DIM SHARED xSpace, ySpace
  16. DIM SHARED table(0 TO 8, 0 TO 2) ' store card indexes as layed out each time
  17. DIM SHARED pass(1 TO 3)
  18. DIM fav, cardsAbove, col, row, i, p$, pick$, f$
  19.  
  20. SCREEN _NEWIMAGE(800, 600, 32)
  21. _SCREENMOVE 200, 60
  22. xSpace = (_WIDTH - 2 * marg) / 9
  23. ySpace = (_HEIGHT - 2 * marg) / 3
  24. WHILE _KEYDOWN(27) = 0
  25.     favAgain:
  26.     COLOR &HFFAAAAFF, &HFF000044: CLS
  27.     yCP 160, "* * *  The 27 Cards Trick  * * *"
  28.     yCP 200, "I present to you a 27 cards trick I learned from the Internet."
  29.     yCP 220, "I will shuffle the deck, and lay out 27 cards in 3 rows."
  30.     yCP 240, "You just need to pick a card and tell me which row the card is in."
  31.     yCP 260, "I will deal cards 2 more times and ask for the row the card is in now."
  32.     yCP 280, "I will then show you your card."
  33.     COLOR mint
  34.     inputG 132, 320, "But first, enter your favorite number between 1 and 27 (inclusive)", f$, 4
  35.     fav = VAL(f$)
  36.     cardsAbove = fav - 1
  37.     IF fav > 0 AND fav < 28 THEN
  38.         pass(3) = INT(cardsAbove / 9)
  39.         pass(2) = INT((cardsAbove - 9 * pass(3)) / 3)
  40.         pass(1) = (cardsAbove - 9 * pass(3)) - pass(2) * 3
  41.     ELSE
  42.         yCP 340, "Number needs to be > 0 and < 28. Try again."
  43.         _DELAY 2
  44.         GOTO favAgain
  45.     END IF
  46.  
  47.     CLS
  48.     Shuffle
  49.     FOR i = 1 TO 3
  50.         IF i = 1 THEN
  51.             p$ = "Choose any card then enter the row: 1, 2 or 3 that card is on >"
  52.         ELSEIF i = 2 THEN
  53.             p$ = "Again, enter the row: 1, 2 or 3 that the card is on now >"
  54.         ELSEIF i = 3 THEN
  55.             p$ = "One last time, enter the row: 1, 2 or 3 that the card is now on >"
  56.         END IF
  57.         tryAgain:
  58.         deal27
  59.         inputG (_WIDTH - 8 * LEN(p$)) / 2, _HEIGHT - 40, p$, pick$, 5
  60.         IF INSTR("123", pick$) THEN
  61.             stacks2deck pass(i), pick$
  62.         ELSE
  63.             'go back and get a proper row
  64.             GOTO tryAgain
  65.         END IF
  66.     NEXT
  67.  
  68.     CLS: i = 0
  69.     FOR row = 0 TO 2
  70.         FOR col = 0 TO 8
  71.             DisplayCard col * xSpace + marg, row * ySpace + marg, Deck(i)
  72.             i = i + 1
  73.             LINE (_WIDTH - 100, _HEIGHT - 100)-STEP(100, 100), &HFF000044, BF
  74.             Text _WIDTH - 98, _HEIGHT - 98, 80, mint, _TRIM$(STR$(i))
  75.             IF i = fav THEN GOTO quiz
  76.             _DELAY .5
  77.         NEXT
  78.     NEXT
  79.  
  80.     quiz:
  81.     p$ = "Isn't that your card at your favorite number," + STR$(fav) + ", on the end?"
  82.     inputG 50, _HEIGHT - 40, p$, f$, 5
  83.     CLS
  84.     p$ = "Want to see the trick again? enter y for yes, any other for no >"
  85.     inputG (_WIDTH - 8 * LEN(p$)) / 2, _HEIGHT / 2 + 10, p$, f$, 15
  86.     IF LCASE$(f$) <> "y" THEN CLS: END
  87.  
  88. SUB deal27
  89.     DIM col, row, i
  90.     CLS
  91.     FOR col = 0 TO 8
  92.         FOR row = 0 TO 2
  93.             DisplayCard col * xSpace + marg, row * ySpace + marg, Deck(i)
  94.             table(col, row) = Deck(i)
  95.             i = i + 1
  96.             _DELAY .1
  97.         NEXT
  98.     NEXT
  99.  
  100. ' I am sure there is a less awkward way to do this but I am eager to share, mod 2 YES! there is!
  101. SUB stacks2deck (place, pick$)
  102.     DIM nPick, i
  103.     nPick = VAL(pick$) - 1
  104.     FOR i = 0 TO 8
  105.         Deck(i + place * 9) = table(i, nPick)
  106.         Deck(i + ((place + 1) MOD 3) * 9) = table(i, ((nPick + 1) MOD 3))
  107.         Deck(i + ((place + 2) MOD 3) * 9) = table(i, ((nPick + 2) MOD 3))
  108.     NEXT
  109.  
  110. SUB DisplayCard (x, y, index)
  111.     DIM suit, value
  112.     suit = index \ 13: value = index MOD 13
  113.     _PUTIMAGE (x, y)-STEP(cardW, cardH), CardImage, 0, (value * cardW, suit * cardH)-STEP(cardW, cardH)
  114.  
  115. SUB yCP (y, s$) 'for xmax pixel wide graphics screen Center Print at pixel y row
  116.     _PRINTSTRING ((_WIDTH - LEN(s$) * 8) / 2, y), s$
  117.  
  118. SUB Shuffle
  119.     DIM i
  120.     FOR i = 0 TO 51: Deck(i) = i: NEXT 'put the cards in the deck
  121.     FOR i = 0 TO 51: SWAP Deck(i), Deck(INT(RND * 52)): NEXT
  122.  
  123. 'INPUT for Graphics screen
  124. SUB inputG (x, y, prmpt$, var$, expectedLenVar%) 'input for a graphics screen x, y is where the prompt will start , returns through var$
  125.     DIM tmp$, k$, saveAD
  126.     saveAD = _AUTODISPLAY
  127.     _KEYCLEAR
  128.     _PRINTSTRING (x, y), prmpt$ + " {}"
  129.     DO
  130.         k$ = INKEY$
  131.         IF LEN(k$) = 1 THEN
  132.             SELECT CASE ASC(k$)
  133.                 CASE 13: var$ = tmp$: EXIT SUB
  134.                 CASE 27: var$ = "": EXIT SUB
  135.                 CASE 8 'backspace
  136.                     IF LEN(tmp$) THEN
  137.                         IF LEN(tmp$) = 1 THEN tmp$ = "" ELSE tmp$ = LEFT$(tmp$, LEN(tmp$) - 1)
  138.                     END IF
  139.                 CASE ELSE: IF ASC(k$) > 31 THEN tmp$ = tmp$ + k$
  140.             END SELECT
  141.             _PRINTSTRING (x, y), prmpt$ + " {" + tmp$ + "}" + SPACE$(expectedLenVar% - LEN(tmp$)) 'spaces needed at end to clear backspace chars
  142.             IF saveAD <> -1 THEN _DISPLAY
  143.         END IF
  144.         _LIMIT 120
  145.     LOOP
  146.  
  147. SUB Text (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  148.     DIM fg AS _UNSIGNED LONG, cur&, I&, mult, xlen
  149.     fg = _DEFAULTCOLOR
  150.     'screen snapshot
  151.     cur& = _DEST
  152.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  153.     _DEST I&
  154.     COLOR K, _RGBA32(0, 0, 0, 0)
  155.     _PRINTSTRING (0, 0), txt$
  156.     mult = textHeight / 16
  157.     xlen = LEN(txt$) * 8 * mult
  158.     _PUTIMAGE (x, y)-STEP(xlen, textHeight), I&, cur&
  159.     COLOR fg
  160.     _FREEIMAGE I&
  161.  

The cards and source code (above) in one nice little .zip package:

Update: 2019-11-08 I have modified the code above since original post (the zip file is still the same).
jack suggested some better wording and I added a do again option and some other minor things.

Update: 2019-11-10 Found much more elegant code to handle the stacking of rows of cards and eliminated some variables and arrays.

Update: 2019-11-10 OK xSpace and ySpace definitely don't need to be recalc'd every loop. Just changed code above.
* 27 Cards Trick mod2.zip (Filesize: 70.17 KB, Downloads: 194)
« Last Edit: November 10, 2019, 01:55:30 pm by bplus »

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
Re: 27 Cards Trick
« Reply #1 on: November 07, 2019, 05:15:34 pm »
hi bplus
you say "choose a number between 1 an 27 inclusive" then later you say "enter row 1, 2, 3, your car is sitting on"
I am confused, there are no cards with numbers above 10, please explain
never mind, I got it
nice trick
« Last Edit: November 07, 2019, 05:20:29 pm by jack »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: 27 Cards Trick
« Reply #2 on: November 07, 2019, 05:41:14 pm »
I saw the same video for this trick, and tried to amp it up to 256 cards — 4 rows of 64, dealt and chosen 4 times, but I got myself lost working it out.  Theory says it should work (and I can find the card doing so), but I can’t position it where I want in the deck yet. 

I was thinking ASCII is 256 characters, so 256 choices would be nice, but I just flubbed it up somewhere.  Maybe you’d want to take a shot to step it up a notch and give it a go.  (Heck, afterwards, you can even share the code/exe with the video guys.  Maybe they’ll give a little shout out to us and raise a little more QB64 interest out there in WWWland!)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: 27 Cards Trick
« Reply #3 on: November 07, 2019, 07:15:09 pm »
Hi jack,

Thanks for feedback. If there is better way to word the prompts I am all ears,it's such a cool trick I want to present it well.


Hi Steve,

My first goal with this is to see if I can get that awkward section more elegantly written (sort of your area). If I can, I may take on higher amounts of cards, I was even considering what new suits I may make up for custom cards. :)
One trick in setting this up is figuring the nines, threes, ones number in base 3 of favorite number. You figure them going in one direction and then use them in the opposite.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
Re: 27 Cards Trick
« Reply #4 on: November 07, 2019, 07:22:25 pm »
bplus, I suggest that on the first screen of cards that instead of "Enter the row: 1, 2 or 3, your card is sitting in "
you say "choose any card, then enter the row: 1, 2 or 3, your card is sitting in "
then in the subsequent screen of card you say "Enter the row: 1, 2 or 3, your card is sitting in "
« Last Edit: November 07, 2019, 07:26:12 pm by jack »

Offline doppler

  • Forum Regular
  • Posts: 241
Re: 27 Cards Trick
« Reply #5 on: November 07, 2019, 08:35:43 pm »
Not much of a trick, it's a very old card trick.  It's also called binary search method.  It's 2 to the power of x attempts.  Pick a number between 1 and 100.  I will guess it with 7 tries.  You only have to tell me if your number is higher or lower than the number I say.  2^7 power is 128.  Since 100 is less than 128.  It's a guarantee to be found.  It's more fun, give me 20 guesses and I will find it in 1,000,000.  A play off the 20 questions game.

The card trick I remember uses 21 cards.  Three rows of 7.  Tell me what row the card is in.  As long as I put that row in the center of the deck.  After 3 card rounds.  The fourth from the top in center row will be the card.  I like to change up the end.  I remember the card and suit.   Ask the mark to shuffle the deck.  Give back the deck.  Fan out all the cards.  Locate the card and say "Here is your card."  They always suspect I position the card next to another card.  But I let them shuffle as many times as they want (mess up the card order).  The trick works because 2^3 is 8, seven cards in a row.  The cards will binary sort after three rounds.  This forces the marks card in position 11.  10 cards above and 10 cards below.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: 27 Cards Trick
« Reply #6 on: November 07, 2019, 09:40:28 pm »
Hi Doppler,

It's not Binary, Binary would work like this:
27 / 2                  1st guess narrows down to 13.5 say 14 cards or say 13 whatever
14 / 2 = 7            2nd guess narrows to 7 cards
7/2                      3rd guess narrows to 3.5 cards
3.5/2                   4th guess still not guaranteed to have it! depends how you split 3.5, 1 or 2

Hi Lo game is Binary and goes like this, say the secret number is 1
You guess 13, high
you guess 6, high
you guess 3, high  >>>> you still need to guess!
you guess 2, high

This card game is done in 3 clues! (and you need all 3, again unlike Binary) Binary still has a ways to go for worst case scenario.

And you are missing the coolest part, putting the card anywhere in the deck. So that at the end of the guessing you count out the "mark's" favorite number of cards and THERE you find his card in the deck. There is no more fooling around after the 3 clues, the card is found at the mark's number in the deck.

I saw the 21 cards trick just before this trick and this trick is 2 x's cooler at least!
Here check the link:


« Last Edit: November 07, 2019, 09:54:34 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: 27 Cards Trick
« Reply #7 on: November 07, 2019, 10:04:20 pm »
Thanks jack, that will be in next edit.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: 27 Cards Trick
« Reply #8 on: November 08, 2019, 02:15:39 am »
OK the OP (original post) has been modified with changes in wording and added a do again loop, the code in the zip file is still the same for now.

Marked as best answer by bplus on November 10, 2019, 08:11:40 am

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: 27 Cards Trick
« Reply #9 on: November 10, 2019, 01:00:44 pm »
Yes there was a much more elegant way to write this sub:
Code: QB64: [Select]
  1. ' I am sure there is a less awkward way to do this but I am eager to share
  2. SUB stacks2deck (place, pick$)
  3.     DIM i, j
  4.     SELECT CASE place
  5.         CASE 0 'make deck 0-8 = picked stack
  6.             FOR i = 0 TO 8
  7.                 SELECT CASE pick$
  8.                     CASE "1": Deck(i) = stack0(i)
  9.                         FOR j = 9 TO 17
  10.                             Deck(j) = stack1(j - 9)
  11.                         NEXT
  12.                         FOR j = 18 TO 26
  13.                             Deck(j) = stack2(j - 18)
  14.                         NEXT
  15.                     CASE "2": Deck(i) = stack1(i)
  16.                         FOR j = 9 TO 17
  17.                             Deck(j) = stack2(j - 9)
  18.                         NEXT
  19.                         FOR j = 18 TO 26
  20.                             Deck(j) = stack0(j - 18)
  21.                         NEXT
  22.                     CASE "3": Deck(i) = stack2(i)
  23.                         FOR j = 9 TO 17
  24.                             Deck(j) = stack0(j - 9)
  25.                         NEXT
  26.                         FOR j = 18 TO 26
  27.                             Deck(j) = stack1(j - 18)
  28.                         NEXT
  29.                 END SELECT
  30.             NEXT
  31.         CASE 1 'make deck 9-17= picked stack
  32.             FOR i = 9 TO 17
  33.                 SELECT CASE pick$
  34.                     CASE "1": Deck(i) = stack0(i - 9)
  35.                         FOR j = 0 TO 8
  36.                             Deck(j) = stack1(j)
  37.                         NEXT
  38.                         FOR j = 18 TO 26
  39.                             Deck(j) = stack2(j - 18)
  40.                         NEXT
  41.                     CASE "2": Deck(i) = stack1(i - 9)
  42.                         FOR j = 0 TO 8
  43.                             Deck(j) = stack2(j)
  44.                         NEXT
  45.                         FOR j = 18 TO 26
  46.                             Deck(j) = stack0(j - 18)
  47.                         NEXT
  48.                     CASE "3": Deck(i) = stack2(i - 9)
  49.                         FOR j = 0 TO 8
  50.                             Deck(j) = stack0(j)
  51.                         NEXT
  52.                         FOR j = 18 TO 26
  53.                             Deck(j) = stack1(j - 18)
  54.                         NEXT
  55.                 END SELECT
  56.             NEXT
  57.         CASE 2 'make deck 18-26 = picked stack
  58.             FOR i = 18 TO 26
  59.                 SELECT CASE pick$
  60.                     CASE "1": Deck(i) = stack0(i - 18)
  61.                         FOR j = 0 TO 8
  62.                             Deck(j) = stack1(j)
  63.                         NEXT
  64.                         FOR j = 9 TO 17
  65.                             Deck(j) = stack2(j - 9)
  66.                         NEXT
  67.                     CASE "2": Deck(i) = stack1(i - 18)
  68.                         FOR j = 0 TO 8
  69.                             Deck(j) = stack2(j)
  70.                         NEXT
  71.                         FOR j = 9 TO 17
  72.                             Deck(j) = stack0(j - 9)
  73.                         NEXT
  74.                     CASE "3": Deck(i) = stack2(i - 18)
  75.                         FOR j = 0 TO 8
  76.                             Deck(j) = stack0(j)
  77.                         NEXT
  78.                         FOR j = 9 TO 17
  79.                             Deck(j) = stack1(j - 9)
  80.                         NEXT
  81.                 END SELECT
  82.             NEXT
  83.     END SELECT

as this:
Code: QB64: [Select]
  1. ' I am sure there is a less awkward way to do this but I am eager to share, mod 2 YES! there is!
  2. SUB stacks2deck (place, pick$)
  3.     DIM nPick, i
  4.     nPick = VAL(pick$) - 1
  5.     FOR i = 0 TO 8
  6.         Deck(i + place * 9) = table(i, nPick)
  7.         Deck(i + ((place + 1) MOD 3) * 9) = table(i, ((nPick + 1) MOD 3))
  8.         Deck(i + ((place + 2) MOD 3) * 9) = table(i, ((nPick + 2) MOD 3))
  9.     NEXT
  10.  

Also eliminated some variables and arrays in mod2 update.
So I will update original post with modifications and new zip.