📄 bot.cpp
字号:
if (WantToReach()) {#ifdef BOT_DEBUG fprintf(stdout, "Bot want to reach\n");#endif } break; }#ifdef BOT_DEBUG fprintf(stdout, "=== CBot::BotThink() end ===\n");#endif}void CBot::UpdateStatus(){#ifdef BOT_DEBUG fprintf(stdout, "=== CBot::UpdateStatus() begin ===\n");#endif // TODO int i; // update tile danger value UpdateDanger(); for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_OPEN) { m_BotBrain.tiledanger[i] = 0; continue; } m_BotBrain.tiledanger[i] = TileDanger(m_Hand.m_Tiles[i].tile); } AnalyzeGoal(); SelectGoal();#ifdef BOT_DEBUG fprintf(stdout, "=== CBot::UpdateStatus() end ===\n");#endif}void CBot::UpdateDanger(){ int i, j, rest_kind[5][9], d[5][9], d2[5][9], n = 0; for (i = 0; i < 5; i++) { for (j = 0; j < 9; j++) { if (i < 3) { int value[] = {250, 440, 700, 800, 870, 800, 700, 440, 250}; m_BotBrain.danger[i][j] = value[j]; } else { m_BotBrain.danger[i][j] = 50; } rest_kind[i][j] = CTile::RemainingTile(CTile((TILESUIT_CHAR << i) | (j + 1))); d[i][j] = d2[i][j] = 0; } } for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_LOCKED) continue; rest_kind[m_Hand.m_Tiles[i].tile.index1()][m_Hand.m_Tiles[i].tile.index2()]--; } if (m_pOpponent->m_fReach) { bool reach = false; for (i = 0; i < m_iNumDiscarded; i++) { if (m_Discarded[i].flags & DT_OPPONENTREACH) { reach = true; } CTile &t = m_Discarded[i].tile; if (reach) { m_BotBrain.danger[t.index1()][t.index2()] = 0; } else { d[t.index1()][t.index2()] = 1; } d2[t.index1()][t.index2()] = 1; } reach = false; for (i = 0; i < m_pOpponent->m_iNumDiscarded; i++) { if (m_pOpponent->m_Discarded[i].flags & DT_REACH) { reach = true; } CTile &t = m_pOpponent->m_Discarded[i].tile; m_BotBrain.danger[t.index1()][t.index2()] = 0; if (!reach) { d[t.index1()][t.index2()] = 1; } d2[t.index1()][t.index2()] = 1; } for (i = 0; i < 3; i++) { if (d[i][1 - 1]) { m_BotBrain.danger[i][2 - 1] *= 4.2f / 4.4f; m_BotBrain.danger[i][3 - 1] *= 6.8f / 7.0f; m_BotBrain.danger[i][4 - 1] *= 6.9f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 9.0f / 8.7f; m_BotBrain.danger[i][6 - 1] *= 8.5f / 8.0f; } if (d[i][9 - 1]) { m_BotBrain.danger[i][8 - 1] *= 4.2f / 4.4f; m_BotBrain.danger[i][7 - 1] *= 6.8f / 7.0f; m_BotBrain.danger[i][6 - 1] *= 6.9f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 9.0f / 8.7f; m_BotBrain.danger[i][4 - 1] *= 8.5f / 8.0f; } if (d[i][2 - 1]) { m_BotBrain.danger[i][1 - 1] *= 1.4f / 2.5f; m_BotBrain.danger[i][3 - 1] *= 5.9f / 7.0f; m_BotBrain.danger[i][4 - 1] *= 8.2f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 7.5f / 8.7f; m_BotBrain.danger[i][6 - 1] *= 9.3f / 8.0f; } if (d[i][8 - 1]) { m_BotBrain.danger[i][9 - 1] *= 1.4f / 2.5f; m_BotBrain.danger[i][7 - 1] *= 5.9f / 7.0f; m_BotBrain.danger[i][6 - 1] *= 8.2f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 7.5f / 8.7f; m_BotBrain.danger[i][4 - 1] *= 9.3f / 8.0f; } if (d[i][3 - 1]) { m_BotBrain.danger[i][1 - 1] *= 0.9f / 2.5f; m_BotBrain.danger[i][2 - 1] *= 1.9f / 4.4f; m_BotBrain.danger[i][4 - 1] *= 6.6f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 8.6f / 8.7f; m_BotBrain.danger[i][6 - 1] *= 6.5f / 8.0f; } if (d[i][7 - 1]) { m_BotBrain.danger[i][9 - 1] *= 0.9f / 2.5f; m_BotBrain.danger[i][8 - 1] *= 1.9f / 4.4f; m_BotBrain.danger[i][6 - 1] *= 6.6f / 8.0f; m_BotBrain.danger[i][5 - 1] *= 8.6f / 8.7f; m_BotBrain.danger[i][4 - 1] *= 6.5f / 8.0f; } if (d[i][4 - 1]) { m_BotBrain.danger[i][2 - 1] *= 2.4f / 4.4f; m_BotBrain.danger[i][3 - 1] *= 3.5f / 7.0f; m_BotBrain.danger[i][5 - 1] *= 7.6f / 8.0f; m_BotBrain.danger[i][6 - 1] *= 8.0f / 8.7f; m_BotBrain.danger[i][7 - 1] *= 5.3f / 7.0f; } if (d[i][6 - 1]) { m_BotBrain.danger[i][8 - 1] *= 2.4f / 4.4f; m_BotBrain.danger[i][7 - 1] *= 3.5f / 7.0f; m_BotBrain.danger[i][5 - 1] *= 7.6f / 8.0f; m_BotBrain.danger[i][4 - 1] *= 8.0f / 8.7f; m_BotBrain.danger[i][3 - 1] *= 5.3f / 7.0f; } if (d[i][5 - 1]) { m_BotBrain.danger[i][2 - 1] *= 1.9f / 4.4f; m_BotBrain.danger[i][3 - 1] *= 5.7f / 7.0f; m_BotBrain.danger[i][4 - 1] *= 5.4f / 8.0f; m_BotBrain.danger[i][6 - 1] *= 5.4f / 8.0f; m_BotBrain.danger[i][7 - 1] *= 5.7f / 7.0f; m_BotBrain.danger[i][8 - 1] *= 1.9f / 4.4f; } } for (i = 0; i < 3; i++) { for (j = 0; j < 5; j++) { if (!d2[i][j] && !d2[i][j + 1] && !d2[i][j + 2]) { m_BotBrain.danger[i][j + 1] *= 1.2f; } } for (j = 0; j < 4; j++) { if (!d2[i][j] && !d2[i][j + 1] && !d2[i][j + 2] && !d2[i][j + 3]) { m_BotBrain.danger[i][j] *= 1.3f; m_BotBrain.danger[i][j + 3] *= 1.3f; } } } for (i = 0; i < 3; i++) { if (rest_kind[i][2 - 1] == 0) { m_BotBrain.danger[i][1 - 1] *= 0.3f; } if (rest_kind[i][2 - 1] == 1) { m_BotBrain.danger[i][1 - 1] *= 0.6f; } if (rest_kind[i][8 - 1] == 0) { m_BotBrain.danger[i][9 - 1] *= 0.3f; } if (rest_kind[i][8 - 1] == 1) { m_BotBrain.danger[i][9 - 1] *= 0.6f; } if (rest_kind[i][3 - 1] == 0) { m_BotBrain.danger[i][1 - 1] *= 0.3f; m_BotBrain.danger[i][2 - 1] *= 0.3f; } if (rest_kind[i][3 - 1] == 1) { m_BotBrain.danger[i][1 - 1] *= 0.6f; m_BotBrain.danger[i][2 - 1] *= 0.6f; } if (rest_kind[i][7 - 1] == 0) { m_BotBrain.danger[i][9 - 1] *= 0.3f; m_BotBrain.danger[i][8 - 1] *= 0.3f; } if (rest_kind[i][7 - 1] == 1) { m_BotBrain.danger[i][9 - 1] *= 0.6f; m_BotBrain.danger[i][8 - 1] *= 0.6f; } for (j = 0; j < 6; j++) { n = rest_kind[i][j] + rest_kind[i][j + (4 - 1)]; if (n > 4) { m_BotBrain.danger[i][j] *= 1.3f; m_BotBrain.danger[i][j + (4 - 1)] *= 1.3f; } } } for (i = 0; i < 4; i++) { switch (rest_kind[3][i]) { case 0: m_BotBrain.danger[3][i] = 0.0f; break; case 1: m_BotBrain.danger[3][i] *= 0.3f; break; case 2: m_BotBrain.danger[3][i] *= 1.0f; break; case 3: m_BotBrain.danger[3][i] *= 3.0f; break; case 4: m_BotBrain.danger[3][i] *= 10.0f; break; } } for (i = 0; i < 3; i++) { switch (rest_kind[4][i]) { case 0: m_BotBrain.danger[4][i] = 0.0f; break; case 1: m_BotBrain.danger[4][i] *= 0.3f; break; case 2: m_BotBrain.danger[4][i] *= 1.0f; break; case 3: m_BotBrain.danger[4][i] *= 3.0f; break; case 4: m_BotBrain.danger[4][i] *= 10.0f; break; } } }#ifdef BOT_DEBUG fprintf(stdout, "-=-=-= CBot::UpdateDanger() result =-=-=-\n"); for (i = 0; i < 5; i++) { for (j = 0; j < 9; j++) { fprintf(stdout, "%3.2f ", m_BotBrain.danger[i][j]); } fprintf(stdout, "\n"); } fprintf(stdout, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");#endif}// Returns how "dangerous" discarding this tile is.float CBot::TileDanger(const CTile &t){ return m_BotBrain.danger[t.index1()][t.index2()];}void CBot::AnalyzeGoal(){ int i, j, num_chow = 0, num_pung = 0; int dorapt = 0, dorapt_minor = 0, dorapt_char = 0; int dorapt_bamboo = 0, dorapt_circle = 0; int yakupt = 0; int char3[2] = {0, 0}, char2[2] = {0, 0}; int bamboo3[2] = {0, 0}, bamboo2[2] = {0, 0}; int circle3[2] = {0, 0}, circle2[2] = {0, 0}; int wd3[2] = {0, 0}, wd2[2] = {0, 0}; int num_char = 0, num_bamboo = 0, num_circle = 0, num_wd = 0; int minor3 = 0, minor3f = 0, minor2 = 0, minorn = 0; int v2_num = 0, v3_num = 0, major_num = 0, major_kinds = 0; int stage = m_iNumDiscarded / 7; int kinds[5][9]; AnalyzeHand();#ifdef BOT_DEBUG fprintf(stdout, "-----------AnalyzeHand()---------\n"); for (i = 0; i < m_BotBrain.num_handresult; i++) { for (j = 0; j < m_BotBrain.handresult[i].m_iNumTileSets; j++) { fprintf(stdout, "%d first=%s type=%x\n", j, m_BotBrain.handresult[i].m_TileSets[j].first.GetCode(), m_BotBrain.handresult[i].m_TileSets[j].type); } for (j = 0; j < m_BotBrain.handresult[i].m_iNumTiles; j++) { fprintf(stdout, "%d %s %d %x\n", j, m_BotBrain.handresult[i].m_Tiles[j].tile.GetCode(), m_BotBrain.handresult[i].m_Tiles[j].tileset, m_BotBrain.handresult[i].m_Tiles[j].flags); } fprintf(stdout, "FREE = %d, REST = %d\n", m_BotBrain.handresult_ft[i], m_BotBrain.handresult_rest); fprintf(stdout, "---------------------------------\n"); } fprintf(stdout, "=====================================\n\n");#endif // clear the goal value array for (i = 0; i < GOAL_COUNT; i++) { m_BotBrain.goalvalue[i] = 0.0f; } // clear the kinds array for (i = 0; i < 5; i++) { for (j = 0; j < 9; j++) { kinds[i][j] = 0; } } bool concealed = m_Hand.IsConcealed(); if (!concealed) { // non-concealed hand m_BotBrain.goalvalue[GOAL_WONDERS] = -1; m_BotBrain.goalvalue[GOAL_PAIRS] = -1; for (i = 0; i < m_Hand.m_iNumTileSets; i++) { minor3f++; if (m_Hand.m_TileSets[i].type & (HT_OPENPUNG | HT_OPENKONG | HT_CLOSEDKONG)) { num_pung++; CTile &t = m_Hand.m_TileSets[i].first; kinds[t.index1()][t.index2()] += 3; if (t.IsMajor()) { m_BotBrain.goalvalue[GOAL_ALLMINOR] = -1; } if (t.GetSuit() & TILESUIT_CHAR) { num_char += 3; char3[0]++; char3[1]++; } else if (t.GetSuit() & TILESUIT_BAMBOO) { num_bamboo += 3; bamboo3[0]++; bamboo3[1]++; } else if (t.GetSuit() & TILESUIT_CIRCLE) { num_circle += 3; circle3[0]++; circle3[1]++; } else { num_wd += 3; wd3[0]++; wd3[1]++; if (t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW")) || t.GetSuit() == TILESUIT_DRAGON) { yakupt += 15; } if (t == (m_iTurn == TURN_EAST ? CTile("EW") : CTile("SW"))) { yakupt += 15; } } } else if (m_Hand.m_TileSets[i].type & HT_OPENCHOW) { num_chow++; m_BotBrain.goalvalue[GOAL_ALLPUNG] = -1; CTile &t = m_Hand.m_TileSets[i].first; assert(t.index2() < 7); kinds[t.index1()][t.index2()]++; kinds[t.index1()][t.index2() + 1]++; kinds[t.index1()][t.index2() + 2]++; if (t.GetValue() == 7 || t.IsMajor()) { m_BotBrain.goalvalue[GOAL_ALLMINOR] = -1; } if (t.GetSuit() & TILESUIT_CHAR) { num_char += 3; char3[0]++; char3[1]++; } else if (t.GetSuit() & TILESUIT_BAMBOO) { num_bamboo += 3; bamboo3[0]++; bamboo3[1]++; } else if (t.GetSuit() & TILESUIT_CIRCLE) { num_circle += 3; circle3[0]++; circle3[1]++; } else { TerminateOnError("CBot::AnalyzeGoal(): chow is non-numeric"); } } } // check for open doras for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_OPEN) { CTile &t = m_Hand.m_Tiles[i].tile; if (gpGame->IsDora(t, false)) { dorapt += 10; if (!t.IsMajor()) { dorapt_minor += 10; } if (t.GetSuit() & TILESUIT_CHAR) { dorapt_char++; } else if (t.GetSuit() & TILESUIT_BAMBOO) { dorapt_bamboo++; } else if (t.GetSuit() & TILESUIT_CIRCLE) { dorapt_circle++; } } } } } for (i = 0; i < m_BotBrain.num_handresult; i++) { CHand &h = m_BotBrain.handresult[i]; for (j = 0; j < h.m_iNumTileSets; j++) { if (h.m_TileSets[i].type & HT_OPEN) { continue; // skip open sets } if (h.m_TileSets[i].type & HT_CLOSEDPUNG) { if (h.m_TileSets[i].first.IsMajor()) { m_BotBrain.goalvalue[GOAL_ALLMINOR] = -1; } else { minor3++; } } else if (h.m_TileSets[i].type & HT_CLOSEDCHOW) { if (h.m_TileSets[i].first.GetValue() != 1 && h.m_TileSets[i].first.GetValue() != 7) { minor3++; } } else if (h.m_TileSets[i].type & (HT_PAIR | HT_TOCHOW)) { if (h.m_TileSets[i].first.IsMinor()) { minor2++; } } if (i < 2) { switch (h.m_TileSets[j].first.GetSuit()) { case TILESUIT_CHAR: if (h.m_TileSets[j].type & (HT_PAIR | HT_TOCHOW)) char2[i]++; else char3[i]++; break; case TILESUIT_BAMBOO: if (h.m_TileSets[j].type & (HT_PAIR | HT_TOCHOW)) bamboo2[i]++; else bamboo3[i]++; break; case TILESUIT_CIRCLE: if (h.m_TileSets[j].type & (HT_PAIR | HT_TOCHOW)) circle2[i]++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -