// 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; }
Indexes Project::indexes() { Indexes idxs; for (Indexes src = source->indexes(); ! nil(src); ++src) if (subset(flds, *src)) idxs.push(*src); return idxs; }
Indexes Project::keys() { Indexes keys; for (Indexes k = source->keys(); ! nil(k); ++k) if (subset(flds, *k)) keys.push(*k); return nil(keys) ? Indexes(flds) : keys; }
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; }
KuhnMunkres::Indexes KuhnMunkres::calculate(const Grid &grid) { grid_ = grid; const Dimensions dimensions = ensure_grid_is_square(); size = static_cast<int>(grid_.size()); #ifdef USE_STL row_covered.resize(size, false); column_covered.resize(size, false); #else row_covered.fill(false, size); column_covered.fill(false, size); #endif z0_row = 0; z0_column = 0; path = make_grid(size * 2, static_cast<int>(ZERO)); marked = make_grid(size, static_cast<int>(ZERO)); int step = 1; while (step) { switch (step) { case 1: step = step1(); break; case 2: step = step2(); break; case 3: step = step3(); break; case 4: step = step4(); break; case 5: step = step5(); break; case 6: step = step6(); break; default: break; } } Indexes indexes; for (int row = 0; row < size; ++row) { for (int column = 0; column < size; ++column) { if ((row < dimensions.first) && (column < dimensions.second) && marked.at(row).at(column) == STAR) #ifdef USE_STL indexes.push_back(std::make_pair(row, column)); #else indexes.push_back(qMakePair(row, column)); #endif } } return indexes; }
FourTree::Indexes FourTree::getIndexes(const RotatedRect& rotatedRect) { Indexes indexes; indexes.resize(0); int i = 0; for (auto& index : mNodes){ sf::FloatRect rect1 = index->mBounds; rect1.top += mWorldLocation.y; rect1.left += mWorldLocation.x; RotatedRect rotateRect1(rect1); if (Utility::rotatedCollision(rotatedRect, rotateRect1)) indexes.push_back(i); i++; } return indexes; }
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; }
void FourTree::getObjects(std::vector<Entity*>& entities, const RotatedRect& rotatedRect, std::vector<sf::FloatRect>& finalIndexesWorldBound) { Indexes indexes; if (isSpilt) indexes = getIndexes(rotatedRect); if (!isSpilt) finalIndexesWorldBound.push_back(this->getWorldBounds()); if (!indexes.empty() && isSpilt){ for (int i : indexes) mNodes[i]->getObjects(entities, rotatedRect, finalIndexesWorldBound); return; } for (Entity *entity : mEntities){ if (std::find(entities.begin(), entities.end(), entity) == entities.end()) entities.push_back(entity); } }
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; }
void FourTree::insert(Entity *ptr) { if (isSpilt){ Indexes indexes = getIndexes(ptr); if (!indexes.empty()){ for (int i : indexes) mNodes[i]->insert(ptr); return; } } mEntities.push_back(ptr); //std::cout << "wee"; //if this level reaches it max objects, seperate it into 4 more cells if (!isSpilt && mEntities.size() > mMaxObjects && mCurrentLevel < mMaxLevels){ //if (mNodes[0] == NULL) //split(); isSpilt = true; int i = 0; while (i < mEntities.size()){ Indexes indexes = getIndexes(mEntities[i]); if (!indexes.empty()){ Entity *newEntity = deleteFromContainer(mEntities[i]); for (int i : indexes) mNodes[i]->insert(newEntity); } else i++; } } }
FourTree::Indexes FourTree::getIndexes(const sf::Vector2f& centerRectPos, const sf::FloatRect& rect) { Indexes indexes; indexes.resize(0); sf::FloatRect updatedBounds = mBounds; updatedBounds.top += mWorldLocation.y; updatedBounds.left += mWorldLocation.x; float verticalMidPoint = updatedBounds.left + (updatedBounds.width / 2); float horizontalMidPoint = updatedBounds.top + (updatedBounds.height / 2); /*TransformableComponent* transformableComp = ptr->comp<TransformableComponent>(); BoxCollisionComponent* boxCollisionComp = ptr->comp<BoxCollisionComponent>(); sf::FloatRect boundingRect = boxCollisionComp->getTransfromedRect(); sf::Vector2f ptrPosition = transformableComp->getWorldPosition(true);*/ sf::FloatRect boundingRect = rect; sf::Vector2f ptrPosition = centerRectPos; float topEntityY = ptrPosition.y - boundingRect.height / 2; float bottomEntityY = ptrPosition.y + boundingRect.height / 2; float leftEntityX = ptrPosition.x - boundingRect.width / 2; float rightEntityX = ptrPosition.x + boundingRect.width / 2; bool topQuardrant = (topEntityY < horizontalMidPoint); bool bottomQuardrant = (bottomEntityY > horizontalMidPoint); bool leftQuardrant = (leftEntityX < verticalMidPoint); bool rightQuardrant = (rightEntityX > verticalMidPoint); if (topQuardrant && leftQuardrant) indexes.push_back(1); if (topQuardrant && rightQuardrant) indexes.push_back(0); if (bottomQuardrant && leftQuardrant) indexes.push_back(2); if (bottomQuardrant && rightQuardrant) indexes.push_back(3); return indexes; }
void AI::BattleTurn(Arena & arena, const Unit & b, Actions & a) { Board* board = Arena::GetBoard(); // reset quality param for board board->Reset(); // set quality for enemy troop board->SetEnemyQuality(b); const Unit* enemy = NULL; bool attack = false; if(b.isArchers() && !b.isHandFighting()) { enemy = arena.GetEnemyMaxQuality(b.GetColor()); if(BattleMagicTurn(arena, b, a, enemy)) return; /* repeat turn: correct spell ability */ attack = true; } else if(b.isHandFighting()) { enemy = AIGetEnemyAbroadMaxQuality(b); if(BattleMagicTurn(arena, b, a, enemy)) return; /* repeat turn: correct spell ability */ attack = true; } else { s16 move = -1; if(b.Modes(SP_BERSERKER)) { const Indexes positions = board->GetNearestTroopIndexes(b.GetHeadIndex(), NULL); if(positions.size()) move = *Rand::Get(positions); } else { if(BattleMagicTurn(arena, b, a, NULL)) return; /* repeat turn: correct spell ability */ // set quality position from enemy board->SetPositionQuality(b); // get passable quality positions const Indexes positions = board->GetPassableQualityPositions(b); attack = true; if(positions.size()) move = AIAttackPosition(arena, b, positions); } if(Board::isValidIndex(move)) { if(b.isFly()) { enemy = AIGetEnemyAbroadMaxQuality(move, b.GetColor()); if(BattleMagicTurn(arena, b, a, enemy)) return; /* repeat turn: correct spell ability */ a.push_back(Battle::Command(MSG_BATTLE_MOVE, b.GetUID(), move)); attack = true; } else { Position dst = Position::GetCorrect(b, move); Indexes path = arena.GetPath(b, dst); if(path.empty()) { const u8 direction = b.GetPosition().GetHead()->GetPos().x > dst.GetHead()->GetPos().x ? RIGHT : LEFT; // find near position while(path.empty() && Board::isValidDirection(dst.GetHead()->GetIndex(), direction)) { const s16 & pos = Board::GetIndexDirection(dst.GetHead()->GetIndex(), direction); if(b.GetHeadIndex() == pos) break; dst.Set(pos, b.isWide(), direction == RIGHT); path = arena.GetPath(b, dst); } } if(path.size()) { if(b.isWide()) { const s16 & head = dst.GetHead()->GetIndex(); const s16 & tail = dst.GetTail()->GetIndex(); if(path.back() == head || path.back() == tail) { enemy = AIGetEnemyAbroadMaxQuality(head, b.GetColor()); if(!enemy) enemy = AIGetEnemyAbroadMaxQuality(tail, b.GetColor()); } } if(! enemy) enemy = AIGetEnemyAbroadMaxQuality(path.back(), b.GetColor()); a.push_back(Battle::Command(MSG_BATTLE_MOVE, b.GetUID(), path.back())); // archers move and short attack only attack = b.isArchers() ? false : true; } } } else enemy = AIGetEnemyAbroadMaxQuality(b); } if(enemy) { if(attack) a.push_back(Battle::Command(MSG_BATTLE_ATTACK, b.GetUID(), enemy->GetUID(), enemy->GetHeadIndex(), 0)); } else { DEBUG(DBG_BATTLE, DBG_TRACE, "enemy: " << "is NULL" << ", board: " << board->AllUnitsInfo()); } // end action a.push_back(Battle::Command(MSG_BATTLE_END_TURN, b.GetUID())); }
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; }