📄 bot.cpp
字号:
for (i = 0; i < GOAL_COUNT; i++) { if (m_BotBrain.goalvalue[i] > value) { goal = i; value = m_BotBrain.goalvalue[i]; } } m_BotBrain.goal = (value >= 700) ? goal : GOAL_NULL;#ifdef BOT_DEBUG fprintf(stdout, "CBot::SelectGoal(): goal = %d\n", m_BotBrain.goal);#endif}bool CBot::WantToChow(){ if (m_BotBrain.goal == GOAL_ALLPUNG || m_BotBrain.goal == GOAL_PAIRS || m_pOpponent->m_iNumDiscarded <= 0 || m_BotBrain.goal == GOAL_NULL) return false; const int param = 300; int i, rest = m_BotBrain.handresult_rest, goal = m_BotBrain.goal; int chow_dir = -1; CHand tmp = m_Hand; botbrain_t bak = m_BotBrain; for (i = CHOW_LOWER; i <= CHOW_UPPER; i++) { if (m_Hand.Chow(m_pOpponent->LastDiscardedTile(), i)) { AnalyzeHand(); AnalyzeGoal(); SelectGoal(); if (m_BotBrain.handresult_rest < rest || (m_BotBrain.handresult_rest == rest && m_BotBrain.goal > goal)) { rest = m_BotBrain.handresult_rest; goal = m_BotBrain.goal; chow_dir = i; } m_Hand = tmp; } } m_BotBrain = bak; if (goal > m_BotBrain.goal || (goal == m_BotBrain.goal && rest < m_BotBrain.handresult_rest)) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToChow(): check 1 ok (%d, %d, %d, %d)\n", goal, m_BotBrain.goal, rest, m_BotBrain.handresult_rest);#endif m_BotBrain.action = PA_CHOW; m_BotBrain.chowlocation = (chow_location)chow_dir; return true; } bool has_fanpai = false; for (i = 0; i < m_Hand.m_iNumTileSets; i++) { if (!(m_Hand.m_TileSets[i].type & (HT_OPENPUNG | HT_CLOSEDPUNG | HT_OPENKONG | HT_CLOSEDKONG))) continue; const CTile &t = m_Hand.m_TileSets[i].first; if (t.GetSuit() == TILESUIT_DRAGON || t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } if (t == ((m_iTurn == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } } if (rest < m_BotBrain.handresult_rest && has_fanpai && (RandomLong(1, 1000) < param || !m_Hand.IsConcealed())) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToChow(): check 2 ok\n");#endif m_BotBrain.action = PA_CHOW; m_BotBrain.chowlocation = (chow_location)chow_dir; return true; } return false;}bool CBot::WantToPung(){ const int param = 300; CHand tmp = m_Hand; int rest = m_BotBrain.handresult_rest, goal = m_BotBrain.goal; if (goal == GOAL_PAIRS || goal == GOAL_WONDERS || m_pOpponent->m_iNumDiscarded <= 0) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToPung(): goal == GOAL_PAIRS || goal == GOAL_WONDERS\n");#endif return false; } botbrain_t bak = m_BotBrain; if (!m_Hand.Pung(m_pOpponent->LastDiscardedTile())) { return false; }#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToPung(): ANALYZE START\n");#endif AnalyzeHand(); AnalyzeGoal(); SelectGoal();#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToPung(): ANALYZE END\n");#endif int goal2 = m_BotBrain.goal, rest2 = m_BotBrain.handresult_rest; m_BotBrain = bak; m_Hand = tmp; if (goal != GOAL_NULL && ((goal2 >= goal && rest2 > rest) || goal2 > goal)) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToPung(): check 1 ok\n");#endif m_BotBrain.action = PA_PUNG; return true; } bool has_fanpai = false, is_fanpai = false; for (int i = 0; i < m_Hand.m_iNumTileSets; i++) { if (!(m_Hand.m_TileSets[i].type & (HT_OPENPUNG | HT_CLOSEDPUNG | HT_OPENKONG | HT_CLOSEDKONG))) continue; const CTile &t = m_Hand.m_TileSets[i].first; if (t.GetSuit() == TILESUIT_DRAGON || t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } if (t == ((m_iTurn == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } } if (!has_fanpai) { const CTile &t = m_pOpponent->LastDiscardedTile(); if (t.GetSuit() == TILESUIT_DRAGON || t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW"))) { is_fanpai = true; } if (t == ((m_iTurn == TURN_EAST) ? CTile("EW") : CTile("SW"))) { is_fanpai = true; } } if ((RandomLong(1, 1000) < param || !m_Hand.IsConcealed()) && (has_fanpai || is_fanpai) && rest2 < rest) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToPung(): check 2 ok\n");#endif m_BotBrain.action = PA_PUNG; return true; } return false;}bool CBot::WantToOpenKong(){ const int param = 300; CHand tmp = m_Hand; int rest = m_BotBrain.handresult_rest, goal = m_BotBrain.goal; if (goal == GOAL_PAIRS || goal == GOAL_WONDERS || m_pOpponent->m_iNumDiscarded <= 0) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToKong(): goal == GOAL_PAIRS || goal == GOAL_WONDERS\n");#endif return false; } botbrain_t bak = m_BotBrain; if (!m_Hand.Kong(m_pOpponent->LastDiscardedTile())) { return false; }#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToKong(): ANALYZE START\n");#endif AnalyzeHand(); AnalyzeGoal(); SelectGoal();#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToKong(): ANALYZE END\n");#endif int num2 = m_BotBrain.num_handresult, rest2 = m_BotBrain.handresult_rest; m_BotBrain = bak; m_Hand = tmp; if (rest2 > 2 && RandomLong(1, 1000) < param) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToKong(): check 1 ok\n");#endif m_BotBrain.action = PA_KONG; return true; } bool has_fanpai = false, is_fanpai = false; for (int i = 0; i < m_Hand.m_iNumTileSets; i++) { if (!(m_Hand.m_TileSets[i].type & (HT_OPENPUNG | HT_CLOSEDPUNG | HT_OPENKONG | HT_CLOSEDKONG))) continue; const CTile &t = m_Hand.m_TileSets[i].first; if (t.GetSuit() == TILESUIT_DRAGON || t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } if (t == ((m_iTurn == TURN_EAST) ? CTile("EW") : CTile("SW"))) { has_fanpai = true; break; } } if (!has_fanpai) { const CTile &t = m_pOpponent->LastDiscardedTile(); if (t.GetSuit() == TILESUIT_DRAGON || t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW"))) { is_fanpai = true; } if (t == ((m_iTurn == TURN_EAST) ? CTile("EW") : CTile("SW"))) { is_fanpai = true; } } if ((RandomLong(1, 1000) < param || !m_Hand.IsConcealed()) && (is_fanpai || (has_fanpai && num2 >= m_BotBrain.num_handresult && rest2 <= m_BotBrain.handresult_rest))) {#ifdef BOT_DEBUG fprintf(stdout, "CBot::WantToKong(): check 2 ok\n");#endif m_BotBrain.action = PA_KONG; return true; } return false;}bool CBot::WantToClosedKong(){ return false; // TODO}bool CBot::WantToReach(){ if (m_pOpponent->m_iNumDiscarded >= 20) { return false; } const int param = 700; if (m_BotBrain.handresult_rest == 1) { if (!m_Hand.IsConcealed()) { return false; } CHand tmp = m_Hand; tmp.RemoveTile(m_BotBrain.act_index); if (!tmp.IsReady()) { return false; } if (RandomLong(1, 1000) * 20 < param * (20 - m_iNumDiscarded)) { m_BotBrain.action = PA_REACH; return true; } } return false;}void CBot::AnalyzeDiscard(){ int rests[MAX_HANDTILE], i; botbrain_t bak = m_BotBrain; for (i = 0; i < m_Hand.m_iNumTiles; i++) { CHand tmp = m_Hand; if (m_Hand.RemoveTile(i)) { AnalyzeHand(); rests[i] = m_BotBrain.handresult_rest; } else { rests[i] = 9999; } m_Hand = tmp; } m_BotBrain = bak; if (m_BotBrain.goal == GOAL_WONDERS) { int n, kinds[5][9]; for (i = 0; i < 5; i++) { for (n = 0; n < 9; n++) { kinds[i][n] = 0; } } for (i = 0; i < m_Hand.m_iNumTiles; i++) { CTile &t = m_Hand.m_Tiles[i].tile; kinds[t.index1()][t.index2()]++; } for (i = 0; i < m_Hand.m_iNumTiles; i++) { CTile &t = m_Hand.m_Tiles[i].tile; if (t.IsMajor()) { if (kinds[t.index1()][t.index2()] == 1) { m_BotBrain.tilevalue[i] = 2000.0f; } else { m_BotBrain.tilevalue[i] = (m_BotBrain.handresult_rest < rests[i]) ? 1000 : 500; } } else { m_BotBrain.tilevalue[i] = (m_BotBrain.handresult_rest < rests[i]) ? 250 : 0; } } } else if (m_BotBrain.goal == GOAL_PAIRS) { int n, kinds[5][9]; for (i = 0; i < 5; i++) { for (n = 0; n < 9; n++) { kinds[i][n] = 0; } } for (i = 0; i < m_Hand.m_iNumTiles; i++) { CTile &t = m_Hand.m_Tiles[i].tile; kinds[t.index1()][t.index2()]++; } for (i = 0; i < n; i++) { CTile &t = m_Hand.m_Tiles[i].tile; if (kinds[t.index1()][t.index2()] == 2) { m_BotBrain.tilevalue[i] = 2000.0f; } else if (m_BotBrain.handresult_rest < rests[i]) { m_BotBrain.tilevalue[i] = 1000.0f; } else { int rem = CTile::RemainingTile(t); m_BotBrain.tilevalue[i] = rem * rem * 60.0f; } } } else { CalcTileValue(rests); } float max = 0; for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_BotBrain.tilevalue[i] > max) { max = m_BotBrain.tilevalue[i]; } } for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (max != 0) { m_BotBrain.tilevalue[i] *= 1000 + m_iNumDiscarded * 20; m_BotBrain.tilevalue[i] /= max; } } AnalyzeDora(); AnalyzeColor(); AnalyzeZone(); AnalyzeNum(); AnalyzeDanger();#ifdef BOT_DEBUG for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) { continue; } int loc = IndexToLoc(i), x, y; x = DRAW_LOCATION(loc); y = (loc % 2) ? 5 : 32; gpGeneral->DrawUTF8Text(va("%3.1f", m_BotBrain.tilevalue[i]), x, y, 0, 255, 255, 0); } gpGeneral->UpdateScreen(); gpGeneral->WaitForAnyKey();#endif // discard the tile with the lowest value float min = 9999; for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) { continue; } if (m_BotBrain.tilevalue[i] < min) { min = m_BotBrain.tilevalue[i]; m_BotBrain.act_index = i; } }}void CBot::CalcTileValue(int rests[]){ int i, j, x, v2_num; bool fanpai_fixed = false; struct pnt_s { int num; int point[MAX_HANDTILE]; CTile tile[MAX_HANDTILE]; }; pnt_s p; pnt_s result_pnt; p.num = result_pnt.num = 0; for (i = 0; i < m_Hand.m_iNumTileSets; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -