Poker-AI.org

Poker AI and Botting Discussion Forum
It is currently Mon Nov 13, 2023 6:49 pm

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Mon Aug 26, 2013 2:56 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
First of all im not very experienced coder. I have done different little coding tasks for all my life and i know the basics. This is just project to have fun with.

Im building my own bot and im going to create script language that the program can read and understand (more of this later). This is for easier implementation of different strategies and playing styles and also makes my next step a little easier. First i want to build my own "client" that simulates hands just like in online poker rooms and for each player i can use different scripted gameplay, make them play against each other and find out mistakes and weaknesses. The "client" would write hand history files so Holdem Manager can read it. This simulation would be easiest, fastest and safest way for stage one testing. Now i need help with this "client", there is different ways of doing this but i think my way is not the best and would need some pointers.

I build this "client" with C++ and i build my deck with a simple string array and store all the cards in it like: cards[0] = {"Ah"} and so on..
Now this is just the deck where i find the cards that is delt to players and to the table. I have boolean array for delt cards and every time i deal a new card it checks if the card is allready used. Now this works fine until i need to figure out what all players have at showdown. I could have integer array for suits (0 = heart, 1 = diamonds and so on..) but this is where i need help. In what way should i build the deck, deal cards and see what everyone have so it wont get too complicated. I can post parts of my code here if needed.

If i get help and make progress i will post here all my steps and ask for more help. I think this thread would work as a tutorial for other beginners too.

This is the code so far (using c++):
Code:
#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
   
   // CARD DECK
   std::string cards[52] = {"Ah","Kh","Qh","Jh","Th","9h","8h","7h","6h","5h","4h","3h","2h",
   "Ad","Kd","Qd","Jd","Td","9d","8d","7d","6d","5d","4d","3d","2d",
   "Ac","Kc","Qc","Jc","Tc","9c","8c","7c","6c","5c","4c","3c","2c",
   "As","Ks","Qs","Js","Ts","9s","8s","7s","6s","5s","4s","3s","2s"};
   
   // USED CARDS (0 = unused, 1 = used)
   int used_cards[52] = {0};
   
   std::string player1cards[2];
   std::string player2cards[2];
   std::string player3cards[2];
   std::string player4cards[2];
   std::string player5cards[2];
   std::string player6cards[2];
   std::string boardcards[5];
   
   srand((unsigned)time(0));
   
   cout << endl;
   
   /////////////////////////////////
   // MOVE BUTTON AND POST BLINDS //
   /////////////////////////////////
   
   // DEALING HOLE CARDS TO PLAYERS
   int counter1 = 0;
   while (counter1 < 6)
    {
      cout << "Player" << counter1 + 1 << ": ";
   
      int counter2 = 0;
      while (counter2 < 2)
      {
         int random_card = (rand()%52);
         while (used_cards[random_card] == 1)
         {
            random_card = (rand()%52);
         }
         if (counter1 == 0)
            {
            player1cards[counter2] = cards[random_card];
            cout << player1cards[counter2] << " ";
            }
         else if (counter1 == 1)
            {
            player2cards[counter2] = cards[random_card];
            cout << player2cards[counter2] << " ";
            }
         else if (counter1 == 2)
            {
            player3cards[counter2] = cards[random_card];
            cout << player3cards[counter2] << " ";
            }
         else if (counter1 == 3)
            {
            player4cards[counter2] = cards[random_card];
            cout << player4cards[counter2] << " ";
            }
         else if (counter1 == 4)
            {
            player5cards[counter2] = cards[random_card];
            cout << player5cards[counter2] << " ";
            }
         else if (counter1 == 5)
            {
            player6cards[counter2] = cards[random_card];
            cout << player6cards[counter2] << " ";
            }
            
         used_cards[random_card] = 1;
         counter2++;
      }
      
      cout << endl;
      counter1++;
    }
   
   /////////////////////
   // PREFLOP ACTIONS //
   /////////////////////
   
   // DEALING FLOP
   cout << endl;
   cout << "Board: ";
   
   int counter3 = 0;
   while (counter3 < 3)
   {
      int random_card = (rand()%52);
      while (used_cards[random_card] == 1)
      {
         random_card = (rand()%52);
      }
   
      boardcards[counter3] = cards[random_card];
      cout << boardcards[counter3] << " ";
         
      used_cards[random_card] = 1;
      counter3++;
   }
   
   //////////////////
   // FLOP ACTIONS //
   //////////////////
   
   // DEALING TURN
   int random_card = (rand()%52);
   while (used_cards[random_card] == 1)
   {
      random_card = (rand()%52);
   }
   
   boardcards[3] = cards[random_card];
   cout << boardcards[3] << " ";
   used_cards[random_card] = 1;
   
   //////////////////
   // TURN ACTIONS //
   //////////////////
   
   // DEALING RIVER
   random_card = (rand()%52);
   while (used_cards[random_card] == 1)
   {
      random_card = (rand()%52);
   }
   
   boardcards[4] = cards[random_card];
   cout << boardcards[4] << " ";
   used_cards[random_card] = 1;
   
   ///////////////////
   // RIVER ACTIONS //
   ///////////////////
   
   ///////////////////
   // RANKING HANDS //
   ///////////////////
   
   /////////////////
   // PAY WINNERS //
   /////////////////
   
   // DEBUGGING
   cout << endl;
   // CALCULATE USED CARDS
   int cards_used = 0;
   int counter4 = 0;
   while (counter4 < 52)
   {
      if (used_cards[counter4] == 1)
         cards_used++;
      counter4++;
   }
   
   cout << endl;
   cout << "Used cards (0 = unused, 1 = used): " << cards_used << endl;
   
   // PRINTING ALL USED AND UNUSED CARDS
   int counter5 = 0;
   while (counter5 < 52)
    {
      cout << "Card " << counter5 + 1 << ": " << used_cards[counter5] << " (" << cards[counter5] << ")" << endl;
        counter5++;
    }
   
   return 0;
}


Last edited by TheCrow on Mon Aug 26, 2013 10:43 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Aug 26, 2013 9:29 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
I decided to do this with c++ instead. And here is my way of dealing cards. It only deals hole cards to one player and marks used cards so it cant deal same card again. Please comment and give pointers if im doing something wrong that might get me in trouble later ie. defining hand strenghts and so on...

Here is the code:
* in first topic *


Last edited by TheCrow on Mon Aug 26, 2013 10:44 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Aug 26, 2013 9:54 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
Ok, writing a little more code. Now it deals cards to 6 players. Counts all used cards (should be 12) and prints hole cards and all the used and unused cards.

Here is the code:
* in first topic *


Top
 Profile  
 
PostPosted: Tue Aug 27, 2013 3:06 pm 
Offline
Junior Member

Joined: Wed May 15, 2013 10:15 pm
Posts: 42
Maybe you should consider to open a GitHub repository and post the code there, and only the documentation and your thought here.


Top
 Profile  
 
PostPosted: Tue Aug 27, 2013 6:47 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
shadehs wrote:
Maybe you should consider to open a GitHub repository and post the code there, and only the documentation and your thought here.

Thats a new for me. Have to take a look.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 6:17 pm 
Offline
Veteran Member

Joined: Wed Mar 20, 2013 1:43 am
Posts: 267
A better approach than using Strings, would be to use ints. Use ints from 1-52 or 0-51 to represent a card. This is faster, takes less memory and is easier to use with most hand evaluators and you will probably want to use some handevaluator code from the internet, because they are hard to program and easy to do wrong.

Of course this isnt a big issue, but if you want to test millions of hands in bot vs bot matches to get a good samplesize, it might help a little.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 8:04 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
Thanks for your replay,

I need the strings anyway for log files and i have started my hand evaluation code already and its tricky but i think i can do it. Straights are pain in the ass at the moment. Reason i post this here is to get help to optimize my code and people to throw red flags if im doing something wrong.

Here is the functions for defining cards from strings:
Code:
int cardstrenght(std::string card)
{
   int strenght;
   if ((card == "Ah") || (card == "Ad") || (card == "Ac") || (card == "As"))
      strenght = 14;
   if ((card == "Kh") || (card == "Kd") || (card == "Kc") || (card == "Ks"))
      strenght = 13;
   if ((card == "Qh") || (card == "Qd") || (card == "Qc") || (card == "Qs"))
      strenght = 12;
   if ((card == "Jh") || (card == "Jd") || (card == "Jc") || (card == "Js"))
      strenght = 11;
   if ((card == "Th") || (card == "Td") || (card == "Tc") || (card == "Ts"))
      strenght = 10;
   if ((card == "9h") || (card == "9d") || (card == "9c") || (card == "9s"))
      strenght = 9;
   if ((card == "8h") || (card == "8d") || (card == "8c") || (card == "8s"))
      strenght = 8;
   if ((card == "7h") || (card == "7d") || (card == "7c") || (card == "7s"))
      strenght = 7;
   if ((card == "6h") || (card == "6d") || (card == "6c") || (card == "6s"))
      strenght = 6;
   if ((card == "5h") || (card == "5d") || (card == "5c") || (card == "5s"))
      strenght = 5;
   if ((card == "4h") || (card == "4d") || (card == "4c") || (card == "4s"))
      strenght = 4;
   if ((card == "3h") || (card == "3d") || (card == "3c") || (card == "3s"))
      strenght = 3;
   if ((card == "2h") || (card == "2d") || (card == "2c") || (card == "2s"))
      strenght = 2;
   return strenght;
}

int cardsuit(std::string card)
{
   int suit;
   if ((card == "Ah") || (card == "Kh") || (card == "Qh") || (card == "Jh") || (card == "Th") || (card == "9h") || (card == "8h") || (card == "7h") || (card == "6h") || (card == "5h") || (card == "4h") || (card == "3h") || (card == "2h"))
      suit = 1;
   if ((card == "Ad") || (card == "Kd") || (card == "Qd") || (card == "Jd") || (card == "Td") || (card == "9d") || (card == "8d") || (card == "7d") || (card == "6d") || (card == "5d") || (card == "4d") || (card == "3d") || (card == "2d"))
      suit = 2;
   if ((card == "Ac") || (card == "Kc") || (card == "Qc") || (card == "Jc") || (card == "Tc") || (card == "9c") || (card == "8c") || (card == "7c") || (card == "6c") || (card == "5c") || (card == "4c") || (card == "3c") || (card == "2c"))
      suit = 3;
   if ((card == "As") || (card == "Ks") || (card == "Qs") || (card == "Js") || (card == "Ts") || (card == "9s") || (card == "8s") || (card == "7s") || (card == "6s") || (card == "5s") || (card == "4s") || (card == "3s") || (card == "2s"))
      suit = 4;
   return suit;
}


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 8:25 pm 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
There are lots of good evaluators already available.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 8:32 pm 
Offline
Veteran Member

Joined: Wed Mar 20, 2013 1:43 am
Posts: 267
spears wrote:
There are lots of good evaluators already available.


true

http://www.codingthewheel.com/archives/ ... r-roundup/

I have spent about a week writing my own evaluator, this was before I knew poker-ai. I was happy about every little improvement in speed, but in the end it was still 1000 times slower than Pokerstove. There are ideas, like LUTs, that you usually dont think of, when you just start writing an algorithm, that makes sense intuivelly.

The speed of the evaluator might not be that crucial for your cleint, you will only need it once per hand to see who won, but you will need a fast one for your bot anyway.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 8:49 pm 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
You could cover much of your initial post by using Poker Academy. It's in java so you'd have to interface to that if you are using c++ but that is possible. Alternatively you could write in java, which would be a lot easier than c++. Or even better, write in Scala

I don't hold with the idea of a scripting language myself, but you really insist, you might consider taking inspiration from open holdem, or just using it outright.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 9:01 pm 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
I want to use scripting language so its easier and faster to write different styles of play and let them play against each other. I can leave the actual code alone and just write the scripts. And in my opininon C++ is not that hard.


Top
 Profile  
 
PostPosted: Fri Aug 30, 2013 9:15 pm 
Offline
Junior Member

Joined: Wed May 15, 2013 10:15 pm
Posts: 42
spears wrote:
I don't hold with the idea of a scripting language myself, but you really insist, you might consider taking inspiration from open holdem, or just using it outright.


I am using OpenHoldem, but the only scripts that i use are the ones that calls my dll functions.
All the AI code it's written with C++ and C#, and it's working pretty good.
Also evaluators are externals, databases, etc...


Top
 Profile  
 
PostPosted: Sat Aug 31, 2013 11:09 am 
Offline
New Member

Joined: Tue Aug 20, 2013 11:32 am
Posts: 7
I will try some of the evaluators. I also want to use my Holdem Manager database without starting Holdem Manager, is this possible? Can someone write guide for this?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group