| 78 | } |
| 79 | |
| 80 | void GameTree::buildChance(shared_ptr<ChanceNode> root,Rule rule){ |
| 81 | //节点上的下注额度 |
| 82 | double pot = (double)rule.get_pot(); |
| 83 | Rule nextrule = Rule(rule); |
| 84 | if(rule.current_round > 3)throw runtime_error(tfm::format("current round not valid : %d",rule.current_round)); |
| 85 | |
| 86 | shared_ptr<GameTreeNode> one_node; |
| 87 | if(rule.oop_commit == rule.ip_commit && rule.oop_commit == rule.stack) { |
| 88 | if(rule.current_round >= 3){ // 3 is river |
| 89 | double p1_commit = rule.ip_commit; |
| 90 | double p2_commit = rule.oop_commit; |
| 91 | double peace_getback = (p1_commit + p2_commit) / 2; |
| 92 | |
| 93 | |
| 94 | vector<vector<double>> payoffs(2); |
| 95 | payoffs[0] = {p2_commit, -p2_commit}; |
| 96 | payoffs[1] = {-p1_commit, p1_commit}; |
| 97 | vector<double> peace_getback_vec = {peace_getback - p1_commit, peace_getback - p2_commit}; |
| 98 | one_node = make_shared<ShowdownNode>(peace_getback_vec, payoffs, GameTreeNode::intToGameRound(rule.current_round), (double) rule.get_pot(), root); |
| 99 | }else { |
| 100 | nextrule.current_round += 1; |
| 101 | if(rule.current_round > 3)throw runtime_error(tfm::format("current round not valid : %d",rule.current_round)); |
| 102 | one_node = make_shared<ChanceNode>(nullptr, GameTreeNode::intToGameRound(rule.current_round + 1), (double) rule.get_pot(), root, this->deck.getCards()); |
| 103 | } |
| 104 | }else { |
| 105 | one_node = make_shared<ActionNode>(vector<GameActions>(), vector<shared_ptr<GameTreeNode>>(), 1, GameTreeNode::intToGameRound(rule.current_round), (double) rule.get_pot(), root); |
| 106 | } |
| 107 | if(rule.current_round > 3)throw runtime_error(tfm::format("current round not valid : %d",rule.current_round)); |
| 108 | this->__build(one_node,nextrule,"begin",0,0); |
| 109 | root->setChildren(one_node); |
| 110 | } |
| 111 | |
| 112 | void GameTree::buildAction(shared_ptr<ActionNode> root,Rule rule,string last_action,int check_times,int raise_times){ |
| 113 | // current player |