void UpdateRHSandBptr(Node *u) { double temp; int x = u->x; int y = u->y; u->bptr = 0; u->rhs = DOUBLE_INF; for (int i = 0; i < lattice.n; ++i) { int x1 = x + lattice.dx[i]; int y1 = y + lattice.dy[i]; if (!isInMap(x1, y1)) continue; Node *t = memory[x1][y1]; if (t == 0 || t->bptr == u) continue; temp = ComputeCost(u, x1, y1); if (temp < u->rhs) { u->rhs = temp; u->bptr = t; } } }
char ArenaMap::getMapTileType( int x, int y ) const { int index = x + ( y * m_width ); if( isInMap( x, y ) ) return m_mapTiles[ index ].tileMaterial; else return ARENA_SQUARE_TYPE_UNKNOWN; }
//---------------------------------------------------------------------- bool ArenaMap::checkTileForNutrient( const TileCoords& pos ) const { bool found = false; if( isInMap( pos.x, pos.y ) ) { const MapTile& tile = getMapTile( pos.x, pos.y ); if( tile.tileMaterial == ARENA_SQUARE_TYPE_FOOD && !tile.isClaimed ) { found = true; } } return found; }
FUNCTION int Q4MJ(obj user) { int Q5NC = 0x00; int Q4NC; loc Q4VS = loc( getLocation(user) ); loc there = loc( Q5I9(user) ); if(!isInMap(there)) { Q4RD(user); systemMessage(user, "There is no room to summon that here."); } else { faceHere(user, getDirectionInternal(Q4VS, there)); if(hasObjVar(this, "magicItemModifier")) { int Q52W = getObjVar(this, "magicItemModifier"); Q4NC = 0x06 * Q52W; } else { if(getSkillLevel(user, 0x19) < 0x0A) { Q4NC = 0x14; } else { Q4NC = 0x14 * getSkillLevel(user, 0x19) / 0x05; } } obj Q4PE = createGlobalNPCAt(0x0259, there, 0x00); if(Q4PE != NULL()) { doLocAnimation(there, 0x3728, 0x0A, 0x0A, 0x00, 0x00); sfx(there, 0x0217, 0x00); setType(Q4PE, 0x0F); animateMobile(Q4PE, 0x0C, 0x0F, 0x01, 0x00, 0x00); attachScript(Q4PE, "destcrea"); setObjVar(Q4PE, "summonDifficulty", 0x02EE); int Q5ND = Q558(Q4PE, user, 0x64, 0x01); callback(Q4PE, Q4NC, 0x08); Q5NC = 0x01; } else { bark(user, "Whoops...something got in the way."); } } Q5UQ(this); return(Q5NC); }
TRIGGER( targetloc )(obj user, loc place, int objtype) { if(!isInMap(place)) { return(0x00); } if(!Q58Z(user, this)) { return(0x00); } obj Q5AO = Q4WU(this, user, place); if(Q5AO != NULL()) { int Q5ND = Q4WZ(Q5AO, this, user); } return(0x01); }
//---------------------------------------------------------------------- bool ArenaMap::shouldMoveSucceed( EntityType entityType, OrderCode orderCode, const TileCoords& currentLoc ) const { TileCoords newTile = currentLoc + AStarPathGenerator::getTileCoordsDirFromOrderCode( orderCode ); bool shouldSucceed = true; if( isInMap( newTile.x, newTile.y ) ) { EntityType tileType = (EntityType)getMapTileType( newTile.x, newTile.y ); if( entityType == ENTITY_TYPE_SOLDIER || entityType == ENTITY_TYPE_WORKER ) { shouldSucceed = ( tileType != ARENA_SQUARE_TYPE_DIRT && tileType != ARENA_SQUARE_TYPE_STONE ); } else if( entityType == ENTITY_TYPE_SCOUT ) { shouldSucceed = tileType != ARENA_SQUARE_TYPE_STONE; } } return shouldSucceed; }
FUNCTION int Q5S4(obj ship, int Q5M5, obj Q62O) { int Q4ID = Q5SM(ship, Q5M5); int Q58G = getMultiType(ship); loc Q4OI; loc Q4OJ; int Q5NC = getMultiExtents(Q58G, Q4OI, Q4OJ); int Q44G = getX(Q4OJ) - getX(Q4OI) + 0x01; int Q44I = getY(Q4OJ) - getY(Q4OI) + 0x01; loc Q5CP = loc( getLocation(ship) ); int Q5EE = 0x00; int Q5EF = 0x00; switch(Q4ID) { case 0x00: case 0x04: Q5EF = Q44I; break; case 0x01: case 0x03: case 0x05: case 0x07: Q5EE = Q44G; Q5EF = Q44I; break; case 0x02: case 0x06: Q5EE = Q44G; break; default: Q5EE = Q44G; Q5EF = Q44I; break; } int Q44F = 0x00; int Q44H = 0x00; switch(Q4ID) { case 0x00: Q44H = 0x00; break; case 0x01: Q44F = 0x02; Q44H = 0x00; break; case 0x02: Q44F = 0x02; break; case 0x03: Q44F = 0x02; Q44H = 0x04; break; case 0x04: Q44H = 0x04; break; case 0x05: Q44F = 0x06; Q44H = 0x04; break; case 0x06: Q44F = 0x06; break; case 0x07: Q44F = 0x06; Q44H = 0x00; break; default: break; } for(; Q5EE > 0x00; Q5EE --) { moveDir(Q5CP, Q44F); } for(; Q5EF > 0x00; Q5EF --) { moveDir(Q5CP, Q44H); } if(isInMap(Q5CP)) { if(hasObjVar(Q62O, "oldshipcommand")) { removeObjVar(Q62O, "oldshipcommand"); } int Q5ND = moveMultiCheck(ship, Q5CP, Q43W); Q65T = 0x01; return(Q5ND); } Q5RY(ship); return(moveMultiMapSwitch(ship, Q5CP, Q43W)); }
const ArenaMap::MapTile& ArenaMap::getMapTile( int x, int y ) const { int index = x + ( y * m_width ); _ASSERT( isInMap( x, y ) ); return m_mapTiles[ index ]; }
/************************************************************************** CostMap handler updates costmap for D* path planning **************************************************************************/ void CostMapHandler(void *data) { LARGE_INTEGER frequency, start, finish; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&start); CostMapConvert(*(reinterpret_cast<CostMapType*>(data))); receivedCostMap = true; receivedNew = true; static bool **cellsUpdated; if(costmap == NULL || !costmap->equals(cmpInt)) { //Todo: actually delete memory here, not just resetting them cout << "Creating new costmap...\n"; if (costmap != NULL) { delete costmap; delete [] cellsUpdated[0]; delete [] cellsUpdated; } /* save the original number for back conversion in the end */ CostMapType *costmapUpdate = reinterpret_cast<CostMapType*>(data); //TODO: Hack this for IGVC 2010 //costmapXMax = costmapUpdate->xMax; //costmapXMin = costmapUpdate->xMin; //costmapXUnit = costmapUpdate->xUnitSize; //costmapYMax = costmapUpdate->yMax; //costmapYMin = costmapUpdate->yMin; //costmapYUnit = costmapUpdate->yUnitSize; xMax = cmpInt->xMax; yMax = cmpInt->yMax; costmap = new CostMapInt(xMax+1, yMax+1); // Variables and arrays to keep track of which cells have been updated and what their old values are cellsUpdated = new bool*[xMax+1]; //cells changed in both cmpInt and squarecosts bool *curPtr1 = new bool[(xMax+1) * (yMax+1)](); for( int i = 0; i < xMax+1; i++) { *(cellsUpdated + i) = curPtr1; curPtr1 += yMax + 1; } } static vector<int> cellsUpdatedXs; static vector<int> cellsUpdatedYs; int cellUpdateCount = 0; //take out in release!!! static const double cellsD = 6; static int cells = 5; costmap->update(cmpInt); //QueryPerformanceCounter(&finish); //double timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; //cout << "Map Update Time: " << timeelapsed << " s\n"; // Clears cellsUpdated, cellsUpdatedXs, and cellsUpdatedYs. //cout << "Cells Updated: " << cellUpdateCount << endl; if (!isInitialSearch) { for (size_t i = 0; i < costmap->cellsUpdatedXs.size(); ++i) { int x = costmap->cellsUpdatedXs[i]; int y = costmap->cellsUpdatedYs[i]; for (int j = 0; j < lattice.update_n; ++j) { //for each corner of updated cell int m = x + lattice.update_dx[j]; int n = y + lattice.update_dy[j]; if (!isInMap(m, n)) continue; if (memory[m][n] == 0) continue; Node *s = GetOrCreateNode(m, n); if (s->bptr == 0) continue; if (s != startNode) { UpdateRHSandBptr(s); UpdateState(s); } } //update itself if (!isInMap(x, y)) continue; if (memory[x][y] == 0) continue; Node *s = GetOrCreateNode(x, y); if (s->bptr == 0) continue; if (s != startNode) { UpdateRHSandBptr(s); UpdateState(s); } } } //use resize() instead of clear() to keep capacity unchanged //this is also done in the costmap internal function, but I'm keeping this here in case no points are updated costmap->cellsUpdatedXs.resize(0); costmap->cellsUpdatedYs.resize(0); QueryPerformanceCounter(&finish); double timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Map Update Time: " << timeelapsed << " s\n"; }
void FindPath(void *data, unsigned long a, unsigned long b) { if (isInitialSearch) { startX = (int)((stateEstimationUpdate.Easting - costmapXMin) / costmapXUnit); startY = (int)((stateEstimationUpdate.Northing - costmapYMin) / costmapYUnit); //startX = 1940; //startY = 1093; //goalX = 1850; //goalY = 2150; InitialSearch(); } else { #ifdef DEBUGMAP static bool searched = false; if (searched == true) return; searched = true; vector<int> cellsUpdatedXs, cellsUpdatedYs; for (int i = 11; i < 20; ++i) for (int j = 7; j < 17; ++j) { cellsUpdatedXs.push_back(i); cellsUpdatedYs.push_back(j); costmap->set(i, j, 3000, 0); } //for (int i = 2; i < 9; ++i) // for (int j = 5; j < 9; ++j) { // cellsUpdatedXs.push_back(i); // cellsUpdatedYs.push_back(j); // costmap->set(i, j, 3000, 2); // } for (size_t i = 0; i < cellsUpdatedXs.size(); ++i) { int x = cellsUpdatedXs[i]; int y = cellsUpdatedYs[i]; for (int j = 0; j < lattice.update_n; ++j) { //for each corner of updated cell int m = x + lattice.update_dx[j]; int n = y + lattice.update_dy[j]; if (!isInMap(m, n)) return; Node *s = GetOrCreateNode(m, n); if (s != startNode) UpdateRHSandBptr(s); UpdateState(s); } //update itself if (!isInMap(x, y)) return; Node *s = GetOrCreateNode(x, y); if (s != startNode) UpdateRHSandBptr(s); UpdateState(s); } #else if (goalX == -1 || goalY == -1) return; //no new waypoints if (receivedWaypoints) { InitialSearch(); receivedWaypoints = false; return; } if(!receivedNew || !receivedCostMap || !receivedStateEstimation ) return; receivedNew = false; LARGE_INTEGER frequency, start, finish; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&start); int oldStartX = startX; int oldStartY = startY; startX = (int)((stateEstimationUpdate.Easting - costmapXMin) / costmapXUnit); startY = (int)((stateEstimationUpdate.Northing - costmapYMin) / costmapYUnit); //startX = 1940; //startY = 1093; //spinCounter++; //if (spinCounter >= 20) spinCounter = 0; //if (spinCounter == 0) { // startX = 2000; // startY = 2000; // goalX = 1700; // goalY = 2300; // receivedNew = true; // receivedCostMap = true; // InitialSearch(); // return; //} else if (spinCounter == 10) { // startX = 2000; // startY = 2000; // goalX = 2500; // goalY = 2500; // receivedNew = true; // receivedCostMap = true; // InitialSearch(); // return; //} //Avoid Oscillations int closestX , closestY, closestIndex; int closestDistSquare = LARGE_INT; for (int i = 0; i < 50; ++i) { if (i == prevPath.size()) break; int prevPathX = int((prevPath[i].x - costmapXMin) / costmapXUnit + 0.5f); int prevPathY = int((prevPath[i].y - costmapYMin) / costmapYUnit + 0.5f); int prevDistSquare = (prevPathX - startX) * (prevPathX - startX) + (prevPathY - startY) * (prevPathY - startY); if (prevDistSquare < closestDistSquare) { closestDistSquare = prevDistSquare; closestX = prevPathX; closestY = prevPathY; closestIndex = i; } } if (closestDistSquare < 40) { startX = int((prevPath[max(closestIndex-20, 0)].x - costmapXMin) / costmapXUnit + 0.5f); startY = int((prevPath[max(closestIndex-20, 0)].y - costmapYMin) / costmapYUnit + 0.5f); } // planning failure if we start in an obstacle if ((*costmap)(startX, startY) > 280){ startX = (int)((stateEstimationUpdate.Easting - costmapXMin) / costmapXUnit); startY = (int)((stateEstimationUpdate.Northing - costmapYMin) / costmapYUnit); } if ((*costmap)(startX, startY) > 280 || (*costmap)(goalX, goalY) > 280) { cout << "Planning failed before it began." << endl; return; } if (memory[startX][startY] != 0) { startNode = memory[startX][startY]; } else { startNode = new Node(startX, startY, DOUBLE_INF, DOUBLE_INF); memory[startX][startY] = startNode; usedXs.push_back(startX); usedYs.push_back(startY); } if (memory[oldStartX][oldStartY] != 0 && memory[oldStartX][oldStartY]->used == false) { usedXs.push_back(oldStartX); usedYs.push_back(oldStartY); memory[oldStartX][oldStartY]->used = true; } if (startNode->used == false) { usedXs.push_back(startX); usedYs.push_back(startY); memory[startX][startY]->used = true; } Node::currStart = startNode; #endif //if (Node::epsilon == 1.9) // Node::epsilon = 1.5; //else if (Node::epsilon == 1.5) // Node::epsilon = 1.1; //else if (Node::epsilon == 1.1) // Node::epsilon = 1.05; //else if (Node::epsilon == 1.05) // Node::epsilon = 1.03; //else if (Node::epsilon == 1.03) // Node::epsilon = 1.02; //else if (Node::epsilon == 1.02) // Node::epsilon = 1.01; //else if (Node::epsilon == 1.01) // Node::epsilon = 1.0; //else if (Node::epsilon == 1.0) { // isInitialSearch = true; // //Node::epsilon = 2.5; // return; //} Node::epsilon = 1.0; vector<Node*> oldOpen = open->clear(); for (size_t i = 0; i < oldOpen.size(); ++i ) { oldOpen[i]->recalcKey(); open->add(oldOpen[i]); } for (list<Node*>::iterator it = incons.begin(); it != incons.end(); ++it) { (*it)->inIncons = false; if (!(*it)->inOpen) { (*it)->recalcKey(); open->add(*it); } } incons.clear(); for (list<Node*>::iterator it = closed.begin(); it != closed.end(); ++it) { (*it)->inClosed = false; } closed.clear(); //cout << "Replanning..." << endl; ComputeOrImprovePath(); #ifdef DEBUGMAP print(memory, 0, 0, xMax, yMax); #else QueryPerformanceCounter(&finish); if (planningFailed) { planningFailed = false; cout << "Planning Failed with " << timesExpanded << " times expanded." << endl; double timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Time: " << timeelapsed << "s" << endl; timesExpanded = 0; return; } if (timesExpanded > 0) { cout << timesExpanded << " times expanded, epsilon = " << Node::epsilon << endl; timesExpanded = 0; double timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Time: " << timeelapsed << "s" << endl; } //cout << "Making path..." << endl; ExtractPath(); #endif } }
void InitialSearch() { Node::epsilon = 1.0; #ifdef DEBUGMAP goalX = 1; goalY = 1; startX = 39; startY = 29; xMax = 40; yMax = 40; costmapXUnit = 1.0; costmapYUnit = 1.0; costmapXMin = 0; costmapYMin = 0; costmap = new CostMapInt(xMax+1, yMax+1); /* for testing only */ static bool searched = false; if (searched == true) return; searched = true; #else if (!receivedNew || !receivedCostMap || !receivedStateEstimation || !receivedWaypoints) return; receivedNew = false; receivedWaypoints = false; cout << "Starting search in InitialSearch()" << endl; if (!isInMap(goalX, goalY) || !isInMap(startX, startY)) return; // planning failure if we start in an obstacle if ((*costmap)(startX, startY) > 280 || (*costmap)(goalX, goalY) > 280) { cout << "Planning failed before it began in InitialSearch()" << endl; return; } #endif LARGE_INTEGER frequency, start, finish; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&start); // Initialize memory (first time only), which holds pointers to all nodes created if (!memory) { memory = new Node**[xMax + 1]; Node **curPtr = new Node* [(xMax+1) * (yMax+1)](); //parenthesis initializes pointers to 0 for( int i = 0; i < xMax+1; i++) { *(memory + i) = curPtr; curPtr += yMax + 1; } } else { vector<int>::iterator itX, itY; for (itX = usedXs.begin(), itY = usedYs.begin(); itX != usedXs.end(); ++itX, ++itY) { memory[*itX][*itY]->reset(); } usedXs.resize(0); usedYs.resize(0); } // Initialize OPEN priority queue if first time if (open != 0) open->clear(); else open = new DStarPriorityQueue(costmap); if (closed.size() != 0) closed.clear(); if (incons.size() != 0) incons.clear(); startNode = new Node(startX, startY, DOUBLE_INF, DOUBLE_INF); Node::currStart = startNode; startNode->oldStart = startNode; goalNode = new Node(goalX, goalY, DOUBLE_INF, 0); usedXs.push_back(startX); usedYs.push_back(startY); usedXs.push_back(goalX); usedYs.push_back(goalY); memory[startX][startY] = startNode; memory[goalX][goalY] = goalNode; open->add(goalNode); QueryPerformanceCounter(&finish); double timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Time (initialization): " << timeelapsed << "s" << endl; QueryPerformanceCounter(&start); ComputeOrImprovePath(); #ifdef DEBUGMAP print(memory, 0, 0, xMax, yMax); #endif if (planningFailed) { planningFailed = false; cout << "Planning Failed with " << timesExpanded << " times expanded." << endl; timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Time: " << timeelapsed << "s" << endl; timesExpanded = 0; return; } ExtractPath(); isInitialSearch = false; PauseDisableType pd; pd.Pause = false; pd.Disable = false; Messages::PauseDisable.publish(&pd); QueryPerformanceCounter(&finish); timeelapsed = ((double)(finish.QuadPart - start.QuadPart))/frequency.QuadPart; cout << "Time (initial search): " << timeelapsed << "s\n"; cout << "Times expanded: " << timesExpanded << " with epsilon = " << Node::epsilon << endl; timesExpanded = 0; }
void ComputeOrImprovePath() { while (1) { if (timesExpanded > MAX_TIMES_EXPANDED) { planningFailed = true; return; } Node *s1 = open->peekTop(); if (s1 == 0) { planningFailed = true; return; } if (less_than(s1->key.k1, startNode->key.k1) || (equals(s1->key.k1, startNode->key.k1) && less_than(s1->key.k2, startNode->key.k2)) || (greater_than(startNode->rhs, startNode->g)) || (startNode->rhs == DOUBLE_INF && startNode->g == DOUBLE_INF)) ; else break; Node *s = open->removeTop(); if (greater_than(s->g, s->rhs)) { s->g = s->rhs; if (!s->inClosed) { s->inClosed = true; closed.push_back(s); } for (int i = 0; i < lattice.n; ++i) { int x = s->x + lattice.dx[i]; int y = s->y + lattice.dy[i]; if (!isInMap(x, y)) continue; Node *v = GetOrCreateNode(x, y); if (s->bptr == v) continue; double newRhs = ComputeCost(v, s->x, s->y); if (greater_than(v->rhs, newRhs)) { v->bptr = s; v->rhs = newRhs; UpdateState(v); } } ++timesExpanded; } else { s->g = DOUBLE_INF; UpdateState(s); for (int i = 0; i < lattice.n; ++i) { int x = s->x + lattice.dx[i]; int y = s->y + lattice.dy[i]; Node *v = GetOrCreateNode(x, y); if (v != goalNode && v->bptr == s) { UpdateRHSandBptr(v); UpdateState(v); } } ++timesExpanded; } } }
//平台从第1回合开始调用此函数获得每回合指令,请勿修改此函数声明。 extern "C" Order makeOrder(DataForAI data) { //printf("===================round%d tank%d==================\n",data.round,data.myID); Order order; order.type=STOP; mydata=data; updateResource(data); if(data.round==1&&data.myID==0) { assignResource(data); //getNext(data); } short range=data.tank[data.myID].range; //printf("range:%d\n",range); short vision=range; Point me; me.row=data.tank[data.myID].row; me.col=data.tank[data.myID].col; for(int i=-vision;i<=vision;i++) { for(int j=-vision;j<=vision;j++) { if(abs(i)+abs(j)<=vision)//in vision { short nr=me.row+i,nc=me.col+j; Point target; target.row=nr; target.col=nc; if(isInMap(nr,nc))//in map if(data.map[nr][nc].whoIsHere!=-1)//tank detected { short n=data.map[nr][nc].whoIsHere; if(data.tank[n].flag!=data.myFlag) { //printf("enemy tank%d\n",n); order.row=nr; order.col=nc; order.type=FIRE; return order; } } else if((data.map[nr][nc].type==BREAKBRICK||data.map[nr][nc].type==BRICK)&&isObstacle(target,nextStep[data.myID]))//bricks detected { //printf("tank%dbricks\n",data.myID); order.row=nr; order.col=nc; order.type=FIRE; return order; } } } } // //printf("the nearest point for tank%d (%d,%d)\n",data.myID,nearestS[data.myID].row,nearestS[data.myID].col); //assert(nearestS[data.myID].row>0); if(data.tank[data.myID].life!=0) { clock_t tstart,tend; float timeuse; tstart=clock(); if(data.map[nearestS[data.myID].row][nearestS[data.myID].col].isHereSource==RedSource||data.map[data.tank[data.myID].row][data.tank[data.myID].col].isHereSource==RedSource||nextStep[data.myID].empty()) { getNearestRS(data); } getNext(data); tend=clock(); timeuse=(tend-tstart)/CLOCKS_PER_SEC; //printf("round%d tank%dchange resource(%d,%d) and next step:(%d,%d),%f seconds used\n",data.round,data.myID,nearestS[data.myID].row,nearestS[data.myID].col,next[data.myID].row,next[data.myID].col,timeuse); }; /* if(data.map[next[data.myID].row][next[data.myID].col].whoIsHere!=-1||next[data.myID].row==-1) { while(1) { srand((int)time(0)); short i=rand()%4; short nr=data.tank[data.myID].row+dir[i][0],nc=data.tank[data.myID].col+dir[i][1]; if(data.map[nr][nc].type==PERVIOUS&&data.map[nr][nc].whoIsHere!=-1) { next[data.myID].row=nr; next[data.myID].col=nc; break; } } } */ short x=next[data.myID].row-data.tank[data.myID].row,y=next[data.myID].col-data.tank[data.myID].col; //printf("(x,y) for tank%d\n",x,y,data.myID); /*if(x<0)x=-1; else if(x>0)x=1; if(y<0)y=-1; else if(y>0)y=1;*/ for(int i=0;i<4;i++) { if(dir[i][0]==x&&dir[i][1]==y) { order.type=direction[i]; //printf("tank%d is going %s\n",data.myID,ds[i]); return order; } else { order.type=STOP; } //random step /* else { srand((int)time(0)); order.type=direction[rand()%4]; return order; }*/ } return order; }
bool Map::isObstacle(const int& x, const int& y, const int& z) const { return (!isInMap(x, y, z) || isSoil(x, y, z)); }