int main(int argc, char** argv) { Matrix<int,ColMajor> Ai(rows,cols); // a column-major integer matrix Matrix<float> Af(rows,cols); // a row-major single precision floating point matrix Matrix<double> Ad(rows,cols); // a row-major double precision floating point matrix // grab seed from the current timestamp unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // instance a random number generator std::default_random_engine generator (seed); // instance a uniform distribution std::uniform_real_distribution<double> random(0.0, 1.0); // note that the loop order is not optimal for the integer matrix size_t k=1; for (size_t i=0;i<rows;++i) { for (size_t j=0;j<cols;++j, k++) { Ai(i,j) = k; Af(i,j) = k+random(generator); // add some random stuff for fun Ad(i,j) = k+random(generator); // add some random stuff for fun } } // print matrices to screen std::cout << "== Integer matrix ==" << std::endl; Ai.print(); std::cout << "== Float matrix ==" << std::endl; Af.print(7); std::cout << "== Double matrix ==" << std::endl; Ad.print(16); return 0; }
void CGroup::LoseMorals() { losingMorals = true; for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->bravery < 10) { M(i)->currentActivity = CEnemy::CurrentActivity::aboutToDesert; } else { if (Ai()->Chance(50)) { if (IsCaptain(M(i))) { if (Ai()->Chance(50)) { M(i)->currentActivity = CEnemy::CurrentActivity::deserting; speechManager->AddSpeech(M(i), Ai(i)->GetSpeechString(M(i), true), captainColor); } } else { M(i)->currentActivity = CEnemy::CurrentActivity::aboutToDesert; } } } } }
vector<Coord> GlCubicBSplineInterpolation::constructInterpolatingCubicBSpline(const vector<Coord> &pointsToInterpolate) { vector<Coord> Ai(pointsToInterpolate.size()); vector<float> Bi(pointsToInterpolate.size()); vector<Coord> di(pointsToInterpolate.size()); di[0] = (pointsToInterpolate[1] - pointsToInterpolate[0]) / 3.0f; di[pointsToInterpolate.size() - 1] = (pointsToInterpolate[pointsToInterpolate.size()-1] - pointsToInterpolate[pointsToInterpolate.size()-2]) / 3.0f; Bi[1] = -0.25f; Ai[1] = (pointsToInterpolate[2] - pointsToInterpolate[0] - di[0]) / 4.0f; for (size_t i = 2; i < pointsToInterpolate.size() - 1; ++i) { Bi[i] = -1.0f /(4.0f + Bi[i-1]); Ai[i] = Coord(-(pointsToInterpolate[i+1] - pointsToInterpolate[i-1] - Ai[i-1])*Bi[i]); } for (size_t i = pointsToInterpolate.size() - 2; i > 0; --i) { di[i] = Ai[i] + di[i+1]*Bi[i]; } vector<Coord> bSplineControlPoints; bSplineControlPoints.push_back(pointsToInterpolate[0]); bSplineControlPoints.push_back(pointsToInterpolate[0]+di[0]); for (size_t i = 1 ; i < pointsToInterpolate.size() - 1 ; ++i) { bSplineControlPoints.push_back(pointsToInterpolate[i]-di[i]); bSplineControlPoints.push_back(pointsToInterpolate[i]); bSplineControlPoints.push_back(pointsToInterpolate[i]+di[i]); } bSplineControlPoints.push_back(pointsToInterpolate[pointsToInterpolate.size() - 1]-di[pointsToInterpolate.size() - 1]); bSplineControlPoints.push_back(pointsToInterpolate[pointsToInterpolate.size() - 1]); return bSplineControlPoints; }
GOGONEURO::matrixD GOGONEURO::inv(matrixD A, bool& st){ int n=A.size(); matrixD I(n,n,0.0), Ai(n,n,0.0); for(int i=0;i<n;i++) I[i][i]=1.0; gauss(n,A,Ai,I,st); return Ai; }
void CGroup::ScanForPlayer() { if (playerScanDelay <= 0) { playerScanDelay = playerScanDelayMax; for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->tookDamage && groupIsAwareOfPlayer == false) { for (int k = 0; k < groupMembers.size(); k++) { groupMembers[k]->tookDamage == false; } GroupGainAwarenessOfPlayer(); lastKnownDirection = Ai()->GetPlayerHorizontalDirection(M(i)); } if (Ai()->Chance(50)) { if (Ai(i)->SeesPlayer(900, M(i))) { M(i)->SetPlayerVisible(true); if (activity == GroupActivity::idle) { CEnemy * closest = Ai(0)->GetEnemyClosestToPlayerFromVector(groupMembers); closest->currentActivity = CEnemy::CurrentActivity::spottedPlayer; } if (!groupIsAwareOfPlayer || activity == GroupActivity::searching) { GroupGainAwarenessOfPlayer(); } timeSincePlayerSpotted = 0; } else { M(i)->SetPlayerVisible(false); } } } } }
void test_svd(const std::string & fn, ScalarType EPS) { std::size_t sz1, sz2; //read matrix // sz1 = 2048, sz2 = 2048; // std::vector<ScalarType> in(sz1 * sz2); // random_fill(in); // read file std::fstream f(fn.c_str(), std::fstream::in); //read size of input matrix read_matrix_size(f, sz1, sz2); std::size_t to = std::min(sz1, sz2); viennacl::matrix<ScalarType> Ai(sz1, sz2), Aref(sz1, sz2), QL(sz1, sz1), QR(sz2, sz2); read_matrix_body(f, Ai); std::vector<ScalarType> sigma_ref(to); read_vector_body(f, sigma_ref); f.close(); // viennacl::fast_copy(&in[0], &in[0] + in.size(), Ai); Aref = Ai; viennacl::tools::timer timer; timer.start(); viennacl::linalg::svd(Ai, QL, QR); viennacl::backend::finish(); double time_spend = timer.get(); viennacl::matrix<ScalarType> result1(sz1, sz2), result2(sz1, sz2); result1 = viennacl::linalg::prod(QL, Ai); result2 = viennacl::linalg::prod(result1, trans(QR)); ScalarType sigma_diff = sigmas_compare(Ai, sigma_ref); ScalarType prods_diff = matrix_compare(result2, Aref); bool sigma_ok = (fabs(sigma_diff) < EPS) && (fabs(prods_diff) < std::sqrt(EPS)); //note: computing the product is not accurate down to 10^{-16}, so we allow for a higher tolerance here printf("%6s [%dx%d] %40s sigma_diff = %.6f; prod_diff = %.6f; time = %.6f\n", sigma_ok?"[[OK]]":"[FAIL]", (int)Aref.size1(), (int)Aref.size2(), fn.c_str(), sigma_diff, prods_diff, time_spend); if (!sigma_ok) exit(EXIT_FAILURE); }
int main(void) { printf("If rows come in identical pairs, then everything works.\n"); cpx a[8] = {0, 1, cpx(1,3), cpx(0,5), 1, 0, 2, 0}; cpx b[8] = {1, cpx(0,-2), cpx(0,1), 3, -1, -3, 1, -2}; cpx A[8]; cpx B[8]; FFT(a, A, 1, 8, 1); FFT(b, B, 1, 8, 1); for(int i = 0 ; i < 8 ; i++) { printf("%7.2lf%7.2lf", A[i].a, A[i].b); } printf("\n"); for(int i = 0 ; i < 8 ; i++) { cpx Ai(0,0); for(int j = 0 ; j < 8 ; j++) { Ai = Ai + a[j] * EXP(j * i * two_pi / 8); } printf("%7.2lf%7.2lf", Ai.a, Ai.b); } printf("\n"); cpx AB[8]; for(int i = 0 ; i < 8 ; i++) AB[i] = A[i] * B[i]; cpx aconvb[8]; FFT(AB, aconvb, 1, 8, -1); for(int i = 0 ; i < 8 ; i++) aconvb[i] = aconvb[i] / 8; for(int i = 0 ; i < 8 ; i++) { printf("%7.2lf%7.2lf", aconvb[i].a, aconvb[i].b); } printf("\n"); for(int i = 0 ; i < 8 ; i++) { cpx aconvbi(0,0); for(int j = 0 ; j < 8 ; j++) { aconvbi = aconvbi + a[j] * b[(8 + i - j) % 8]; } printf("%7.2lf%7.2lf", aconvbi.a, aconvbi.b); } printf("\n"); return 0; }
void time_svd(std::size_t sz1, std::size_t sz2) { std::vector<ScalarType> in(sz1 * sz2); random_fill(in); viennacl::matrix<ScalarType> Ai(sz1, sz2), QL(sz1, sz1), QR(sz2, sz2); viennacl::fast_copy(&in[0], &in[0] + in.size(), Ai); Timer timer; timer.start(); viennacl::linalg::svd(Ai, QL, QR); viennacl::backend::finish(); double time_spend = timer.get(); printf("[%dx%d] time = %.6f\n", static_cast<int>(sz1), static_cast<int>(sz2), time_spend); }
//============================================================================= int Amesos_Dscpack::PerformSymbolicFactorization() { ResetTimer(0); ResetTimer(1); MyPID_ = Comm().MyPID(); NumProcs_ = Comm().NumProc(); Epetra_RowMatrix *RowMatrixA = Problem_->GetMatrix(); if (RowMatrixA == 0) AMESOS_CHK_ERR(-1); const Epetra_Map& OriginalMap = RowMatrixA->RowMatrixRowMap() ; const Epetra_MpiComm& comm1 = dynamic_cast<const Epetra_MpiComm &> (Comm()); int numrows = RowMatrixA->NumGlobalRows(); int numentries = RowMatrixA->NumGlobalNonzeros(); Teuchos::RCP<Epetra_CrsGraph> Graph; Epetra_CrsMatrix* CastCrsMatrixA = dynamic_cast<Epetra_CrsMatrix*>(RowMatrixA); if (CastCrsMatrixA) { Graph = Teuchos::rcp(const_cast<Epetra_CrsGraph*>(&(CastCrsMatrixA->Graph())), false); } else { int MaxNumEntries = RowMatrixA->MaxNumEntries(); Graph = Teuchos::rcp(new Epetra_CrsGraph(Copy, OriginalMap, MaxNumEntries)); std::vector<int> Indices(MaxNumEntries); std::vector<double> Values(MaxNumEntries); for (int i = 0 ; i < RowMatrixA->NumMyRows() ; ++i) { int NumEntries; RowMatrixA->ExtractMyRowCopy(i, MaxNumEntries, NumEntries, &Values[0], &Indices[0]); for (int j = 0 ; j < NumEntries ; ++j) Indices[j] = RowMatrixA->RowMatrixColMap().GID(Indices[j]); int GlobalRow = RowMatrixA->RowMatrixRowMap().GID(i); Graph->InsertGlobalIndices(GlobalRow, NumEntries, &Indices[0]); } Graph->FillComplete(); } // // Create a replicated map and graph // std::vector<int> AllIDs( numrows ) ; for ( int i = 0; i < numrows ; i++ ) AllIDs[i] = i ; Epetra_Map ReplicatedMap( -1, numrows, &AllIDs[0], 0, Comm()); Epetra_Import ReplicatedImporter(ReplicatedMap, OriginalMap); Epetra_CrsGraph ReplicatedGraph( Copy, ReplicatedMap, 0 ); AMESOS_CHK_ERR(ReplicatedGraph.Import(*Graph, ReplicatedImporter, Insert)); AMESOS_CHK_ERR(ReplicatedGraph.FillComplete()); // // Convert the matrix to Ap, Ai // std::vector <int> Replicates(numrows); std::vector <int> Ap(numrows + 1); std::vector <int> Ai(EPETRA_MAX(numrows, numentries)); for( int i = 0 ; i < numrows; i++ ) Replicates[i] = 1; int NumEntriesPerRow ; int *ColIndices = 0 ; int Ai_index = 0 ; for ( int MyRow = 0; MyRow <numrows; MyRow++ ) { AMESOS_CHK_ERR( ReplicatedGraph.ExtractMyRowView( MyRow, NumEntriesPerRow, ColIndices ) ); Ap[MyRow] = Ai_index ; for ( int j = 0; j < NumEntriesPerRow; j++ ) { Ai[Ai_index] = ColIndices[j] ; Ai_index++; } } assert( Ai_index == numentries ) ; Ap[ numrows ] = Ai_index ; MtxConvTime_ = AddTime("Total matrix conversion time", MtxConvTime_, 0); ResetTimer(0); // // Call Dscpack Symbolic Factorization // int OrderCode = 2; std::vector<double> MyANonZ; NumLocalNonz = 0 ; GlobalStructNewColNum = 0 ; GlobalStructNewNum = 0 ; GlobalStructOwner = 0 ; LocalStructOldNum = 0 ; NumGlobalCols = 0 ; // MS // Have to define the maximum number of processes to be used // MS // This is only a suggestion as Dscpack uses a number of processes that is a power of 2 int NumGlobalNonzeros = GetProblem()->GetMatrix()->NumGlobalNonzeros(); int NumRows = GetProblem()->GetMatrix()->NumGlobalRows(); // optimal value for MaxProcs == -1 int OptNumProcs1 = 1+EPETRA_MAX( NumRows/10000, NumGlobalNonzeros/1000000 ); OptNumProcs1 = EPETRA_MIN(NumProcs_,OptNumProcs1 ); // optimal value for MaxProcs == -2 int OptNumProcs2 = (int)sqrt(1.0 * NumProcs_); if( OptNumProcs2 < 1 ) OptNumProcs2 = 1; // fix the value of MaxProcs switch (MaxProcs_) { case -1: MaxProcs_ = EPETRA_MIN(OptNumProcs1, NumProcs_); break; case -2: MaxProcs_ = EPETRA_MIN(OptNumProcs2, NumProcs_); break; case -3: MaxProcs_ = NumProcs_; break; } #if 0 if (MyDscRank>=0 && A_and_LU_built) { DSC_ReFactorInitialize(PrivateDscpackData_->MyDSCObject); } #endif // if ( ! A_and_LU_built ) { // DSC_End( PrivateDscpackData_->MyDSCObject ) ; // PrivateDscpackData_->MyDSCObject = DSC_Begin() ; // } // MS // here I continue with the old code... OverheadTime_ = AddTime("Total Amesos overhead time", OverheadTime_, 1); DscNumProcs = 1 ; int DscMax = DSC_Analyze( numrows, &Ap[0], &Ai[0], &Replicates[0] ); while ( DscNumProcs * 2 <=EPETRA_MIN( MaxProcs_, DscMax ) ) DscNumProcs *= 2 ; MyDscRank = -1; DSC_Open0( PrivateDscpackData_->MyDSCObject_, DscNumProcs, &MyDscRank, comm1.Comm()) ; NumLocalCols = 0 ; // This is for those processes not in the Dsc grid if ( MyDscRank >= 0 ) { assert( MyPID_ == MyDscRank ) ; AMESOS_CHK_ERR( DSC_Order ( PrivateDscpackData_->MyDSCObject_, OrderCode, numrows, &Ap[0], &Ai[0], &Replicates[0], &NumGlobalCols, &NumLocalStructs, &NumLocalCols, &NumLocalNonz, &GlobalStructNewColNum, &GlobalStructNewNum, &GlobalStructOwner, &LocalStructOldNum ) ) ; assert( NumGlobalCols == numrows ) ; assert( NumLocalCols == NumLocalStructs ) ; } if ( MyDscRank >= 0 ) { int MaxSingleBlock; const int Limit = 5000000 ; // Memory Limit set to 5 Terabytes AMESOS_CHK_ERR( DSC_SFactor ( PrivateDscpackData_->MyDSCObject_, &TotalMemory_, &MaxSingleBlock, Limit, DSC_LBLAS3, DSC_DBLAS2 ) ) ; } // A_and_LU_built = true; // If you uncomment this, TestOptions fails SymFactTime_ = AddTime("Total symbolic factorization time", SymFactTime_, 0); return(0); }
int CrsMatrixTranspose( Epetra_CrsMatrix *In, Epetra_CrsMatrix *Out ) { int iam = In->Comm().MyPID() ; int numentries = In->NumGlobalNonzeros(); int NumRowEntries = 0; double *RowValues = 0; int *ColIndices = 0; int numrows = In->NumGlobalRows(); int numcols = In->NumGlobalCols(); std::vector <int> Ap( numcols+1 ); // Column i is stored in Aval(Ap[i]..Ap[i+1]-1) std::vector <int> nextAp( numcols+1 ); // Where to store next value in Column i std::vector <int> Ai( EPETRA_MAX( numcols, numentries) ) ; // Row indices std::vector <double> Aval( EPETRA_MAX( numcols, numentries) ) ; if ( iam == 0 ) { assert( In->NumMyRows() == In->NumGlobalRows() ) ; // // Count the number of entries in each column // std::vector <int>RowsPerCol( numcols ) ; for ( int i = 0 ; i < numcols ; i++ ) RowsPerCol[i] = 0 ; for ( int MyRow = 0; MyRow <numrows; MyRow++ ) { assert( In->ExtractMyRowView( MyRow, NumRowEntries, RowValues, ColIndices ) == 0 ) ; for ( int j = 0; j < NumRowEntries; j++ ) { RowsPerCol[ ColIndices[j] ] ++ ; } } // // Set Ap and nextAp based on RowsPerCol // Ap[0] = 0 ; for ( int i = 0 ; i < numcols ; i++ ) { Ap[i+1]= Ap[i] + RowsPerCol[i] ; nextAp[i] = Ap[i]; } // // Populate Ai and Aval // for ( int MyRow = 0; MyRow <numrows; MyRow++ ) { assert( In->ExtractMyRowView( MyRow, NumRowEntries, RowValues, ColIndices ) == 0 ) ; for ( int j = 0; j < NumRowEntries; j++ ) { Ai[ nextAp[ ColIndices[j] ] ] = MyRow ; Aval[ nextAp[ ColIndices[j] ] ] = RowValues[j] ; nextAp[ ColIndices[j] ] ++ ; } } // // Insert values into Out // for ( int MyRow = 0; MyRow <numrows; MyRow++ ) { int NumInCol = Ap[MyRow+1] - Ap[MyRow] ; Out->InsertGlobalValues( MyRow, NumInCol, &Aval[Ap[MyRow]], &Ai[Ap[MyRow]] ); assert( Out->IndicesAreGlobal() ) ; } } else { assert( In->NumMyRows() == 0 ) ; } assert( Out->FillComplete()==0 ) ; return 0 ; }
int KrylovAccelerator2::accelerate(Vector &vStar, LinearSOE &theSOE, IncrementalIntegrator &theIntegrator) { const Vector &R = theSOE.getB(); int k = dimension; // Store residual for differencing at next iteration *(Av[k]) = R; // If subspace is not empty if (dimension > 0) { // Compute Av_k = f(y_{k-1}) - f(y_k) = r_{k-1} - r_k Av[k-1]->addVector(1.0, R, -1.0); int i,j; // Put subspace vectors into AvData Matrix A(AvData, numEqns, k); for (i = 0; i < k; i++) { Vector &Ai = *(Av[i]); for (j = 0; j < numEqns; j++) A(j,i) = Ai(j); } for (i = 0; i < k; i++) { for (int j = i+1; j < k; j++) { double sum = 0.0; double sumi = 0.0; double sumj = 0.0; for (int ii = 0; ii < numEqns; ii++) { sum += A(ii,i)*A(ii,j); sumi += A(ii,i)*A(ii,i); sumj += A(ii,j)*A(ii,j); } sumi = sqrt(sumi); sumj = sqrt(sumj); sum = sum/(sumi*sumj); //if (fabs(sum) > 0.99) //opserr << sum << ' ' << i << ' ' << j << " "; } } // Put residual vector into rData (need to save r for later!) Vector B(rData, numEqns); B = R; // No transpose char *trans = "N"; // The number of right hand side vectors int nrhs = 1; // Leading dimension of the right hand side vector int ldb = (numEqns > k) ? numEqns : k; // Subroutine error flag int info = 0; // Call the LAPACK least squares subroutine #ifdef _WIN32 unsigned int sizeC = 1; DGELS(trans, &sizeC, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #else //SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK, // $ INFO ) dgels_(trans, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #endif // Check for error returned by subroutine if (info < 0) { opserr << "WARNING KrylovAccelerator2::accelerate() - \n"; opserr << "error code " << info << " returned by LAPACK dgels\n"; return info; } Vector Q(numEqns); Q = R; // Compute the correction vector double cj; for (j = 0; j < k; j++) { // Solution to least squares is written to rData cj = rData[j]; // Compute w_{k+1} = c_1 v_1 + ... + c_k v_k vStar.addVector(1.0, *(v[j]), cj); // Compute least squares residual // q_{k+1} = r_k - (c_1 Av_1 + ... + c_k Av_k) Q.addVector(1.0, *(Av[j]), -cj); } theSOE.setB(Q); //opserr << "Q: " << Q << endln; } theSOE.solve(); vStar.addVector(1.0, theSOE.getX(), 1.0); // Put accelerated vector into storage for next iteration *(v[k]) = vStar; dimension++; return 0; }
void TPZArtDiff::PrepareFastestDiff(TPZFMatrix<REAL> &jacinv, TPZVec<STATE> &sol, TPZFMatrix<STATE> &dsol, TPZFMatrix<REAL> &phi, TPZFMatrix<REAL> &dphi, TPZVec<TPZVec<STATE> > & TauDiv, TPZVec<TPZDiffMatrix<STATE> > & dTauDiv) { #ifdef _TFAD typedef TFad<dim+2, REAL> TFADREALdim; #endif #ifdef _FAD typedef Fad<REAL> TFADREALdim; #endif #ifdef _TINYFAD typedef TinyFad<dim+2, REAL> TFADREALdim; #endif const int nstate = sol.NElements(); const int nshape = phi.Rows(); TPZVec<TFADREALdim > FADsol(nstate); TPZVec<TPZDiffMatrix<TFADREALdim> > FADAi(dim); TPZVec<TPZDiffMatrix<REAL> > Ai(dim); TPZVec<TPZDiffMatrix<TFADREALdim> > FADTau(dim); TPZVec<TPZDiffMatrix<STATE> > Tau(dim); TPZVec<TPZVec<TFADREALdim> > FADTauDiv(dim); TFADREALdim temp; int i, j, k, l; for(i = 0; i < nstate; i++) { FADsol[i] = sol[i]; FADsol[i].diff(i, nstate); } TPZEulerConsLaw::JacobFlux(fGamma, dim, FADsol, FADAi); ComputeTau(dim, jacinv, FADsol, FADAi, FADTau); for( k = 0; k < dim; k++) { Tau[k].Redim(nstate, nstate); Ai [k].Redim(nstate, nstate); for(i = 0; i < nstate; i++) for( j = 0; j < nstate; j++) { Tau[k](i,j) = FADTau[k](i,j).val(); Ai [k](i,j) = FADAi [k](i,j).val(); } } TPZVec<STATE> Div; TPZDiffMatrix<STATE> dDiv; //Computing the divergent with derivatives Divergent(dsol, phi, dphi, FADAi, Div, &dDiv); TauDiv. Resize(dim); dTauDiv.Resize(dim); //Computing Tau * Div and DTau * Div for(k=0;k<dim;k++) { TauDiv [k].Resize(nstate); dTauDiv[k].Redim(nstate, nstate); //FADTau[k].Multiply(Div, FADTauDiv[k]); FADTauDiv[k].Resize(nstate); for(i = 0; i < nstate; i++) { temp = 0.; for(j = 0; j < nstate; j++) temp += FADTau[k](i,j) * ((REAL)Div[j]); FADTauDiv[k][i] = temp; }// // copying data using REAL dTauDiv[k].Redim(nstate, nstate * nshape); for(i = 0; i < nstate; i++) { TauDiv[k][i] = FADTauDiv[k][i].val(); for(j = 0; j < nstate; j++) { for(l = 0; l < nshape; l++) dTauDiv[k](i,l * nstate + j) = FADTauDiv[k][i].dx/*fastAccessDx*/(j) * phi(l,0); } } } TPZDiffMatrix<STATE> TaudDiv_k; // temporary storage for(k = 0; k < dim; k++) { Tau[k].Multiply(dDiv, TaudDiv_k); dTauDiv[k].Add(TaudDiv_k, 1.); } //Computing DTauDiv = DTau * Div + Tau * DDiv }
bool CGroup::Update() { if (Ai()->GroupDistanceToPlayer(groupMembers) > 1920) return false; if (groupMembers.size() == 0) return true; DecreaseDelays(); ScanForPlayer(); for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->currentActivity == CEnemy::CurrentActivity::fighting || M(i)->currentActivity == CEnemy::CurrentActivity::braveryboost || M(i)->currentActivity == CEnemy::CurrentActivity::spottedPlayer || M(i)->currentActivity == CEnemy::CurrentActivity::retreating) { if (M(i)->timeUntilAimCorrection >= 0) { if (M(i)->GetPlayerVisible()) M(i)->SetOptimalXhairAngle(AIVector->at(M(i)->AI)->GetOptimalXhairAngle(M(i))); } else { if (M(i)->GetPlayerVisible()) M(i)->timeUntilAimCorrection -= g_time; } M(i)->Aim(); } } if (IsAlone()) { if (Ai()->ContinuousChance(32000)) { CEnemy::CurrentActivity tempActivity = M(0)->currentActivity; M(0)->currentActivity = CEnemy::CurrentActivity::alone; speechManager->AddSpeech(M(0), Ai()->GetSpeechString(M(0), IsCaptain(M(0))), GetColor(M(0))); } } if (groupIsAwareOfPlayer && timeSincePlayerSpotted > 7000 && activity != GroupActivity::alert) { groupIsAwareOfPlayer = false; for (int i = 0; i < groupMembers.size(); i++) { M(i)->SetAwareOfPlayer(false); M(i)->currentActivity = CEnemy::CurrentActivity::alert; M(i)->SetXhairAngle(0); } activity = GroupActivity::alert; } else if (groupIsAwareOfPlayer && timeSincePlayerSpotted > 2000 && activity != GroupActivity::searching) { activity = GroupActivity::searching; InitDelays(); for (int i = 0; i < groupMembers.size(); i++) { if (Ai()->Chance(40)) { M(i)->SetAwareOfPlayer(false); } if (M(i)->currentActivity != CEnemy::CurrentActivity::deserting) M(i)->currentActivity = CEnemy::CurrentActivity::searching; } } if (!losingMorals) { if (!IsGroupBrave() && AIVector->at(0)->ContinuousChance(2000)) { LoseMorals(); } } else { for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->currentActivity == CEnemy::CurrentActivity::aboutToDesert) { if (Ai(i)->ContinuousChance(1600)) { M(i)->currentActivity = CEnemy::CurrentActivity::deserting; if (Ai()->Chance(50)) { speechManager->AddSpeech(M(i), Ai(i)->GetSpeechString(M(i), IsCaptain(M(i))), GetColor(i)); } } } } } switch (activity) { case GroupActivity::alert: for (int i = 0; i < groupMembers.size(); i++) { Ai(i)->Idle(M(i)); if (Ai(i)->ContinuousChance(12000) && !IsAlone()) { speechManager->AddSpeech(M(i), Ai(i)->GetSpeechString(M(i), IsCaptain(M(i))), GetColor(i)); } } break; case GroupActivity::idle: for (int i = 0; i < groupMembers.size(); i++) { Ai(i)->Idle(M(i)); if (Ai(i)->ContinuousChance(22000)) { speechManager->AddSpeech(M(i), Ai(i)->GetSpeechString(M(i), IsCaptain(M(i))), GetColor(i)); } } break; case GroupActivity::gainingAwareness: { bool allAware = true; for (int i = 0; i < groupMembers.size(); i++) { if (!M(i)->IsAwareOfPlayer()) { if (IsDelayZero(i)) { M(i)->SetAwareOfPlayer(true); if (M(i)->currentActivity == CEnemy::CurrentActivity::spottedPlayer) { if (Ai()->Chance(90) && groupMembers.size() > 1) { speechManager->AddSpeech(M(i), AIVector->at(M(i)->AI)->GetSpeechString(M(i), (IsCaptain(M(i)))), GetColor(M(i))); } } else if (M(i) == captain && groupMembers.size() > 1) { if (Ai()->Chance(50)) { captain->currentActivity = CEnemy::CurrentActivity::spottedPlayer; speechManager->AddSpeech(captain, AIVector->at(captain->AI)->GetSpeechString(captain, true), captainColor); } } } else allAware = false; } else { M(i)->currentActivity = CEnemy::CurrentActivity::fighting; Ai(i)->Attack(M(i)); if (M(i)->GetPlayerVisible()) M(i)->Aim(); } } if (allAware) { activity = GroupActivity::fighting; } } break; case GroupActivity::retreating: for (int i = 0; i < groupMembers.size(); i++) { if (IsDelayZero(i)) { if (M(i)->currentActivity == CEnemy::CurrentActivity::retreating) Ai(i)->Retreat(M(i)); } if (Ai()->ContinuousChance(7000)) { InitDelays(); activity = GroupActivity::fighting; } } break; case GroupActivity::fighting: for (int i = 0; i < groupMembers.size(); i++) { if (IsDelayZero(i)) { if (M(i)->currentActivity != CEnemy::CurrentActivity::deserting) { Ai(i)->Attack(M(i)); if (Ai(i)->ContinuousChance(20000)) speechManager->AddSpeech(M(i), Ai(i)->GetSpeechString(M(i), (IsCaptain(M(i)))), GetColor(M(i))); } } } if (Ai()->ContinuousChance(100000) && IsCaptainAlive() && HasSufferedCasualties() && groupMembers.size() > 1) { captain->currentActivity = CEnemy::CurrentActivity::retreating; speechManager->AddSpeech(captain, Ai(0)->GetSpeechString(captain, true), captainColor); activity = GroupActivity::retreating; InitDelays(); for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->currentActivity != CEnemy::CurrentActivity::deserting) { M(i)->currentActivity = CEnemy::CurrentActivity::retreating; } } } if (Ai()->ContinuousChance(30000) && IsCaptainAlive() && captain->currentActivity != CEnemy::CurrentActivity::deserting && losingMorals) { braveryBoost = 100; captain->currentActivity = CEnemy::CurrentActivity::braveryboost; if (!IsAlone()) speechManager->AddSpeech(captain, Ai()->GetSpeechString(captain, true), GetColor(captain)); captain->currentActivity = CEnemy::CurrentActivity::fighting; for (int i = 0; i < groupMembers.size(); i++) { if (groupMembers[i]->currentActivity == CEnemy::CurrentActivity::deserting) { groupMembers[i]->currentActivity = CEnemy::CurrentActivity::fighting; } } } lastKnownDirection = Ai()->GetPlayerHorizontalDirection(Ai()->GetEnemyClosestToPlayerFromVector(groupMembers)); case GroupActivity::searching: for (int i = 0; i < groupMembers.size(); i++) { if (M(i)->currentActivity == CEnemy::CurrentActivity::searching) { Ai(i)->Search(M(i), lastKnownDirection); } } if (Ai(0)->ContinuousChance(15000) && !IsAlone()) { CEnemy * closest = Ai()->GetEnemyClosestToPlayerFromVector(groupMembers); speechManager->AddSpeech(closest, Ai(closest)->GetSpeechString(closest, IsCaptain(closest)), GetColor(closest)); } } return false; }