home *** CD-ROM | disk | FTP | other *** search
/ 100 Great Games for Palm OS 1 / 100PalmV1.iso / Cards / pocketjack / PJ12.csl < prev    next >
Text File  |  1999-03-06  |  21KB  |  920 lines

  1. # PocketJack, Version 1.2 release.
  2. # Copyright (C) March 1999, Frank O'Brien, 
  3. #  dianfrank@worldnet.att.net.
  4. # PocketJack name, program, manual, and source code are 
  5. #  copyrighted by Frank O'Brien.  Absolutely no warranty is 
  6. #  given.
  7. # This program is freeware.  The program and source code 
  8. #  may be distributed as long as there is no fee.
  9. # Source code may be changed and distributed.  Distributed 
  10. #  changes shall be documented with name, type and date.  
  11. #  Please also add a note to about box.  Distribution shall 
  12. #  be under these same terms (no fee).
  13.  
  14. # when compiling this file, FOPJ has been reserved as a 
  15. #  unique creator id.  "PocketJack" is used as desktop name.
  16. #  PJ11.cic is provided for use as pilot icon image.
  17.  
  18. #BlackJack program for the Pilot
  19. #20Dec97, Frank O'Brien
  20. # BJ10.csl version 1.0
  21.  
  22. # *** bugs/new features
  23. # on windows, after draw, all labels are updated on display,
  24. #  causes some clear of down card
  25.  
  26. # 25-26Dec97
  27. # OK- only deduct 1 ace, not all
  28. # OK - clear hands at game start, not wide enough
  29. # OK - pilot hit loop takes too many cards
  30. # OK - when dealer busts, Wins not updated
  31. # OK - doesn't deal cards down yet
  32. # OK - pay double for bj and 5cc, triple for 6cc
  33. # OK - feature to change bet 1-5, replace new button with
  34. #  pick bet event
  35. # OK - after human busts, flip pilot last card
  36. # OK - add total, Wins, and who won labels
  37. # OK - about box
  38. # OK - basic info on rules
  39. # OK - when player gets 6cc, pilot for some reason still goes,
  40. #  winner is player with triple bet.
  41.  
  42. #27Dec97
  43. # OK - improve GUI look, maybe add lines - added little side bordering,
  44. #  standardized all positions and sizes with variables 
  45. #  and functions
  46.  
  47. #28dec97
  48. # added delay to pilot play
  49. # added delay to deal loop
  50. # added sound to deal
  51. # added menu options to change delay and sound defaults
  52. # added win/lose sound, plays double if win double.
  53. # adjusted cards to be a little shorter, little narrower,
  54. #  labels a little wider.
  55.  
  56. #29dec97
  57. # hit/stay row lower a little, sometimes overlapped with label
  58.  
  59. #30dec97
  60. # added char graphic history list to remove long redraw after
  61. #  toggle off msgbox frame
  62.  
  63. #31dec97
  64. # still need redraw labels after msgbox, changed put to show
  65. # no text box overflow auto scroll, so sRules must stay small,
  66. #  took out math symbols, added english.
  67.  
  68. #1jan98
  69. # start of BJ11.csl version 1.1
  70. # started to clean up logic flow
  71.  
  72. #2jan98
  73. # continue with timer loops, determined user controls won't 
  74. #  get "focus" if inside while or timer loops.  therefore 
  75. #  kept control similar to before.  game starts with slBet, 
  76. #  then control to btHit/btStay, then repeats.
  77. # per manual, added "call" statement to all function calls
  78. # gave things shorter names, added more comments
  79. # added tie push option
  80.  
  81. #12jan98
  82. # start of PJ11.csl
  83. # changed program name to PocketJack
  84. # added slight changes to rules and about msg
  85.  
  86. #6Mar99, fob
  87. # for all those card counters out there, the deck is now a single
  88. #  deck.  after its been dealt, there's a reshuffle, (no last
  89. #  card option stuff).
  90. # added better help and about info.
  91.  
  92. # source code headings
  93. # 0 compiler variables
  94. # 1 variables
  95.     # 1.1 game
  96.     # 1.2 reserved
  97.     # 1.3 options
  98.     # 1.5 screen coordinate constants for card graphics
  99. # 2 objects
  100.     # 2.1 main frame objects
  101.     # 2.2 help frame objects
  102. # 2a library files
  103. # 3 functions
  104.     # 3.1 returns 1 dimen index, given 2 dimen index
  105.     # 3.2 visual object origin functions
  106.     # 3.3 help functions
  107.     # 3.4 option stuff
  108.     # 3.5 game data 2 dimen access functions
  109.     # 3.6 draw card functions
  110.     # 3.7 game play functions
  111.     # 3.8 player interface functions
  112.     # 3.9 system startup/shutdown
  113.  
  114. # 0 compiler variables
  115.  
  116. variables;
  117.     # compiler setting, i distribute in single folder, 
  118.     #  but on my machine, some cpk files are in library folder
  119.     # default is true()
  120.     numeric bSingleFolder=false();
  121. end;
  122.  
  123. # 1 variables
  124.  
  125. variables;
  126.     #
  127.     # 1.1 game
  128.     #
  129.     # 0-11 player*cards arrays are actually accessed with 
  130.     #  player 0-1, and card 0-5 indexes,
  131.     #  see nfIndex() for 2 dimen access
  132.     numeric nMax=6;
  133.     numeric nFace[2*nMax];
  134.     numeric nSuit[2*nMax];
  135.     numeric nValue[2*nMax];
  136.     # 0-1 player arrays
  137.     numeric nLast[2]=-1;    # last dealt card index, 0-5
  138.     numeric nTotal[2]=0;    # total in hand
  139.     # betting status
  140.     numeric nWins=0;
  141.     numeric nBet=1;
  142.     # selector contents
  143.     string sBet[5]="1","2","5","10","20";
  144.     # "state control" with hide/show BetSelector, Hit, Stay 
  145.     #  buttons
  146.     # other state control variables
  147.     numeric nDealState; # 0-4 for deal timer loop
  148.     numeric bUp;    # flag=f=pilot 2nd card down, =t=up
  149.     #
  150.     # 1.3 options
  151.     #
  152.     numeric bSound; # boolean flag
  153.     string sSound[2]=" Sound"," Silent";
  154.     numeric nDelay; # ms
  155.      string sSpeed[3]="Fast","Normal","Slow";
  156.     numeric nSpeed[3]=0,200,500;
  157.     numeric bPush; # boolean flag
  158.     string sPush[2]=" Tie=0"," Tie=-1";
  159.     # 1.5 screen coordinate constants for card graphics.
  160.     #
  161.     # screen is grid of "slots", 0-2 columns, 0-10 rows.
  162.     # the grid is positioned on screen at L, T.
  163.     # larger frame things "Ob1", like cards borders, are 
  164.     #  positioned within a slot at BW1, BH1.
  165.     # smaller internal things "Ob2", like labels, are postioned
  166.     # at BW1+BW2, BH1+BH2.
  167.     # the size of larger things Ob1 are SlotW-2*BW1, 
  168.     #  SlotH-2*BH1.
  169.     # the size of smaller things Ob2 are SlotW-2*(BW1+BW2), 
  170.     #  SlotH-2*(BH1+BH2).
  171.     # the size of the card border is SlotW-2*BW1, 
  172.     #  3*SlotH-2*BH1.
  173.     numeric nPx=1000/160;
  174.     numeric nL=5*nPx;
  175.     numeric nT=16*nPx;
  176.     numeric nChW=10*nPx;
  177.     numeric nChH=11*nPx; #9
  178.     numeric nBW1=2*nL;
  179.     numeric nBH1=nPx;
  180.     numeric nBW2=nPx;
  181.     numeric nBH2=0;#nPx;
  182.     numeric nOb2W=3*nChW;
  183.     numeric nOb2H=nChH;
  184.     numeric nOb1W=2*nBW2+nOb2W;
  185.     numeric nOb1H=2*nBH2+nOb2H;
  186.     numeric nSlotW=2*nBW1+nOb1W;
  187.     numeric nSlotH=2*nBH1+nOb1H;
  188.     numeric nCardW=nOb1W;
  189.     numeric nCardH=3*nSlotH-2*nBH1;
  190. end;
  191.  
  192. # 2 objects
  193.  
  194. # constants are used for pixel sizing all visual objects,
  195. #  postioning of objects is done during program startup,
  196. #  using defined origin functions
  197.  
  198. # 2.1 main frame objects
  199.  
  200. frame frMain;
  201.     display "PocketJack";
  202. end;
  203.  
  204. button btHit, frMain;
  205.     display "Hit";
  206.     pixel_size nOb1W,nOb1H;
  207.     hidden;
  208. end;
  209.  
  210. button btStay, frMain;
  211.     display "Stay";
  212.     pixel_size nOb1W,nOb1H;
  213.     hidden;
  214. end;
  215.  
  216. label lbFace[12], frMain;
  217.     font "stdfont","",0;
  218.     pixel_size nOb2W,nOb2H;
  219. end;
  220.  
  221. label lbTotal[2], frMain;
  222.     font "stdfont","",0;
  223.     pixel_size nOb2W,nOb2H;
  224. end;
  225.  
  226. label lbWins, frMain;
  227.     font "stdfont","",0;
  228.     pixel_size nOb2W,nOb2H;
  229. end;
  230.  
  231. label lbWhoseHand[2], frMain;
  232.     pixel_size 1*nOb2W,1*nOb2H;
  233. end;
  234.  
  235. label lbWinsLabel, frMain;
  236.     pixel_size nOb2W,nOb2H;
  237.     display "Wins";
  238. end;
  239.  
  240. text lbStatus, frMain;
  241.     font "stdfont","",0;
  242.     pixel_size nOb1W,2*nSlotH-2*nBH1;
  243.     no_input;
  244.     display "";
  245. end;
  246.  
  247. selector slBet, frMain;
  248.     pixel_size nOb2W, 5*nSlotH-2*(nBH1+nBH2);
  249.     list sBet;
  250. end;
  251.  
  252. label lbBetLabel, frMain;
  253.     pixel_size nOb2W,nOb2H;
  254.     display "Bet";
  255. end;
  256.  
  257. label lbBet, frMain;
  258.     font "stdfont","",0;
  259.     pixel_size nOb2W,nOb2H;
  260.     display sBet[0];
  261.     hidden;
  262. end;
  263.  
  264. menu_top mtOptions, frMain;
  265.     display "Options";
  266. end;
  267.  
  268. menu_item miOption[5], mtOptions
  269. ;end;
  270.  
  271. # 2a library files
  272.  
  273. compile_if bSingleFolder;
  274.     # default machines
  275.     include "msgbox_fo.cpk";
  276.     include "deckofcards_fo.cpk";
  277. compile_else;
  278.     # my machine
  279.     include "..\library\msgbox_fo.cpk";
  280.     include "..\library\deckofcards_fo.cpk";
  281. compile_end_if;
  282.  
  283. # 3 functions
  284.  
  285. # 3.1 returns 1 dimen index, given 2 dimen index
  286.  
  287. # p=player=0-1, i=index=0-5, returns 1 dimen index 0-11
  288. function nfIndex(numeric p, numeric i) as numeric;
  289.     nfIndex=nMax*p+i;    
  290. end;
  291.  
  292. # 3.2 visual object origin functions
  293.  
  294. # constants are defined for all sizeW, sizeH, and 
  295. #  borderW, borderH.
  296.  
  297. function nfSlotX(numeric c, numeric r) as numeric;
  298.     nfSlotX=nL+c*nSlotW;
  299. end;
  300.  
  301. function nfSlotY(numeric c, numeric r) as numeric;
  302.     nfSlotY=nT+r*nSlotH;
  303. end;
  304.  
  305. function nfOb1X(numeric c, numeric r) as numeric;
  306.     nfOb1X=nfSlotX(c,r)+nBW1;
  307. end;
  308.  
  309. function nfOb1Y(numeric c, numeric r) as numeric;
  310.     nfOb1Y=nfSlotY(c,r)+nBH1;
  311. end;
  312.  
  313. function nfOb2X(numeric c, numeric r) as numeric;
  314.     nfOb2X=nfOb1X(c,r)+nBW2;
  315. end;
  316.  
  317. function nfOb2Y(numeric c, numeric r) as numeric;
  318.     nfOb2Y=nfOb1Y(c,r)+nBH2;
  319. end;
  320.  
  321. # 3.3 help message box functions
  322.  
  323. #define help constants
  324. #
  325. function InitHelp;
  326.     mb_sTitle="PocketJack";
  327.     mb_sVersion="1.2";
  328.     mb_sDate="6Mar99";
  329.     mb_sAbstract="PalmPilot version of the standard ";
  330.     mb_sAbstract=mb_sAbstract+"BlackJack card game.  ";
  331.     mb_sDocName="pj12doc.htm"; 
  332.     mb_sHelpBody="Object: Get closer to 21 than Pilot without "+
  333.      "going over."+char(10)+char(10)+"Rules: Cards are worth their ";
  334.     mb_sHelpBody=mb_sHelpBody+"face value, except J, Q, K are worth 10, ";
  335.     mb_sHelpBody=mb_sHelpBody+"and A is worth 11 or 1.  ";
  336.     mb_sHelpBody=mb_sHelpBody+"21 in 2 cards wins ";
  337.     mb_sHelpBody=mb_sHelpBody+"double.  5 cards not over 21 wins ";
  338.     mb_sHelpBody=mb_sHelpBody+"double.  6 cards not over 21 wins ";
  339.     mb_sHelpBody=mb_sHelpBody+"triple.  ";
  340.     mb_sHelpBody=mb_sHelpBody+"Pilot hits on 16 or ";
  341.     mb_sHelpBody=mb_sHelpBody+"less."+char(10)+char(10);
  342.     mb_sHelpBody=mb_sHelpBody+"To Play: 1) select bet, 2) ";
  343.     mb_sHelpBody=mb_sHelpBody+"tap Hit or Stay, 3) repeat.";
  344.     mb_sWebSite="http://home.att.net/~dianfrank/pilot_apps.htm";
  345.     call mb_AppendAbout(dc_sCredits);
  346. end;
  347.  
  348. # pilot evidently redraws objects then graphics, since
  349. #  graphics cover card face label objects, must
  350. #  redraw card face labels
  351. #
  352. function mb_Redraw;
  353.     variables;
  354.         numeric p;
  355.         numeric i;
  356.         numeric n;
  357.     end;
  358.     p=0;
  359.     while p<2;
  360.         i=0;
  361.         while i<=nLast[p];
  362.             n=nfIndex(p,i);
  363.             if p<>1 or i<>1 or bUp;
  364.                 show lbFace[n];
  365.             end_if;
  366.             i=i+1;
  367.         end_while;
  368.         p=p+1;
  369.     end_while;
  370. end;
  371.  
  372. # 3.4 option stuff
  373.  
  374. function CardSound;
  375.     if bSound;
  376.         play "131,50"; # play lowest C, 1/20 s
  377.     end_if;
  378. end;
  379.  
  380. function WinSound(numeric w);
  381.     if bSound and w<>0;
  382.         play "494,100"; # play middle B, 1/10 s
  383.         play "392,100"; # play middle G, 1/10 s
  384.         play "523,200"; # play high C, 2/10 s
  385.         call WinSound(w-1);
  386.     end_if;
  387. end;
  388.  
  389. function LoseSound(numeric w);
  390.     if bSound and w<>0;
  391.         play "294,100"; # play middle D, 1/10 s
  392.         play "392,100"; # play middle G, 1/10 s
  393.         play "262,200"; # play middle C, 2/10 s
  394.         call LoseSound(w-1);
  395.     end_if;
  396. end;
  397.  
  398. function TieSound;
  399.     if bSound;
  400.         play "392,100"; # play middle G, 1/10 s
  401.         play "392,100"; # play middle G, 1/10 s
  402.         play "392,100"; # play middle G, 1/10 s
  403.     end_if;
  404. end;
  405.  
  406. function SetPush(numeric p);
  407.     bPush=p;
  408.     put miOption[4],sPush[p];
  409. end;
  410.  
  411. function SetSound(numeric s);
  412.     bSound=s;
  413.     put miOption[3],sSound[s];
  414. end;
  415.  
  416. function SetSpeed(numeric s);
  417.     variables;
  418.         numeric i;
  419.     end;
  420.     nDelay=nSpeed[s];
  421.     i=0;
  422.     while i<3;
  423.         if i=s;
  424.             # dot for selected option
  425.             put miOption[i],char(149)+sSpeed[i];
  426.         else;
  427.             put miOption[i],char(32)+sSpeed[i];
  428.         end_if;
  429.         i=i+1;
  430.     end_while;
  431. end;
  432.  
  433. function miOption;
  434.     if invokersub=4;
  435.         # push toggle
  436.         call SetPush(not bPush);
  437.     else;
  438.         if invokersub=3;
  439.             # sound toggle
  440.             call SetSound(not bSound);
  441.         else;
  442.             # speed choice
  443.             call SetSpeed(invokersub);
  444.         end_if;
  445.     end_if;
  446. end;
  447.  
  448. # 3.5 game data 2 dimen access functions
  449.  
  450. # f=face num=0-12, s=suit=0-3, returns string of card label
  451. #
  452. function sfFace(numeric f, numeric s) as string;
  453.     variables;             
  454.         string ss;
  455.     end;
  456.     # do suit string for each platform, windows font doesn't have suit char
  457.     if platform = "windows";
  458.         if s=0;
  459.             ss="d";
  460.         end_if;
  461.         if s=1;
  462.             ss="c";
  463.         end_if;
  464.         if s=2;
  465.             ss="h";
  466.         end_if;
  467.         if s=3;
  468.             ss="s";
  469.         end_if;
  470.     else;
  471.         # pilot platform
  472.         ss=Char(141+s);
  473.     end_if;
  474.     # do face string
  475.     f=f+1; # 1-13
  476.     if f = 1; # ace 
  477.         sfFace=Char(65)+ss;
  478.     end_if;
  479.     if f = 10; # 10
  480.         sfFace=Char(49)+Char(48)+ss;
  481.     end_if;
  482.     if f = 11; # jack
  483.         sfFace=Char(74)+ss;
  484.     end_if;
  485.     if f = 12; # queen
  486.         sfFace=Char(81)+ss;
  487.     end_if;
  488.     if f = 13; # king
  489.         sfFace=Char(75)+ss;
  490.     end_if;
  491.     if f > 1 and f < 10; # number 2-9
  492.         sfFace=Char(48+f)+ss;
  493.     end_if;
  494. end;
  495.  
  496. # f=face num=0-12, returns bj value of card
  497. #
  498. function nfValue(numeric f) as numeric;
  499.     f=f+1; # 1-13
  500.     if f = 1; # ace 
  501.         nfValue=11; # dealer makes low ace, as needed
  502.     end_if;
  503.     if f = 10; # 10
  504.         nfValue=10;
  505.     end_if;
  506.     if f = 11; # jack
  507.         nfValue=10;
  508.     end_if;
  509.     if f = 12; # queen
  510.         nfValue=10;
  511.     end_if;
  512.     if f = 13; # king
  513.         nfValue=10;
  514.     end_if;
  515.     if f > 1 and f < 10; # number 2-9
  516.         nfValue=f;
  517.     end_if;
  518. end;
  519.  
  520. # 3.6 draw card functions
  521.  
  522. # p=player=0-1, generate a card as if a full deck 
  523. #  is shuffled for each dealt card
  524. # never call if already have max cards, will overflow arrays
  525. #
  526. function GenerateCard(numeric p);
  527.     variables;
  528.         numeric i;
  529.         numeric n;
  530.         numeric c;
  531.     end;
  532.     # update nLast index
  533.     i=nLast[p]+1;
  534.     nLast[p]=i;
  535.     n=nfIndex(p,i);
  536.     # store card data
  537.     c=dc_nfNextCard;
  538.     nFace[n]=dc_nfFace(c)-2; # 0-12
  539.     nSuit[n]=dc_nfSuit(c); # 0-3
  540.     nValue[n]=nfValue(nFace[n]); # 2-11
  541. end;
  542.  
  543. # p=player=0-1, i=card index=0-nLast[p],
  544. # draw card face, update total, display total,
  545. #  i may be modified.
  546. #
  547. function DrawFace(numeric p, numeric i);
  548.     variables;
  549.         numeric n;
  550.     end;
  551.     n=nfIndex(p,i);
  552.     # draw card face
  553.     set frMain, pen, nfOb1X(p,i), nfOb1Y(p,i);
  554.     draw frMain, rectangle, nCardW, nCardH;
  555.     put lbFace[n], sfFace(nFace[n],nSuit[n]);
  556.     # update total
  557.     nTotal[p]=nTotal[p]+nValue[n];
  558.     # adjust for any high ace, high ace stored as
  559.     #  11 in nValue[], low ace as 1
  560.     i=0;
  561.     while nTotal[p]>21 and i<=nLast[p];
  562.         n=nfIndex(p,i);
  563.         if nValue[n]=11;
  564.             # high ace found, deduct 10
  565.             nValue[n]=1;
  566.             nTotal[p]=nTotal[p]-10;
  567.         end_if;
  568.         i=i+1;
  569.     end_while;
  570.     # display total
  571.     if nTotal[p]>21;
  572.         put lbTotal[p], "Bust";
  573.     else;
  574.         put    lbTotal[p], nTotal[p];
  575.     end_if;
  576.     # provides optional sound
  577.     call CardSound;
  578. end;
  579.  
  580. # p=player=0-1, i=card index=0-nLast[p],
  581. #  display black card back, no data update
  582. #
  583. function DrawBack(numeric p, numeric i);
  584.     # draw card    down, don't update card total
  585.     set frMain, pen, nfOb1X(p,i), nfOb1Y(p,i);
  586.     fill frMain, rectangle, nCardW, nCardH;
  587.     # provides optional sound
  588.     call CardSound;
  589. end;
  590.  
  591. # p=player=0-1, deals card up, updates all data arrays and
  592. #  display for card and total, adjusts for ace
  593. # never call if already have max cards, will overflow arrays
  594. #
  595. function NewCardU(numeric p);
  596.     variables;
  597.         numeric i;
  598.     end;
  599.     # generate a card
  600.      call GenerateCard(p);
  601.     i=nLast[p];
  602.     # draw card face
  603.     call DrawFace(p,i);
  604. end;
  605.  
  606. # p=player=0-1, deals card up, updates card data arrays and
  607. #  displays black card back
  608. # never call if already have max cards, will overflow arrays
  609. #
  610. function NewCardD(numeric p);
  611.     variables;
  612.         numeric i;
  613.         numeric n;
  614.     end;
  615.     # generate a card
  616.      call GenerateCard(p);
  617.     i=nLast[p];
  618.     call DrawBack(p,i);
  619. end;
  620.  
  621. # p=player=0-1, flips last card up, updates total data array and
  622. #  displays card and total, adjusts for ace
  623. #
  624. function LastCardU(numeric p);
  625.     variables;
  626.         numeric i;
  627.     end;
  628.     # calculate last card pointers
  629.      i=nLast[p];
  630.     # draw card face
  631.     call DrawFace(p,i);
  632.     # set pilot 2nd card up flag
  633.     if p=1;
  634.         bUp=true();
  635.     end_if;
  636. end;
  637.  
  638. # 3.7 game play functions
  639.  
  640. # hide/show user controls
  641. #
  642. function SetState(numeric s);
  643.     if s=0;
  644.         # processing state, user inactive
  645.         hide btHit;
  646.         hide btStay;
  647.         hide slBet;
  648.         show lbBet;
  649.     else;
  650.         if s=1;
  651.             # get bet state
  652.             hide btHit;
  653.             hide btStay;
  654.             hide lbBet;
  655.             show slBet;
  656.         else;
  657.             # state=2, get human move state
  658.             hide slBet;
  659.             show lbBet;
  660.             show btHit;
  661.             show btStay;
  662.         end_if;
  663.     end_if;
  664. end;
  665.  
  666. # p=0=human won, p=1=pilot won, w=weight=1-3
  667. #
  668. function UpdateWins(numeric p, numeric w);
  669.     variables;
  670.         string s;
  671.     end;
  672.     if p=0;
  673.         # player wins
  674.         nWins=nWins+w*nBet;
  675.         s="Win"+string(w*nBet," ##")+"!";
  676.         call WinSound(w);
  677.     else;
  678.         if p=1;
  679.             # pilot wins
  680.             nWins=nWins-w*nBet;
  681.             s="Lose"+string(w*nBet," ##");
  682.             call LoseSound(w);
  683.         else;
  684.             # tie
  685.             s="Tie";
  686.             call TieSound;
  687.         end_if;
  688.     end_if;
  689.     put lbWins, nWins;
  690.     put lbStatus, s;
  691. end;
  692.  
  693. # stay, determine winner, already known player 
  694. #  total<=21 and not bj, not 5cc, not 6cc
  695. #
  696. function PilotStays;
  697.     if nTotal[1]>21;
  698.         # pilot busted
  699.         call UpdateWins(0,1);
  700.     else;
  701.         if nTotal[0]>nTotal[1];
  702.             # human wins
  703.             call UpdateWins(0,1);
  704.         else;
  705.             if bPush and nTotal[0]=nTotal[1];
  706.                  # tie
  707.                 call UpdateWins(2,0);
  708.             else;
  709.                 # pilot wins
  710.                 call UpdateWins(1,1);
  711.             end_if;
  712.         end_if;
  713.     end_if;
  714.     # new game state
  715.     call SetState(1);
  716. end;
  717.  
  718. # pilot plays loop
  719. #
  720. function PilotPlays;
  721.     if nTotal[1]<17 and nLast[1]<5;
  722.         call NewCardU(1);
  723.         timer PilotPlays, nDelay;
  724.     else;
  725.         # loop exit
  726.         call PilotStays;
  727.     end_if;
  728. end;
  729.  
  730. # recursive timer loop, deal 1 card up to each player, 
  731. #  1 card down, flip human's last card up
  732. # uses nDealState to guide control
  733. #
  734. function Deal;
  735.     if nDealState=0; # p=0 and i=0;
  736.         call NewCardU(0);
  737.         nDealState=1;
  738.         timer Deal, nDelay;
  739.     else;
  740.         if nDealState=1; # p=1 and i=0;
  741.             call NewCardU(1);
  742.             nDealState=2;
  743.             timer Deal, nDelay;
  744.         else;
  745.             if nDealState=2; # p=0 and i=1;
  746.                 call NewCardD(0);
  747.                 nDealState=3;
  748.                 timer Deal, nDelay;
  749.             else;
  750.                 if nDealState=3; # p=1 and i=1
  751.                     call NewCardD(1);
  752.                     # set pilot 2nd card up flag
  753.                     bUp=false();
  754.                     nDealState=4;
  755.                     timer Deal, nDelay;
  756.                 else;
  757.                     # nDealState=4, exit loop
  758.                     call LastCardU(0);
  759.                     # determine if human has bj, otherwise human plays
  760.                     if nTotal[0]=21;
  761.                         # human wins double, show pilot's card, update Wins
  762.                         call LastCardU(1);
  763.                         call UpdateWins(0,2);
  764.                         call SetState(1); # new game
  765.                     else;
  766.                         # human's turn
  767.                         call SetState(2);
  768.                     end_if;
  769.                 end_if;
  770.             end_if;
  771.         end_if;
  772.     end_if;
  773. end;
  774.  
  775. # init new game
  776. #
  777. function InitGame;
  778.     variables;
  779.         numeric i;
  780.         numeric p;
  781.     end;
  782.     # clear graphic history list
  783.     clear frMain, rectangle, 0,0;
  784.     # clear card display
  785.     i=0;
  786.     while i<12;
  787.         put lbFace[i],"";
  788.         i=i+1;
  789.     end_while;
  790.     set frMain, pen, nfSlotX(0,0), nfSlotY(0,0);
  791.     clear frMain, rectangle, 2*nSlotW, 8*nSlotH;
  792.     # init last card and total arrays, and total display
  793.     put lbStatus,"";
  794.     p=0;
  795.     while p<2;
  796.         nLast[p]=-1;
  797.         nTotal[p]=0;
  798.         put    lbTotal[p], 0;
  799.         p=p+1;
  800.     end_while;
  801. end;
  802.  
  803. # 3.8 player interface functions
  804.  
  805. # set global bet variable, starts new game
  806. #
  807. function slBet;
  808.     variables;
  809.         numeric i;
  810.     end;
  811.     get slBet, i;
  812.     put lbBet, sBet[i];
  813.     call SetState(0);
  814.     nBet=value(sBet[i]);
  815.     call InitGame;
  816.     nDealState=0;
  817.     timer Deal, nDelay;
  818. end;
  819.  
  820. # give human new card, stay in state if not auto win/loss
  821. #
  822. function btHit;
  823.     call NewCardU(0);
  824.     # check if busted
  825.     if nTotal[0]>21;
  826.         # show pilot's card, update Wins
  827.         call LastCardU(1);
  828.         call UpdateWins(1,1);
  829.         call SetState(1); # new game
  830.     else;
  831.         # not busted, check if 6 card charlie
  832.         if nLast[0]=5;
  833.             # 6cc auto win, show pilot's card, update Wins
  834.             call LastCardU(1);
  835.             call UpdateWins(0,3);
  836.             call SetState(1); # new game
  837.         end_if;
  838.     end_if;
  839. end;
  840.  
  841. # passes to pilot state if not auto win
  842. #
  843. function btStay;
  844.     # not busted, check if 5 card charlie
  845.     if nLast[0]=4;
  846.         # 5cc, show pilot's card, update Wins
  847.         call LastCardU(1);
  848.         call UpdateWins(0,2);
  849.         call SetState(1); # new game
  850.     else;
  851.         call SetState(0); # pilot turn
  852.         # flip card
  853.         call LastCardU(1);
  854.         timer PilotPlays, nDelay;
  855.     end_if;
  856. end;
  857.  
  858. # 3.9 system startup/shutdown
  859.  
  860. # start up game stuff
  861. #
  862. function startup;
  863.     variables;
  864.         numeric i;
  865.         numeric j;
  866.         numeric n;
  867.     end;
  868.     # init help
  869.     call InitHelp;
  870.     # init deck
  871.     call dc_InitDeck;
  872.     # init menu option items
  873.     call SetPush(1);
  874.     call SetSound(1);
  875.     call SetSpeed(1);
  876.     # columns=player 0-1, rows=card slot 0-5, 
  877.     #  total labels rows 8-9
  878.     # draw lines around play table
  879.     set frMain, pen, nfSlotX(2,0), nfSlotY(2,0);
  880.     draw frMain, line, 0, 8*nSlotH;
  881.     set frMain, pen, nfSlotX(0,8), nfSlotY(0,8);
  882.      draw frMain, line, 2*nSlotW, 0;
  883.     # move card and player labels into place
  884.     i=0;
  885.     while i<2;
  886.         j=0;
  887.         while j<nMax;
  888.             # move card labels into place
  889.             n=nfIndex(i,j);
  890.             move lbFace[n], nfOb2X(i,j), nfOb2Y(i,j);
  891.             j=j+1;
  892.         end_while;
  893.         # move total labels into place
  894.         move lbWhoseHand[i], nfOb2X(i,8), nfOb2Y(i,8);
  895.         move lbTotal[i], nfOb2X(i,9), nfOb2Y(i,9);
  896.         i=i+1;
  897.     end_while;
  898.     put lbWhoseHand[0],"You";
  899.     put lbWhoseHand[1],"Pilot";
  900.     # move other visual objects into place
  901.     move lbBetLabel, nfOb2X(2,0), nfOb2Y(2,0);
  902.     move lbBet, nfOb2X(2,1), nfOb2Y(2,1);
  903.     move slBet, nfOb1X(2,1), nfOb1Y(2,1);
  904.     move lbStatus, nfOb1X(2,6), nfOb1Y(2,6);
  905.     move lbWinsLabel, nfOb2X(2,8), nfOb2Y(2,8);
  906.     # BH1=0, so used Ob2 origin position for these OB1's
  907.     move lbWins, nfOb2X(2,9), nfOb2Y(2,9);
  908.     move btHit, nfOb1X(0,10), nfOb1Y(0,10);
  909.     move btStay, nfOb1X(1,10), nfOb1Y(1,10);
  910.     # display intial wins
  911.     nWins=0;
  912.     put lbWins,0;
  913.     # force redraw in case movement caused any problems
  914.     show frMain;
  915.     # init new game
  916.     call SetState(1);
  917. end;
  918.  
  919.  
  920.