/** * 主要是为了调整power用,为了避免power过大而跑过可 * 目标点。原则视为了更高层协调,power只可能减小不可 * 能增大。为了不必要到dash,power也可可能为零。也就 * dash不执行 * power 的正负由外面给定 * This funcition is mainly used to adjust ( usually decrease ) the dash power * to avoid run over the target position by using a big power. The final power * could be 0 to avoid an unnecessary dash. * The sign of power is given outside the function. * @param player the player to caculate. * @param target the target position to go to. * @param buffer * @param power orignal power given. * @return power adjusted. */ double Dasher::AdjustPowerForDash(const PlayerState & player, Vector target, double buffer, double power) { const double & speedmax = player.GetEffectiveSpeedMax(); const double & effort = player.GetEffort(); const double & accrate = player.GetDashPowerRate(); const Vector & pos = player.GetPos(); const Vector & vel = player.GetVel(); const double & facing = player.GetBodyDir(); if (pos.Dist(target) > speedmax + buffer){ //怎么跑的都不会跑过 return power; } if((pos + vel).Dist(target) < buffer) { //不跑也能到到达,就不用跑了 return 0.0; } Line dash_line(Ray(pos, player.GetBodyDir())); Vector projective_target = dash_line.GetProjectPoint(target); Vector acc = projective_target - pos - vel; double dash_power = acc.Mod() / (effort * accrate); if (GetAngleDegDiffer(acc.Dir(), facing) > 90.0){ dash_power = -dash_power; } if (power > 0){ return MinMax(ServerParam::instance().minDashPower(), dash_power, power); } else { return MinMax(power, dash_power, ServerParam::instance().maxDashPower()); } }
int MinMax(struct tree *node){ int bestValue,value; if(isTerminalNode(node)==1){ node->previous->score=node->score; return (node->score); } if(node->type==0){ bestValue=-1000000; value=MinMax(node->left); bestValue=max(bestValue,value); value=MinMax(node->right); bestValue=max(bestValue,value); node->score=bestValue; } else{ bestValue=100000; value=MinMax(node->left); bestValue=min(bestValue,value); value=MinMax(node->right); bestValue=min(bestValue,value); node->score=bestValue; } return bestValue; }
bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection) { int minSourceX, maxSourceX, minSourceY, maxSourceY; MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX); MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY); int minClipX, maxClipX, minClipY, maxClipY; MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX); MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY); if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY || maxSourceY <= minClipY) { if (intersection) { intersection->x = minSourceX; intersection->y = maxSourceY; intersection->width = maxSourceX - minSourceX; intersection->height = maxSourceY - minSourceY; } return false; } else { if (intersection) { intersection->x = std::max(minSourceX, minClipX); intersection->y = std::max(minSourceY, minClipY); intersection->width = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX); intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY); } return true; } }
int main(int argc, char* argv[]) { int minimum = MinMax([] (auto x, auto y) { return x < y ? x : y; }, 1.5, 2); int maximum = MinMax([] (auto x, auto y) { return x > y ? x : y; }, 1, 2, 3, 4.5); std::cout << "min:" << minimum << "\nmax:" << maximum << "\n"; // std::cout << vmin(1,2,3,4); }
//-------------------------------------------------------------------------------- // CArrayIterator::InitBounds //-------------------------------------------------------------------------------- void CArrayIterator::InitBounds(ArrayIndex itsLowBound, ArrayIndex itsHighBound, Boolean itsForward) { fHighBound = (fDynamicArray->fSize > 0) ? MinMax(0, itsHighBound, fDynamicArray->fSize - 1) : kEmptyIndex; fLowBound = (fHighBound > kEmptyIndex) ? MinMax(0, itsLowBound, fHighBound) : kEmptyIndex; fIterateForward = itsForward; Reset(); } // CArrayIterator::Init
IMAGE Difference (IMAGE a, IMAGE b) { IMAGE t=0; int i=0, j=0, rmax=0, rmin=0, cmax=0, cmin=0; MinMax (a, b, &rmax, &cmax, &rmin, &cmin); t = newimage (rmax-rmin+1, cmax-cmin+1); t->info->oi = -rmin; t->info->oj = -cmin; if (t == 0) { printf ("Out of storage in Difference!\n"); exit (1); } for (i=rmin; i<rmax; i++) { for (j=cmin; j< cmax; j++) { if (pget(a,i,j)==1 && pget(b,i,j)!=1) pset (t, i, j, 1); else pset (t, i, j, 0); } } return t; }
int SPU_Init(int coreid, int buffersize) { int i, j; //for(int i=0;i<256;i++) // cos_lut[i] = cos(i/256.0*M_PI); SPU_core = new SPU_struct(740); SPU_Reset(); for(i = 0; i < 16; i++) { for(j = 0; j < 89; j++) { precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8); if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i]; } } for(i = 0; i < 8; i++) { for(j = 0; j < 89; j++) { precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88); } } return SPU_ChangeSoundCore(coreid, buffersize); }
//static double cos_lut[256]; int SPU_Init(int coreid, int buffersize) { int i, j; //for some reason we dont use the cos lut anymore... did someone decide it was slow? //for(int i=0;i<256;i++) // cos_lut[i] = cos(i/256.0*M_PI); SPU_core = new SPU_struct((int)ceil(samples_per_hline)); SPU_Reset(); //create adpcm decode accelerator lookups for(i = 0; i < 16; i++) { for(j = 0; j < 89; j++) { precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8); if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i]; } } for(i = 0; i < 8; i++) { for(j = 0; j < 89; j++) { precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88); } } return SPU_ChangeSoundCore(coreid, buffersize); }
void ToggleTrackEdit(GtkWidget *widget,gpointer data) { GripInfo *ginfo; GripGUI *uinfo; ginfo=(GripInfo *)data; uinfo=&(ginfo->gui_info); if(uinfo->track_edit_visible) { gtk_window_resize(GTK_WINDOW(uinfo->app), uinfo->win_width, uinfo->win_height); gtk_widget_hide(uinfo->track_edit_box); UpdateGTK(); } else { if(uinfo->minimized) MinMax(NULL,(gpointer)ginfo); gtk_widget_show(uinfo->track_edit_box); gtk_window_resize(GTK_WINDOW(uinfo->app), uinfo->win_width, uinfo->win_height_edit); } uinfo->track_edit_visible=!uinfo->track_edit_visible; }
main(int argc, char *argv[]){ //question1 double test[] = {6.5,2.0,4.4,8.1,3.3}; double *values; values = MinMax(test, 5); printf("The min is %lf the max is %lf",values[0],values[1]); printf("\n"); int v = 14 % 5 / 3; printf("%d",v); //question3 //char s[] = {"xyabbAaaecccDEf"}; //int six = removeVowelArray(s); //printf("removed %d vowels and the remaining string is %s",six,s); //char testCh[] = {"test"}; //char *testingCh; //char testingCh[] = {"testing"}; //testingCh = testCh; //printf("new array is now %s ", testingCh); //question 4 /* while (--argc > 0 ){ printf("%s\n", *(argv+argc)); } printf("%c\n", argv[0][5]); printf("%c\n", *(argv[2]+3)); */ }
//============================================================ void im_color::Whiten() { // Calculate current min max values short MinR, MaxR, MinG, MaxG, MinB, MaxB; MinMax(MinR, MaxR, MinG, MaxG, MinB, MaxB); // Calculate current white value float AveR = 0; float AveG = 0; float AveB = 0; for (int i=0; i<R.NumPixels; i++) { AveR += R.Data1D[i]; AveG += G.Data1D[i]; AveB += B.Data1D[i]; } AveR /= R.NumPixels; AveG /= R.NumPixels; AveB /= R.NumPixels; // Whiten image float Ave = (AveR + AveG + AveB) / 3; float ScaleR = Ave / AveR; float ScaleG = Ave / AveG; float ScaleB = Ave / AveB; for (int i=0; i<R.NumPixels; i++) { R.Data1D[i] = (short)(R.Data1D[i] * ScaleR); G.Data1D[i] = (short)(G.Data1D[i] * ScaleG); B.Data1D[i] = (short)(B.Data1D[i] * ScaleB); if (R.Data1D[i] > MaxR) R.Data1D[i] = MaxR; if (G.Data1D[i] > MaxG) G.Data1D[i] = MaxG; if (B.Data1D[i] > MaxB) B.Data1D[i] = MaxB; } }
extern "C" int SPU_Init(NDS_state *state, int coreid, int buffersize) { int i, j; //__asm int 3; //for(int i=0;i<256;i++) // cos_lut[i] = cos(i/256.0*M_PI); state->SPU_core = new SPU_struct(state, 44100); //pick a really big number just to make sure the plugin doesnt request more SPU_Reset(state); for(i = 0; i < 16; i++) { for(j = 0; j < 89; j++) { precalcdifftbl[j][i] = (((i & 0x7) * 2 + 1) * adpcmtbl[j] / 8); if(i & 0x8) precalcdifftbl[j][i] = -precalcdifftbl[j][i]; } } for(i = 0; i < 8; i++) { for(j = 0; j < 89; j++) { precalcindextbl[j][i] = MinMax((j + indextbl[i]), 0, 88); } } //return SPU_ChangeSoundCore(coreid, buffersize); return 0; }
void MeshBuilder::centerAndNormalizeMesh() { const MinMax minMax = for_each(m_Vertices.begin(), m_Vertices.end(), MinMax()); const Vector3f size(minMax.max - minMax.min); const Vector3f center = (minMax.max + minMax.min) / 2; const float maxDimension = max(size.x, max(size.y, size.z)); const float scale = maxDimension == 0 ? 1 : 1 / maxDimension; for_each(m_Vertices.begin(), m_Vertices.end(), MoveAndScale(-center, scale)); }
Color OrenNayarIllum( Point3& N, Point3& L, Point3& V, float rough, Color& rho, float* pDiffIntensOut, float NL ) { // float a = NL >= -1.0f ? float( acos( NL / Len(L) )) : AngleBetween( N, L ); // use the non-uniform scale corrected NL if ( NL < -1.0f ) NL = Dot( N, L ); // float a = float( acos( NL / Len(L) )) ; float a = 0.0f; if( NL < 0.9999f ) a = acosf( NL ); a = Bound( a, -Pi*0.49f, Pi*0.49f ); float NV = Dot( N, V ); // need this to accomodate double sided materials if( NV < 0.0f ){ NV = -NV; V = -V; } float b = 0.0f; if( NV < 0.9999f ) b = acosf( NV ); MinMax( b, a ); // b gets min, a gets max //N.V is the length of the projection of v onto n; times N is a vector along N of that length // V - that pt gives a tangent vector in the plane of N, for measuring phi Point3 tanV = V - N * NV; Point3 tanL = L - N * NL; float w = Len( tanV ) * Len( tanL ); float cosDPhi = (Abs(w) < 1e-4) ? 1.0f : Dot( tanV, tanL ) / w; cosDPhi = Bound( cosDPhi, -1.0f, 1.0f ); // float bCube = (cosDPhi >= 0.0f) ? 0.0f : Cube( 2.0f * b * PiIvr ); float bCube = (cosDPhi >= 0.0f) ? Cube( 2.0f * -b * PiIvr ) : Cube( 2.0f * b * PiIvr ); // these three can be pre-calc'd for speed float sigma2 = Sqr( rough ); float sigma3 = sigma2 / (sigma2 + 0.09f); float c1 = 1.0f - 0.5f * (sigma2 / (sigma2 + 0.33f)); float c2 = 0.45f * sigma3 * (float(sin(a)) - bCube); float c3 = 0.125f * sigma3 * Sqr( 4.0f * a * b * Pi2Ivr ); float tanB = float( tan(b) ); float tanAB = float( tan( (a+b) * 0.5f )); tanB = Bound( tanB, -100.0f, 100.0f ); tanAB = Bound( tanAB, -100.0f, 100.0f ); Color o; float l1 = ( c1 + c2 * cosDPhi * tanB + c3 * (1.0f - Abs( cosDPhi )) * tanAB ); float l2 = 0.17f * (sigma2 / (sigma2 + 0.13f)) * ( 1.0f - cosDPhi * Sqr( 2.0f * b * PiIvr )); if( pDiffIntensOut ) *pDiffIntensOut = l1+l2; o.r = l1 * rho.r + l2 * Sqr( rho.r ); o.g = l1 * rho.g + l2 * Sqr( rho.g ); o.b = l1 * rho.b + l2 * Sqr( rho.b ); return UBound( o ); }
int main(){ insert(&root,M); int x; MinMax(root); //printf("%d\n",x); //print_tree(root); play(root); }
/** * Get min max pairs as a tuple. * @param minProperty : Property name for the min property * @param maxProperty : Property name for the max property * @return A tuple consisting of min, max */ ReflectometryWorkflowBase::MinMax ReflectometryWorkflowBase::getMinMax( const std::string& minProperty, const std::string& maxProperty) const { const double min = getProperty(minProperty); const double max = getProperty(maxProperty); if (min > max) { throw std::invalid_argument("Cannot have any WavelengthMin > WavelengthMax"); } return MinMax(min, max); }
/** * Get ball velocity after tackle. * \param agent. * \param angle tackle angle. * \return ball velocity. */ Vector Tackler::GetBallVelAfterTackle(const Agent & agent, AngleDeg tackle_angle) { UpdateTackleData(agent); tackle_angle = GetNormalizeAngleDeg(tackle_angle, 0.0); int idx1 = ang2idx(tackle_angle); //下界 int idx2 = ang2idx(tackle_angle + 1.0); //上界 double rate = MinMax(0.0, idx2 - tackle_angle, 1.0); return mBallVelAfterTackle[idx1] * rate + mBallVelAfterTackle[idx2] * (1.0 - rate); }
int SubSet (IMAGE a, IMAGE b) { int i=0, j=0; int rmax=0, rmin=0, cmax=0, cmin=0; MinMax (a, b, &rmax, &cmax, &rmin, &cmin); for (i=rmin; i<rmax; i++) for (j=cmin; j< cmax; j++) if (pget(a,i,j)==1 && pget(b,i,j)==0) return 0; return 1; }
/******************************************************************************\ * main * \******************************************************************************/ int main(void) { char p; readboard(); if(piece_counter < 4) { if(board[columns/2 * total_rows + 0] == SPACE){ column = columns/2; piece = BLUE; } else { column = columns/2 +1; piece = BLUE; } } else { int * result; result = MinMax(7); column = result[0]; piece = result[1]; } freeboard(); switch(piece) { case SPACE: p = 's'; break; case RED: p = 'r'; break; case BLUE: p = 'b'; break; case GREEN: p = 'g'; break; } printf("(%d, %c)", column, p); return 0; } /* main */
void ScanlineFill() { Matrix polygon; int boxLeft, boxRight, boxHigh, boxLow; int i,j,k; int edgeXat_i,lim_y_up,lim_y_down; Matrix xlist; AcceptPolygon(&polygon); InitGraph(); DrawPolygon(&polygon); InitEdges(&polygon); MinMax(&polygon,0,0,polygon.rows-1,&boxLeft,&boxRight); MinMax(&polygon,1,0,polygon.rows-1,&boxLow,&boxHigh); InitMatrix(&xlist,polygon.rows-1,1); for(i=boxLow+1,k=0;i<boxHigh;i++,k=0) { for(j=0;j<polygon.rows-1;j++) { if((int)polygon.matrix[j][0] == (int)polygon.matrix[j+1][0]) edgeXat_i = polygon.matrix[j][0]; else if((int)polygon.matrix[j][1] == (int)polygon.matrix[j+1][1]) edgeXat_i = polygon.matrix[j][0]<polygon.matrix[j+1][0]?polygon.matrix[j][0]:polygon.matrix[j+1][0]; else edgeXat_i = (i - polygon.matrix[j][3])/polygon.matrix[j][2]; if(edgeXat_i>=boxLeft && edgeXat_i<=boxRight ) { lim_y_up = polygon.matrix[j][1]<polygon.matrix[j+1][1]?polygon.matrix[j][1]:polygon.matrix[j+1][1]; lim_y_down = polygon.matrix[j][1]>polygon.matrix[j+1][1]?polygon.matrix[j][1]:polygon.matrix[j+1][1]; if(lim_y_up<=i && i<=lim_y_down) xlist.matrix[k++][0] = edgeXat_i; } DPQS(&xlist,0,0,k-1); } for(j=0;j<k;j+=2) line(xlist.matrix[j][0]+1,i,xlist.matrix[j+1][0],i); } }
IMAGE Intersection (IMAGE a, IMAGE b) { IMAGE t=0; int i=0, j=0, rmin=0, rmax=0, cmin=0, cmax=0; MinMax (a, b, &rmax, &cmax, &rmin, &cmin); t = newimage (rmax-rmin, cmax-cmin); t->info->oi = -rmin; t->info->oj = -cmin; for (i=rmin; i<rmax; i++) for (j=cmin; j< cmax; j++) if (pget(a,i,j)==1 && pget(b,i,j)==1) pset(t, i,j,1); else pset (t, i, j, 0); return t; }
void DblMatrix::SaveAsBMP(std::string Name) { double Min=DBL_MAX, Max=-DBL_MAX; MinMax(Min, Max); IplImage* Output = cvCreateImage(cvSize(GetWidth(), GetHeight()), IPL_DEPTH_8U, 1); for(int j=0; j<GetHeight(); j++) for(int i=0; i<GetWidth(); i++) { double u = (*this)[j][i]; double v = 255.0 * (u-Min)/(Max-Min); cvSetReal2D(Output, j, i, v); } cvSaveImage(Name.c_str(), Output); cvReleaseImage(&Output); }
int ImCompare (IMAGE a, IMAGE b) { int i=0, j=0, rmin=0, rmax=0, cmin=0, cmax=0, x=0, y=0; MinMax (a, b, &rmax, &cmax, &rmin, &cmin); for (i=rmin; i<rmax; i++) for (j=cmin; j< cmax; j++) { x = pget (a, i, j); y = pget (b, i, j); if (x==1 && y == 0) return 0; if (x==0 && y == 1) return 0; } return 1; }
int main(int argc, const char *argv[]) { std::vector<std::vector<int>> mat{ {15,10,0,-6,17}, {3,14,8,9,2}, {1,5,14,20,-3}, {7,19,10,2,0} }; double param = 0.21; std::cout << "Init matrix" << std::endl; print(mat); MinMax(mat); Sav(mat); HW(mat, param); return 0; }
MinMax MoneyBox::FindMinMaxSum(int weight, TList<Coin>* coins) { int count = coins->GetCount(); MinMax* sumArray = new MinMax[weight+1]; sumArray[0] = MinMax(0, 0); //for each weight from 1 till weight find min and max sums for(int i = 1; i <= weight; i++) { MinMax currentMinMax; for(int j = 0; j < count; j++) { //Find index of sum without this coin Coin coin = coins->GetElement(j); int prevSumIndex = i - coin.weight; //If can add coin to money box if (prevSumIndex >= 0 && sumArray[prevSumIndex].min != -1 && sumArray[prevSumIndex].max != -1) { //Update current min int minPrice = sumArray[prevSumIndex].min + coin.price; if (currentMinMax.min == -1 || minPrice < currentMinMax.min) { currentMinMax.min = minPrice; } //Update current max int maxPrice = sumArray[prevSumIndex].max + coin.price; if (maxPrice > currentMinMax.max) { currentMinMax.max = maxPrice; } } } sumArray[i] = currentMinMax; } MinMax resultSum = sumArray[weight]; delete sumArray; return resultSum; }
static long read_Cell_Data(void) { static char linebuf[MAX_LINE]; static char *lbp = NULL; static char format[MAX_LINE]; int state = STATE_VIEW_TOP; int i; Cell *gp = grid; int view_ct = 1; /* * First time through... * 1) initialize line-buffer pointer and try to fill the line buffer * 2) build the format for sscanf() */ if (lbp == NULL) { lbp = linebuf; bu_fgets(lbp, MAX_LINE, filep); bu_strlcpy(format, "%lf %lf", sizeof(format)); if (color_flag) bu_strlcat(format, " %d %d %d", sizeof(format)); else { /* Skip to field of interest */ for (i = 1; i < field; i++) bu_strlcat(format, " %*lf", sizeof(format)); bu_strlcat(format, " %lf", sizeof(format)); } } /* EOF encountered before we found the desired view? */ if (feof(filep)) return 0; /* Read the data */ do { double x, y; int r, g, b; cell_val value; if (lbp[strlen(lbp) - 1] != '\n') bu_exit (1, "Overlong line\n"); /* Have we run out of room for the cells? If so reallocate memory */ if (gp - grid >= maxcells) { long ncells = gp - grid; maxcells *= 2; grid = (Cell *) bu_realloc((char *) grid, sizeof(Cell) * maxcells, "grid"); if (debug_flag & CFB_DBG_MEM) bu_log("cell-fb: maxcells increased to %ld\n", maxcells); gp = grid + ncells; } /* Process any non-data (i.e. view-header) lines */ while ((state != STATE_BEYOND_DATA) && ((color_flag && (sscanf(lbp, format, &x, &y, &r, &g, &b) != 5)) || (! color_flag && (sscanf(lbp, format, &x, &y, &value.v_scalar) != 3)))) { if (state == STATE_VIEW_TOP) state = STATE_IN_HEADER; else if (state == STATE_IN_DATA) state = STATE_BEYOND_DATA; if (feof(filep) || bu_fgets(lbp, MAX_LINE, filep) == NULL) return gp - grid; } /* * At this point we know we have a line of cell data, * though it might be the first line of the next view. */ if (state == STATE_BEYOND_DATA) { state = STATE_VIEW_TOP; if ((view_flag == 0) || (view_flag == view_ct++)) return gp - grid; else /* Not the selected view, read the next one. */ continue; } else state = STATE_IN_DATA; /* If user has selected a view, only store values for that view. */ if ((view_flag == 0) || (view_flag == view_ct)) { MinMax(xmin, xmax, x); MinMax(ymin, ymax, y); if (debug_flag & CFB_DBG_MINMAX) bu_log("x=%g, y=%g, xmin=%g, xmax=%g, ymin=%g, ymax=%g\n", x, y, xmin, xmax, ymin, ymax); gp->c_x = x; gp->c_y = y; if (color_flag) { gp->c_val.v_color[RED] = r; gp->c_val.v_color[GRN] = g; gp->c_val.v_color[BLU] = b; } else gp->c_val.v_scalar = value.v_scalar; gp++; } } while (bu_fgets(lbp, MAX_LINE, filep) != NULL); return gp - grid; }
/** * 计算用同一dash_power到达某点需要的时间 * Caculate cycles needed to a target position with a certain dash power. * @param player the player to caculate. * @param target the target position to go to. * @param dash_power the power for dash to predict. * @return an integer to show the cycles caculated. */ int Dasher::CyclePredictedToPoint(const PlayerState& player , Vector target , double dash_power) { double corrected_dash_power = dash_power; double effective_power; double predicted_stamina = player.GetStamina(); double predicted_effort = player.GetEffort(); double predicted_recovery = player.GetRecovery(); double predicted_capacity = player.GetCapacity(); double myang = player.GetBodyDir(); Vector position = player.GetPos(); Vector velocity; if (player.GetVelConf() < FLOAT_EPS) { velocity = Vector(0,0); } else { velocity = player.GetVel(); } Vector last_position = position; int max_cyc = (int)(position.Dist(target) / player.GetEffectiveSpeedMax() + 100); int last_action = 0; /* 0 -- turn , 1 -- dash*/ for (int i = 0;i < max_cyc;i++) { if (position.Dist(target) < PlayerParam::instance().AtPointBuffer()) { return i; } if (position.Dist(target) > last_position.Dist(target) + FLOAT_EPS && last_action == 1) { return i; } last_position = position; /*decide if we should turn*/ double targ_ang; if (dash_power > 0) { targ_ang = (target - position).Dir() - myang; } else { targ_ang = (target - position).Dir() - GetNormalizeAngleDeg(myang + 180); } double max_go_to_point_angle_err = 4; //见08CP_max_go_to_point_angle_err if (fabs(GetNormalizeAngleDeg(targ_ang)) > max_go_to_point_angle_err) { /*turnint*/ double this_turn = MinMax(-player.GetMaxTurnAngle(), GetNormalizeAngleDeg(targ_ang) , player.GetMaxTurnAngle()); myang += this_turn; corrected_dash_power = 0; last_action = 0; } else { corrected_dash_power = player.CorrectDashPowerForStamina(dash_power); if (fabs(corrected_dash_power) > predicted_stamina) { effective_power = Sign(corrected_dash_power) * predicted_stamina; } else { effective_power = corrected_dash_power; } effective_power *= predicted_effort; effective_power *= player.GetDashPowerRate(); velocity += Polar2Vector(effective_power , myang); last_action = 1; } if (velocity.Mod() > player.GetEffectiveSpeedMax()) { velocity *= (player.GetEffectiveSpeedMax()/ velocity.Mod()); } position += velocity; velocity *= player.GetPlayerDecay(); //08 内UpdatePredictStaminaWithDash函数 直接写入此函数 if (dash_power > 0) { predicted_stamina -= dash_power; } else { predicted_stamina -= 2 * dash_power; } if (predicted_stamina < 0) { predicted_stamina = 0; } if (predicted_stamina < ServerParam::instance().recoverDecStamina() && predicted_recovery > ServerParam::instance().recoverMin()) { predicted_recovery -= ServerParam::instance().recoverDec(); } if (predicted_stamina < ServerParam::instance().effortDecStamina() && predicted_effort > player.GetEffortMin()) { predicted_effort -= ServerParam::instance().effortDec(); } if (predicted_stamina > ServerParam::instance().effortIncStamina() && predicted_effort < player.GetEffortMax()) { predicted_effort += ServerParam::instance().effortDec(); } //增加capacity改进 double stamina_inc = Min(predicted_recovery * player.GetStaminaIncMax() , predicted_capacity); predicted_stamina += stamina_inc; if (predicted_stamina > ServerParam::instance().staminaMax()) { predicted_stamina = ServerParam::instance().staminaMax(); } predicted_capacity -= stamina_inc; if (predicted_capacity < 0) { predicted_capacity = 0; } } return max_cyc; }
/** * 考虑转身或直接dash * Planing to turn or to dash. * @param agent the agent itself. * @param act an atomic action to return the caculated decision. * @param target the target position to go to. * @param buffer * @param power the intend power for dash. * @param inverse true means running backwards. * @param turn_first true means turn first manually. */ void Dasher::TurnDashPlaning(Agent & agent, AtomicAction & act, Vector target, double buffer, double power, bool inverse, bool turn_first) { act.Clear(); power = inverse? -fabs(power): fabs(power); power = agent.GetSelf().CorrectDashPowerForStamina(power); PlayerState & self = agent.Self(); const Vector & my_pre_pos = self.GetPredictedPos(1); double target_dist = my_pre_pos.Dist(target); AngleDeg target_ang = inverse? GetNormalizeAngleDeg((my_pre_pos - target).Dir() - agent.GetSelf().GetBodyDir()): GetNormalizeAngleDeg((target - my_pre_pos).Dir() - agent.GetSelf().GetBodyDir()); //需要转身的角度 //DT_none //处理转身问题,可能1dash + 1turn更好 double bufang; if(buffer > FLOAT_EPS){ bufang = ASin(buffer / target_dist / 2) * 2; bufang = Max(10.0, bufang); } else{ bufang = 0.0; } const double & effort = self.GetEffort(); const double & accrate = self.GetDashPowerRate(); const double & inertia_moment = self.GetInertiaMoment(); const double & decay = self.GetPlayerDecay(); const double & speedmax = self.GetEffectiveSpeedMax(); const Vector & vel = self.GetVel(); const double & facing = self.GetBodyDir(); double speed = vel.Mod(); double diffang = fabs(target_ang); double oneturnang = self.GetMaxTurnAngle(); if(buffer < FLOAT_EPS && target_dist > 2.6){ oneturnang += 2.6; } if(turn_first || diffang <= oneturnang || speed < 0.04){ //由于噪声的存在,在非身体方向也有速度,调也调不过来,太小时不如直接转,0.04是一般队员的误差极值 act.mType = CT_Turn; act.mTurnAngle = target_ang; act.mSucceed = true; return; } else { //计算1 dash + 1turn; //下面都是算dash到什么速度最好 double mspd1 = (180.0/ ( diffang + 10 ) - 1.0 ) / inertia_moment; //10是buf,不然容易调整后正好还转不过来 double dash2spd = Min(mspd1 / decay, speedmax) / (1 + ServerParam::instance().playerRand()); if( fabs(GetNormalizeAngleDeg(vel.Dir() - facing)) > 90.0){ speed = -speed; } double spd_inf = Max(speed - accrate * ServerParam::instance().maxDashPower(), -dash2spd); double spd_sup = Min(speed + accrate * ServerParam::instance().maxDashPower(), dash2spd); Ray cur_r(self.GetPos(), facing); Vector pt_inf = cur_r.GetPoint(spd_inf * (1.0 + decay)); Vector pt_sup = cur_r.GetPoint(spd_sup * (1.0 + decay)); Vector pt;//要取得点 bool bnegtive;//要跑的点是不是在身后 Line pdl = Line(cur_r).GetPerpendicular(target);//垂线 if(pdl.IsPointInSameSide(pt_inf, pt_sup)){ if(fabs(GetNormalizeAngleDeg(facing-target_ang)) < 90.0){ pt = pt_sup; bnegtive = (spd_sup<0); } else{ pt = pt_inf; bnegtive = (spd_inf<0); } } else{ double dist; bnegtive = !cur_r.Intersection(pdl, dist); //垂点 pt = cur_r.GetPoint(dist); } double dis = pt.Dist(target);//两个周期后离point的距离,用来compare with 2 turn double twoturnang = oneturnang + 180.0 / (1.0 + inertia_moment * fabs(speed) * decay); if(twoturnang > diffang){ const Vector & pt2 = self.GetPredictedPos(2); double dis2 = pt2.Dist(target); if(dis2 < dis || diffang > 102.6){ //一次转太大,误差也大不如直接2turn act.mType = CT_Turn; act.mTurnAngle = target_ang; act.mSucceed = true; return; } } double spd_need; if(bnegtive){ spd_need = -(pt - self.GetPos()).Mod() / (1.0 + decay); } else{ spd_need = (pt - self.GetPos()).Mod() / (1.0 + decay); } //会总是dash而dash后又转不过来...,看着就像不拿球 double turnang_after_dash = 180.0 / (1.0 + inertia_moment * fabs(spd_need) * decay) - 5.0; if(GetAngleDegDiffer((target - pt).Dir(), facing) > turnang_after_dash ){ act.mType = CT_Turn; act.mTurnAngle = target_ang; act.mSucceed = true; return; } double power = ( spd_need - speed ) / accrate / effort; power = MinMax(-ServerParam::instance().maxDashPower(), power, ServerParam::instance().maxDashPower()); //I over act.mType = CT_Dash; act.mDashPower = AdjustPowerForDash(self, pt, FLOAT_EPS, power); act.mDashPower = agent.GetSelf().CorrectDashPowerForStamina(act.mDashPower); if(fabs(act.mDashPower) > FLOAT_EPS) { act.mSucceed = true; } else { act.mType = CT_Turn; //power为零时就不要执行了,没意义 act.mTurnAngle = 0.0; act.mSucceed = true; } } }
/* returns whether we are in the right place or not */ Bool go_to_static_ball(float kick_ang, float dash_pow) { Line l; LogAction6(50, "go_to_static_ball: ball at (%.1f, %.1f) for kick angle %.2f, dash_pow %.2f", Mem->BallX(), Mem->BallY(), kick_ang, dash_pow); if (!Mem->BallPositionValid()) my_error("go_to_static_ball: lost ball"); /* we can be pretty tolerant of angle errors, but distance errors start to matter real quickly */ Vector targ_pt = get_static_ball_pos(Mem->BallAbsolutePosition(), kick_ang); /* we want to try and face the ball at all times */ turn_neck(Mem->LimitTurnNeckAngle(Mem->BallAngleFromNeck())); if (Mem->MySpeed() == 0 && Mem->DistanceTo(targ_pt) <= Mem->CP_static_kick_dist_err) { LogAction3(60, "go_to_static_ball: I am done %.2f", Mem->DistanceTo(targ_pt)); return TRUE; } /* if we are real far from the ball, just use the regular go_to_point */ if (Mem->BallDistance() > 2 * Mem->My_kickable_area()) { LogAction2(60, "go_to_static_ball: far away, using go_to_point"); if (go_to_point(targ_pt, 0 /* no buffer */, dash_pow) != AQ_ActionQueued) my_error("go_to_static_ball: far away, why didn't go_to_point do anything?"); return FALSE; } /* make sure that we go around the ball */ l.LineFromTwoPoints(Mem->MyPos(), targ_pt); Vector proj_ball_pt = l.ProjectPoint(Mem->BallAbsolutePosition()); if (proj_ball_pt.dist(Mem->BallAbsolutePosition()) <= Mem->My_size() + Mem->SP_ball_size + Mem->CP_collision_buffer && l.InBetween(proj_ball_pt, Mem->MyPos(), targ_pt)) { /* we'll do a 90 degree dodge -we always go right */ Vector dodge_pt = Mem->MyPos() + Polar2Vector(Mem->My_size(), Mem->BallAngleFromBody() + Mem->MyBodyAng() + 90); LogAction2(60, "go_to_static_ball: dodging the ball"); if (go_to_point(dodge_pt, 0 /* no buffer */, dash_pow) != AQ_ActionQueued) my_error("go_to_static_ball: dodging, why didn't go_to_point do anything?"); return FALSE; } /* now we need to get to the target_point */ /* first see if we need to turn */ l.LineFromRay(Mem->MyPos(), Mem->MyBodyAng()); float ang = Mem->AngleToFromBody(targ_pt); if (fabs(ang) > 90 || (l.dist(targ_pt) > Mem->CP_static_kick_dist_err && ang > Mem->CP_static_kick_ang_err)) { LogAction2(60, "go_to_static_ball: turning to target_point"); turn(Mem->AngleToFromBody(targ_pt)); return FALSE; } /* now calculate the speed we should be going to land right on the point */ float targ_speed = SolveForFirstTermInfGeomSeries(Mem->My_decay(), Mem->DistanceTo(targ_pt)); float dash_pow_to_use = MinMax(-dash_pow / 2, (targ_speed - Mem->MySpeed()) / Mem->My_dash_power_rate(), dash_pow); LogAction5(60, "go_to_static_ball: targ_speed: %.2f\tMySpeed: %.2f\tdash_pow: %.2f", targ_speed, Mem->MySpeed(), dash_pow_to_use); if (fabs(dash_pow_to_use) > 1) { LogAction3(70, "go_to_static_ball: dash power is too small %.2f", dash_pow_to_use); dash(Mem->CorrectDashPowerForStamina(dash_pow_to_use)); return FALSE; } return TRUE; }
ConvertInt64::ConvertInt64(int64 minval, int64 maxval, bool notnull) { MinMax(minval, maxval); NotNull(notnull); }