template <class XPR> vtab_t eval(const XPR & xxi){ vtab_t xi = rowvect(xxi); itab_t index = nt2::bsearch (breaks, xi); vtab_t val = coefs(index, 1); for(size_t i=2; i <= order; ++i){ val = mul(colvect(xi-breaks(index)), val) + coefs(index,i); } val = nt2::reshape(val, size(xxi)); return val; }
/* Be sure this corresponds with what happens to player-thrown objects in * dothrow.c (for consistency). --KAA * Returns 0 if object still exists (not destroyed). */ static int drop_throw(struct obj *obj, boolean ohit, int x, int y) { int retvalu = 1; int create; struct monst *mtmp; struct trap *t; if (breaks(obj, x, y)) return 1; if (ohit && (is_multigen(obj) || obj->otyp == ROCK)) create = !rn2(3); else create = 1; if (create && !((mtmp = m_at(level, x, y)) && (mtmp->mtrapped) && (t = t_at(level, x, y)) && (is_pit_trap(t->ttyp)))) { int objgone = 0; if (down_gate(x, y) != -1) objgone = ship_object(obj, x, y, FALSE); if (!objgone) { if (!flooreffects(obj, x, y, "fall")) { /* don't double-dip on damage */ place_object(obj, level, x, y); if (!mtmp && x == u.ux && y == u.uy) mtmp = &youmonst; if (mtmp && ohit) passive_obj(mtmp, obj, NULL); stackobj(obj); retvalu = 0; } } } else obfree(obj, NULL); return retvalu; }
static QList<double> _calcJenksBreaks( QList<double> values, int classes, double minimum, double maximum, int maximumSize = 1000 ) { // Jenks Optimal (Natural Breaks) algorithm // Based on the Jenks algorithm from the 'classInt' package available for // the R statistical prgramming language, and from Python code from here: // http://danieljlewis.org/2010/06/07/jenks-natural-breaks-algorithm-in-python/ // and is based on a JAVA and Fortran code available here: // https://stat.ethz.ch/pipermail/r-sig-geo/2006-March/000811.html // Returns class breaks such that classes are internally homogeneous while // assuring heterogeneity among classes. if ( !values.count() ) return QList<double>(); if ( classes <= 1 ) { return QList<double>() << maximum; } if ( classes >= values.size() ) { return values; } QVector<double> sample; // if we have lots of values, we need to take a random sample if ( values.size() > maximumSize ) { // for now, sample at least maximumSize values or a 10% sample, whichever // is larger. This will produce a more representative sample for very large // layers, but could end up being computationally intensive... qsrand( time( 0 ) ); sample.resize( qMax( maximumSize, values.size() / 10 ) ); QgsDebugMsg( QString( "natural breaks (jenks) sample size: %1" ).arg( sample.size() ) ); QgsDebugMsg( QString( "values:%1" ).arg( values.size() ) ); sample[ 0 ] = minimum; sample[ 1 ] = maximum;; for ( int i = 2; i < sample.size(); i++ ) { // pick a random integer from 0 to n double r = qrand(); int j = floor( r / RAND_MAX * ( values.size() - 1 ) ); sample[ i ] = values[ j ]; } } else { sample = values.toVector(); } int n = sample.size(); // sort the sample values qSort( sample ); QVector< QVector<int> > matrixOne( n + 1 ); QVector< QVector<double> > matrixTwo( n + 1 ); for ( int i = 0; i <= n; i++ ) { matrixOne[i].resize( classes + 1 ); matrixTwo[i].resize( classes + 1 ); } for ( int i = 1; i <= classes; i++ ) { matrixOne[0][i] = 1; matrixOne[1][i] = 1; matrixTwo[0][i] = 0.0; for ( int j = 2; j <= n; j++ ) { matrixTwo[j][i] = std::numeric_limits<double>::max(); } } for ( int l = 2; l <= n; l++ ) { double s1 = 0.0; double s2 = 0.0; int w = 0; double v = 0.0; for ( int m = 1; m <= l; m++ ) { int i3 = l - m + 1; double val = sample[ i3 - 1 ]; s2 += val * val; s1 += val; w++; v = s2 - ( s1 * s1 ) / ( double ) w; int i4 = i3 - 1; if ( i4 != 0 ) { for ( int j = 2; j <= classes; j++ ) { if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] ) { matrixOne[l][j] = i4; matrixTwo[l][j] = v + matrixTwo[i4][j - 1]; } } } } matrixOne[l][1] = 1; matrixTwo[l][1] = v; } QVector<double> breaks( classes ); breaks[classes-1] = sample[n-1]; for ( int j = classes, k = n; j >= 2; j-- ) { int id = matrixOne[k][j] - 1; breaks[j - 2] = sample[id]; k = matrixOne[k][j] - 1; } return breaks.toList(); } //_calcJenksBreaks
//------------------------------------------------------------------------------- // // checkDictionary This function handles all processing of characters in // the "dictionary" set. It will determine the appropriate // course of action, and possibly set up a cache in the // process. // //------------------------------------------------------------------------------- int32_t BreakIterator::checkDictionary(int32_t startPos, int32_t endPos, UBool reverse) { #if 1 return reverse ? startPos : endPos; #else // Reset the old break cache first. uint32_t dictionaryCount = fDictionaryCharCount; reset(); if (dictionaryCount <= 1 || (endPos - startPos) <= 1) { return (reverse ? startPos : endPos); } // Starting from the starting point, scan towards the proposed result, // looking for the first dictionary character (which may be the one // we're on, if we're starting in the middle of a range). utext_setNativeIndex(fText, reverse ? endPos : startPos); if (reverse) { UTEXT_PREVIOUS32(fText); } int32_t rangeStart = startPos; int32_t rangeEnd = endPos; uint16_t category; int32_t current; UErrorCode status = U_ZERO_ERROR; UStack breaks(status); int32_t foundBreakCount = 0; UChar32 c = utext_current32(fText); UTRIE_GET16(&fData->fTrie, c, category); // Is the character we're starting on a dictionary character? If so, we // need to back up to include the entire run; otherwise the results of // the break algorithm will differ depending on where we start. Since // the result is cached and there is typically a non-dictionary break // within a small number of words, there should be little performance impact. if (category & 0x4000) { if (reverse) { do { utext_next32(fText); // TODO: recast to work directly with postincrement. c = utext_current32(fText); UTRIE_GET16(&fData->fTrie, c, category); } while (c != U_SENTINEL && (category & 0x4000)); // Back up to the last dictionary character rangeEnd = (int32_t)UTEXT_GETNATIVEINDEX(fText); if (c == U_SENTINEL) { // c = fText->last32(); // TODO: why was this if needed? c = UTEXT_PREVIOUS32(fText); } else { c = UTEXT_PREVIOUS32(fText); } } else { do { c = UTEXT_PREVIOUS32(fText); UTRIE_GET16(&fData->fTrie, c, category); } while (c != U_SENTINEL && (category & 0x4000)); // Back up to the last dictionary character if (c == U_SENTINEL) { // c = fText->first32(); c = utext_current32(fText); } else { utext_next32(fText); c = utext_current32(fText); } rangeStart = (int32_t)UTEXT_GETNATIVEINDEX(fText);; } UTRIE_GET16(&fData->fTrie, c, category); } // Loop through the text, looking for ranges of dictionary characters. // For each span, find the appropriate break engine, and ask it to find // any breaks within the span. // Note: we always do this in the forward direction, so that the break // cache is built in the right order. if (reverse) { utext_setNativeIndex(fText, rangeStart); c = utext_current32(fText); UTRIE_GET16(&fData->fTrie, c, category); } while(U_SUCCESS(status)) { while((current = (int32_t)UTEXT_GETNATIVEINDEX(fText)) < rangeEnd && (category & 0x4000) == 0) { utext_next32(fText); // TODO: tweak for post-increment operation c = utext_current32(fText); UTRIE_GET16(&fData->fTrie, c, category); } if (current >= rangeEnd) { break; } // We now have a dictionary character. Get the appropriate language object // to deal with it. const LanguageBreakEngine *lbe = getLanguageBreakEngine(c); // Ask the language object if there are any breaks. It will leave the text // pointer on the other side of its range, ready to search for the next one. if (lbe != NULL) { foundBreakCount += lbe->findBreaks(fText, rangeStart, rangeEnd, FALSE, fBreakType, breaks); } // Reload the loop variables for the next go-round c = utext_current32(fText); UTRIE_GET16(&fData->fTrie, c, category); } // If we found breaks, build a new break cache. The first and last entries must // be the original starting and ending position. if (foundBreakCount > 0) { int32_t totalBreaks = foundBreakCount; if (startPos < breaks.elementAti(0)) { totalBreaks += 1; } if (endPos > breaks.peeki()) { totalBreaks += 1; } fCachedBreakPositions = (int32_t *)uprv_malloc(totalBreaks * sizeof(int32_t)); if (fCachedBreakPositions != NULL) { int32_t out = 0; fNumCachedBreakPositions = totalBreaks; if (startPos < breaks.elementAti(0)) { fCachedBreakPositions[out++] = startPos; } for (int32_t i = 0; i < foundBreakCount; ++i) { fCachedBreakPositions[out++] = breaks.elementAti(i); } if (endPos > fCachedBreakPositions[out-1]) { fCachedBreakPositions[out] = endPos; } // If there are breaks, then by definition, we are replacing the original // proposed break by one of the breaks we found. Use following() and // preceding() to do the work. They should never recurse in this case. if (reverse) { return preceding(endPos - 1); } else { return following(startPos); } } // If the allocation failed, just fall through to the "no breaks found" case. } // If we get here, there were no language-based breaks. Set the text pointer // to the original proposed break. utext_setNativeIndex(fText, reverse ? startPos : endPos); return (reverse ? startPos : endPos); #endif }
// ***************************************************************** // GenerateCategories() // ***************************************************************** vector<CategoriesData>* FieldClassification::GenerateCategories(CString fieldName, FieldType fieldType, vector<VARIANT*>& srcValues, tkClassificationType ClassificationType, long numClasses, long& errorCode) { CComVariant minValue, maxValue; minValue.vt = VT_EMPTY; maxValue.vt = VT_EMPTY; long numShapes = srcValues.size(); /* we won't define intervals for string values */ if (ClassificationType != ctUniqueValues && fieldType == STRING_FIELD) { errorCode = tkNOT_UNIQUE_CLASSIFICATION_FOR_STRINGS; return NULL; } if ((numClasses <= 0 || numClasses > 1000) && (ClassificationType != ctUniqueValues)) { errorCode = tkTOO_MANY_CATEGORIES; return NULL; } if (ClassificationType == ctStandardDeviation) { errorCode = tkINVALID_PARAMETER_VALUE; return NULL; } // natural breaks aren't designed to work otherwise if (numShapes < numClasses && ClassificationType == ctNaturalBreaks) { numClasses = numShapes; } // values in specified range should be classified bool useRange = minValue.vt != VT_EMPTY && maxValue.vt != VT_EMPTY && fieldType == DOUBLE_FIELD; if (useRange) //fieldType == DOUBLE_FIELD) { double max, min; dVal(minValue, min); dVal(maxValue, max); minValue.vt = VT_R8; maxValue.vt = VT_R8; minValue.dblVal = min; maxValue.dblVal = max; } //bool useRange = minValue.vt == VT_R8 && maxValue.vt == VT_R8 && fieldType != STRING_FIELD; std::vector<CategoriesData>* result = new std::vector<CategoriesData>; if (ClassificationType == ctUniqueValues) { std::set<CComVariant> dict; CComVariant val; for (long i = 0; i < numShapes; i++) { VariantCopy(&val, srcValues[i]); if (useRange && (val.dblVal < minValue.dblVal || val.dblVal > maxValue.dblVal)) continue; if (dict.find(val) == dict.end()) dict.insert(val); } /* creating categories */ std::vector<CComVariant> values; copy(dict.begin(), dict.end(), inserter(values, values.end())); for (int i = 0; i < (int)values.size(); i++) { CategoriesData data; data.minValue = values[i]; data.maxValue = values[i]; result->push_back(data); } dict.clear(); values.clear(); } else if (ClassificationType == ctEqualSumOfValues) { CComVariant val; // sorting the values std::vector<double> values; double totalSum = 0, dValue; for (int i = 0; i < numShapes; i++) { VariantCopy(&val, srcValues[i]); if (useRange && (val.dblVal < minValue.dblVal || val.dblVal > maxValue.dblVal)) continue; dVal(val, dValue); val.Clear(); values.push_back(dValue); totalSum += dValue; } sort(values.begin(), values.end()); double step = totalSum / (double)numClasses; int index = 1; double sum = 0; for (int i = 0; i < (int)values.size(); i++) { sum += values[i]; if (sum >= step * (double)index || i == numShapes - 1) { CategoriesData data; if (index == numClasses) data.maxValue = values[values.size() - 1]; else if (i != 0) data.maxValue = (values[i] + values[i - 1]) / 2; else data.maxValue = values[0]; if (index == 1) data.minValue = values[0]; else data.minValue = (*result)[result->size() - 1].maxValue; result->push_back(data); index++; } } } else if (ClassificationType == ctEqualIntervals) { CComVariant vMin, vMax; if (useRange) { vMin = minValue; vMax = maxValue; } else { GetMinValue(srcValues, vMin, true); GetMinValue(srcValues, vMax, false); } double dMin, dMax; dVal(vMin, dMin); dVal(vMax, dMax); vMin.Clear(); vMax.Clear(); /* creating classes */ double dStep = (dMax - dMin) / (double)numClasses; while (dMin < dMax) { CategoriesData data; data.minValue = dMin; data.maxValue = dMin + dStep; result->push_back(data); dMin += dStep; } } else if (ClassificationType == ctEqualCount) { CComVariant vMin, vMax; if (useRange) { vMin = minValue; vMax = maxValue; } else { GetMinValue(srcValues, vMin, true); GetMinValue(srcValues, vMax, false); } double dMin, dMax; dVal(vMin, dMin); dVal(vMax, dMax); vMin.Clear(); vMax.Clear(); // sorting the values std::vector<double> values; for (int i = 0; i < numShapes; i++) { VariantCopy(&vMin, srcValues[i]); dVal(vMin, dMin); vMin.Clear(); values.push_back(dMin); } sort(values.begin(), values.end()); /* creating classes */ int i = 0; int count = numShapes / numClasses; for (int i = 0; i < numShapes; i += count) { dMin = values[i]; if (i + count < numShapes) dMax = values[i + count]; else dMax = values[numShapes - 1]; CategoriesData data; data.minValue = dMin; data.maxValue = dMax; result->push_back(data); } values.clear(); } else if (ClassificationType == ctNaturalBreaks) { CComVariant vMin; double dMin; // sorting the values std::vector<double> values; for (int i = 0; i < numShapes; i++) { VariantCopy(&vMin, srcValues[i]); if (useRange && (vMin.dblVal < minValue.dblVal || vMin.dblVal > maxValue.dblVal)) continue; dVal(vMin, dMin); vMin.Clear(); values.push_back(dMin); } sort(values.begin(), values.end()); CJenksBreaks breaks(&values, numClasses); if (breaks.Initialized()) { breaks.Optimize(); std::vector<long>* startIndices = breaks.get_Results(); //std::vector<int>* startIndices = breaks.TestIt(&values, numClasses); if (startIndices) { for (unsigned int i = 0; i < startIndices->size(); i++) { CategoriesData data; data.minValue = values[(*startIndices)[i]]; if (i == startIndices->size() - 1) data.maxValue = values[values.size() - 1]; else data.maxValue = values[(*startIndices)[i + 1]]; result->push_back(data); } delete startIndices; } } } // TODO: implement this as well; then it can be used in table class //else if (ClassificationType == ctStandardDeviation) // ------------------------------------------------------ // generating text expressions // ------------------------------------------------------ if (ClassificationType == ctUniqueValues) { USES_CONVERSION; for (int i = 0; i < (int)result->size(); i++) { //CString strExpression; CString strValue; CComVariant* val = &(*result)[i].minValue; switch (val->vt) { case VT_BSTR: strValue = OLE2CA(val->bstrVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = \"" + strValue + "\""; break; case VT_R8: strValue.Format("%g", val->dblVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = " + strValue; break; case VT_I4: strValue.Format("%i", val->lVal); (*result)[i].name = strValue; (*result)[i].expression = "[" + fieldName + "] = " + strValue; break; } } } else //if (ClassificationType == ctEqualIntervals || ClassificationType == ctEqualCount) { // in case % is present, we need to put to double it for proper formatting fieldName.Replace("%", "%%"); for (int i = 0; i < (int)result->size(); i++) { CategoriesData* data = &((*result)[i]); CString strExpression, strName, sFormat; if (i == 0) { data->minValue.dblVal = floor(data->minValue.dblVal); } else if (i == result->size() - 1) { data->maxValue.dblVal = ceil(data->maxValue.dblVal); } CString upperBound = (i == result->size() - 1) ? "<=" : "<"; switch (data->minValue.vt) { case VT_R8: sFormat = "%g"; data->name = Utility::FormatNumber(data->minValue.dblVal, sFormat) + " - " + Utility::FormatNumber(data->maxValue.dblVal, sFormat); data->expression.Format("[" + fieldName + "] >= %f AND [" + fieldName + "] " + upperBound + " %f", data->minValue.dblVal, data->maxValue.dblVal); break; case VT_I4: sFormat = "%i"; data->name = Utility::FormatNumber(data->minValue.dblVal, sFormat) + " - " + Utility::FormatNumber(data->maxValue.dblVal, sFormat); data->expression.Format("[" + fieldName + "] >= %i AND [" + fieldName + "] " + upperBound + " %i", data->minValue.lVal, data->maxValue.lVal); break; } } } if (result->size() > 0) { return result; } else { delete result; return NULL; } }
static void colSums(SWMat<TNumMat> mat, Vec<TNumVec> vec, int nthreads){ if (mat.ncol != vec.len) throw std::invalid_argument("provided vector has invalid length"); nthreads = std::max(nthreads, 1); TNumVec* cs = vec.ptr; const int nrow = mat.nrow; const int step = mat.step; //in this case the normal colSums is probably faster: if (step*4 > nrow){ colSums<TNumMat, TNumVec, SWMat>(mat, vec, nthreads); return; } const int ncol = mat.ncol; const int iold = -step; const int inew = nrow - step; //splitting the computation manually for multithreading. //Even though it is really hard to think of a case where multithreading here would //make any difference... std::vector<int> breaks(nthreads + 1); double facc = 0, f = ncol/((double)nthreads); for (int i = 1; i < nthreads; ++i){ breaks[i] = round(facc); facc += f; } breaks[nthreads] = ncol; #pragma omp parallel for schedule(static) num_threads(nthreads) for (int chunk = 0; chunk < nthreads; ++chunk){ int firstcol = breaks[chunk]; int lastcol = breaks[chunk+1]; if (lastcol > firstcol){ //first iteration without recursion TNumMat* colValues = mat.colptr(firstcol); TNumMat tmp = 0; for (int row = 0; row < nrow; ++row){ tmp += colValues[row]; } cs[firstcol] = tmp; //other iterations with recursion //it would be much more readable to place this if inside the loop, //but there is no guarantee that the compiler puts it here // (or, even more efficient, before) // (or, even more efficient, before) if (step == 1){ for (int col = firstcol + 1; col < lastcol; ++col){ colValues += 1; tmp += colValues[inew] - colValues[-1]; cs[col] = tmp; } } else if (step == 2){ for (int col = firstcol + 1; col < lastcol; ++col){ colValues += 2; tmp += colValues[inew] + colValues[inew + 1] - colValues[-2] - colValues[-1]; cs[col] = tmp; } } else { for (int col = firstcol + 1; col < lastcol; ++col){ colValues += step; //subtracting old values for (int i = iold; i < 0; ++i){ tmp -= colValues[i]; } //adding new ones for (int i = inew; i < nrow; ++i){ tmp += colValues[i]; } cs[col] = tmp; } } } } }
/* TRUE iff thrown/kicked/rolled object doesn't pass through iron bars */ boolean hits_bars(struct obj ** obj_p, /* *obj_p will be set to NULL if object breaks */ int x, int y, int always_hit, /* caller can force a hit for items which would fit through */ int whodidit) { /* 1==hero, 0=other, -1==just check whether it'll pass thru */ struct obj *otmp = *obj_p; int obj_type = otmp->otyp; boolean hits = always_hit; if (!hits) switch (otmp->oclass) { case WEAPON_CLASS: { int oskill = objects[obj_type].oc_skill; hits = (oskill != -P_BOW && oskill != -P_CROSSBOW && oskill != -P_DART && oskill != -P_SHURIKEN && oskill != P_SPEAR && oskill != P_JAVELIN && oskill != P_KNIFE); /* but not dagger */ break; } case ARMOR_CLASS: hits = (objects[obj_type].oc_armcat != ARM_GLOVES); break; case TOOL_CLASS: hits = (obj_type != SKELETON_KEY && obj_type != LOCK_PICK && obj_type != CREDIT_CARD && obj_type != TALLOW_CANDLE && obj_type != WAX_CANDLE && obj_type != LENSES && obj_type != TIN_WHISTLE && obj_type != MAGIC_WHISTLE); break; case ROCK_CLASS: /* includes boulder */ if (obj_type != STATUE || mons[otmp->corpsenm].msize > MZ_TINY) hits = TRUE; break; case FOOD_CLASS: if (obj_type == CORPSE && mons[otmp->corpsenm].msize > MZ_TINY) hits = TRUE; else hits = (obj_type == MEAT_STICK || obj_type == HUGE_CHUNK_OF_MEAT); break; case SPBOOK_CLASS: case WAND_CLASS: case BALL_CLASS: case CHAIN_CLASS: hits = TRUE; break; default: break; } if (hits && whodidit != -1) { if (whodidit ? hero_breaks(otmp, x, y, FALSE) : breaks(otmp, x, y)) *obj_p = otmp = 0; /* object is now gone */ /* breakage makes its own noises */ else if (obj_type == BOULDER || obj_type == HEAVY_IRON_BALL) pline("Whang!"); else if (otmp->oclass == COIN_CLASS || objects[obj_type].oc_material == GOLD || objects[obj_type].oc_material == SILVER) pline("Clink!"); else pline("Clonk!"); } return hits; }
/* returns number of scattered objects */ long scatter(int sx, int sy, /* location of objects to scatter */ int blastforce, /* force behind the scattering */ unsigned int scflags, struct obj *obj) { /* only scatter this obj */ struct obj *otmp; struct level *lev = obj ? obj->olev : level; int tmp; int farthest = 0; uchar typ; long qtmp; boolean used_up; boolean individual_object = obj ? TRUE : FALSE; struct monst *mtmp; struct scatter_chain *stmp, *stmp2 = 0; struct scatter_chain *schain = NULL; long total = 0L; boolean visible = (lev == level && cansee(sx, sy)); while ((otmp = individual_object ? obj : lev->objects[sx][sy]) != 0) { if (otmp->quan > 1L) { qtmp = otmp->quan - 1; if (qtmp > LARGEST_INT) qtmp = LARGEST_INT; qtmp = (long)rnd((int)qtmp); otmp = splitobj(otmp, qtmp); } else { obj = NULL; /* all used */ } obj_extract_self(otmp); used_up = FALSE; /* 9 in 10 chance of fracturing boulders or statues */ if ((scflags & MAY_FRACTURE) && ((otmp->otyp == BOULDER) || (otmp->otyp == STATUE)) && rn2(10)) { if (otmp->otyp == BOULDER) { if (visible) pline("%s apart.", Tobjnam(otmp, "break")); fracture_rock(otmp); place_object(otmp, lev, sx, sy); if ((otmp = sobj_at(BOULDER, lev, sx, sy)) != 0) { /* another boulder here, restack it to the top */ obj_extract_self(otmp); place_object(otmp, lev, sx, sy); } } else { struct trap *trap; if ((trap = t_at(lev, sx, sy)) && trap->ttyp == STATUE_TRAP) deltrap(lev, trap); if (visible) pline("%s.", Tobjnam(otmp, "crumble")); break_statue(otmp); place_object(otmp, lev, sx, sy); /* put fragments on floor */ } used_up = TRUE; /* 1 in 10 chance of destruction of obj; glass, egg destruction */ } else if ((scflags & MAY_DESTROY) && (!rn2(10) || (objects[otmp->otyp].oc_material == GLASS || otmp->otyp == EGG))) { if (breaks(otmp, (xchar) sx, (xchar) sy)) used_up = TRUE; } if (!used_up) { stmp = malloc(sizeof (struct scatter_chain)); stmp->next = NULL; stmp->obj = otmp; stmp->ox = sx; stmp->oy = sy; tmp = rn2(8); /* get the direction */ stmp->dx = xdir[tmp]; stmp->dy = ydir[tmp]; tmp = blastforce - (otmp->owt / 40); if (tmp < 1) tmp = 1; stmp->range = rnd(tmp); /* anywhere up to that determ. by wt */ if (farthest < stmp->range) farthest = stmp->range; stmp->stopped = FALSE; if (!schain) schain = stmp; else stmp2->next = stmp; stmp2 = stmp; } } while (farthest-- > 0) { for (stmp = schain; stmp; stmp = stmp->next) { if ((stmp->range-- > 0) && (!stmp->stopped)) { bhitpos.x = stmp->ox + stmp->dx; bhitpos.y = stmp->oy + stmp->dy; typ = lev->locations[bhitpos.x][bhitpos.y].typ; if (!isok(bhitpos.x, bhitpos.y)) { bhitpos.x -= stmp->dx; bhitpos.y -= stmp->dy; stmp->stopped = TRUE; } else if (!ZAP_POS(typ) || closed_door(lev, bhitpos.x, bhitpos.y)) { bhitpos.x -= stmp->dx; bhitpos.y -= stmp->dy; stmp->stopped = TRUE; } else if ((mtmp = m_at(lev, bhitpos.x, bhitpos.y)) != 0) { if (scflags & MAY_HITMON) { stmp->range--; if (ohitmon(mtmp, stmp->obj, 1, FALSE)) { stmp->obj = NULL; stmp->stopped = TRUE; } } } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) { if (scflags & MAY_HITYOU) { int hitvalu, hitu; action_interrupted(); hitvalu = 8 + stmp->obj->spe; if (bigmonst(youmonst.data)) hitvalu++; hitu = thitu(hitvalu, dmgval(stmp->obj, &youmonst), stmp->obj, NULL); if (hitu) stmp->range -= 3; } } else { if (scflags & VIS_EFFECTS) { /* tmpsym_at(bhitpos.x, bhitpos.y); */ /* delay_output(); */ } } stmp->ox = bhitpos.x; stmp->oy = bhitpos.y; } } } for (stmp = schain; stmp; stmp = stmp2) { int x, y; stmp2 = stmp->next; x = stmp->ox; y = stmp->oy; if (stmp->obj) { if (x != sx || y != sy) total += stmp->obj->quan; place_object(stmp->obj, lev, x, y); stackobj(stmp->obj); } free(stmp); if (lev == level) newsym(x, y); } return total; }
int main(int argc, char *argv[]) { int format = UNKNOWN; int gaps = APPEND; int ret = 0; /* return value of breaks() */ /* option variables */ int c; /* getopt_long() variables */ extern char *optarg; extern int optind; static struct option longopts[] = { {"help", no_argument, NULL, 'h'}, {"input-format", required_argument, NULL, 'i'}, {"append-gaps", no_argument, NULL, 'a'}, {"prepend-gaps", no_argument, NULL, 'p'}, {"split-gaps", no_argument, NULL, 's'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; progname = argv[0]; while (-1 != (c = getopt_long(argc, argv, "hi:V", longopts, NULL))) { switch (c) { case 'h': usage(0); break; case 'i': if (0 == strcmp("cue", optarg)) { format = CUE; } else if (0 == strcmp("toc", optarg)) { format = TOC; } else { fprintf(stderr, "%s: error: unknown input file" " format `%s'\n", progname, optarg); usage(1); } break; case 'a': gaps = APPEND; break; case 'p': gaps = PREPEND; break; case 's': gaps = SPLIT; break; case 'V': version(); break; default: usage(1); break; } } /* What we do depends on the number of operands. */ if (optind == argc) { /* No operands: report breakpoints of stdin. */ ret = breaks("-", format, gaps); } else { /* Report track breakpoints for each operand. */ for (; optind < argc; optind++) { ret = breaks(argv[optind], format, gaps); /* Exit if breaks() returns nonzero. */ if (!ret) { break; } } } return ret; }
void print_non_overlapping_pairs(std::vector<int>& v) { std::vector<bool> breaks(v.size() - 1, false); // breaks used for segmenting print_vec(v, breaks, 0); }