void CMap::Input(Vec2I position) { Vec2I end_pos(position.x / GRID_WIDTH, position.y / GRID_HEIGHT); DEBUG_TRACE("start:%d,%d\tend:%d,%d\n", m_pos.x, m_pos.y, end_pos.x, end_pos.y); if (! IsFree(end_pos)) return; QWORD start_time = GetTimer()->GetTime(); if (m_Astar.FindPath(m_pos, end_pos)) { QWORD end_time = GetTimer()->GetTime(); DEBUG_TRACE("find path time:%f\n", GetTimer()->GetTimeMillisec(end_time - start_time)); m_findPath.clear(); std::vector<Vec2I>& vec = m_Astar.GetPath(); m_findPath.reserve(vec.size()); for (int i = 0; i < vec.size(); ++i) { Vec2I pt = vec[i]; m_findPath.push_back(Grid2CenterPt(pt)); } m_pos = end_pos; m_rect.SetRect(m_pos.x * GRID_WIDTH, m_pos.y * GRID_HEIGHT, (m_pos.x + 1) * GRID_WIDTH, (m_pos.y + 1) * GRID_HEIGHT); } }
int main() { int array[12][12] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, { 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1}, { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1}, { 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1}, { 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1}, { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, { 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }; CAStar* pAStar = new CAStar(array); CPoint* start = new CPoint(1, 1); CPoint* end = new CPoint(6, 10); CPoint* point = pAStar->FindPath(start, end, false); while(point != NULL) { std::cout << "(" << point->X << "," << point->Y << ");" << std::endl; point = point->m_parentPoint; } return 0; }
void CMap::Init() { m_vecBackLine.reserve((GRID_X_NUM + 1) * 2 + (GRID_Y_NUM + 1) * 2); //back line x for (int i = 0; i < GRID_X_NUM + 1; ++i) { Vec2F pt; pt.x = i * GRID_WIDTH; pt.y = 0; m_vecBackLine.push_back(pt); pt.x = i * GRID_WIDTH; pt.y = GRID_Y_NUM * GRID_HEIGHT; m_vecBackLine.push_back(pt); } //back line y for (int i = 0; i < GRID_Y_NUM + 1; ++i) { Vec2F pt; pt.x = 0; pt.y = i * GRID_HEIGHT; m_vecBackLine.push_back(pt); pt.x = GRID_X_NUM * GRID_WIDTH; pt.y = i * GRID_HEIGHT ; m_vecBackLine.push_back(pt); } m_vecGrid.reserve(GRID_X_NUM * GRID_Y_NUM); m_vecRect.reserve(GRID_X_NUM * GRID_Y_NUM); // grid for (int i = 0; i < GRID_X_NUM; ++i) { for (int j = 0; j < GRID_Y_NUM; ++j) { stGrid grid; grid.pt.Set(i, j); grid.bBlock = false; m_vecGrid.push_back(grid); RectF rect; rect.SetRect(i * GRID_WIDTH, j * GRID_HEIGHT, (i + 1) * GRID_WIDTH, (j + 1) * GRID_HEIGHT); m_vecRect.push_back(rect); } } // block grid m_vecBlock.reserve(BLOCK_NUM); // BLOCK_NUM 个随机数,范围 num = [1 - GRID_X_NUM * GRID_Y_NUM) // 输出到坐标:row = num / GRID_X_NUM, col = num % GRID_X_NUM int grid_num[GRID_X_NUM * GRID_Y_NUM]; int size = count_of(grid_num); for (int i = 0; i < size; ++i) { grid_num[i] = i; } // 打乱前BLOCK_NUM数 for (int i = 0; i < BLOCK_NUM; ++i) { int index = random<int>(i, size - 1); rd_swap(grid_num[i], grid_num[index]); int num = grid_num[i]; int row = num / GRID_X_NUM; int col = num % GRID_X_NUM; m_vecGrid[num].bBlock = true; RectF rect; rect.SetRect(col * GRID_WIDTH, row * GRID_HEIGHT, (col + 1) * GRID_WIDTH, (row + 1) * GRID_HEIGHT); m_vecBlock.push_back(rect); } //随机生成人物的位置,在红色格子上 while (true) { int index = rand() % m_vecGrid.size(); if (! m_vecGrid[index].bBlock) { m_pos = m_vecGrid[index].pt; m_rect.SetRect(m_pos.x * GRID_WIDTH, m_pos.y * GRID_HEIGHT, (m_pos.x + 1) * GRID_WIDTH, (m_pos.y + 1) * GRID_HEIGHT); break; } } m_Astar.SetTileJudge(this); }
void CAStar::BuildPath(void *pUser) { CAStar* pSelf = (CAStar*)pUser; { CServerInfo Info; pSelf->Client()->GetServerInfo(&Info); if(!g_Config.m_ClPathFinding || !(IsRace(&Info) || IsDDNet(&Info))) return; } int SolutionLength = -1; int *pSolution = 0; int Start = pSelf->GetStart(); int Finish = pSelf->GetFinish(); /* if(Start == -1) dbg_msg("path", "didn't find start tile"); if(Finish == -1) dbg_msg("path", "didn't find finish tile"); */ if(Start >= 0 && Finish >= 0) { pSelf->FillGrid(true); pSolution = astar_compute((const char *)pSelf->m_pField, &SolutionLength, pSelf->Collision()->GetWidth(), pSelf->Collision()->GetHeight(), Start, Finish); dbg_msg("path", "start=%i, finish=%i, length=%i", Start, Finish, SolutionLength); } if(SolutionLength == -1) // try again, ignoring freeze { pSelf->FillGrid(false); pSolution = astar_compute((const char *)pSelf->m_pField, &SolutionLength, pSelf->Collision()->GetWidth(), pSelf->Collision()->GetHeight(), Start, Finish); dbg_msg("path", "ignored freeze: start=%i, finish=%i, length=%i", Start, Finish, SolutionLength); } if(g_Config.m_ClNotifications) { if(SolutionLength != -1) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Found path. Length: %i", SolutionLength); pSelf->m_pClient->m_pHud->PushNotification(aBuf); } else pSelf->m_pClient->m_pHud->PushNotification("No possible path found."); } if(pSolution) { if(SolutionLength > 0) { pSelf->m_PathFound = true; for(int i = SolutionLength; i >= 0 ; i--) { pSelf->m_Path.add(pSelf->Collision()->GetPos(pSolution[i])); thread_sleep(10); if(pSelf->m_ThreadShouldExit) { return; } } } free(pSolution); } }
int main(int argc,char** argv) { CGameMap gamemap; gamemap.Init(); GameMap* game_map = gamemap.GetGameMap(); CAStar star; star.Init(0,244); std::list<lihj_uint16> pathlist; bool bok = star.BeginStar(game_map); if (bok) { //star.PrintCloseList(); star.GetPath(pathlist); } //std::list<lihj_uint16>::iterator iter = pathlist.begin(); for (lihj_uint16 y = 0; y < game_map->uint16_highth; y ++ ) { for (lihj_uint16 x = 0; x < game_map->uint16_width; x ++) { lihj_uint16 cell_index = x + y * game_map->uint16_width; path_node node; bool inopenlist = star.InOpenList(cell_index,node); bool incloselist = inopenlist || star.InCloseList(cell_index,node); if (inopenlist || incloselist) { bool bfind = false; for (std::list<lihj_uint16>::const_iterator iter = pathlist.begin(); iter != pathlist.end(); ++ iter) { if ((*iter) == cell_index) { bfind = true; break; } } if (bfind) { LogInfo("[%04u %04u]",cell_index,node.insert_counter); } else if(inopenlist) { LogDebug("[%04u %04u]",cell_index,node.insert_counter); } else { LogFatal("[%04u %04u]",cell_index,node.insert_counter); } } else { if (game_map->mapcell[cell_index].uint8_type == 2) { LogDebug1("[%04u %04u]",cell_index ,0); } else { LogError("[%04u %04u]",cell_index ,0); } } } LogDebug("\n"); } star.EndStar(); gamemap.Uninit(); system("pause"); return 0; }