ShipBattle::Hits ShipBattle::AutoAssignHits(const Dice& dice, const Game& game) const { Hits hits; Dice remainingDice = dice; std::map<int, std::set<int>> destroyedShips; // group index, ship indices. // Try to destroy ships (biggest type and most damaged ship first.) std::vector<int> groupIndices = GetTargetGroupIndicesBiggestFirst(); for (int groupIndex : groupIndices) { if (remainingDice.empty()) break; const Group& group = m_groups[groupIndex]; int toHit = GetToHitRoll(group.shipType, game); Hits groupHits = GetHitsToDestroy(group, remainingDice, toHit); hits.insert(hits.begin(), groupHits.begin(), groupHits.end()); // Remember destroyed ships so we don't try to damage them. for (auto& hit : groupHits) destroyedShips[groupIndex].insert(hit.shipIndex); } // Try to damage remaining ships. Only need to consider the weakest ship of each group. for (int groupIndex : groupIndices) { if (remainingDice.empty()) break; const Group& group = m_groups[groupIndex]; const auto shipIndices = GetShipIndicesWeakestFirst(group); // Check if the whole group has been destroyed. // We can't just check if shipIndices is empty, because the damamge hasn't been applied yet. if (destroyedShips[groupIndex].size() == shipIndices.size()) continue; int toHit = GetToHitRoll(group.shipType, game); for (int shipIndex : shipIndices) { if (destroyedShips[groupIndex].count(shipIndex) == 0) // Still alive. { Dice used = remainingDice.RemoveAll(toHit); if (!used.empty()) hits.push_back(Hit(group.shipType, shipIndex, used)); break; // No point checking healthier ships. } } } return hits; }
list<int> *Searcher::search(list<string> &terms, list<int> &res) { int ndocs = getDocs(); vector<double> A(ndocs + 1); list<int> numhits; BOOST_FOREACH(string &term, terms) { Hits hits = getHits(term); int ft = hits.size(); if(hits.size() == 0) continue; Hits::iterator ai; for(ai = hits.begin(); ai != hits.end(); ++ai) { Node &anode = *ai; int doc = anode.doc; double wdt = getWdt(anode.freq, getWd()[doc]); double wqt = getWqt(ndocs, ft); A[doc] += wdt * wqt; } hits.free(); }
bool Picker::getObjectIDs(const Hits& results, std::set<ObjectID>& out_objectIDs) const { ObjectIndex* index = Registry::objectIndex(); for(Hits::const_iterator hit = results.begin(); hit != results.end(); ++hit) { bool found = false; // check for the uniform. const osg::NodePath& path = hit->nodePath; for(osg::NodePath::const_reverse_iterator n = path.rbegin(); n != path.rend(); ++n ) { osg::Node* node = *n; if ( node && node->getStateSet() ) { osg::Uniform* u = node->getStateSet()->getUniform( index->getObjectIDUniformName() ); if ( u ) { ObjectID oid; if ( u->get(oid) ) { out_objectIDs.insert( oid ); found = true; } } } } if ( !found ) { // check the geometry. const osg::Geometry* geom = hit->drawable ? hit->drawable->asGeometry() : 0L; if ( geom ) { const ObjectIDArray* ids = dynamic_cast<const ObjectIDArray*>( geom->getVertexAttribArray(index->getObjectIDAttribLocation()) ); if ( ids ) { for(unsigned i=0; i < hit->indexList.size(); ++i) { unsigned index = hit->indexList[i]; if ( index < ids->size() ) { ObjectID oid = (*ids)[index]; out_objectIDs.insert( oid ); } } } } } } return !out_objectIDs.empty(); }