📄 bot.cpp
字号:
else circle3[i]++; break; default: if (h.m_TileSets[j].type & (HT_PAIR | HT_TOCHOW)) wd2[i]++; else wd3[i]++; break; } } } if (minor3 * 2 + minor2 > minorn) minorn = minor3 * 2 + minor2; } for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_LOCKED) { continue; // skip locked tiles } CTile &t = m_Hand.m_Tiles[i].tile; kinds[t.index1()][t.index2()]++; 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 < 5; i++) { for (j = 0; j < 9; j++) { if ((i == 3 && j > 3) || (i == 4 && j > 2)) break; CTile t = CTile((TILESUIT_CHAR << i) | (j + 1)); if (kinds[i][j] == 2) { v2_num++; } else if (kinds[i][j] == 3) { v3_num++; } if (t.IsMajor()) { major_num += kinds[i][j]; if (kinds[i][j]) { major_kinds++; } if (kinds[i][j] == 0 && CTile::RemainingTile(t) == 0) { m_BotBrain.goalvalue[GOAL_WONDERS] = -1; } } else { if (kinds[i][j] >= 3 || (kinds[i][j] == 2 && CTile::RemainingTile(t) > 0)) { if (t == ((gpGame->GetRound() == TURN_EAST) ? CTile("EW") : CTile("SW")) || t.GetSuit() == TILESUIT_DRAGON) { yakupt += ((kinds[i][j] >= 3) ? 15 : 10); } if (t == (m_iTurn == TURN_EAST ? CTile("EW") : CTile("SW"))) { yakupt += ((kinds[i][j] >= 3) ? 15 : 10); } } } } } if (m_BotBrain.goalvalue[GOAL_PAIRS] >= 0) { m_BotBrain.goalvalue[GOAL_PAIRS] = (v2_num + v3_num) * 700 / (4 + stage); m_BotBrain.goalvalue[GOAL_PAIRS] += (yakupt + dorapt) * 5; m_BotBrain.goalvalue[GOAL_PAIRS] += m_BotBrain.aggression * 50; } if (m_BotBrain.goalvalue[GOAL_WONDERS] >= 0) { m_BotBrain.goalvalue[GOAL_WONDERS] = major_kinds * 700 / (10 - stage); m_BotBrain.goalvalue[GOAL_WONDERS] -= m_BotBrain.aggression * 50; } if (m_BotBrain.handresult_rest < 3 && yakupt > 0) { m_BotBrain.goalvalue[GOAL_FANPAI] = (dorapt + yakupt) * 20; m_BotBrain.goalvalue[GOAL_FANPAI] += (3 - m_BotBrain.handresult_rest) * 100; m_BotBrain.goalvalue[GOAL_FANPAI] += m_BotBrain.aggression * 50; } if (m_BotBrain.goalvalue[GOAL_ALLPUNG] >= 0) { int n = (v2_num > 5 - v3_num) ? (5 - v3_num) : v2_num; m_BotBrain.goalvalue[GOAL_ALLPUNG] = (v3_num * 2 + n) * 700 / 6; m_BotBrain.goalvalue[GOAL_ALLPUNG] += (yakupt + dorapt) * 5; m_BotBrain.goalvalue[GOAL_ALLPUNG] += m_BotBrain.aggression * 50; } if (num_bamboo <= 0 && num_circle <= 0 && bamboo2[0] <= 0 && bamboo2[1] <= 0 && circle2[0] <= 0 && circle2[1] <= 0) { int n = (char3[0] + wd3[0]) * 2 + char2[0] + wd2[0]; if (n < (char3[1] + wd3[1]) * 2 + char2[1] + wd2[1]) { n = (char3[1] + wd3[1]) * 2 + char2[1] + wd2[1]; } m_BotBrain.goalvalue[GOAL_ALLCHAR] = n * 700 / 6; m_BotBrain.goalvalue[GOAL_ALLCHAR] += (yakupt + dorapt_char) * 5; m_BotBrain.goalvalue[GOAL_ALLCHAR] += m_BotBrain.aggression * 50; } if (num_char <= 0 && num_circle <= 0 && char2[0] <= 0 && char2[1] <= 0 && circle2[0] <= 0 && circle2[1] <= 0) { int n = (bamboo3[0] + wd3[0]) * 2 + bamboo2[0] + wd2[0]; if (n < (bamboo3[1] + wd3[1]) * 2 + bamboo2[1] + wd2[1]) { n = (bamboo3[1] + wd3[1]) * 2 + bamboo2[1] + wd2[1]; } m_BotBrain.goalvalue[GOAL_ALLBAMBOO] = n * 700 / 6; m_BotBrain.goalvalue[GOAL_ALLBAMBOO] += (yakupt + dorapt_bamboo) * 5; m_BotBrain.goalvalue[GOAL_ALLBAMBOO] += m_BotBrain.aggression * 50; } if (num_bamboo <= 0 && num_char <= 0 && bamboo2[0] <= 0 && bamboo2[1] <= 0 && char2[0] <= 0 && char2[1] <= 0) { int n = (circle3[0] + wd3[0]) * 2 + circle2[0] + wd2[0]; if (n < (circle3[1] + wd3[1]) * 2 + circle2[1] + wd2[1]) { n = (circle3[1] + wd3[1]) * 2 + circle2[1] + wd2[1]; } m_BotBrain.goalvalue[GOAL_ALLCIRCLE] = n * 700 / 6; m_BotBrain.goalvalue[GOAL_ALLCIRCLE] += (yakupt + dorapt_circle) * 5; m_BotBrain.goalvalue[GOAL_ALLCIRCLE] += m_BotBrain.aggression * 50; } if (m_BotBrain.goalvalue[GOAL_ALLMINOR] >= 0) { m_BotBrain.goalvalue[GOAL_ALLMINOR] = (minor3f * 2 + minorn) * 100; m_BotBrain.goalvalue[GOAL_ALLMINOR] += dorapt_minor * 5; m_BotBrain.goalvalue[GOAL_ALLMINOR] -= m_BotBrain.aggression * 50; }#ifdef BOT_DEBUG fprintf(stdout, "\n-----------AnalyzeGoal()---------\n"); for (i = 1; i < GOAL_COUNT; i++) { fprintf(stdout, "GOAL %d - VALUE %f\n", i, m_BotBrain.goalvalue[i]); } fprintf(stdout, "---------------------------------\n\n");#endif}void CBot::AnalyzeHand(){ int i, j; m_BotBrain.num_handresult = 0; for (i = 0; i < 5; i++) { for (j = 0; j < 9; j++) { m_BotBrain.ahand_kinds[i][j] = 0; } } for (i = 0; i < m_Hand.m_iNumTiles; i++) { if (m_Hand.m_Tiles[i].flags & HT_LOCKED) continue; // skip locked tiles CTile &t = m_Hand.m_Tiles[i].tile; m_BotBrain.ahand_kinds[t.index1()][t.index2()]++; } int m = 0, h = 0; for (i = 0; i < 5; i++) { for (j = 0; j < 9; j++) { if ((i == 3 && j > 3) || (i == 4 && j > 2)) { break; } CTile t((TILESUIT_CHAR << i) | (j + 1)); if (!t.IsMajor()) { continue; } if (m_BotBrain.ahand_kinds[i][j]) { m++; if (m_BotBrain.ahand_kinds[i][j] >= 2) { h = 1; } } } } m_BotBrain.handresult_rest = 14 - m - h; // for thirteen-wonders CHand hand = m_Hand; hand.Sort(); AnalyzeHand_real(hand, 0); AnalyzeHand_sort();}void CBot::AnalyzeHand_real(CHand &hand, int begin){ int i, j; bool ended = true; CTile prev = 0; for (i = begin; i < hand.m_iNumTiles; i++) { if (hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) continue; // skip locked tiles CTile &t = hand.m_Tiles[i].tile; if (prev == t) continue; // don't process 2 same tiles prev = t; CHand tmp; for (j = 0; j < i; j++) { if (tmp.m_Tiles[j].flags & (HT_LOCKED | HT_TOCHOW)) continue; // skip locked tiles if (hand.m_Tiles[i].tile == hand.m_Tiles[j].tile) break; } if (j >= i) { tmp = hand; if (tmp.Pung(tmp.m_Tiles[i].tile, false)) { ended = false; AnalyzeHand_real(tmp, i + 1); } } tmp = hand; if (tmp.Chow(tmp.m_Tiles[i].tile, CHOW_LOWER, false)) { ended = false; AnalyzeHand_real(tmp, i + 1); } tmp = hand; for (j = i + 1; j < tmp.m_iNumTiles; j++) { if (tmp.m_Tiles[j].flags & (HT_LOCKED | HT_TOCHOW)) continue; // skip locked tiles int f = 0; if (tmp.m_Tiles[i].tile.GetSuit() == tmp.m_Tiles[j].tile.GetSuit()) { if (tmp.m_Tiles[i].tile == tmp.m_Tiles[j].tile) { f = HT_PAIR; } else if (tmp.m_Tiles[i].tile.GetSuit() & (TILESUIT_WIND | TILESUIT_DRAGON)) { // do nothing here } else if (tmp.m_Tiles[i].tile.GetValue() == tmp.m_Tiles[j].tile.GetValue() - 1) { if (tmp.m_Tiles[i].tile.GetValue() != 1) { f |= HT_TOCHOWLOWER; } if (tmp.m_Tiles[i].tile.GetValue() != 8) { f |= HT_TOCHOWUPPER; } } else if (tmp.m_Tiles[i].tile.GetValue() == tmp.m_Tiles[j].tile.GetValue() - 2) { f = HT_TOCHOWMIDDLE; } } if (f != 0) { tmp.m_Tiles[i].flags |= f; tmp.m_Tiles[j].flags |= f; tmp.m_Tiles[i].tileset = tmp.m_Tiles[j].tileset = tmp.m_iNumTileSets; // Add this pair to the tileset tmp.m_TileSets[tmp.m_iNumTileSets].first = tmp.m_Tiles[i].tile; tmp.m_TileSets[tmp.m_iNumTileSets].type = f; tmp.m_iNumTileSets++; ended = false; AnalyzeHand_real(tmp, i + 1); break; // no need to go further } } } if (ended) { int ft = 0; for (i = 0; i < hand.m_iNumTiles; i++) { if (hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) continue; ft++; } AnalyzeHand_add(hand, ft); }}void CBot::AnalyzeHand_add(CHand &hand, int ft){ int i, rest, v2 = 0, two = 0, three = 0, total = 0, m, over; for (i = 0; i < hand.m_iNumTileSets; i++) { if (hand.m_TileSets[i].type & (HT_LOCKED & ~HT_PAIR)) { three++; total += 3; } else { two++; total += 2; if (hand.m_TileSets[i].type & HT_PAIR) { v2++; } } } three += (14 - total - ft) / 3; if (v2) { m = two + three - 1; } else { m = two + three; } if (m > 4) { over = m - 4; } else { over = 0; } rest = 9 - (three + three + two) + over; if (rest > 7 - v2) { rest = 7 - v2; if (v2 == 6) { int same = 0, j; for (i = 0; i < hand.m_iNumTiles; i++) { if (hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) { continue; } for (j = 0; j < hand.m_iNumTileSets; j++) { if (hand.m_Tiles[i].tile == hand.m_TileSets[j].first) { same++; } } } if (same == ft) { rest++; } } } // check for unready hand if (rest == 1 && three == 4 && ft == 1) { CTile r = 0; for (i = 0; i < hand.m_iNumTiles; i++) { if (hand.m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) { continue; } r = hand.m_Tiles[i].tile; break; } for (i = 0; i < hand.m_iNumTileSets; i++) { if (hand.m_TileSets[i].type & (HT_OPENPUNG | HT_CLOSEDPUNG | HT_OPENKONG | HT_CLOSEDKONG)) { if (hand.m_TileSets[i].first == r) { rest++; break; } } } } if (rest == 1 && three == 3) { CTile m1 = 0, m2 = 0; for (i = 0; i < hand.m_iNumTileSets; i++) { if (hand.m_TileSets[i].type & HT_TOCHOWUPPER) { m1 = hand.m_TileSets[i].first() - 1; } if (hand.m_TileSets[i].type & HT_TOCHOWMIDDLE) { m1 = hand.m_TileSets[i].first() + 1; } if (hand.m_TileSets[i].type & HT_TOCHOWLOWER) { m2 = hand.m_TileSets[i].first() + 2; } } bool p = false; if (m1() != 0 && m2() != 0) { if (m_BotBrain.ahand_kinds[m1.index1()][m1.index2()] + m_BotBrain.ahand_kinds[m2.index1()][m2.index2()] == 8) { p = true; } } if (m1() != 0 && m2() == 0 && m_BotBrain.ahand_kinds[m1.index1()][m1.index2()] == 4) { p = true; } if (m1() == 0 && m2() != 0 && m_BotBrain.ahand_kinds[m2.index1()][m2.index2()] == 4) { p = true; } rest += (p ? 1 : 0); } if (m_BotBrain.handresult_rest > rest) { m_BotBrain.handresult_rest = rest; m_BotBrain.num_handresult = 0; } else if (m_BotBrain.handresult_rest < rest) { return; // discard this one } if (m_BotBrain.num_handresult > MAX_HANDRESULT) { fprintf(stderr, "WARNING, max hand result reached\n"); return; } m_BotBrain.handresult[m_BotBrain.num_handresult] = hand; m_BotBrain.handresult_ft[m_BotBrain.num_handresult] = ft; m_BotBrain.num_handresult++;}// sort the analyze results by number of "free" tilesvoid CBot::AnalyzeHand_sort(){ CHand tmp; int i, j, t; for (i = 0; i < m_BotBrain.num_handresult; i++) { bool changed = false; for (j = 0; j < m_BotBrain.num_handresult - i - 1; j++) { if (m_BotBrain.handresult_ft[j + 1] < m_BotBrain.handresult_ft[j]) { tmp = m_BotBrain.handresult[j + 1]; m_BotBrain.handresult[j + 1] = m_BotBrain.handresult[j]; m_BotBrain.handresult[j] = tmp; t = m_BotBrain.handresult_ft[j + 1]; m_BotBrain.handresult_ft[j + 1] = m_BotBrain.handresult_ft[j]; m_BotBrain.handresult_ft[j] = t; changed = true; } } if (!changed) { break; } }}void CBot::SelectGoal(){ int goal = GOAL_NULL, i; float value = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -