// the mappings in default_pairs will override the ones in user_pairs string_pairs merge_pairs(const string_pairs& default_pairs, const string_pairs& user_pairs) { typedef std::map<string, int> Indexes; Indexes indexes; int index = 0; for (string_pairs::const_iterator it = default_pairs.begin(); it != default_pairs.end(); ++it, ++index) { Indexes::iterator found = indexes.find(it->first); if (found == indexes.end()) { indexes[it->first] = index; } else { // it is a paired punct. indexes[it->first] = -found->second; } } string_pairs result(default_pairs); for (string_pairs::const_iterator it = user_pairs.begin(); it != user_pairs.end(); ++it) { Indexes::iterator found = indexes.find(it->first); if (found == indexes.end()) { result.push_back(*it); } else if (found->second >= 0) { result[found->second] = *it; } else { // it is a paired punct, // but we don't support this kind of mapping yet, // so quietly ignore it. } } return result; }
s16 Battle::AIAttackPosition(Arena & arena, const Unit & b, const Indexes & positions) { s16 res = -1; if(b.isMultiCellAttack()) { res = AIMaxQualityPosition(positions); } else if(b.isDoubleCellAttack()) { Indexes results; results.reserve(12); const Units enemies(arena.GetForce(b.GetColor(), true), true); if(1 < enemies.size()) { for(Units::const_iterator it1 = enemies.begin(); it1 != enemies.end(); ++it1) { const Indexes around = Board::GetAroundIndexes(**it1); for(Indexes::const_iterator it2 = around.begin(); it2 != around.end(); ++it2) { const Unit* unit = Board::GetCell(*it2)->GetUnit(); if(unit && enemies.end() != std::find(enemies.begin(), enemies.end(), unit)) results.push_back(*it2); } } if(results.size()) { // find passable results Indexes passable = Arena::GetBoard()->GetPassableQualityPositions(b); Indexes::iterator it2 = results.begin(); for(Indexes::const_iterator it = results.begin(); it != results.end(); ++it) if(passable.end() != std::find(passable.begin(), passable.end(), *it)) *it2++ = *it; if(it2 != results.end()) results.resize(std::distance(results.begin(), it2)); // get max quality if(results.size()) res = AIMaxQualityPosition(results); } } } return 0 > res ? AIShortDistance(b.GetHeadIndex(), positions) : res; }
s16 Battle::AIMaxQualityPosition(const Indexes & positions) { s16 res = -1; for(Indexes::const_iterator it = positions.begin(); it != positions.end(); ++it) if(Board::isValidIndex(*it)) { if(res < 0) res = *it; else if(Board::GetCell(res)->GetQuality() < Board::GetCell(*it)->GetQuality()) res = *it; } return res; }
s16 Battle::AIShortDistance(s16 from, const Indexes & indexes) { u16 len = MAXU16; s16 res = -1; for(Indexes::const_iterator it = indexes.begin(); it != indexes.end(); ++it) { const u16 length = Board::GetDistance(from, *it); if(len > length) { len = length; res = *it; } } DEBUG(DBG_BATTLE, DBG_TRACE, res); return res; }
s16 Battle::AIAreaSpellDst(const HeroBase & hero) { std::map<s16, u8> dstcount; Arena* arena = GetArena(); Units enemies(arena->GetForce(hero.GetColor(), true), true); for(Units::const_iterator it1 = enemies.begin(); it1 != enemies.end(); ++it1) { const Indexes around = Board::GetAroundIndexes(**it1); for(Indexes::const_iterator it2 = around.begin(); it2 != around.end(); ++it2) dstcount[*it2] += 1; } // find max std::map<s16, u8>::const_iterator max = std::max_element(dstcount.begin(), dstcount.end(), MaxDstCount); return max != dstcount.end() ? (*max).first : -1; }
const Battle::Unit* Battle::AIGetEnemyAbroadMaxQuality(s16 position, u8 color) { const Unit* res = NULL; s32 quality = 0; const Indexes around = Board::GetAroundIndexes(position); for(Indexes::const_iterator it = around.begin(); it != around.end(); ++it) { const Cell* cell = Board::GetCell(*it); const Unit* enemy = cell ? cell->GetUnit() : NULL; if(enemy && enemy->GetColor() != color && quality < cell->GetQuality()) { res = enemy; quality = cell->GetQuality(); } } return res; }