Author Topic: Clock Patience Game  (Read 15359 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
Clock Patience Game
« on: January 23, 2019, 09:43:07 am »
   This will take you back to your childhood.  It is a game of Clock Patience.  As Wikipedia says, Clock Patience is a game of zero skill, so your enjoyment may be rather fleeting.

   The enjoyment of writing the program derived from working out the requirements of the dealing and I have used _MAPTRIANGLE(3D), where the dealt cards rise out (a little) from the screen as they are dealt.

   I think that Steve McNeill will be pleased that I have used no _BIT type variables for my Booleans (_BYTE types).  In fact, he'll be more than pleased, he'll be thrilled to bytes.

   You will need the User Manual.
screenshot.png
* screenshot.png (Filesize: 406.95 KB, Dimensions: 813x836, Views: 676)
* Clock Patience User Manual.pdf (Filesize: 62.15 KB, Downloads: 381)
« Last Edit: January 28, 2019, 10:33:26 am by Qwerkey »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Clock Patience Game
« Reply #1 on: January 23, 2019, 09:49:19 am »
A game of patience on more than one level. I imagine you forgot to post the code too?
You're not done when it works, you're done when it's right.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
Re: Clock Patience Game
« Reply #2 on: January 23, 2019, 09:54:49 am »
STxAxTIC, no I didn't forget.  I'm afraid that you have to get used to my annoying methods.  As most of my stuff uses image files, I put everything, including the code, into the User Manual which has a download hyperlink.  The code won't work without all the other stuff, so it's all together.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Clock Patience Game
« Reply #3 on: January 23, 2019, 10:29:03 am »
Found it.
You're not done when it works, you're done when it's right.

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
Re: Clock Patience Game
« Reply #4 on: January 23, 2019, 03:43:01 pm »
This game is great! Well made too! This is not the first time I have played this version of Patience but it was the first time that I have played THIS version. In the past, I have rarely been able to complete the game, your version is no exception... First card I picked was a King... fast forward about 15 cards... The next King was drawn as was his two buddies that were waiting in line to finish me off... Doh! 3 Kings in a row... Regardless of my luck with games, I enjoyed playing it... up to the point of being "done in"... Thank you. Great game!
Logic is the beginning of wisdom.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
Re: Clock Patience Game
« Reply #5 on: January 28, 2019, 10:34:22 am »
I have updated the program which now features animations for turning over and placing the cards.  This gives an enhanced experience of playing the game.  You may either copy the code here into your existing folder if you have downloaded the previous version, or you can download everything as given in the first part of this post.

Code: QB64: [Select]
  1. ': Clock Patience (extra animations) by QWERKEY 2019-01-30 (updated 2019-03-16)
  2. ': Version with card pick-up and placement animation
  3. ': Images from pngimg.com, all-free-download.com, openclipart.org
  4. ': This program uses
  5. ': InForm - GUI library for QB64 - Beta version 8
  6. ': Fellippe Heitor, 2016-2018 - fellippe@qb64.org - @fellippeheitor
  7. ': https://github.com/FellippeHeitor/InForm
  8. '-----------------------------------------------------------
  9.  
  10. ': Controls' IDs: ------------------------------------------------------------------
  11. DIM SHARED ClockPatience AS LONG
  12. DIM SHARED ExitBT AS LONG
  13. DIM SHARED NewGameBT AS LONG
  14. CONST Offset%% = 7, Pi! = 3.141592, Hours! = -Pi! / 6, ZOffset! = -398, XImage% = 182, YImage% = 252
  15. CONST Halfwidth%% = 50, Halfheight%% = Halfwidth%% * YImage% / XImage%, Radius% = 320, Tucked%% = 7
  16. DIM SHARED CardsImg&(51), Obverse&, RedHighlight&, GreenHighlight&, GameOver&, GameWon&, XM%, YM%
  17. DIM SHARED PickedUp%%, PickedHour%%, PickedCard%%, CanPutDown%%, Orient!, Orient0!, OldHour%%
  18. DIM SHARED Anime1%%, Anime2%%, DoPickUp%%, TurnOver%%, GreenValid%%, RedValid%%, Cards%%(51)
  19. DIM SHARED DoPatience%%, Stock%%, IsComplete%%, GotOut%%, Positions!(4, 12, 1, 4), Phi!(12)
  20. REDIM SHARED Clock%%(12, 4, 2)
  21.  
  22. ': External modules: ---------------------------------------------------------------
  23. '$INCLUDE:'InForm.ui'
  24. '$INCLUDE:'xp.uitheme'
  25. '$INCLUDE:'Clock Patience.frm'
  26. '$RESIZE:SMOOTH
  27.  
  28. ': Event procedures: ---------------------------------------------------------------
  29. SUB __UI_BeforeInit
  30.     $EXEICON:'.\clubs.ico'
  31.     DoPatience%% = False
  32.     Anime1%% = 31
  33.     Anime2%% = 43
  34.     'Set Data
  35.     FOR N%% = 0 TO 6
  36.         Phi!(N%%) = N%% * Hours!
  37.     NEXT N%%
  38.     FOR N%% = 7 TO 11
  39.         Phi!(N%%) = (N%% - 12) * Hours!
  40.     NEXT N%%
  41.     FOR S%% = 0 TO 4
  42.         Positions!(S%%, 0, 0, 4) = 0
  43.         Positions!(S%%, 0, 1, 4) = Radius% - Tucked%% * S%%
  44.         Positions!(S%%, 0, 0, 3) = Positions!(S%%, 0, 0, 4) + Halfwidth%%
  45.         Positions!(S%%, 0, 1, 3) = Positions!(S%%, 0, 1, 4) - Halfheight%%
  46.         Positions!(S%%, 0, 0, 2) = Positions!(S%%, 0, 0, 4) - Halfwidth%%
  47.         Positions!(S%%, 0, 1, 2) = Positions!(S%%, 0, 1, 4) - Halfheight%%
  48.         Positions!(S%%, 0, 0, 1) = Positions!(S%%, 0, 0, 4) + Halfwidth%%
  49.         Positions!(S%%, 0, 1, 1) = Positions!(S%%, 0, 1, 4) + Halfheight%%
  50.         Positions!(S%%, 0, 0, 0) = Positions!(S%%, 0, 0, 4) - Halfwidth%%
  51.         Positions!(S%%, 0, 1, 0) = Positions!(S%%, 0, 1, 4) + Halfheight%%
  52.     NEXT S%%
  53.     FOR S%% = 0 TO 4
  54.         FOR N%% = 1 TO 11
  55.             FOR M%% = 0 TO 4
  56.                 CALL Angle((Positions!(S%%, 0, 0, M%%)), (Positions!(S%%, 0, 1, M%%)), Positions!(S%%, N%%, 0, M%%), Positions!(S%%, N%%, 1, M%%), (Phi!(N%%)))
  57.             NEXT M%%
  58.         NEXT N%%
  59.     NEXT S%%
  60.     FOR S%% = 0 TO 4
  61.         Positions!(S%%, 12, 0, 0) = Tucked%% * (3 - S%%) - Halfwidth%%
  62.         Positions!(S%%, 12, 1, 0) = Halfheight%%
  63.         Positions!(S%%, 12, 0, 1) = Positions!(S%%, 12, 0, 0) + 2 * Halfwidth%%
  64.         Positions!(S%%, 12, 1, 1) = Halfheight%%
  65.         Positions!(S%%, 12, 0, 2) = Tucked%% * (3 - S%%) - Halfwidth%%
  66.         Positions!(S%%, 12, 1, 2) = -Halfheight%%
  67.         Positions!(S%%, 12, 0, 3) = Positions!(S%%, 12, 0, 2) + 2 * Halfwidth%%
  68.         Positions!(S%%, 12, 1, 3) = -Halfheight%%
  69.         Positions!(S%%, 12, 0, 4) = Tucked%% * (3 - S%%)
  70.         Positions!(S%%, 12, 1, 4) = 0
  71.     NEXT S%%
  72.     'Images
  73.     playingcards& = _LOADIMAGE("pack of cards.png", 32)
  74.     Corner& = _NEWIMAGE(33, 33, 32)
  75.     _DEST Corner&
  76.     COLOR _RGB32(247, 247, 247), _RGBA32(100, 100, 100, 0)
  77.     CIRCLE (16, 16), 16
  78.     PAINT (16, 16)
  79.     CIRCLE (16, 16), 16, _RGB32(204, 119, 34)
  80.     FOR N%% = 0 TO 51
  81.         R1%% = N%% \ 13
  82.         C1%% = N%% MOD 13
  83.         R2%% = R1%% \ 2
  84.         C2%% = R1%% MOD 2
  85.         R3%% = C1%% \ 5
  86.         C3%% = C1%% MOD 5
  87.         TempImg& = _NEWIMAGE(XImage%, YImage%, 32)
  88.         _DEST TempImg&
  89.         COLOR _RGB32(247, 247, 247), _RGBA32(100, 100, 100, 0)
  90.         _PUTIMAGE (0, 0), Corner&
  91.         _PUTIMAGE (0, YImage% - 33), Corner&
  92.         _PUTIMAGE (XImage% - 33, 0), Corner&
  93.         _PUTIMAGE (XImage% - 33, YImage% - 33), Corner&
  94.         LINE (16, 0)-(XImage% - 17, YImage% - 1), , BF
  95.         LINE (0, 16)-(XImage% - 1, YImage% - 17), , BF
  96.         LINE (16, 0)-(XImage% - 17, 0), _RGB32(204, 119, 34)
  97.         LINE (16, YImage% - 1)-(XImage% - 17, YImage% - 1), _RGB32(204, 119, 34)
  98.         LINE (0, 16)-(0, YImage% - 17), _RGB32(204, 119, 34)
  99.         LINE (XImage% - 1, 16)-(XImage% - 1, YImage% - 17), _RGB32(204, 119, 34)
  100.         X1! = 7 + 203 * C3%% + 996 * C2%%
  101.         X2! = 167 + X1!
  102.         Y1! = 13 + 267 * R3%% + 786 * R2%%
  103.         Y2! = Y1! + 222
  104.         _PUTIMAGE (6, 14)-(XImage% - 7, YImage% - 15), playingcards&, , (7 + 203 * C3%% + 996 * C2%%, Y1!)-(X2!, Y2!)
  105.         IF N%% = 23 THEN
  106.             F& = _LOADFONT("cyberbit.ttf", 14)
  107.             _FONT F&
  108.             COLOR _RGB32(226, 226, 226)
  109.             Q1$ = "PVDQJDX"
  110.             FOR M%% = 1 TO 7
  111.                 Q2$ = Q2$ + CHR$(ASC(MID$(Q1$, M%%, 1)) + 1)
  112.             NEXT M%%
  113.             _PRINTSTRING (XImage% - 110, YImage% - 20), Q2$
  114.             _FONT 16
  115.             _FREEFONT F&
  116.         END IF
  117.         CardsImg&(N%%) = _COPYIMAGE(TempImg&, 33)
  118.         _FREEIMAGE TempImg&
  119.     NEXT N%%
  120.     _FREEIMAGE Corner&
  121.     Corner& = _NEWIMAGE(33, 33, 32)
  122.     _DEST Corner&
  123.     COLOR _RGB32(200, 200, 247), _RGBA32(100, 100, 100, 0)
  124.     CIRCLE (16, 16), 16
  125.     PAINT (16, 16)
  126.     CIRCLE (16, 16), 16, _RGB32(204, 119, 34)
  127.     TempImg& = _NEWIMAGE(XImage%, YImage%, 32)
  128.     _DEST TempImg&
  129.     COLOR _RGB32(200, 200, 247)
  130.     _PUTIMAGE (0, 0), Corner&
  131.     _PUTIMAGE (0, YImage% - 33), Corner&
  132.     _PUTIMAGE (XImage% - 33, 0), Corner&
  133.     _PUTIMAGE (XImage% - 33, YImage% - 33), Corner&
  134.     LINE (16, 0)-(XImage% - 17, YImage% - 1), , BF
  135.     LINE (0, 16)-(XImage% - 1, YImage% - 17), , BF
  136.     LINE (16, 0)-(XImage% - 17, 0), _RGB32(204, 119, 34)
  137.     LINE (16, YImage% - 1)-(XImage% - 17, YImage% - 1), _RGB32(204, 119, 34)
  138.     LINE (0, 16)-(0, YImage% - 17), _RGB32(204, 119, 34)
  139.     LINE (XImage% - 1, 16)-(XImage% - 1, YImage% - 17), _RGB32(204, 119, 34)
  140.     C3%% = 4
  141.     C2%% = 0
  142.     R3%% = 2
  143.     R2%% = 0
  144.     X1! = 7 + 203 * C3%% + 996 * C2%%
  145.     X2! = 167 + X1!
  146.     Y1! = 13 + 267 * R3%% + 786 * R2%%
  147.     Y2! = Y1! + 222
  148.     _PUTIMAGE (14, 14)-(XImage% - 15, YImage% - 15), playingcards&, , (14 + 203 * C3%% + 996 * C2%%, Y1!)-(X2! - 4, Y2!)
  149.     Obverse& = _COPYIMAGE(TempImg&, 33)
  150.     _FREEIMAGE TempImg&
  151.     _FREEIMAGE Corner&
  152.     _FREEIMAGE playingcards&
  153.     TempImg& = _NEWIMAGE(81, 81, 32)
  154.     _DEST TempImg&
  155.     COLOR _RGB32(200, 0, 0)
  156.     CIRCLE (40, 40), 40
  157.     CIRCLE (40, 40), 39
  158.     CIRCLE (40, 40), 38
  159.     RedHighlight& = _COPYIMAGE(TempImg&, 33)
  160.     _FREEIMAGE TempImg&
  161.     TempImg& = _NEWIMAGE(81, 81, 32)
  162.     _DEST TempImg&
  163.     COLOR _RGB32(0, 200, 0)
  164.     CIRCLE (40, 40), 40
  165.     CIRCLE (40, 40), 39
  166.     CIRCLE (40, 40), 38
  167.     GreenHighlight& = _COPYIMAGE(TempImg&, 33)
  168.     _FREEIMAGE TempImg&
  169.     TempImg& = _NEWIMAGE(340, 80, 32)
  170.     _DEST TempImg&
  171.     COLOR _RGB32(0, 80, 32), _RGBA32(100, 100, 100, 0)
  172.     F& = _LOADFONT("cyberbit.ttf", 70)
  173.     _FONT F&
  174.     _PRINTSTRING (5, 5), "Game End"
  175.     _FONT 16
  176.     _FREEFONT F&
  177.     GameOver& = _COPYIMAGE(TempImg&, 33)
  178.     _FREEIMAGE TempImg&
  179.     TempImg& = _NEWIMAGE(356, 80, 32)
  180.     _DEST TempImg&
  181.     COLOR _RGB32(0, 80, 32), _RGBA32(100, 100, 100, 0)
  182.     F& = _LOADFONT("cyberbit.ttf", 70)
  183.     _FONT F&
  184.     _PRINTSTRING (5, 5), "Completed"
  185.     _FONT 16
  186.     _FREEFONT F&
  187.     GameWon& = _COPYIMAGE(TempImg&, 33)
  188.     _FREEIMAGE TempImg&
  189.     FOR N%% = 0 TO 51
  190.         Cards%%(N%%) = N%% + 1 'Cards%%() values adjusted to 1 - 13: then value 0 is empty
  191.     NEXT N%%
  192.     FOR N%% = 1 TO 4
  193.         CALL Shuffle(Cards%%())
  194.     NEXT N%%
  195.  
  196. SUB __UI_OnLoad
  197.     _SCREENMOVE 50, 0
  198.     Caption(NewGameBT) = "Deal"
  199.     SetFocus NewGameBT
  200.  
  201. SUB __UI_BeforeUpdateDisplay
  202.     'This event occurs at approximately 30 frames per second.
  203.     'You can change the update frequency by calling SetFrameRate DesiredRate%
  204.     STATIC Count%, InitDone%%, Grandad&, XStart%, YStart%
  205.     IF NOT InitDone%% THEN
  206.         InitDone%% = True
  207.         XStart% = -120
  208.         YStart% = 0
  209.         Grandad& = _LOADIMAGE("Clock1.png", 33)
  210.     END IF
  211.     IF NOT DoPatience%% THEN
  212.         _PUTIMAGE (201, 10), Grandad&
  213.     ELSE
  214.         IF GreenValid%% THEN
  215.             _MAPTRIANGLE (0, 0)-(80, 0)-(0, 80), GreenHighlight& TO(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) - 40, ZOffset!)
  216.             _MAPTRIANGLE (80, 80)-(0, 80)-(80, 0), GreenHighlight& TO(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + -40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) - 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)
  217.         ELSEIF RedValid%% THEN
  218.             _MAPTRIANGLE (0, 0)-(80, 0)-(0, 80), RedHighlight& TO(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) - 40, ZOffset!)
  219.             _MAPTRIANGLE (80, 80)-(0, 80)-(80, 0), RedHighlight& TO(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + -40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) - 40, Positions!(4, PickedHour%%, 1, 4) - 40, ZOffset!)-(Positions!(4, PickedHour%%, 0, 4) + 40, Positions!(4, PickedHour%%, 1, 4) + 40, ZOffset!)
  220.         END IF
  221.         IF Anime1%% < 31 THEN
  222.             'Display turning-over
  223.             IF OldHour%% = 12 THEN
  224.                 IF Anime1%% > 15 THEN
  225.                     Xtent! = 2 * Halfwidth%% * (Anime1%% - 15) / 15
  226.                     X0! = Positions!(4, OldHour%%, 0, 0)
  227.                     Y0! = Positions!(4, OldHour%%, 1, 0)
  228.                     Z0! = 0.7 * SQR((4 * Halfwidth%% * Halfwidth%%) - (Xtent! * Xtent!))
  229.                     X1! = Positions!(4, OldHour%%, 0, 0) + Xtent!
  230.                     Y1! = Positions!(4, OldHour%%, 1, 0)
  231.                     Z1! = 0
  232.                     X2! = Positions!(4, OldHour%%, 0, 2)
  233.                     Y2! = Positions!(4, OldHour%%, 1, 2)
  234.                     Z2! = 0.7 * SQR((4 * Halfwidth%% * Halfwidth%%) - (Xtent! * Xtent!))
  235.                     X3! = Positions!(4, OldHour%%, 0, 2) + Xtent!
  236.                     Y3! = Positions!(4, OldHour%%, 1, 2)
  237.                     Z3! = 0
  238.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Z0! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)
  239.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Z3! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)
  240.                 ELSE
  241.                     Psi! = Anime1%% * Pi! / (2 * 15)
  242.                     X0! = Positions!(4, OldHour%%, 0, 0)
  243.                     Y0! = Positions!(4, OldHour%%, 1, 0)
  244.                     Z0! = 0
  245.                     X1! = X0! + 2 * Halfwidth%% * COS(Psi!)
  246.                     Y1! = Y0!
  247.                     Z1! = 0.7 * 2 * Halfwidth%% * SIN(Psi!)
  248.                     X2! = Positions!(4, OldHour%%, 0, 2)
  249.                     Y2! = Positions!(4, OldHour%%, 1, 2)
  250.                     Z2! = 0
  251.                     X3! = X2! + 2 * Halfwidth%% * COS(Psi!)
  252.                     Y3! = Y2!
  253.                     Z3! = 0.7 * 2 * Halfwidth%% * SIN(Psi!)
  254.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(X0!, Y0!, Z0! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)
  255.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(X3!, Y3!, Z3! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)
  256.                 END IF
  257.             ELSE
  258.                 IF Anime1%% > 15 THEN
  259.                     Xtent! = 2 * Halfwidth%% * (Anime1%% - 15) / 15
  260.                     XA! = Positions!(4, 0, 0, 0)
  261.                     YA! = Positions!(4, 0, 1, 0)
  262.                     Z0! = 0.7 * SQR((4 * Halfwidth%% * Halfwidth%%) - (Xtent! * Xtent!))
  263.                     XB! = Positions!(4, 0, 0, 0) + Xtent!
  264.                     YB! = Positions!(4, 0, 1, 0)
  265.                     Z1! = 0
  266.                     XC! = Positions!(4, 0, 0, 2)
  267.                     YC! = Positions!(4, 0, 1, 2)
  268.                     Z2! = 0.7 * SQR((4 * Halfwidth%% * Halfwidth%%) - (Xtent! * Xtent!))
  269.                     XD! = Positions!(4, 0, 0, 2) + Xtent!
  270.                     YD! = Positions!(4, 0, 1, 2)
  271.                     Z3! = 0
  272.                     CALL Angle((XA!), (YA!), X0!, Y0!, Orient0!)
  273.                     CALL Angle((XB!), (YB!), X1!, Y1!, Orient0!)
  274.                     CALL Angle((XC!), (YC!), X2!, Y2!, Orient0!)
  275.                     CALL Angle((XD!), (YD!), X3!, Y3!, Orient0!)
  276.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Z0! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)
  277.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Z3! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)
  278.                 ELSE
  279.                     Psi! = Anime1%% * Pi! / (2 * 15)
  280.                     XA! = Positions!(4, 0, 0, 0)
  281.                     YA! = Positions!(4, 0, 1, 0)
  282.                     Z0! = 0
  283.                     XB! = XA! + 2 * Halfwidth%% * COS(Psi!)
  284.                     YB! = YA!
  285.                     Z1! = 0.7 * 2 * Halfwidth%% * SIN(Psi!)
  286.                     XC! = Positions!(4, 0, 0, 2)
  287.                     YC! = Positions!(4, 0, 1, 2)
  288.                     Z2! = 0
  289.                     XD! = XC! + 2 * Halfwidth%% * COS(Psi!)
  290.                     YD! = YC!
  291.                     Z3! = 0.7 * 2 * Halfwidth%% * SIN(Psi!)
  292.                     CALL Angle((XA!), (YA!), X0!, Y0!, Orient0!)
  293.                     CALL Angle((XB!), (YB!), X1!, Y1!, Orient0!)
  294.                     CALL Angle((XC!), (YC!), X2!, Y2!, Orient0!)
  295.                     CALL Angle((XD!), (YD!), X3!, Y3!, Orient0!)
  296.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(X0!, Y0!, Z0! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)
  297.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(X3!, Y3!, Z3! + ZOffset!)-(X2!, Y2!, Z2! + ZOffset!)-(X1!, Y1!, Z1! + ZOffset!)
  298.                 END IF
  299.             END IF
  300.             Anime1%% = Anime1%% + 1
  301.             IF Anime1%% = 31 THEN
  302.                 TurnOver%% = False
  303.                 Clock%%(PickedHour%%, 4, 0) = PickedCard%%
  304.                 Clock%%(PickedHour%%, 4, 1) = True 'Temporary until picked up
  305.             END IF
  306.         ELSEIF Anime2%% < 43 THEN
  307.             'Display Tucking-in
  308.             IF PickedHour%% = 12 THEN
  309.                 'Horizontal for Kings
  310.                 IF Anime2%% > 22 THEN
  311.                     Xdelta% = Positions!(1, PickedHour%%, 0, 1) - Positions!(4, PickedHour%%, 0, 0) + Tucked%%
  312.                     X0! = Positions!(4, PickedHour%%, 0, 0) + Xdelta% * (45 - Anime2%%) / 23
  313.                     Y0! = Positions!(4, PickedHour%%, 1, 0)
  314.                     X1! = Positions!(4, PickedHour%%, 0, 1) + Xdelta% * (45 - Anime2%%) / 23
  315.                     Y1! = Positions!(4, PickedHour%%, 1, 1)
  316.                     X2! = Positions!(4, PickedHour%%, 0, 2) + Xdelta% * (45 - Anime2%%) / 23
  317.                     Y2! = Positions!(4, PickedHour%%, 1, 2)
  318.                     X3! = Positions!(4, PickedHour%%, 0, 3) + Xdelta% * (45 - Anime2%%) / 23
  319.                     Y3! = Positions!(4, PickedHour%%, 1, 3)
  320.                     Zpos! = -0.5
  321.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)
  322.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)
  323.                 ELSE
  324.                     Xdelta% = Positions!(1, PickedHour%%, 0, 1) - Positions!(4, PickedHour%%, 0, 0) + Tucked%%
  325.                     X0! = Positions!(4, PickedHour%%, 0, 0) + Xdelta% * Anime2%% / 22
  326.                     Y0! = Positions!(4, PickedHour%%, 1, 0)
  327.                     X1! = Positions!(4, PickedHour%%, 0, 1) + Xdelta% * Anime2%% / 22
  328.                     Y1! = Positions!(4, PickedHour%%, 1, 1)
  329.                     X2! = Positions!(4, PickedHour%%, 0, 2) + Xdelta% * Anime2%% / 22
  330.                     Y2! = Positions!(4, PickedHour%%, 1, 2)
  331.                     X3! = Positions!(4, PickedHour%%, 0, 3) + Xdelta% * Anime2%% / 22
  332.                     Y3! = Positions!(4, PickedHour%%, 1, 3)
  333.                     Zpos! = 0.5
  334.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)
  335.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)
  336.                 END IF
  337.             ELSE
  338.                 'Vertical for others
  339.                 IF Anime2%% > 22 THEN
  340.                     Ydelta% = Positions!(0, 0, 1, 0) - Positions!(4, 0, 1, 2) + Tucked%%
  341.                     XA! = Positions!(4, 0, 0, 0)
  342.                     YA! = Positions!(4, 0, 1, 0) + Ydelta% * (45 - Anime2%%) / 23
  343.                     XB! = Positions!(4, 0, 0, 1)
  344.                     YB! = Positions!(4, 0, 1, 1) + Ydelta% * (45 - Anime2%%) / 23
  345.                     XC! = Positions!(4, 0, 0, 2)
  346.                     YC! = Positions!(4, 0, 1, 2) + Ydelta% * (45 - Anime2%%) / 23
  347.                     XD! = Positions!(4, 0, 0, 3)
  348.                     YD! = Positions!(4, 0, 1, 3) + Ydelta% * (45 - Anime2%%) / 23
  349.                     CALL Angle((XA!), (YA!), X0!, Y0!, Orient!)
  350.                     CALL Angle((XB!), (YB!), X1!, Y1!, Orient!)
  351.                     CALL Angle((XC!), (YC!), X2!, Y2!, Orient!)
  352.                     CALL Angle((XD!), (YD!), X3!, Y3!, Orient!)
  353.                     Zpos! = -0.5
  354.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)
  355.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)
  356.                 ELSE
  357.                     Ydelta% = Positions!(0, 0, 1, 0) - Positions!(4, 0, 1, 2) + Tucked%%
  358.                     XA! = Positions!(4, 0, 0, 0)
  359.                     YA! = Positions!(4, 0, 1, 0) + Ydelta% * Anime2%% / 22
  360.                     XB! = Positions!(4, 0, 0, 1)
  361.                     YB! = Positions!(4, 0, 1, 1) + Ydelta% * Anime2%% / 22
  362.                     XC! = Positions!(4, 0, 0, 2)
  363.                     YC! = Positions!(4, 0, 1, 2) + Ydelta% * Anime2%% / 22
  364.                     XD! = Positions!(4, 0, 0, 3)
  365.                     YD! = Positions!(4, 0, 1, 3) + Ydelta% * Anime2%% / 22
  366.                     CALL Angle((XA!), (YA!), X0!, Y0!, Orient!)
  367.                     CALL Angle((XB!), (YB!), X1!, Y1!, Orient!)
  368.                     CALL Angle((XC!), (YC!), X2!, Y2!, Orient!)
  369.                     CALL Angle((XD!), (YD!), X3!, Y3!, Orient!)
  370.                     Zpos! = 0.5
  371.                     _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)
  372.                     _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)
  373.                 END IF
  374.             END IF
  375.             Anime2%% = Anime2%% + 1
  376.             IF Anime2%% = 43 THEN CanPutDown%% = True
  377.         ELSEIF PickedUp%% THEN
  378.             'Display picked-up card
  379.             IF __UI_MouseLeft > 680 AND __UI_MouseTop > 738 THEN
  380.                 'Do Nothing
  381.             ELSE
  382.                 CALL Angle(-Halfwidth%%, Halfheight%, X0!, Y0!, Orient!)
  383.                 CALL Angle(Halfwidth%%, Halfheight%, X1!, Y1!, Orient!)
  384.                 CALL Angle(-Halfwidth%%, -Halfheight%, X2!, Y2!, Orient!)
  385.                 CALL Angle(Halfwidth%%, -Halfheight%, X3!, Y3!, Orient!)
  386.                 X0! = X0! + XM%
  387.                 Y0! = Y0! + YM%
  388.                 X1! = X1! + XM%
  389.                 Y1! = Y1! + YM%
  390.                 X2! = X2! + XM%
  391.                 Y2! = Y2! + YM%
  392.                 X3! = X3! + XM%
  393.                 Y3! = Y3! + YM%
  394.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(PickedCard%% - 1) TO(X0!, Y0!, ZOffset!)-(X1!, Y1!, ZOffset!)-(X2!, Y2!, ZOffset!)
  395.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(PickedCard%% - 1) TO(X3!, Y3!, ZOffset!)-(X2!, Y2!, ZOffset!)-(X1!, Y1!, ZOffset!)
  396.             END IF
  397.         END IF
  398.         'Display Piles
  399.         FOR S%% = 4 TO 0 STEP -1 'Maptriangle order is backwards
  400.             FOR N%% = 0 TO 12
  401.                 IF Clock%%(N%%, S%%, 0) <> 0 THEN
  402.                     IF Clock%%(N%%, S%%, 1) THEN
  403.                         _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), CardsImg&(Clock%%(N%%, S%%, 0) - 1) TO(Positions!(S%%, N%%, 0, 0), Positions!(S%%, N%%, 1, 0), ZOffset!)-(Positions!(S%%, N%%, 0, 1), Positions!(S%%, N%%, 1, 1), ZOffset!)-(Positions!(S%%, N%%, 0, 2), Positions!(S%%, N%%, 1, 2), ZOffset!)
  404.                         _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), CardsImg&(Clock%%(N%%, S%%, 0) - 1) TO(Positions!(S%%, N%%, 0, 3), Positions!(S%%, N%%, 1, 3), ZOffset!)-(Positions!(S%%, N%%, 0, 2), Positions!(S%%, N%%, 1, 2), ZOffset!)-(Positions!(S%%, N%%, 0, 1), Positions!(S%%, N%%, 1, 1), ZOffset!)
  405.                     ELSE
  406.                         _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(Positions!(S%%, N%%, 0, 0), Positions!(S%%, N%%, 1, 0), ZOffset!)-(Positions!(S%%, N%%, 0, 1), Positions!(S%%, N%%, 1, 1), ZOffset!)-(Positions!(S%%, N%%, 0, 2), Positions!(S%%, N%%, 1, 2), ZOffset!)
  407.                         _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(Positions!(S%%, N%%, 0, 3), Positions!(S%%, N%%, 1, 3), ZOffset!)-(Positions!(S%%, N%%, 0, 2), Positions!(S%%, N%%, 1, 2), ZOffset!)-(Positions!(S%%, N%%, 0, 1), Positions!(S%%, N%%, 1, 1), ZOffset!)
  408.                     END IF
  409.                 END IF
  410.             NEXT N%%
  411.         NEXT S%%
  412.         IF Stock%% > 0 THEN
  413.             'Display Stock
  414.             IF Stock%% > 1 THEN
  415.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(XStart% - Halfwidth%%, YStart% + Halfheight%%, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%%, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%%, ZOffset!)
  416.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(XStart% + Halfwidth%%, YStart% - Halfheight%%, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%%, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%%, ZOffset!)
  417.             END IF
  418.             IF Stock%% > 10 THEN
  419.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(XStart% - Halfwidth%%, YStart% + Halfheight%% - 1, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 1, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 1, ZOffset!)
  420.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(XStart% + Halfwidth%%, YStart% - Halfheight%% - 1, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 1, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 1, ZOffset!)
  421.             END IF
  422.             IF Stock%% > 20 THEN
  423.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(XStart% - Halfwidth%%, YStart% + Halfheight%% - 2, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 2, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 2, ZOffset!)
  424.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(XStart% + Halfwidth%%, YStart% - Halfheight%% - 2, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 2, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 2, ZOffset!)
  425.             END IF
  426.             IF Stock%% > 30 THEN
  427.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(XStart% - Halfwidth%%, YStart% + Halfheight%% - 3, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 3, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 3, ZOffset!)
  428.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(XStart% + Halfwidth%%, YStart% - Halfheight%% - 3, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 3, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 3, ZOffset!)
  429.             END IF
  430.             IF Stock%% > 41 THEN
  431.                 _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(XStart% - Halfwidth%%, YStart% + Halfheight%% - 4, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 4, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 4, ZOffset!)
  432.                 _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(XStart% + Halfwidth%%, YStart% - Halfheight%% - 4, ZOffset!)-(XStart% - Halfwidth%%, YStart% - Halfheight%% - 4, ZOffset!)-(XStart% + Halfwidth%%, YStart% + Halfheight%% - 4, ZOffset!)
  433.             END IF
  434.             'Display dealt card
  435.             S%% = (52 - Stock%%) \ 13
  436.             N%% = (52 - Stock%%) MOD 13
  437.             Count% = Count% + 1
  438.             Zpos! = 50 * SIN(Pi! * Count% / 15)
  439.             ActualAngle! = Phi!(N%%) * Count% / 15
  440.             XPos! = XStart% + (Positions!(S%%, N%%, 0, 4) - XStart%) * Count% / 15
  441.             YPos! = YStart% + (Positions!(S%%, N%%, 1, 4) - YStart%) * Count% / 15
  442.             CALL Angle((-Halfwidth%%), (Halfheight%%), X0!, Y0!, (ActualAngle!))
  443.             CALL Angle((Halfwidth%%), (Halfheight%%), X1!, Y1!, (ActualAngle!))
  444.             CALL Angle((-Halfwidth%%), (-Halfheight%%), X2!, Y2!, (ActualAngle!))
  445.             CALL Angle((Halfwidth%%), (-Halfheight%%), X3!, Y3!, (ActualAngle!))
  446.             X0! = XPos! + X0!
  447.             Y0! = YPos! + Y0!
  448.             X1! = XPos! + X1!
  449.             Y1! = YPos! + Y1!
  450.             X2! = XPos! + X2!
  451.             Y2! = YPos! + Y2!
  452.             X3! = XPos! + X3!
  453.             Y3! = YPos! + Y3!
  454.             _MAPTRIANGLE (0, 0)-(XImage% - 1, 0)-(0, YImage% - 1), Obverse& TO(X0!, Y0!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)
  455.             _MAPTRIANGLE (XImage% - 1, YImage% - 1)-(0, YImage% - 1)-(XImage% - 1, 0), Obverse& TO(X3!, Y3!, Zpos! + ZOffset!)-(X2!, Y2!, Zpos! + ZOffset!)-(X1!, Y1!, Zpos! + ZOffset!)
  456.             IF Count% = 15 THEN
  457.                 Count% = 0
  458.                 Clock%%((52 - Stock%%) MOD 13, 1 + ((52 - Stock%%) \ 13), 0) = Clock%%((52 - Stock%%) MOD 13, 1 + ((52 - Stock%%) \ 13), 2)
  459.                 Stock%% = Stock%% - 1
  460.             END IF
  461.         END IF
  462.         IF IsComplete%% THEN
  463.             _PUTIMAGE (230, 246), GameOver&
  464.             IF GotOut%% THEN _PUTIMAGE (222, 490), GameWon&
  465.         END IF
  466.     END IF
  467.  
  468. SUB __UI_BeforeUnload
  469.     'If you set __UI_UnloadSignal = False here you can
  470.     'cancel the user's request to close.
  471.  
  472. SUB __UI_Click (id AS LONG)
  473.     SELECT CASE id
  474.         CASE ClockPatience
  475.             IF GreenValid%% THEN
  476.                 DoPickUp%% = True
  477.             ELSEIF RedValid%% THEN
  478.                 Anime2%% = 0
  479.             END IF
  480.         CASE ExitBT
  481.             SYSTEM
  482.         CASE NewGameBT
  483.             IF NOT DoPatience%% THEN
  484.                 Control(NewGameBT).Disabled = True
  485.                 Control(NewGameBT).Hidden = True
  486.                 Caption(NewGameBT) = "New Game"
  487.                 SetFocus ExitBT
  488.                 CALL Patience
  489.             ELSE
  490.                 DoPatience%% = False
  491.                 Caption(NewGameBT) = "Deal"
  492.             END IF
  493.     END SELECT
  494.  
  495. SUB __UI_MouseEnter (id AS LONG)
  496.  
  497. SUB __UI_MouseLeave (id AS LONG)
  498.  
  499. SUB __UI_FocusIn (id AS LONG)
  500.  
  501. SUB __UI_FocusOut (id AS LONG)
  502.     'This event occurs right before a control loses focus.
  503.     'To prevent a control from losing focus, set __UI_KeepFocus = True below.
  504.  
  505. SUB __UI_MouseDown (id AS LONG)
  506.  
  507. SUB __UI_MouseUp (id AS LONG)
  508.  
  509. SUB __UI_KeyPress (id AS LONG)
  510.     'When this event is fired, __UI_KeyHit will contain the code of the key hit.
  511.     'You can change it and even cancel it by making it = 0
  512.  
  513. SUB __UI_TextChanged (id AS LONG)
  514.  
  515. SUB __UI_ValueChanged (id AS LONG)
  516.  
  517. SUB __UI_FormResized
  518.  
  519.  
  520. SUB Angle (Xin!, Yin!, Xout!, Yout!, Theta!)
  521.     Xout! = Xin! * COS(Theta!) - Yin! * SIN(Theta!)
  522.     Yout! = Xin! * SIN(Theta!) + Yin! * COS(Theta!)
  523.  
  524. SUB Patience
  525.     BadDeal%% = True
  526.     WHILE BadDeal%%
  527.         REDIM Clock%%(12, 4, 2)
  528.         CALL Shuffle(Cards%%())
  529.         'Deal Sim
  530.         FOR N%% = 0 TO 51
  531.             S%% = N%% \ 13
  532.             R%% = N%% MOD 13
  533.             Clock%%(R%%, S%% + 1, 2) = Cards%%(N%%)
  534.         NEXT N%%
  535.         BadDeal%% = False
  536.         FOR M%% = 0 TO 12 'Cards are in S 1 to 4
  537.             IF Clock%%(M%%, 1, 2) MOD 13 = Clock%%(M%%, 2, 2) MOD 13 AND Clock%%(M%%, 1, 2) MOD 13 = Clock%%(M%%, 3, 2) MOD 13 AND Clock%%(M%%, 1, 2) MOD 13 = Clock%%(M%%, 4, 2) MOD 13 THEN BadDeal%% = True
  538.         NEXT M%%
  539.     WEND
  540.     Stock%% = 52
  541.     Anime1%% = 31
  542.     Anime2%% = 43
  543.     TurnOver%% = True
  544.     DoPickUp%% = False
  545.     PickedUp%% = False
  546.     PickedCard%% = 0
  547.     PickedHour%% = 12
  548.     CanPutDown%% = False
  549.     IsComplete%% = False
  550.     DoPatience%% = True
  551.     HangOn%% = True
  552.     HangStop%% = 50
  553.     HCount%% = 0
  554.     WHILE DoPatience%%
  555.         _LIMIT 60
  556.         GreenValid%% = False
  557.         RedValid%% = False
  558.         IF Stock%% = 0 AND HangOn%% THEN
  559.             HCount%% = HCount%% + 1
  560.             IF HCount%% = HangStop%% THEN
  561.                 HangOn%% = False
  562.                 HCount%% = 0
  563.                 HangStop%% = 20
  564.             END IF
  565.         END IF
  566.         IF Stock%% = 0 AND NOT IsComplete%% AND Anime1%% = 31 AND Anime2%% = 43 AND NOT HangOn%% THEN
  567.             'In _MAPTRIANGLE3D, all distances relative to centre of screen
  568.             XM% = __UI_MouseLeft - _WIDTH / 2
  569.             YM% = _HEIGHT / 2 - __UI_MouseTop
  570.             IF TurnOver%% THEN
  571.                 Orient0! = Phi!(PickedHour%%) 'Start orientation is from where the card is taken
  572.                 PickedCard%% = Clock%%(PickedHour%%, 4, 0) 'From 1 to 52
  573.                 Clock%%(PickedHour%%, 4, 0) = 0
  574.                 OldHour%% = PickedHour%%
  575.                 Anime1%% = 0
  576.             ELSEIF NOT DoPickUp%% AND NOT PickedUp%% THEN
  577.                 IF SQR((Positions!(4, PickedHour%%, 0, 4) - XM%) * (Positions!(4, PickedHour%%, 0, 4) - XM%) + (Positions!(4, PickedHour%%, 1, 4) - YM%) * (Positions!(4, PickedHour%%, 1, 4) - YM%)) < 40 THEN GreenValid%% = True
  578.             ELSEIF DoPickUp%% THEN
  579.                 IF PickedHour%% = 12 THEN
  580.                     FOR R%% = 4 TO 2 STEP -1
  581.                         Clock%%(PickedHour%%, R%%, 0) = Clock%%(PickedHour%%, R%% - 1, 0)
  582.                         Clock%%(PickedHour%%, R%%, 1) = Clock%%(PickedHour%%, R%% - 1, 1)
  583.                     NEXT R%%
  584.                     Clock%%(PickedHour%%, 1, 0) = 0
  585.                 ELSE
  586.                     FOR R%% = 4 TO 1 STEP -1
  587.                         Clock%%(PickedHour%%, R%%, 0) = Clock%%(PickedHour%%, R%% - 1, 0)
  588.                         Clock%%(PickedHour%%, R%%, 1) = Clock%%(PickedHour%%, R%% - 1, 1)
  589.                     NEXT R%%
  590.                     Clock%%(PickedHour%%, 0, 0) = 0
  591.                 END IF
  592.                 PickedHour%% = PickedCard%% MOD 13
  593.                 IF PickedHour%% = 0 THEN
  594.                     PickedHour%% = 12
  595.                 ELSEIF PickedHour%% = 12 THEN
  596.                     PickedHour%% = 0
  597.                 END IF
  598.                 Orient1! = Phi!(PickedHour%%)
  599.                 PickedUp%% = True
  600.                 DoPickUp%% = False
  601.             ELSEIF PickedUp%% THEN
  602.                 IF SQR((Positions!(4, PickedHour%%, 0, 4) - XM%) * (Positions!(4, PickedHour%%, 0, 4) - XM%) + (Positions!(4, PickedHour%%, 1, 4) - YM%) * (Positions!(4, PickedHour%%, 1, 4) - YM%)) < 40 THEN
  603.                     IF NOT CanPutDown%% THEN RedValid%% = True
  604.                     Orient! = Orient1!
  605.                 ELSEIF SQR((Positions!(4, OldHour%%, 0, 4) - XM%) * (Positions!(4, OldHour%%, 0, 4) - XM%) + (Positions!(4, OldHour%%, 1, 4) - YM%) * (Positions!(4, OldHour%%, 1, 4) - YM%)) < 40 THEN
  606.                     Orient! = Orient0!
  607.                 ELSE
  608.                     Orient! = 0
  609.                 END IF
  610.                 IF CanPutDown%% THEN
  611.                     CanPutDown%% = False
  612.                     PickedUp%% = False
  613.                     HangOn%% = True
  614.                     IF PickedHour%% = 12 THEN
  615.                         Clock%%(PickedHour%%, 1, 0) = PickedCard%%
  616.                         Clock%%(PickedHour%%, 1, 1) = True
  617.                     ELSE
  618.                         Clock%%(PickedHour%%, 0, 0) = PickedCard%%
  619.                         Clock%%(PickedHour%%, 0, 1) = True
  620.                     END IF
  621.                     PickedCard%% = 0
  622.                     IF Clock%%(12, 4, 1) AND Clock%%(12, 1, 0) <> 0 THEN 'Game Finished
  623.                         IsComplete%% = True
  624.                         Control(NewGameBT).Disabled = False
  625.                         Control(NewGameBT).Hidden = False
  626.                         SetFocus NewGameBT
  627.                         GotOut%% = True
  628.                         M%% = 0
  629.                         WHILE M%% <= 11 AND GotOut%%
  630.                             IF NOT Clock%%(M%%, 4, 1) THEN GotOut%% = False
  631.                             M%% = M%% + 1
  632.                         WEND
  633.                     END IF
  634.                     IF NOT IsComplete%% THEN TurnOver%% = True
  635.                 END IF
  636.             END IF
  637.         END IF
  638.         __UI_DoEvents
  639.     WEND
  640.  
  641. SUB Shuffle (Pack%%()) 'Fisher Yates or Knuth shuffle
  642.     FOR S%% = 51 TO 1 STEP -1
  643.         R%% = INT(RND * S%%) '+ 1
  644.         SWAP Pack%%(R%%), Pack%%(S%%)
  645.     NEXT S%%
« Last Edit: June 08, 2019, 08:00:11 am by Qwerkey »