home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1986 / 02 / jones.feb < prev    next >
Text File  |  1986-02-27  |  19KB  |  690 lines

  1.  
  2.         LISTING 1 - Draw Poker Program written in Ada
  3.  
  4. begin
  5.   Open_New(STOCK);
  6.   loop
  7.     put("How many dollars do you want to bet? "); get(WAGER);
  8.     exit when WAGER = 0;
  9.     Shuffle(STOCK);
  10.     Open_New(PLAYERS_HAND);
  11.     for i in 1 .. 5 loop
  12.       Deal_A_Card(PLAYERS_HAND,STOCK);
  13.     end loop;
  14.     put(PLAYERS_HAND);
  15.     Discard_From(PLAYERS_HAND);
  16.     loop
  17.       exit when Filled(PLAYERS_HAND);
  18.       Deal_A_Card(PLAYERS_HAND, STOCK);
  19.     end loop;
  20.     put(PLAYERS_HAND);
  21.     VALUE := Value_Of(PLAYERS_HAND);
  22.     case VALUE is
  23.       when ROYAL_FLUSH => PAYOFF := 250;
  24.       when STRAIGHT_FLUSH => PAYOFF := 50;
  25.       when FOUR_OF_A_KIND => PAYOFF := 25;
  26.       when FULL_HOUSE => PAYOFF := 6;
  27.       when FLUSH => PAYOFF := 5;
  28.       when STRAIGHT => PAYOFF := 4;
  29.       when THREE_OF_A_KIND => PAYOFF := 3;
  30.       when TWO_PAIR => PAYOFF := 2;
  31.       when others => PAYOFF := 0;
  32.     end case;
  33.     if PAYOFF = 0
  34.       then put_line("Sorry, you lose.");
  35.       else put("You have ");put(VALUE);put("!");new_line;
  36.            put("You win"); put(WAGER*PAYOFF); put_line(" dollars!");
  37.     end if;
  38.   end loop;
  39. end Draw_Poker;
  40.  
  41. ------------------------------------------------------------
  42.  
  43.         LISTING 2 - The general form of a procedure
  44.  
  45.         procedure *1 is
  46.           *2
  47.         begin
  48.           *3
  49.         exception
  50.           *4
  51.         end *5;
  52.  
  53. -----------------------------------------------------------------
  54.  
  55.         LISTING 3 - The Open_New procedure
  56.  
  57.   procedure Open_New(DECK : out Decks) is
  58.     i : integer := 0;
  59.     CARD : Cards;
  60.   begin
  61.     for S in Suits loop
  62.       for R in Ranks loop
  63.         CARD.SUIT := S;
  64.         CARD.RANK := R;
  65.         i := i+1;
  66.         DECK.FAN(i) := CARD;
  67.       end loop;
  68.     end loop;
  69.     DECK.CARDS_LEFT := i;
  70.     if i /= CARDS_IN_DECK then raise DECK_ERROR; end if;
  71.   exception
  72.     -- CONSTRAINT_ERROR or DECK_ERROR may be raised by this
  73.     -- procedure if the number of cards in a deck does not
  74.     -- equal the number of cards generated.
  75.     when DECK_ERROR | CONSTRAINT_ERROR =>
  76.       raise DECK_ERROR; -- convert all errors to DECK_ERROR;
  77.   end Open_New;
  78.  
  79.  
  80.  
  81. -------------------------------------------------------------
  82.         Listing 4 (Part A) - PLAYING_CARDS package specification
  83.  
  84.  
  85. --                      CARDS.ADA
  86. --                      19 JULY 1984
  87. --                      DO-WHILE JONES
  88.  
  89. package PLAYING_CARDS is
  90.  
  91.   CARDS_IN_DECK : constant integer := 52;
  92.   CARDS_IN_HAND : constant integer := 5;
  93.  
  94.   DECK_ERROR    : exception; -- raised by Open_New
  95.   DECK_EXHAUSED : exception; -- raised by Deal_A_Card
  96.   HAND_FULL     : exception; -- raised by Deal_A_Card
  97.  
  98.   type Suits is (CLUBS, DIAMONDS, HEARTS, SPADES);
  99.   type Ranks is (TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
  100.     JACK, QUEEN, KING, ACE);
  101.  
  102.   type Cards is
  103.     record
  104.       SUIT : Suits;
  105.       RANK : Ranks;
  106.     end record;
  107.  
  108.   type Fans is array(integer range <>) of Cards;
  109.   type Status is array(integer range <>) of boolean;
  110.  
  111.   type Decks is
  112.     record
  113.       CARDS_LEFT : integer;
  114.       FAN        : Fans(1..CARDS_IN_DECK);
  115.     end record;
  116.  
  117.   type Hands is
  118.     record
  119.       PLAYED : Status(1..CARDS_IN_HAND);
  120.       FAN    : Fans(1..CARDS_IN_HAND);
  121.     end record;
  122.  
  123.   function Card_Number(X : integer; HAND : Hands) return Cards;
  124.   function Played_Card_Number(X : integer; HAND : Hands) return boolean;
  125.  
  126.   function Suit_of(CARD : Cards) return Suits;
  127.   function Rank_of(CARD : Cards) return Ranks;
  128.  
  129.  
  130.  
  131.   procedure put(SUIT : Suits);
  132.   procedure put(RANK : Ranks);
  133.   procedure put(CARD : Cards);
  134.   procedure put(HAND : Hands);
  135.  
  136.  
  137.   procedure Open_New(DECK : out Decks);         -- create a new deck
  138.   procedure Shuffle(DECK : in out Decks);       -- shuffle a deck
  139.  
  140.   procedure Open_New(HAND : out Hands);         -- create a new hand
  141.   procedure Sort(HAND : in out Hands);  -- sort by rank, ignore suits
  142.   procedure Discard_From(HAND : in out Hands);
  143.   function Filled(HAND : Hands) return boolean; -- is the hand full?
  144.  
  145.   procedure Deal_A_Card(HAND : in out Hands; DECK : in out Decks);
  146.   
  147. end PLAYING_CARDS;
  148.  
  149. -------------------------------------------------------------
  150.         LISTING 4 (Part B) - PLAYING_CARDS package body
  151.  
  152.  
  153. --                      CARDB.ADA
  154. --                      19 JULY 1984
  155. --                      DO-WHILE JONES
  156.  
  157. with CON_IO; use CON_IO;
  158. with APL; use APL;
  159. package body PLAYING_CARDS is
  160.  
  161.   CONSTRAINT_ERROR : exception; -- required only by Maranatha A
  162.  
  163.   function Card_Number(X : integer; HAND : Hands) return Cards is
  164.   begin
  165.     return HAND.FAN(X);
  166.   end Card_Number;
  167.  
  168.   function Played_Card_Number(X : integer; HAND : Hands) return boolean is
  169.   begin
  170.     return HAND.PLAYED(X);
  171.   end Played_Card_Number;
  172.  
  173.   function Suit_of(CARD : Cards) return Suits is
  174.   begin
  175.     return CARD.SUIT;
  176.   end Suit_of;
  177.  
  178.   function Rank_of(CARD : Cards) return Ranks is
  179.   begin
  180.     return CARD.RANK;
  181.   end Rank_of;
  182.   
  183.   procedure put(SUIT : Suits) is
  184.   begin
  185.   case SUIT is
  186.     when CLUBS => put("CLUBS");
  187.     when DIAMONDS => put("DIAMONDS");
  188.     when HEARTS => put("HEARTS");
  189.     when SPADES => put("SPADES");
  190.   end case;
  191.   end put;
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.   procedure put(RANK : Ranks) is
  200.   begin
  201.   case RANK is
  202.     when TWO => put("TWO");
  203.     when THREE => put("THREE");
  204.     when FOUR => put("FOUR");
  205.     when FIVE => put("FIVE");
  206.     when SIX => put("SIX");
  207.     when SEVEN => put("SEVEN");
  208.     when EIGHT => put("EIGHT");
  209.     when NINE => put("NINE");
  210.     when TEN => put("TEN");
  211.     when JACK => put("JACK");
  212.     when QUEEN => put("QUEEN");
  213.     when KING => put("KING");
  214.     when ACE => put("ACE");
  215.   end case;
  216.   end put;
  217.  
  218.   procedure put(CARD : Cards) is
  219.     RANK : Ranks;
  220.     SUIT : Suits;
  221.   begin
  222.     put(Rank_of(CARD)); put(" of "); put(Suit_of(CARD));
  223.   end put;
  224.  
  225.   procedure put(HAND : Hands) is
  226.   begin
  227.   for i in 1..CARDS_IN_HAND loop
  228.     if Played_Card_Number(i,HAND) then
  229.       null; -- don't display a card that isn't there
  230.     else
  231.       put(Card_Number(i,HAND));
  232.       put("  "); -- separate cards with two blanks
  233.     end if;
  234.   end loop;
  235.   new_line;
  236.   end put;
  237.  
  238.  
  239.  
  240.  
  241.  
  242.   procedure Open_New(DECK : out Decks) is
  243.     i : integer := 0;
  244.     CARD : Cards;
  245.   begin
  246.     for S in Suits loop
  247.       for R in Ranks loop
  248.         CARD.SUIT := S;
  249.         CARD.RANK := R;
  250.         i := i+1;
  251.         DECK.FAN(i) := CARD;
  252.       end loop;
  253.     end loop;
  254.     DECK.CARDS_LEFT := i;
  255.     if i /= CARDS_IN_DECK then raise DECK_ERROR; end if;
  256.   exception
  257.     -- CONSTRAINT_ERROR or DECK_ERROR may be raised by this
  258.     -- procedure if the number of cards in a deck does not
  259.     -- equal the number of cards generated.
  260.     when DECK_ERROR | CONSTRAINT_ERROR =>
  261.       raise DECK_ERROR; -- convert all errors to DECK_ERROR;
  262.   end Open_New;
  263.  
  264.   procedure Shuffle(DECK : in out Decks) is
  265.     SEQUENCE : Random_Sequence(1..CARDS_IN_DECK);
  266.     TEMP     : DECKS;
  267.   begin
  268.     TEMP.CARDS_LEFT := CARDS_IN_DECK;
  269.     SEQUENCE := Deal(CARDS_IN_DECK, CARDS_IN_DECK);
  270.     for i in 1..CARDS_IN_DECK loop
  271.       TEMP.FAN(i) := DECK.FAN(SEQUENCE(i));
  272.     end loop;
  273.     DECK := TEMP;
  274.   end Shuffle;
  275.  
  276.  
  277.  
  278.  
  279.  
  280.   procedure Deal_A_Card(HAND : in out Hands; DECK : in out Decks) is
  281.     X : integer := 0;
  282.   begin
  283.     -- find an empty slot in the hand
  284.     loop
  285.       X := X+1;
  286.       if X > CARDS_IN_HAND then raise HAND_FULL; end if;
  287.       exit when Played_Card_Number(X, HAND);
  288.     end loop;
  289.     -- draw a card from the deck and put it in the empty slot
  290.     if DECK.CARDS_LEFT < 1
  291.       then raise DECK_EXHAUSED;
  292.       else DECK.CARDS_LEFT := DECK.CARDS_LEFT-1;
  293.     end if;
  294.     HAND.FAN(X) := DECK.FAN(CARDS_IN_DECK - DECK.CARDS_LEFT);
  295.     HAND.PLAYED(X) := FALSE;
  296.   end Deal_A_Card;
  297.  
  298.   procedure Sort(HAND : in out Hands) is
  299.     SORTED : boolean;
  300.     TEMP : Cards;
  301.   begin
  302.     loop
  303.       SORTED := TRUE;
  304.       for i in 1..CARDS_IN_HAND loop
  305.         if Rank_of(Card_Number(i, HAND)) > Rank_of(Card_Number(i+1, HAND)) then
  306.           TEMP := Card_Number(i, HAND);
  307.           HAND.FAN(i) := Card_Number(i+1, HAND);
  308.           HAND.FAN(i+1) := TEMP;
  309.           SORTED := FALSE;
  310.         end if;
  311.       end loop;
  312.     exit when SORTED;
  313.     end loop;
  314.   end Sort;
  315.   
  316.   procedure Open_New(HAND : out Hands) is
  317.   begin
  318.     for i in 1..CARDS_IN_HAND loop
  319.       HAND.PLAYED(i) := TRUE; -- hand is empty (all cards have been played)
  320.     end loop;
  321.   end Open_New;
  322.  
  323.  
  324.   procedure Discard_From(HAND : in out Hands) is
  325.     RESPONSE : character;
  326.   begin
  327.     for i in 1..CARDS_IN_HAND loop
  328.       put("Do you want to discard the ");
  329.       put(Card_Number(i, HAND));
  330.       put("? (Y/N) ");
  331.       get(RESPONSE); new_line;
  332.       if RESPONSE = 'Y' or RESPONSE = 'y'
  333.         then HAND.PLAYED(i) := TRUE;
  334.       end if;
  335.     end loop;
  336.   end Discard_From;
  337.  
  338.   function Filled(HAND : Hands) return boolean is
  339.   begin
  340.     for i in 1..CARDS_IN_HAND loop
  341.       if Played_Card_Number(i, HAND) then
  342.         return FALSE; -- if any card is played, hand is not filled
  343.       end if;
  344.     end loop;
  345.     return TRUE;  -- if no cards played, hand is filled
  346.   end Filled;
  347.  
  348. end PLAYING_CARDS;
  349.  
  350.  
  351.  
  352.         LISTING 5 (Part A) - APL package specification
  353.  
  354.  
  355. --                      APLS.ADA
  356. --                      20 JULY 1984
  357. --                      DO-WHILE JONES
  358.  
  359. --      This package simulates some APL functions.
  360.  
  361. --      Roll(X) returns a random integer in the range 1..X.
  362.  
  363. --      Deal(X,Y) returns a random sequence of X elements all
  364. --        of which are in the range 1..Y. No element appears
  365. --        twice in the random sequence.
  366.  
  367. package APL is
  368.  
  369.   subtype positive is integer range 1..integer'last;
  370.   -- The above line is not required in Ada.
  371.   -- (It is required for Maranatha A.)
  372.  
  373.   type Random_Sequence is array(positive range <>) of positive;
  374.  
  375.   function Roll(LIMIT : positive) return positive;
  376.  
  377.   function Deal(NUMBER, LIMIT : positive) return Random_Sequence;
  378.  
  379. end APL;
  380.  
  381.  
  382.  
  383.         LISTING 5 (Part B) - APL package body
  384.  
  385.  
  386. --                      APLB.ADA
  387. --                      20 JULY 1984
  388. --                      DO-WHILE JONES
  389.  
  390. --      This package simulates two APL functions.
  391.  
  392. --      Note: Roll uses the RND function which returns a random
  393. --      real number between 0.0 and 1.0. The RND function is
  394. --      implementation specific to Maranatha A.
  395.  
  396. package body APL is
  397.  
  398.   function Roll(LIMIT : positive) return positive is
  399.     RANDOM : float;
  400.   begin
  401.     RANDOM := float(LIMIT)*RND(0.0);  -- RND is implementation specific.
  402.     return positive(RANDOM+0.5);
  403.   end Roll;
  404.  
  405.   function Deal(NUMBER, LIMIT : positive) return Random_Sequence is
  406.     MAX    : positive := LIMIT;
  407.     RS     : Random_Sequence(1..NUMBER);
  408.     SOURCE : Random_Sequence(1..LIMIT);
  409.     RANDOM_INDEX : positive;
  410.   begin
  411.     for i in 1..LIMIT loop
  412.       SOURCE(i) := i; -- SOURCE has one of every number
  413.     end loop;
  414.     for i in 1..NUMBER loop
  415.       RANDOM_INDEX := Roll(MAX);
  416.       RS(i) := SOURCE(RANDOM_INDEX); -- pick a random number from SOURCE
  417.       for j in RANDOM_INDEX..MAX-1 loop
  418.         SOURCE(j) := SOURCE(j+1); -- remove that number from the SOURCE
  419.       end loop;
  420.       MAX := MAX-1; -- there is now 1 less number in the source array
  421.     end loop;
  422.     return RS;
  423.   end Deal;
  424.  
  425. end APL;
  426.  
  427.         LISTING 6 - Complete Draw Poker program
  428.  
  429.  
  430. --                      DPOKER.ADA
  431. --                      19 JULY 1984
  432. --                      DO-WHILE JONES
  433.  
  434. with CON_IO; use CON_IO;
  435. with PLAYING_CARDS; use PLAYING_CARDS;
  436. procedure Draw_Poker is
  437.  
  438.   type Values is (NOTHING, TWO_PAIR, THREE_OF_A_KIND, STRAIGHT,
  439.     FLUSH, FULL_HOUSE, FOUR_OF_A_KIND, STRAIGHT_FLUSH, ROYAL_FLUSH);
  440.  
  441.   STOCK         : Decks;
  442.   PLAYERS_HAND  : Hands;
  443.   WAGER, PAYOFF : integer;
  444.   VALUE         : Values;
  445.   
  446.   procedure put(X : Values) is
  447.   begin
  448.     case X is
  449.       when TWO_PAIR => put("Two Pair");
  450.       when THREE_OF_A_KIND => put("Three of a Kind");
  451.       when STRAIGHT => put("a Straight");
  452.       when FLUSH => put("a Flush");
  453.       when FULL_HOUSE => put("a Full House");
  454.       when FOUR_OF_A_KIND => put("Four of a Kind");
  455.       when STRAIGHT_FLUSH => put("a Straight Flush");
  456.       when ROYAL_FLUSH => put("a Royal Flush");
  457.       when NOTHING => put("a losing hand");
  458.     end case;
  459.   end put;
  460.  
  461.   function Value_of(HAND : Hands) return Values is separate;
  462.   
  463.  
  464.  
  465.  
  466.  
  467. begin
  468.   Open_New(STOCK);
  469. loop
  470.   put("How many dollars do you want to bet? "); get(WAGER);
  471.   exit when WAGER = 0;
  472.   Shuffle(STOCK);
  473.   Open_New(PLAYERS_HAND);
  474.   for i in 1 .. 5 loop
  475.     Deal_A_Card(PLAYERS_HAND,STOCK);
  476.   end loop;
  477.   put(PLAYERS_HAND);
  478.   Discard_From(PLAYERS_HAND);
  479.   loop
  480.     exit when Filled(PLAYERS_HAND);
  481.     Deal_A_Card(PLAYERS_HAND, STOCK);
  482.   end loop;
  483.   put(PLAYERS_HAND);
  484.   VALUE := Value_Of(PLAYERS_HAND);
  485.   case VALUE is
  486.     when ROYAL_FLUSH => PAYOFF := 250;
  487.     when STRAIGHT_FLUSH => PAYOFF := 50;
  488.     when FOUR_OF_A_KIND => PAYOFF := 25;
  489.     when FULL_HOUSE => PAYOFF := 6;
  490.     when FLUSH => PAYOFF := 5;
  491.     when STRAIGHT => PAYOFF := 4;
  492.     when THREE_OF_A_KIND => PAYOFF := 3;
  493.     when TWO_PAIR => PAYOFF := 2;
  494.     when others => PAYOFF := 0;
  495.   end case;
  496.   if PAYOFF = 0
  497.     then put_line("Sorry, you lose.");
  498.     else put("You have ");put(VALUE);put("!");new_line;
  499.          put("You win"); put(WAGER*PAYOFF); put_line(" dollars!");
  500.   end if;
  501. end loop;
  502. end Draw_Poker;
  503.  
  504.                 LISTING 7 - Value_of subprogram
  505.  
  506.  
  507. --                      VALUE.ADA
  508. --                      19 JULY 1984
  509. --                      DO-WHILE JONES
  510.  
  511.  
  512.   separate (Draw_Poker); -- real Ada doesn't have a semicolon here
  513.   function Value_of(HAND : Hands) return Values is
  514.  
  515.     PATTERN : String(1..CARDS_IN_HAND-1);
  516.     X : Hands;
  517.  
  518.     function Flush_in(HAND : Hands) return boolean is
  519.     begin
  520.       for i in 1..CARDS_IN_HAND-1 loop
  521.         if Suit_of(Card_Number(i, HAND)) /= Suit_of(Card_Number(i+1, HAND))
  522.           then return FALSE;
  523.         end if;
  524.       end loop;
  525.       return TRUE;
  526.     end Flush_in;
  527.   
  528.     function Straight_in(HAND : Hands) return boolean is
  529.     begin
  530.       for i in 1..CARDS_IN_HAND-1 loop
  531.         if Ranks'pos(Rank_of(Card_Numeer(i, HAND)))
  532.          /= Ranks'pos(Rank_of(Card_Number(i+1, HAND)))-1 then
  533.           return FALSE;
  534.         end if;
  535.       end loop;
  536.       return TRUE;
  537.     end Straight_in;
  538.   
  539.  
  540.  
  541.  
  542.  
  543.   begin
  544.     X := HAND; -- make a copy of HAND so it can be sorted
  545.     Sort(X);
  546.     for i in 1..CARDS_IN_HAND-1 loop
  547.       if Rank_of(Card_Number(i, X)) = Rank_of(Card_Number(i+1, X)) then
  548.         PATTERN(i) := 'S'; -- adjacent cards have SAME rank
  549.       else
  550.         PATTERN(i) := 'D'; -- adjacent cards have DIFFERENT rank
  551.       end if;
  552.     end loop;
  553.     if Flush_in(X) and Straight_in(X) then
  554.       if Rank_of(Card_Number(5, X)) = ACE then
  555.         return ROYAL_FLUSH;
  556.       else
  557.         return STRAIGHT_FLUSH;
  558.       end if;
  559.     end if;
  560.   
  561.     if PATTERN = "SSSD" or PATTERN = "DSSS" then
  562.       return FOUR_OF_A_KIND;
  563.     end if;
  564.   
  565.     if PATTERN = "SSDS" or PATTERN = "SDSS" then
  566.       return FULL_HOUSE;
  567.     end if;
  568.   
  569.     if Flush_in(X) then
  570.       return FLUSH;
  571.     end if;
  572.   
  573.     if Straight_in(X) then
  574.       return STRAIGHT;
  575.     end if;
  576.   
  577.     if PATTERN = "SSDD" or PATTERN = "DSSD" or PATTERN = "DDSS" then
  578.       return THREE_OF_A_KIND;
  579.     end if;
  580.   
  581.     if PATTERN = "SDSD" or PATTERN = "DSDS" or PATTERN = "SDDS" then
  582.       return TWO_PAIR;
  583.     end if;
  584.   
  585.     return NOTHING;
  586.   
  587.   end Value_of;
  588.  
  589.  
  590.  
  591.  
  592.         LISTING 8 - Corrected Value_of subprogram
  593.  
  594. --                      VALUE2.ADA
  595. --                      9 NOVEMBER 1984
  596. --                      DO-WHILE JONES
  597.  
  598. --      This revision recognizes that TWO, THREE, FOUR,
  599. --      FIVE, ACE is a straight (but not a royal flush).
  600.  
  601.  
  602.  
  603.   separate (Draw_Poker); -- real Ada doesn't have a semicolon
  604.   function Value_of(HAND : Hands) return Values is
  605.  
  606.     PATTERN : String(1..CARDS_IN_HAND-1);
  607.     X : Hands;
  608.  
  609.     function Flush_in(HAND : Hands) return boolean is
  610.     begin
  611.       for i in 1..CARDS_IN_HAND-1 loop
  612.         if Suit_of(Card_Number(i, HAND)) /= Suit_of(Card_Number(i+1, HAND))
  613.           then return FALSE;
  614.         end if;
  615.       end loop;
  616.       return TRUE;
  617.     end Flush_in;
  618.   
  619.     function Straight_in(HAND : Hands) return boolean is
  620.     -- HAND must already be sorted for this procedure to work
  621.     begin
  622.       if Rank_of(Card_Number(1,HAND)) = TWO   and
  623.          Rank_of(Card_Number(2,HAND)) = THREE and
  624.          Rank_of(Card_Number(3,HAND)) = FOUR  and
  625.          Rank_of(Card_Number(4,HAND)) = FIVE  and
  626.          Rank_of(Card_Number(5,HAND)) = ACE then
  627.            return TRUE;
  628.        end if;
  629.       for i in 1..CARDS_IN_HAND-1 loop
  630.         if Ranks'pos(Rank_of(Card_Number(i, HAND)))
  631.          /= Ranks'pos(Rank_of(Card_Number(i+1, HAND)))-1 then
  632.           return FALSE;
  633.         end if;
  634.       end loop;
  635.       return TRUE;
  636.     end Straight_in;
  637.   
  638.  
  639.  
  640.  
  641.  
  642.   begin
  643.     X := HAND; -- make a copy of HAND so it can be sorted
  644.     Sort(X);
  645.     for i in 1..CARDS_IN_HAND-1 loop
  646.       if Rank_of(Card_Number(i, X)) = Rank_of(Card_Number(i+1, X)) then
  647.         PATTERN(i) := 'S'; -- adjacent cards have SAME rank
  648.       else
  649.         PATTERN(i) := 'D'; -- adjacent cards have DIFFERENT rank
  650.       end if;
  651.     end loop;
  652.     if Flush_in(X) and Straight_in(X) then
  653.       if Rank_of(Card_Number(4, X)) = KING then
  654.         return ROYAL_FLUSH;
  655.       else
  656.         return STRAIGHT_FLUSH;
  657.       end if;
  658.     end if;
  659.   
  660.     if PATTERN = "SSSD" or PATTERN = "DSSS" then
  661.       return FOUR_OF_A_KIND;
  662.     end if;
  663.   
  664.     if PATTERN = "SSDS" or PATTERN = "SDSS" then
  665.       return FULL_HOUSE;
  666.     end if;
  667.   
  668.     if Flush_in(X) then
  669.       return FLUSH;
  670.     end if;
  671.   
  672.     if Straight_in(X) then
  673.       return STRAIGHT;
  674.     end if;
  675.   
  676.     if PATTERN = "SSDD" or PATTERN = "DSSD" or PATTERN = "DDSS" then
  677.       return THREE_OF_A_KIND;
  678.     end if;
  679.   
  680.     if PATTERN = "SDSD" or PATTERN = "DSDS" or PATTERN = "SDDS" then
  681.       return TWO_PAIR;
  682.     end if;
  683.   
  684.     return NOTHING;
  685.   
  686.   end Value_of;
  687. ;
  688.   
  689.   end Value_of;
  690.