| 35 | } |
| 36 | |
| 37 | float BestResponse::printExploitability(shared_ptr<GameTreeNode> root, int iterationCount, float initial_pot, |
| 38 | uint64_t initialBoard) { |
| 39 | if(this->reach_probs.empty()) |
| 40 | this->reach_probs = vector<vector<float>> (this->player_number); |
| 41 | |
| 42 | qDebug().noquote() << QString::fromStdString(tfm::format(QObject::tr("Iter: %s").toStdString().c_str(),iterationCount)); |
| 43 | float exploitible = 0; |
| 44 | // 构造双方初始reach probs(按照手牌weights) |
| 45 | for (int player_id = 0; player_id < this->player_number; player_id++) { |
| 46 | if(reach_probs[player_id].empty()) { |
| 47 | reach_probs[player_id] = vector<float>(private_combos[player_id].size()); |
| 48 | } |
| 49 | for (int hc = 0; hc < private_combos[player_id].size(); hc++) |
| 50 | reach_probs[player_id][hc] = private_combos[player_id][hc].weight; |
| 51 | } |
| 52 | |
| 53 | for (int player_id = 0; player_id < this->player_number; player_id++) { |
| 54 | float player_exploitability = getBestReponseEv(root, player_id, reach_probs, initialBoard, 0); |
| 55 | exploitible += player_exploitability; |
| 56 | qDebug().noquote() << (QString::fromStdString(tfm::format(QObject::tr("player %s exploitability %s").toStdString().c_str(), player_id, player_exploitability))); |
| 57 | } |
| 58 | float total_exploitability = exploitible / this->player_number / initial_pot * 100; |
| 59 | qDebug().noquote() << QString::fromStdString(tfm::format(QObject::tr("Total exploitability %s precent").toStdString().c_str(), total_exploitability)); |
| 60 | return total_exploitability; |
| 61 | } |
| 62 | |
| 63 | float BestResponse::getBestReponseEv(shared_ptr<GameTreeNode> node, int player, vector<vector<float>> reach_probs, |
| 64 | uint64_t initialBoard, int deal) { |