void M::SearchAntForTarget(int targetRow, int targetCol, Bot* bot, Target target) { vector<Cell> closedCells, openCells, neighborCells; Cell start; start.col = targetCol; start.row = targetRow; start.gScore = 0; openCells.push_back(start); int steps = 0; auto ito = openCells.begin(); for(int i = 0; ; i++) { if(openCells[i].gScore > MAX_DIST_TO_FOOD) break; Cell *cell = new Cell(openCells[i].row, openCells[i].col, openCells[i].gScore, 0, 0, openCells[i].parent); if (SearchAntIsComplete(targetRow, targetCol, cell, bot)) { return; } GetNeighborCells(cell, &neighborCells, bot->water); for (auto itn = neighborCells.begin(); itn != neighborCells.end(); itn++) { if (find(openCells.begin(), openCells.end(), *itn) != openCells.end()) { continue; } openCells.push_back(Cell(itn->row, itn->col, cell->gScore + 1, 0, 0, cell)); } steps++; } return; }
char M::SearchPathForAnt(Ant* ant, Bot* bot) { vector<Cell> closedCells, openCells, neighborCells; Cell start; start.col = ant->location.col; start.row = ant->location.row; start.gScore = 0; start.hScore = GetDirectDistance(ant->location.row, ant->location.col, ant->destination.row, ant->destination.col); start.fScore = start.gScore + start.hScore; openCells.push_back(start); while(!openCells.empty()) { vector<Cell>::iterator cellIt = openCells.begin(); for(auto it = openCells.begin(); it != openCells.end(); it++) if ((*it).fScore <= cellIt->fScore) cellIt = it; Cell *cell = new Cell((*cellIt).row, (*cellIt).col, (*cellIt).gScore,(*cellIt).hScore, (*cellIt).fScore, (*cellIt).parent); if (SearchPathIsComplete(cell, ant) || cell->gScore > DIST_TO_TARGET) { Cell *currentCell = cell; if(cell->gScore > DIST_TO_TARGET) { ant->destination.row = cell->row; ant->destination.col = cell->col; } if(currentCell->parent) while(currentCell->parent->parent != NULL) { currentCell = currentCell->parent; } ant->direction = GetDirection(currentCell->row, currentCell->col, ant->location.row, ant->location.col); return ant->direction; } closedCells.push_back(*cell); openCells.erase(cellIt); GetNeighborCells(cell, &neighborCells, bot->water); for (auto it = neighborCells.begin(); it != neighborCells.end(); it++) { if (find(closedCells.begin(), closedCells.end(), *it) != closedCells.end()) continue; int neighborGScore = cell->gScore + GetDistance(cell->row, cell->col, (*it).row, (*it).col); if(find(openCells.begin(), openCells.end(), *it) == openCells.end()) { int gScore = neighborGScore; float hScore = (*it).hScore = GetDirectDistance((*it).row, (*it).col, ant->destination.row, ant->destination.col); float fScore = neighborGScore + hScore; openCells.push_back(Cell((*it).row, (*it).col, gScore, hScore, fScore, cell)); } } } }
void ComputeForces() { for(int i = 0; i < numCells; ++i) { Cell *cell = &cells[i]; int np = cnumPars[i]; for(int j = 0; j < np; ++j) { cell->density[j % PARTICLES_PER_CELL] = 0.0; cell->a[j % PARTICLES_PER_CELL] = externalAcceleration; //move pointer to next cell in list if end of array is reached if(j % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { cell = cell->next; } } } int neighCells[3*3*3]; int cindex = 0; for(int ck = 0; ck < nz; ++ck) { for(int cj = 0; cj < ny; ++cj) { for(int ci = 0; ci < nx; ++ci, ++cindex) { int np = cnumPars[cindex]; if(np == 0) continue; int numNeighCells = GetNeighborCells(ci, cj, ck, neighCells); Cell *cell = &cells[cindex]; for(int ipar = 0; ipar < np; ++ipar) { for(int inc = 0; inc < numNeighCells; ++inc) { int cindexNeigh = neighCells[inc]; Cell *neigh = &cells[cindexNeigh]; int numNeighPars = cnumPars[cindexNeigh]; for(int iparNeigh = 0; iparNeigh < numNeighPars; ++iparNeigh) { //Check address to make sure densities are computed only once per pair if(&neigh->p[iparNeigh % PARTICLES_PER_CELL] < &cell->p[ipar % PARTICLES_PER_CELL]) { fptype distSq = (cell->p[ipar % PARTICLES_PER_CELL] - neigh->p[iparNeigh % PARTICLES_PER_CELL]).GetLengthSq(); if(distSq < hSq) { fptype t = hSq - distSq; fptype tc = t*t*t; cell->density[ipar % PARTICLES_PER_CELL] += tc; neigh->density[iparNeigh % PARTICLES_PER_CELL] += tc; } } //move pointer to next cell in list if end of array is reached if(iparNeigh % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { neigh = neigh->next; } } } //move pointer to next cell in list if end of array is reached if(ipar % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { cell = cell->next; } } } } } const fptype tc = hSq*hSq*hSq; for(int i = 0; i < numCells; ++i) { Cell *cell = &cells[i]; int np = cnumPars[i]; for(int j = 0; j < np; ++j) { cell->density[j % PARTICLES_PER_CELL] += tc; cell->density[j % PARTICLES_PER_CELL] *= densityCoeff; //move pointer to next cell in list if end of array is reached if(j % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { cell = cell->next; } } } cindex = 0; for(int ck = 0; ck < nz; ++ck) { for(int cj = 0; cj < ny; ++cj) { for(int ci = 0; ci < nx; ++ci, ++cindex) { int np = cnumPars[cindex]; if(np == 0) continue; int numNeighCells = GetNeighborCells(ci, cj, ck, neighCells); Cell *cell = &cells[cindex]; for(int ipar = 0; ipar < np; ++ipar) { for(int inc = 0; inc < numNeighCells; ++inc) { int cindexNeigh = neighCells[inc]; Cell *neigh = &cells[cindexNeigh]; int numNeighPars = cnumPars[cindexNeigh]; for(int iparNeigh = 0; iparNeigh < numNeighPars; ++iparNeigh) { //Check address to make sure forces are computed only once per pair if(&neigh->p[iparNeigh % PARTICLES_PER_CELL] < &cell->p[ipar % PARTICLES_PER_CELL]) { Vec3 disp = cell->p[ipar % PARTICLES_PER_CELL] - neigh->p[iparNeigh % PARTICLES_PER_CELL]; fptype distSq = disp.GetLengthSq(); if(distSq < hSq) { #ifndef ENABLE_DOUBLE_PRECISION fptype dist = sqrtf(std::max(distSq, (fptype)1e-12)); #else fptype dist = sqrt(std::max(distSq, 1e-12)); #endif //ENABLE_DOUBLE_PRECISION fptype hmr = h - dist; Vec3 acc = disp * pressureCoeff * (hmr*hmr/dist) * (cell->density[ipar % PARTICLES_PER_CELL]+neigh->density[iparNeigh % PARTICLES_PER_CELL] - doubleRestDensity); acc += (neigh->v[iparNeigh % PARTICLES_PER_CELL] - cell->v[ipar % PARTICLES_PER_CELL]) * viscosityCoeff * hmr; acc /= cell->density[ipar % PARTICLES_PER_CELL] * neigh->density[iparNeigh % PARTICLES_PER_CELL]; cell->a[ipar % PARTICLES_PER_CELL] += acc; neigh->a[iparNeigh % PARTICLES_PER_CELL] -= acc; } } //move pointer to next cell in list if end of array is reached if(iparNeigh % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { neigh = neigh->next; } } } //move pointer to next cell in list if end of array is reached if(ipar % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) { cell = cell->next; } } } } } }