Poker-AI.org

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

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: GameTreez
PostPosted: Wed Jan 15, 2014 4:39 pm 
Offline
Junior Member

Joined: Wed Sep 04, 2013 6:05 pm
Posts: 47
Hi Guyz,

I'm finishing my AI for FLHUNE but i'm stucked at how to represent gametree and save it to binary... The problem is coming from the fact for each round the number of buckets for regret and average probability will be different specially in perfect recall... so I will have to store it in array of different size...

So for the moment I have a class Node :

Code:
class Node
{
   public:
      Node();
      int PreviousAction;
      int PreviousNode;
      int NextNodes[3];
      int Round;
      int Player;
      int Pot[2];
      
      double* regret;
      double* average_probability;

};


All nodes are stored in an array :

Code:
NodeArray = new Node[8801];


And based on the round I will create a dynamic array to store regret and average probability...

Till now that's fine but how will I save it ?

Are you working in a different way ?

any suggestion to my problem ?

Thanks for your help.

MrNice


Top
 Profile  
 
 Post subject: Re: GameTreez
PostPosted: Thu Jan 16, 2014 7:01 pm 
Offline
New Member

Joined: Mon Mar 04, 2013 7:48 pm
Posts: 7
My data is stored in huge structs, which can be saved/loaded directly to disk.
I'm mostly writing in plain C.
I am aware that I'm wasting a bit of memory by impossible nodes (each node will be a triple even if fold or raise is not possible) but memory is cheap, and with my current abstraction, the tables are only about 3GB each.
Since I have perfect recall of the actions, I don't need to store the pot, player etc..

#define MAX_FLOP_INDEX 1000
#define MAX_TURN_INDEX 1000
#define MAX_RIVER_INDEX 98
#define MAX_TURN_BOARDS 6
#define MAX_FLOP_BOARDS 18
#define MAX_PREFLOP_ACTION_NODES 8
#define MAX_ACTION_NODES 10
#define MAX_HISTORY_NODES 9
#define MAX_PREFLOP_HISTORY_NODES 7

typedef struct
{
double preflop[MAX_PREFLOP_INDEX][MAX_PREFLOP_ACTION_NODES][3];
double flop [MAX_FLOP_INDEX][MAX_FLOP_BOARDS][MAX_PREFLOP_HISTORY_NODES][MAX_ACTION_NODES][3];
double turn [MAX_TURN_INDEX][MAX_FLOP_BOARDS][MAX_TURN_BOARDS][MAX_PREFLOP_HISTORY_NODES][MAX_HISTORY_NODES][MAX_ACTION_NODES][3];
double river[MAX_RIVER_INDEX][MAX_FLOP_BOARDS][MAX_TURN_BOARDS][MAX_PREFLOP_HISTORY_NODES][MAX_HISTORY_NODES][MAX_HISTORY_NODES][MAX_ACTION_NODES][3];
}


Top
 Profile  
 
 Post subject: Re: GameTreez
PostPosted: Fri Jan 17, 2014 9:09 am 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
Why not add the following methods to Node:
int noBuckets() // returns the length of regret
void save() // write noBuckets, regret and av_probability to a file, then invokes save() on each child node
void restore() // read noBuckets, regret and av_probability from file, then invokes restore() on each child node

// Assume tree is constructed before restore is invoked. Maybe restore can be put in constructor.


Top
 Profile  
 
 Post subject: Re: GameTreez
PostPosted: Fri Jan 17, 2014 7:34 pm 
Offline
Junior Member

Joined: Wed Sep 04, 2013 6:05 pm
Posts: 47
Hi Guyz,


Thanks for your advices.


I will post my code shortly (I hope :D)

Regards,


Top
 Profile  
 
 Post subject: Re: GameTreez
PostPosted: Mon Jan 27, 2014 12:22 pm 
Offline
Junior Member

Joined: Wed Sep 04, 2013 6:05 pm
Posts: 47
Hey Guyz,

As promised my code :

Code:

NodeArray = new Node[8801];

void initializeGameTree()
{
   NodeArray = new Node[8801];
}


void save_average_probability(char* filename)
{
   int maxbucket[4] = {8, 8, 8, 8};
   fstream f_bin(filename, ios::out|ios::binary);
   
   f_bin.seekg(ios::beg);
   
   for(int i=0; i<8801; i++)
   {
      f_bin.write((char*)NodeArray[i].average_probability, (getnumberofbuckets(NodeArray[i].Round, maxbucket, 2, 3))*sizeof(double));
      
   }
   
   f_bin.close();
}

void load_average_probability(char* filename)
{
   int maxbucket[4] = {8, 8, 8, 8};
   fstream f_bin(filename, ios::in|ios::binary);
   
   f_bin.seekg(ios::beg);
   
   for(int i=0; i<8801; i++)
   {
      NodeArray[i].regret = new double[getnumberofbuckets(NodeArray[i].Round, maxbucket, 2, 3)];
      NodeArray[i].average_probability = new double[getnumberofbuckets(NodeArray[i].Round, maxbucket, 2, 3)];
      f_bin.read((char*)NodeArray[i].average_probability, (getnumberofbuckets(NodeArray[i].Round, maxbucket, 2, 3))*sizeof(double));
   }
   
   f_bin.close();
}

void saveGameTreetoFile(char* filename)
{
   fstream f_bin(filename, ios::out|ios::binary);
   
   f_bin.seekg(ios::beg);
   
   f_bin.write((char*)NodeArray, 8801*sizeof(Node));
   
   f_bin.close();

}
void loadGameTreefromFile(char* filename)
{

   fstream f_bin(filename, ios::in|ios::binary);
   
   f_bin.seekg(ios::beg);
   
   f_bin.read((char*)NodeArray, 8801*sizeof(Node));
   
   f_bin.close();

}



Saving the tree :
Code:
//Create GameTree
//Compute regret and average probability
saveGameTreetoFile("FLNU_GameTree.bin");
save_average_probability("PR-8-8-8-8-750k_avgprob.bin");


Loading the tree :
Code:
initializeGameTree();
loadGameTreefromFile("FLNU_GameTree.bin");
load_average_probability("PR-8-8-8-8-750k_avgprob.bin");



Thanks for your help and advices ;)


MrNice


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 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