Help using Base SAS procedures

Teaching my computer to beat me at poker

Reply
Occasional Contributor
Posts: 5

Teaching my computer to beat me at poker

Hi,

I have recently begun very slow process of getting to know and (eventually) mastering SAS for work. Instead of using the technique I've been using (looking at old code written before me and trying to follow it), I've decided that a much more engaging way to learn is to create for myself a project that sounds interesting and then complete it in SAS. The project I decided on is a way of getting my computer to be able to (over time) always beat me at poker. Boy what a rabbit hole I have jumped down.

I detailed my project on paper- in essence, the program needs to know all possible hand combinations, what combinations are possible given what's known on the board (Texan Holdem is the game), the rank/strength of hands for both lists, the odds of winning, and whether or not and how much to bet given a particular pot amount. Easy, huh?

No. I am stupid for thinking I can get through this. But, I am also one of those idiots who won't stop trying until it kills me /gets me fired. What I have come up with on my own (and when i say come up with, I of course mean found on Google) is a nifty little macro by user Hai.kuo that generates all possible hands AND ranks them in order of strength- very cool stuff (it can be found here; PM me if the link ever breaks and I'll send over the code)

Now, what I need to do is find a way to adapt that list to what cards are on the table. Basically, I need to limit the list down to what is possible with the shown cards (I'll worry about the cards in hand after I figure this out) to see what combinations are possible for ANY player to have. I am unsure how to do this. I am thinking about something in the data step that limits output to any combination including the cards on the table. The problem I am having is, since it's holdem, it has to be any combination of hand which include n minus 2 of the cards shown. For instance, on the turn the table cards are (04H, 06C, 09C, 10S); I need every combination that contains AT LEAST two of the cards in that set. And that is my rub- I have know idea how to get them.

If anyone has any ideas of a procedure that I can use, please let me know- any help is appreciated! And I am sorry if this is too long, not a proper topic, or the incorrect board to put this in- I am relatively new to the site and and still getting my bearings! 

Super User
Posts: 19,822

Re: Teaching my computer to beat me at poker

SAS Super FREQ
Posts: 3,753

Re: Teaching my computer to beat me at poker

Welcome to SAS! I think it is great that you have found a fun project to learn a new computer language.  I, too, like to learn programming by taking on interesting projects.

When I teach programming, one advice I give my students is to start with a problem for which you know the answer. Otherwise, how do you know whether your program is performing correctly?  With that in mind, I suggest that a simpler game (tic-tac-toe anyone?) might be more fun to pursue. In the past I've programmed Tic-Tac-Toe, Hangman, Yatzee, and Connect Four.

Another factor is that the strength of Base SAS is in data manipulation and analysis. You can use the DATA step as a general-purpose programming language, but you might find the SAS/IML language more flexible for sophisticated applications. Here are some games I've solved in SAS. You might want to choose one of these:

1. Dice game of "Craps": http://blogs.sas.com/content/iml/2012/10/04/dice-probabilities-and-the-game-of-craps.html

2. Card shuffling: http://blogs.sas.com/content/iml/2011/04/13/a-statistical-model-of-card-shuffling.html

3. The Jumble word puzzle: http://blogs.sas.com/content/iml/2010/10/15/solving-scrambled-word-puzzles.html

4. The Game of Life: http://blogs.sas.com/content/iml/2014/10/15/game-of-life.html

5. The Cryptoquote: http://blogs.sas.com/content/iml/2014/10/29/frequency-analysis-cryptoquote.html

Occasional Contributor
Posts: 5

Re: Teaching my computer to beat me at poker

Hi Rick!

Yes, I had realized almost instantly after starting my little project that I should have started with something a bit simpler, but now that I'm in it I'm going to try to trudge along Smiley Wink

I have been looking at your games though, it will be fun to pick them apart and get all those 'aha!' moments when I finally figure out whats going on in them!

Super User
Posts: 11,343

Re: Teaching my computer to beat me at poker

It's been awhile since I've seen any Texas Hold'em so I may not have quite exactly what you need but the following program creates all of the hands possible with 3 player cards and 5 shared pairing one player card with 4 from the shared, 2 player cards and 3 shared, and 3 player cards with 2 shared.

You could drop all of the loop counter variables, the pcomb and scomb and possibly everything except the H variables. The exercise for the interested reader is what to do with each smaller set of cards as the information becomes known at each round.

data possible;
      /* array p represents 3 cards held by player*/
      array p $ p1-p3  ('05S','KH','QD');
      /* and s for shared cards*/
      array s $ s1-s5  ('03C','10S','JH','09D','02H');
      array h $ h1-h5 ; /* the "hand" to evaluate*/
      do pc= 1 to 3; /* how many of the players cards are used*/
        
         pcomb=comb(3,pc);   /* determine number of combinations of players card to consider*/
         do j= 1 to pcomb;
            /* make sure the "hand" is empty*/
            call missing(of h

  • );
                /* Select a combination of size PC from the cards*/
                call allcomb(j,pc, of p
  • );
                /* copy the selected player cards to the 'hand', the first PC number values are the selected ones*/
                do m= 1 to pc;
                   h= p;
                end;
                /* combine with ALL combinations of the shared cards of size 5-pc*/
                scomb=comb(5,5-pc); /* number of combinations from shared cards*/
                do k=1 to scomb;
                   call allcomb(k,5-pc, of s
  • );
                   /* copy the selected SHARED cards to the 'hand'*/
                   do m= 1 to (5-pc);
                      h[m+pc]= s[m+pc];
                   end;
  •             output;
                end;
            
             end; /* j loop*/
          end; /* pc loop*/
    run;

    Occasional Contributor
    Posts: 5

    Re: Teaching my computer to beat me at poker

    Hi ballarw,

    This looks interesting! I am sad to say that I am at home and will not have access to SAS till work on Monday, but this looks pretty neat- and thank you for adding in all the comments! I will admit that one area I am struggling with is arrays (which was one impetus for taking on the project), and I've never used the comb function, so this should be fun to diagnose. The only problem is that there are 2 cards in a hand (not 3), but it should be an easy enough fix. Hopefully this will be enough to get me going and learning, so thank you very much!

    I will update with any progress I make with it =)

    Super User
    Posts: 19,822

    Re: Teaching my computer to beat me at poker

    You can download SAS UE for home Smiley Wink

    Super User
    Posts: 11,343

    Re: Teaching my computer to beat me at poker

    The tricky part is actually the ALLCOMB function which shifts the original list of items around.

    Warning: combinations of numbers go up quickly. This approach may not be practical for some purposes involving more than 30 items.

    Occasional Contributor
    Posts: 5

    Re: Teaching my computer to beat me at poker

    Good point- I realized that this was computing every single combination of all the cards, not just 5 card hands. See, learning already! I'm pretty sure I can just use the output produced by haikuo bian to solve that problem, hopefully I can start producing some results soon.

    Occasional Contributor
    Posts: 5

    Re: Teaching my computer to beat me at poker

    So, I tried using the above code- worked just as it should, thanks ballardw! I am trying to plan around and modify it now, which involves setting up all possible combinations of those cards. So, when it says:

    data possible;

          /* array p represents 3 cards held by player*/

          array p $ p1-p3  ('05S','KH','QD');

          /* and s for shared cards*/

          array s $ s1-s5  ('03C','10S','JH','09D','02H');

          array h $ h1-h5 ; /* the "hand" to evaluate*/

          do pc= 1 to 3; /* how many of the players cards are used*/

    I replaced the s array for all possible cards (52) and then used array p to see what combinations were possible. The problem I'm getting is that it says ALLPERM can't handle more than 20 variables- am I not specifying something correctly, or does this mean what it says it does?

    ERROR: The ALLPERM routine cannot permute more than 20

           variables, but 52 variables were specified.

    If this is the case then it appears that my project is doomed, at least down this line of thought. But I am assuming I do not know enough about the function in general (probably an understatement), and was wondering if anyone has run into this error before?

    In case you want to see the code I am currently trying to run:

    data possible;

          /* array p represents 3 cards held by player*/

          array p $ p1-p5  ('C02','S12','H14','D05','H08');

          /* and s for shared cards*/

          array s $ s1-s52  (&HANDS.);

          array h $ h1-h5 ; /* the "hand" to evaluate*/

          do pc= 3 to 5; /* how many of the players cards are used*/

            

             pcomb=comb(5,pc);   /* determine number of combinations of players card to consider*/

             do j= 1 to pcomb;

                /* make sure the "hand" is empty*/

                call missing(of h

  • );
  •             /* Select a combination of size PC from the cards*/

                call allcomb(j,pc, of p

  • );
  •             /* copy the selected player cards to the 'hand', the first PC number values are the selected ones*/

                do m= 1 to pc;

                   h= p;

                end;

                /* combine with ALL combinations of the shared cards of size 5-pc*/

                scomb=comb(52,52-pc); /* number of combinations from shared cards*/

                do k=1 to scomb;

                   call allcomb(k,52-pc, of s

  • );
  •                /* copy the selected SHARED cards to the 'hand'*/

                   do m= 1 to (5-pc);

                      h[m+pc]= s[m+pc];

                   end;

                output;

                end;

            

             end; /* j loop*/

          end; /* pc loop*/

    run;

    Ask a Question
    Discussion stats
    • 9 replies
    • 430 views
    • 3 likes
    • 4 in conversation