// 自己组合1096680 双组合690908400
#include "numeral211/game_numeral211.hpp"
#include "numeral211/hand_numeral211.hpp"
#include "numeral211/strategy_numeral211.hpp"
#include "numeral211/regret_strategy_numeral211.hpp"
#include "numeral211/evaluator_numeral211.hpp"
#include "template/algorithm/recursive/multithread_cs_mccfr.hpp"
#include "template/algorithm/iteration/multithread_best_response.hpp"
#include <boost/program_options.hpp>
#include <iostream>
// #include "template/domain_independent/abstraction.h"
#include "template/hand_work/abstr_hits.hpp"
#include "template/hand_work/full_resolution_abstr.hpp"
#include "template/hand_work/xriso_abstr.hpp"
#include "template/hand_work/suite_abstr.hpp"
#include <filesystem>

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>

#include "template/domain_independent/multithread_player_terminal_reach.hpp"

namespace po = boost::program_options;
using Poker_t = Numeral211;

// #include <cmath>
// bool assert_reach(const PlayerTerminalReach<Poker_t>& old_reach, const MultithreadPlayerTerminalReach<Poker_t>& new_reach){
//     double difference = 0;
//     double max_difference = 0; int u0 = -1; uint64_t iso0;
//     double max_difference_ratio = 0; int u1 = -1; uint64_t iso1;
//     int64_t difference_count = 0;
//     int64_t node_count = 0;
//     for(int u = Game<Poker_t>::num_internal; u < Game<Poker_t>::num_total; ++u) {
//         int r = Game<Poker_t>::round[u];
//         uint64_t priso_size = Hand<Poker_t>::get_isomorphism_size(r, 0);
//         node_count += priso_size;
//         for (uint64_t iso = 0; iso < priso_size; ++iso) {
//             double old_reach_d = old_reach.get_reach(u, iso);
//             double new_reach_d = new_reach.get_reach(u, iso);
//             if (fabsl(old_reach_d-new_reach_d) > overall_define::epsilon){
//                 difference += fabsl(old_reach_d-new_reach_d);
//                 ++difference_count;
//                 if (fabsl(old_reach_d-new_reach_d)/(old_reach_d+new_reach_d) > max_difference_ratio) {
//                     max_difference_ratio = fabsl(old_reach_d-new_reach_d)/(old_reach_d+new_reach_d);
//                     u0 = u; iso0 = iso;
//                 }
//                 if (fabsl(old_reach_d-new_reach_d) > max_difference) {
//                     max_difference = fabsl(old_reach_d-new_reach_d);
//                     u1 = u; iso1 = iso;
//                 }
//             }

//         }
//     }
//     printf("%d, %ld, %d, %ld", u0, iso0, u1, iso1);
//     return true;
// }
// gdb --args ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 15555 --logs 15 
// nohup stdbuf -o0 ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 15555 --logs 15 &
// gdb --args ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 23007 --end 34052 --logs 2 
// nohup stdbuf -o0 ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 23007 --end 34052 --logs 2 &
// gdb --args ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 233570 --logs 22 
// nohup stdbuf -o0 ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 233570 --logs 22 &
// gdb --args ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 
// nohup stdbuf -o0 ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 50209 --logs 18 &
// gdb --args ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 34188 --logs 17 
// nohup stdbuf -o0 ./build/multithread_train_with_br_numeral211 --epoch_or_time epoch --sample_batch 1096680 --interval_linear_or_power power --start 73 --end 34188 --logs 17 &


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 0.1
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p1w2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p1w2.csv

// 0.2
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p0p1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p0p1.csv

// 0.3
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p0p0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_p0p0p0.csv

// 0.4
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_w0w1w2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_w0w1w2.csv

// 0.5
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22__r0r0r0_w0w0w1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22__r0r0r0_w0w0w1.csv

// 0.6
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_w0w0w0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_w0w0w0.csv

// 0.7
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_r0r1r2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_r0r1r2.csv

// 0.8
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_r0r0r1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0_r0r0r1.csv

// 0.9 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd753.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd753.csv

// 0.10  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd111.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd111.csv

// 0.11  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd1641.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd1641.csv

// 0.12  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd357.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0p1KrwEmd357.csv

// 0.13 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs1.csv

// 0.14  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs2.csv

// 0.15  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs3.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_Ehs3.csv

// 0.16 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd1.csv

// 0.17 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd2.csv

// 0.18 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd3.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_PaEmd3.csv

// 0.19
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd53KrwEmd753.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd53KrwEmd753.csv

// 0.20  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd11KrwEmd111.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd11KrwEmd111.csv

// 0.21  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd41KrwEmd1641.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd41KrwEmd1641.csv
    
// 0.22  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd57KrwEmd357.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0r0r0_r0KrwEmd57KrwEmd357.csv
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1.1
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2_r0r0r0.csv

// 1.2
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1_r0r0r0.csv

// 1.3
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0_r0r0r0.csv

// 1.4
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2_r0r0r0.csv

// 1.5
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1_r0r0r0.csv

// 1.6
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0_r0r0r0.csv

// 1.7
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2_r0r0r0.csv

// 1.8
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1_r0r0r0.csv

// 1.9 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd753_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd753_r0r0r0.csv

// 1.10  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd111_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd111_r0r0r0.csv

// 1.11  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd1641_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd1641_r0r0r0.csv

// 1.12  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd357_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd357_r0r0r0.csv

// 1.13 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs1_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs1_r0r0r0.csv

// 1.14  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs2_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs2_r0r0r0.csv

// 1.15  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs3_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs3_r0r0r0.csv

// 1.16 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd1_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd1_r0r0r0.csv

// 1.17  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd2_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd2_r0r0r0.csv

// 1.18  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd3_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd3_r0r0r0.csv

// 1.19
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd53KrwEmd753_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd53KrwEmd753_r0r0r0.csv

// 1.20  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd11KrwEmd111_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd11KrwEmd111_r0r0r0.csv

// 1.21  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd41KrwEmd1641_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd41KrwEmd1641_r0r0r0.csv
    
// 1.22  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd57KrwEmd357_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd57KrwEmd357_r0r0r0.csv
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 2.1
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2.csv

// 2.2
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1.csv

// 2.3
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0.csv

// 2.4
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2.csv

// 2.5
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1.csv

// 2.6
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0.csv

// 2.7
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2.csv

// 2.8
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1.csv

// 2.9
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0.csv
//////////////////
// 2.10 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd753.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd753.csv

// 2.11  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd111.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd111.csv

// 2.12  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd1641.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd1641.csv

// 2.13  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd357.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0p1KrwEmd357.csv

// 2.14 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs1.csv

// 2.15  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs2.csv

// 2.16  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs3.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_Ehs3.csv

// 2.17 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd1.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd1.csv

// 2.18 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd2.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd2.csv

// 2.19 
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd3.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_PaEmd3.csv

// 2.20  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd53KrwEmd753.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd53KrwEmd753.csv

// 2.21  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd11KrwEmd111.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd11KrwEmd111.csv

// 2.22  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd41KrwEmd1641.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd41KrwEmd1641.csv
    
// 2.23  
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd57KrwEmd357.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_50209_l18_r0KrwEmd57KrwEmd357.csv

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 3.1
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p1w2exploiter.csv

// 3.2
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p1exploiter.csv

// 3.3
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_p0p0p0exploiter.csv

// 3.4
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w1w2exploiter.csv

// 3.5
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w1exploiter.csv

// 3.6
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_w0w0w0exploiter.csv

// 3.7
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r1r2exploiter.csv

// 3.8
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r1exploiter.csv

// 3.9
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0exploiter.log
// tail -fn 30 ./data/numeral211/remote/multithread_train_with_br_sb1096680_ep_73_233570_l22_r0r0r0exploiter.csv

int main(int argc, char **argv){ // sample_batch, epoch, data_per_log, abs1, abs2
// --epoch_or_time epoch --sample_batch 5000 --interval 300 --logs 10
#ifndef DEBUG
    boost::log::core::get()->set_filter (boost::log::trivial::severity >= boost::log::trivial::info);
#endif
    std::filesystem::create_directories("data/numeral211/remote/");
    std::string program_name = "data/numeral211/remote/multithread_train_with_br";
    bool b_epoch = false;
    bool b_time = false;
    bool b_linear = false;
    bool b_power = false;
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("sample_batch", po::value<uint64_t>())
        ("epoch_or_time", po::value<std::string>())
        ("interval_linear_or_power", po::value<std::string>())
        ("start", po::value<int32_t>())
        ("end", po::value<int32_t>())
        ("logs", po::value<uint64_t>())
    ;

    po::variables_map vm;        
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    uint64_t sample_batch;
    uint64_t logs;
    int32_t et_start;
    int32_t et_end;

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 0;
    }

    if (vm.count("sample_batch")){
        sample_batch = vm["sample_batch"].as<uint64_t>();
        program_name += "_sb" + std::to_string(sample_batch);
    }
    else
        return 0;

    if (vm.count("epoch_or_time") && vm["epoch_or_time"].as< std::string>() == "epoch") {
        b_epoch = true;
        program_name += "_e";
    }
    else if (vm.count("epoch_or_time") && vm["epoch_or_time"].as< std::string >() == "time") {
        b_time = true;
        program_name += "_t";
    }
    else {
        return 0;
    }

    if (vm.count("interval_linear_or_power") && vm["interval_linear_or_power"].as< std::string>() == "linear") {
        b_linear = true;
        program_name += "l";
    }
    else if (vm.count("interval_linear_or_power") && vm["interval_linear_or_power"].as< std::string >() == "power") {
        b_power = true;
        program_name += "p";
    }
    else {
        return 0;
    }

    if (vm.count("start")){
        et_start = vm["start"].as<int32_t>();
        program_name += "_" + std::to_string(et_start);
    }
    else
        return 0;

    if (vm.count("end")){
        et_end = vm["end"].as<int32_t>();
        program_name += "_" + std::to_string(et_end);
    }
    else
        return 0;

    if (vm.count("logs")){
        logs = vm["logs"].as<uint64_t>();
        program_name += "_l";
        program_name += std::to_string(logs);
        assert(logs > 1);
    }
    else
        return 0;

    /* 为全局随机数生成器赋种子 */
    overall_define::mt_rand.seed(0);

    /* 初始化各种与博弈游戏相关的常数 */
    Game<Poker_t>::init();
    Hand<Poker_t>::init();
    Evaluator<Poker_t>::init();
    printf("num_internal: %d\n", Game<Poker_t>::num_internal);
    printf("num_chance: %d\n", Game<Poker_t>::num_chance);
    printf("num_terminal: %d\n", Game<Poker_t>::num_terminal);
    printf("num_total: %d\n", Game<Poker_t>::num_total);

{
    assert(Game<Poker_t>::initialized);
    assert(Hand<Poker_t>::initialized);
    assert(Evaluator<Poker_t>::initialized);


    /* 为博弈参与人创建抽象 */
    printf("creating abstractions...\n");

    // 0.###
    // Abstraction<Poker_t> abstraction[Poker_t::num_players]{
    //     Abstraction<Poker_t>(argc > argc_ ? argv[4] : nullptr),
    //     Abstraction<Poker_t>(argc > argc_ ? argv[5] : nullptr),
    // };

//////////////////////////////////////////////////////////////////////////////////////////////////
    //// 1. p0 exploit p1
    // // 0.1._r0r0r0_p0p1w2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_p0p1w2";

    // // 0.2._r0r0r0_p0p0p1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_p0p0p1";

    // // 0.3._r0r0r0_p0p0p0
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_p0p0p0";

    // // 0.4._r0r0r0_w0w1w2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_w0w1w2";

    // // 0.5._r0r0r0_w0w0w1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_w0w0w1";

    // // 0.6._r0r0r0_w0w0w0
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_w0w0w0";

    // // 0.7 _r0r0r0_r0r1r2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 1, 2}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0r1r2";

    // // 0.8._r0r0r0_r0r0r1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 1}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0r0r1";

    // // 0.9  _r0r0r0_r0p1KrwEmd753
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0p1KrwEmd753";

    // // 0.10  _r0r0r0_r0p1KrwEmd111
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0p1KrwEmd111";

    // // 0.11  _r0r0r0_r0p1KrwEmd1641
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0p1KrwEmd1641";
    
    // // 0.12  _r0r0r0_r0p1KrwEmd357
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0p1KrwEmd357";

    // // 0.13  _r0r0r0_Ehs1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs1";

    // // 0.14  _r0r0r0_Ehs2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs2";

    // // 0.15  _r0r0r0_Ehs3
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs3";

    // // 0.16  _r0r0r0_PaEmd1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd1";

    // // 0.17  _r0r0r0_PaEmd2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd2";

    // // 0.18  _r0r0r0_PaEmd3
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd3";

    // // 0.19  _r0r0r0_r0KrwEmd53KrwEmd753
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd53KrwEmd753";

    // // 0.20  _r0r0r0_r0KrwEmd11KrwEmd111
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd11KrwEmd111";

    // // 0.21  _r0r0r0_r0KrwEmd41KrwEmd1641
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/7"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd41KrwEmd1641";
    
    // // 0.22  _r0r0r0_r0KrwEmd57KrwEmd357
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/8"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd57KrwEmd357";

    // // 0.23  _r0r0r0_Ehs4
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs4";

    // // 0.24  _r0r0r0_Ehs5
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs5";

    // // 0.25  _r0r0r0_Ehs6
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_Ehs6";

    // // 0.26  _r0r0r0_PaEmd4
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd4";

    // // 0.27  _r0r0r0_PaEmd5
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd5";

    // // 0.28  _r0r0r0_PaEmd6
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd6";

    // // 0.29  _r0r0r0_r0KrwEmd53-753
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/9"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd53-753";

    // // 0.30  _r0r0r0_r0KrwEmd11-111
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/10"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd11-111";

    // // 0.31  _r0r0r0_r0KrwEmd41-1641
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/11"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd41-1641";
    
    // // 0.32  _r0r0r0_r0KrwEmd57-357
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/12"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_r0KrwEmd57-357";

    // // 0.33  _r0r0r0_PaEmd7
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/7"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd7";

    // // 0.34  _r0r0r0_PaEmd8
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/8"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0_PaEmd8";
///////////////////////////////////////////////////////////////////////////////////
    //// 1. p1 exploit p0
    // // 1.1._p0p1w2_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p1w2_r0r0r0";

    // // 1.2._p0p0p1_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p0p1_r0r0r0";

    // // 1.3._p0p0p0_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p0p0_r0r0r0";

    // // 1.4._w0w1w2_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w1w2_r0r0r0";

    // // 1.5._w0w0w1_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w0w1_r0r0r0";

    // // 1.6._w0w0w0_r0r0r0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w0w0_r0r0r0";

    // // 1.7 _r0r1r2_r0r0r0
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 1, 2}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r1r2_r0r0r0";

    // // 1.8._r0r0r1_r0r0r0
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 1}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r1_r0r0r0";

    // // 1.9  _r0p1KrwEmd753_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/1"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd753_r0r0r0";

    // // 1.10  _r0p1KrwEmd111_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/2"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd111_r0r0r0";

    // // 1.11  _r0p1KrwEmd1641_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/3"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd1641_r0r0r0";
    
    // // 1.12  _r0p1KrwEmd357_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/4"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd357_r0r0r0";

    // // 1.13  _Ehs1_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/1"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs1_r0r0r0";

    // // 1.14  _Ehs2_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/2"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs2_r0r0r0";

    // // 1.15  _Ehs3_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/3"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs3_r0r0r0";

    // // 1.16  _PaEmd1_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/1"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd1_r0r0r0";

    // // 1.17  _PaEmd2_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/2"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd2_r0r0r0";

    // // 1.18  _PaEmd3_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/3"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd3_r0r0r0";

    // // 1.19  _r0KrwEmd53KrwEmd753_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/5"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd53KrwEmd753_r0r0r0";

    // // 1.20  _r0KrwEmd11KrwEmd111_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/6"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd11KrwEmd111_r0r0r0";

    // // 1.21  _r0KrwEmd41KrwEmd1641_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/7"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd41KrwEmd1641_r0r0r0";
    
    // // 1.22  _r0KrwEmd57KrwEmd357_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/8"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd57KrwEmd357_r0r0r0";

    // // 1.23  _Ehs4_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/4"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs4_r0r0r0";

    // // 1.24  _Ehs5_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/5"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs5_r0r0r0";

    // // 1.25  _Ehs6_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/6"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs6_r0r0r0";

    // // 1.26  _PaEmd4_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/4"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd4_r0r0r0";

    // // 1.27  _PaEmd5_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/5"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd5_r0r0r0";

    // // 1.28  _PaEmd6_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/6"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd6_r0r0r0";

    // // 1.29  _r0KrwEmd53-753_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/9"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd53-753_r0r0r0";

    // // 1.30  _r0KrwEmd11-111_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/10"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd11-111_r0r0r0";

    // // 1.31  _r0KrwEmd41-1641_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/11"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd41-1641_r0r0r0";
    
    // // 1.32  _r0KrwEmd57-357_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/12"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd57-357_r0r0r0";

    // // 1.33  _PaEmd7_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/7"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd7_r0r0r0";

    // // 1.34  _PaEmd8_r0r0r0
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/8"));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd8_r0r0r0";
///////////////////////////////////////////////////////////
    ///// 2. exploit each other
    // // 2.1._p0p1w2
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p1w2";

    // // 2.2._p0p0p1
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p0p1";

    // // 2.3._p0p0p0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_p0p0p0";

    // // 2.4._w0w1w2
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w1w2";

    // // 2.5._w0w0w1
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w0w1";

    // // 2.6._w0w0w0
    // Abstraction<Poker_t> train0_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> train1_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}}, "Numeral211"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_w0w0w0";

    //  // 2.7._r0r1r2
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 1, 2}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 1, 2}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r1r2";

    //  // 2.8._r0r0r1
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 1}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 1}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r1";

    //  // 2.9._r0r0r0
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0r0r0";

    // // 2.10  _r0p1KrwEmd753
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/1"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd753";

    // // 2.11  _r0p1KrwEmd111
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/2"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd111";

    // // 2.12  _r0p1KrwEmd1641
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/3"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd1641";
    
    // // 2.13  _r0p1KrwEmd357
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/4"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0p1KrwEmd357";

    // // 2.14  _Ehs1
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/1"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs1";

    // // 2.15  _Ehs2
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/2"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs2";

    // // 2.16  _Ehs3
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/3"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs3";

    // // 2.17  _PaEmd1
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/1"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/1"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd1";

    // // 2.18  _PaEmd2
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/2"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/2"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd2";

    // // 2.19  _PaEmd3
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/3"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/3"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd3";

    // // 2.20  _r0KrwEmd53KrwEmd753
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/5"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd53KrwEmd753";

    // // 2.21  _r0KrwEmd11KrwEmd111
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/6"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd11KrwEmd111";

    // // 2.22  _r0KrwEmd41KrwEmd1641
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/7"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/7"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd41KrwEmd1641";
    
    // // 2.23  _r0KrwEmd57KrwEmd357
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/8"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/8"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd57KrwEmd357";

    // // 2.24  _Ehs4
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/4"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs4";

    // // 2.25  _Ehs5
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/5"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs5";

    // // 2.26  _Ehs6
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/6"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/Ehs/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_Ehs6";

    // // 2.27  _PaEmd4
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/4"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/4"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd4";

    // // 2.28  _PaEmd5
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/5"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/5"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd5";

    // // 2.29  _PaEmd6
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/6"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/6"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd6";

    // // 2.30  _r0KrwEmd53-753
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/9"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/9"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd53-753";

    // // 2.31  _r0KrwEmd11-111
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/10"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/10"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd11-111";

    // // 2.32  _r0KrwEmd41-1641
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/11"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/11"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd41-1641";
    
    // // 2.33  _r0KrwEmd57-357
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/12"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/KrwEmd/12"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_r0KrwEmd57-357";

    // // 2.34  _PaEmd7
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/7"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/7"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd7";

    // // 2.35  _PaEmd8
    // Abstraction<Poker_t> train0_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/8"));
    // Abstraction<Poker_t> train1_abstr(SuiteAbstr<Poker_t>("data/CustomCluster/Numeral211/PaEmd/8"));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // program_name += "_PaEmd8";
//////////////////////////////////////////////////////////////////////////////////////////////////
    ///// 3. certain exploiter
    // // 3.1._p0p1w2exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // program_name += "_p0p1w2exploiter";

    // // 3.2._p0p0p1exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 1}}, "Numeral211"));
    // program_name += "_p0p0p1exploiter";

    // // 3.3._p0p0p0exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}, ResolutionConfig{PotentialTrace, 0}}, "Numeral211"));
    // program_name += "_p0p0p0exploiter";

    // // 3.4._w0w1w2exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}, ResolutionConfig{WinningTrace, 2}}, "Numeral211"));
    // program_name += "_w0w1w2exploiter";

    // // 3.5._w0w0w1exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 1}}, "Numeral211"));
    // program_name += "_w0w0w1exploiter";

    // // 3.6._w0w0w0exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(FullResolutionAbstr<Poker_t>({ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}, ResolutionConfig{WinningTrace, 0}}, "Numeral211"));
    // program_name += "_w0w0w0exploiter";

    //  // 3.7._r0r1r2exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 1, 2}));
    // program_name += "_r0r1r2exploiter";

    //  // 3.8._r0r0r1exploiter
    // Abstraction<Poker_t> train0_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> train1_abstr(XrisoAbstr<Poker_t>({0, 0, 0}));
    // Abstraction<Poker_t> exploiter_abstr(XrisoAbstr<Poker_t>({0, 0, 1}));
    // program_name += "_r0r0r1exploiter";
//////////////////////////////////////////////////////////////////////////////////////////////////

    // 4.5  r0p1KrwEmd753_r0r0r0
    // 4.6  r0p1KrwEmd111_r0r0r0
    // 4.7  r0p1KrwEmd1641_r0r0r0
    // 4.9  r0p1KrwEmd357_r0r0r0
    // 4.10 r0p1KrwEmd753
    // 4.11 r0p1KrwEmd111
    // 4.12 r0p1KrwEmd1641
    // 4.13 r0p1KrwEmd357

    Abstraction<Poker_t> *train_abstr[]{&train0_abstr, &train1_abstr};
    PrAbstrHits<Poker_t> brabstrhits;
    brabstrhits.perfect_recall_config(exploiter_abstr);

    /* open file*/
    FILE * log_file = fopen((program_name+".log").c_str(), "wt");
    assert(log_file);
    FILE * csv_file = fopen((program_name+".csv").c_str(), "wt");
    assert(log_file);

    fprintf(log_file, "num_internal: %d\n", Game<Poker_t>::num_internal);
    fprintf(log_file, "num_chance: %d\n", Game<Poker_t>::num_chance);
    fprintf(log_file, "num_terminal: %d\n", Game<Poker_t>::num_terminal);
    fprintf(log_file, "num_total: %d\n", Game<Poker_t>::num_total);


    fprintf(log_file, "train0 abstraction:\n");
    train_abstr[0]->print(log_file);
    fprintf(log_file, "train1 abstraction:\n");
    train_abstr[1]->print(log_file);
    fprintf(log_file, "br abstraction:\n");
    exploiter_abstr.print(log_file);
    fprintf(log_file, "br abstrhits:\n");
    brabstrhits.print(log_file);

    /* initialize memory  */
    fprintf(log_file, "initializing strategies...\n");
    std::shared_ptr<RegretStrategy<Poker_t, true>> sp_regret_strat[2] = {
        std::make_shared<RegretStrategy<Poker_t, true>>( 0
                                                 , train_abstr[0]->bucket_sizes()),
        std::make_shared<RegretStrategy<Poker_t, true>>( 1
                                                 , train_abstr[1]->bucket_sizes()),
    };

    // train variable
    MultithreadCS_MCCFR<Poker_t> m_cs_mccfr(sample_batch, overall_define::num_threads, sp_regret_strat);
    double acfr[Poker_t::num_players];
    std::memset(acfr, 0, sizeof(double)*Poker_t::num_players);
    uint64_t (*buckets)[Poker_t::num_players][Poker_t::num_rounds];
    type::rank_t (*ranks)[Poker_t::num_players];
    buckets = new uint64_t[sample_batch][Poker_t::num_players][Poker_t::num_rounds];
    ranks = new type::rank_t[sample_batch][Poker_t::num_players];

    // br varialbe
    MultithreadPlayerTerminalReach<Poker_t> m_player_terminal_reaches[Poker_t::num_players] {
        MultithreadPlayerTerminalReach<Poker_t>(overall_define::num_threads),
        MultithreadPlayerTerminalReach<Poker_t>(overall_define::num_threads),
    };
    std::function<double(int, uint64_t)> get_reach_funcs[Poker_t::num_players]{
        std::bind(&MultithreadPlayerTerminalReach<Poker_t>::get_reach, &m_player_terminal_reaches[0], std::placeholders::_1, std::placeholders::_2), 
        std::bind(&MultithreadPlayerTerminalReach<Poker_t>::get_reach, &m_player_terminal_reaches[1], std::placeholders::_1, std::placeholders::_2)
    };
    Strategy<Poker_t> strategy[Poker_t::num_players];
    MultithreadBestResponse<Poker_t> best_response(overall_define::num_threads);

    time_t time_start_stamp;
    time_start_stamp = time(NULL);
    double time_upto = difftime( time(NULL), time_start_stamp);
    fprintf(log_file, "train start: %s\n", ctime(&time_start_stamp));

    // fprintf(csv_file, "updates, upto-updates-time, p1acfr, p2acfr, p1br, p2br, upto-br-time\n");
    uint64_t epk = 0;
    for(uint64_t l = 0; l<logs; ++l) {

        do {
            ++epk;
            for (uint64_t b = 0; b < sample_batch; ++b) {
                /* deal hand */
                type::card_t holes[Poker_t::num_players][Poker_t::hole_len[Poker_t::num_rounds-1]], board[Poker_t::board_len[Poker_t::num_rounds-1]];
                deal_all_hand<Poker_t>(holes, board);

                std::vector<Hand<Poker_t>> hand;
                hand.reserve(Poker_t::num_players);
                /*construct hand and abstract the hand*/
                for (int j = 0; j < Poker_t::num_players; ++j){
                    hand.emplace_back(holes[j], board, 0);
                    for(int r = 0; r < Poker_t::num_rounds; ++r){
                        if(r>0)
                            hand[j].add_deal(holes[j]+Poker_t::hole_len[r-1], board+Poker_t::board_len[r-1]);
                        buckets[b][j][r] = train_abstr[j]->abstract_view(hand[j]);
                    }
                }

                // evaluate ranks
                Evaluator<Poker_t>::evaluate_ranks(holes, board, ranks[b]);
            }

            //updata regret
            double reach[Poker_t::num_players];
            std::fill(reach, reach+Poker_t::num_players, 1.);
            double ev[Poker_t::num_players], cfr[Poker_t::num_players];

            m_cs_mccfr.train( buckets
                            , ranks
                            , reach
                            , ev
                            , cfr
                            );

            /* update average CFR*/
            if (epk == 1){
                std::memcpy(acfr, cfr, sizeof(double)*Poker_t::num_players);
            }
            else {
                for (int j=0; j<Poker_t::num_players; ++j){
                    acfr[j] = 1. * (epk-1)/epk * (acfr[j] + cfr[j]/(epk-1));
                }
            }
            time_upto = difftime( time(NULL), time_start_stamp);
        } while ( (b_epoch && b_linear && (epk-et_start) * (logs-1) < (et_end-et_start) * l) 
               || (b_time && b_linear && (time_upto-et_start) * (logs-1) < (et_end-et_start) * l)
               || (b_epoch && b_power && log(1.0*epk/et_start) * (logs-1) < log(1.0*et_end/et_start) * l)
               || (b_time && b_power && log(1.0*time_upto/et_start) * (logs-1) < log(1.0*et_end/et_start) * l));

        fprintf(csv_file, "updates, %lu, time, %.1fs, ", epk * sample_batch, difftime( time(NULL), time_start_stamp));
        
        // acfr
        for(int p = 0;  p < Poker_t::num_players; ++p) {
            fprintf(csv_file, "acfr%d, %.2lf, ", p, acfr[p]);
        }
        fflush(csv_file);

        // // #0 player 0 exploit player 1 
        // m_player_terminal_reaches[1].compute_reach(*sp_regret_strat[1], *train_abstr[1]);
        // double player_br = best_response.compute_br(get_reach_funcs, 0, brabstrhits);
        // fprintf(csv_file, "player%dexploit_his_opponents, %lf, ", 0, player_br);
        // fflush(csv_file);

        // // #1 player 1 exploit player 0
        // m_player_terminal_reaches[0].compute_reach(*sp_regret_strat[0], *train_abstr[0]);
        // double player_br = best_response.compute_br(get_reach_funcs, 1, brabstrhits);
        // fprintf(csv_file, "player%dexploit_his_opponents, %lf, ", 1, player_br);
        // fflush(csv_file);

        // // #2 exploit each other 
        // for(int p = 0; p < Poker_t::num_players; ++p) {
        //     m_player_terminal_reaches[p].compute_reach(*sp_regret_strat[p], *train_abstr[p]);
        //     // assert(assert_reach(*p_player_terminal_reachs[p], m_player_terminal_reaches[p]));
        // }
        // for(int p = 0; p < Poker_t::num_players; ++p) {
        //     double player_br = best_response.compute_br(get_reach_funcs, p, brabstrhits);
        //     fprintf(csv_file, "player%dexploit_his_opponents, %lf, ", p, player_br);
        //     fflush(csv_file);
        // }
        /////////////////////

        fprintf(csv_file, "time, %.1fs\n", difftime( time(NULL), time_start_stamp));
        fflush(csv_file);
    }

    delete[] buckets;
    delete[] ranks;

    time_t time_end_stamp = time(NULL);
    printf("train end: %s\n", ctime(&time_end_stamp));

    printf("saving strategies\n");
    std::string output_str[Poker_t::num_players]{
        "data/numeral211/1numeral211",
        "data/numeral211/2numeral211",
    };
    for (int i = 0; i < Poker_t::num_players; ++i){

        printf("saving player %d to %s...\n", i+1, output_str[i].c_str());

        /* open file*/
        FILE * file = fopen(output_str[i].c_str(), "wt");
        assert(file);

        /* write the header */
        time_t time_start_stamp = time(NULL);
        train_abstr[i]->print(file);
        fprintf(file, 
            "#\n"
            "# numeral211 strategy %s\n"
            "# made on:       %s"
            "# epochs:    %lu\n"
            "#\n",
            output_str[i].c_str(),
            ctime(&time_start_stamp),
            epk);

        /* recover the strategy */
        Strategy<Poker_t> strat;
        strat.recover_average_strategy(*train_abstr[i], *sp_regret_strat[i]);

        // /* write the strategy */
        // strat.save_txt(file);

        /* close the file */
        fclose(file);
    }
    fprintf(log_file, "end:  %fs", difftime( time(NULL), time_start_stamp));

    fclose(csv_file);
    fclose(log_file);
}
    Evaluator<Poker_t>::free();
    Hand<Poker_t>::free();
    Game<Poker_t>::free();
}

// #include <yaml-cpp/yaml.h>
// #include <iostream>
// #include <fstream>
// #include <vector>

// int main() {
//     try {
//         YAML::Node config = YAML::LoadFile("alg_configs.yaml");
//         for (size_t street = 0; street < config["alg_configs"].size(); ++street) {
//             YAML::Node alg = config["alg_configs"][street];
//             std::cout << "Index: " << street << std::endl;
//             std::cout << "Type: " << alg["type"].as<std::string>() << std::endl;
//             std::cout << "Recall from: " << alg["recall_from"].as<size_t>() << std::endl;
//         }
//     } catch (const std::exception& e) {
//         std::cerr << "Exception caught: " << e.what() << std::endl;
//     }

//     return 0;
// }