Coord Solver::advise(BaseField &field, float &probability) { Coord point; probability = 1; delete d->facts; d->facts = new AdviseFast::FactSet(&field); delete d->rules; d->rules = new AdviseFast::RuleSet(d->facts); if( AdviseFast::adviseFast(&point, d->facts, d->rules) ) return point; CoordSet surePoints; AdviseFull::ProbabilityMap probabilities; AdviseFull::adviseFull(d->facts, &surePoints, &probabilities); // return one of the sure point (random choice to limit the tropism) [NH] if( !surePoints.empty() ) { KRandomSequence r; uint k = r.getLong(surePoints.size()); CoordSet::iterator it = surePoints.begin(); for (uint i=0; i<k; i++) ++it; return *it; } // Just a minimum probability logic here if( !probabilities.empty() ) { probability = probabilities.begin()->first; return probabilities.begin()->second; } // Otherwise the Field is already solved :) return Coord(-1,-1); }
void AdviseFast::FactSet::addFact( Coord const &point, Fact const &fact) { if(this->count(point)) this->deleteFact(point); Fact &f = ((*this)[point] = fact); // Remove marked points CoordSet marked; set_intersection( f.pointSet.begin(), f.pointSet.end(), _marked.begin(), _marked.end(), inserter(marked, marked.begin())); CoordSet::iterator i; for(i=marked.begin(); i!=marked.end(); ++i) f.pointSet.erase(*i); f.mines -= marked.size(); // Don't insert empty fact if(f.pointSet.empty()) { this->erase(point); return;} for(i=f.pointSet.begin(); i!=f.pointSet.end(); ++i) _containingFacts[*i].insert(point); }