C语言吧有没有高手,自动避障要怎么做?
c语言吧
全部回复
仅看楼主
level 5
白芦花 楼主
2025年01月15日 00点01分 1
level 10
你想要什么效果?效果最完美的当然是最短路径算法,此外就是迷宫算法。或者,向着目标前进,遇障碍就优先尝试交替左转/右转,这比较接近小鼠走迷宫。
2025年01月15日 01点01分 2
你好角色控制代码在楼下,要加哪里?
2025年01月15日 02点01分
level 5
白芦花 楼主
void 角色控制(int &HGX, int &X2, int &Y2, int &LR){
char A = ' ';
static int mx, my;
static bool jb = true;
int sx, sy;
if (MouseHit()) {
MOUSEMSG m = GetMouseMsg(); // 获取鼠标消息
switch (m.uMsg)
{
case WM_MOUSEMOVE://鼠标移动消息
break;
case WM_RBUTTONDOWN://右键按下
break;
case WM_RBUTTONUP://右键抬起
break;
case WM_LBUTTONDOWN://左键按下
mx = m.x, my = m.y;
jb = false;
break;
case WM_LBUTTONUP://左键抬起
break;
//case WM_MOUSEWHEEL://滑轮缩放
//break;
default:break;
}
}
if (!jb) {
sx = mx - X2;
sy = my - Y2;
if (abs(sx) > abs(sy)) {
if (abs(sx) > 4) {
if (sx>0)
A = 'D';
else
A = 'A';
}
}
else {
if (abs(sy) > 4) {
if (sy > 4)
A = 'S';
else
A = 'W';
}
}
}
if (kbhit()) {
A = getch(); A = toupper(A); jb = true;
}
if (A == 'D') {
X2 = X2 + 4, LR = 1;//2
if (碰撞right(X2, Y2, HGX))
X2 -= 4;
}
else if (A == 'A') {
X2 = X2 - 4, LR = 0;//1
if (碰撞left(X2, Y2, HGX))
X2 += 4;
}//else
if (A == 'W') {
Y2 = Y2 - 4; LR = 3;
if (碰撞top(X2, Y2, HGX))
Y2 += 4;
}
else if (A == 'S') {
Y2 = Y2 + 4; LR = 2;
if (碰撞bottom(X2, Y2, HGX))
Y2 -= 4;
}
Y2 = max(0, Y2); Y2 = min(480-26, Y2);
//X2--
if (X2 < 60 && HGX < - 4) {
X2 += 4; HGX += 4;
}
else if (X2 < 0 && HGX<-4) {
X2 = 0; HGX += -X2; HGX = min(0, HGX);
}
else if (X2 < 0) {
X2 = 0;
}
//X2++
if (X2 >(640-16)- 60 && HGX > -320+4) {//
X2 -= 4; HGX -= 4;
}
else if (X2 >(640 - 16) && HGX>-320) {//
X2 = (640 - 16); HGX -= X2- (640 - 16); HGX = max(-320, HGX);
}
else if (X2 > (640 - 16)) {
X2 = (640 - 16);
}
}
2025年01月15日 01点01分 3
level 11
这就是加寻路算法
2025年01月15日 05点01分 4
谢谢!好的,我找一找寻路算法.
2025年01月15日 06点01分
level 3
a*或jps
2025年01月15日 07点01分 5
找了一个能运行的"A星寻路代码(完整)",在楼下,不知道能不能用上?
2025年01月16日 00点01分
level 5
白芦花 楼主
A星寻路代码(完整)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int ROW = 10;
const int COL = 10;
const int ZXDJ = 10;//直线代价
const int XXDJ = 14;//斜线代价
enum Dir { p_up, p_down, p_left, p_right, p_lup, p_ldown, p_rup, p_rdown };
struct Mypoint
{
int row;
int col;
int f, g, h;
bool operator==(const Mypoint& pos)
{
return (pos.row == row && pos.col == col);
}
void GetH(const Mypoint& Begpos, const Mypoint& Endpos)
{
int x = abs(Begpos.col - Endpos.col);//计算水平差距
int y = abs(Begpos.row - Endpos.row);//计算垂直差距
h = x + y;//计算总的差距
}
inline void GetF()
{
f = g + h;//计算f
}
};
//树结构存储节点
struct TreeNode
{
Mypoint pos;//当前点坐标
TreeNode* pParent;//当前点的父节点
vector<TreeNode*> pChild;//存储当前点的所有孩子节点
//构造函数
TreeNode(const Mypoint& pos)
{
this->pos = pos;
pParent = nullptr;
}
};
//判断某个点能否走
bool CanWalk(int map[ROW][COL], bool vis[ROW][COL], const Mypoint& pos)
{
//如果越界,不能走
if (pos.row < 0 || pos.col < 0 || pos.row >= ROW || pos.col >= COL)
{
return false;
}
//如果是墙,不能走
if (map[pos.row][pos.col])
{
return false;
}
//如果已经走过,不能走
if (vis[pos.row][pos.col])
{
return false;
}
return true;//否则能走
}
int main()
{
//地图,1表示墙,0表示路径
int map[ROW][COL] =
{
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,1,1,0,1,0,0,0},
{0,0,0,0,1,0,1,0,0,0},
{0,0,0,0,1,0,1,0,0,0},
{0,0,1,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,1,1,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
};
//起始点和终点
Mypoint Begpos = { 1,1 };
Mypoint Endpos = { 6,5 };
//标记有没有走过
bool vis[ROW][COL] = { false };
//创建树根,即根节点
TreeNode* pRoot = new TreeNode(Begpos);
vector<TreeNode*> buff;//存储孩子节点的数组
TreeNode* pCurrent = pRoot;//记录当前点
TreeNode* pTemp = nullptr;//试探节点,用于试探下一个位置的点
bool isFindEnd = false;//终点标记
//开始寻路
while (1)
{
//1. 某个点八个方向依次遍历 计算g代价
for (int i = 0; i < 8; ++i)
{
//确定试探点的属性
pTemp = new TreeNode(pCurrent->pos);
//八个方向进行试探!
switch (i)
{
//直线代价
case p_up://上
pTemp->pos.row--;
pTemp->pos.g += ZXDJ;
break;
case p_down://下
pTemp->pos.row++;
pTemp->pos.g += ZXDJ;
break;
case p_left://左
pTemp->pos.col--;
pTemp->pos.g += ZXDJ;
break;
case p_right://右
pTemp->pos.col++;
pTemp->pos.g += ZXDJ;
break;
//斜线代价
case p_lup://左上
pTemp->pos.row--;
pTemp->pos.col--;
pTemp->pos.g += XXDJ;
break;
case p_ldown://左下
pTemp->pos.row++;
pTemp->pos.col--;
pTemp->pos.g += XXDJ;
break;
case p_rup://右上
pTemp->pos.row--;
pTemp->pos.col++;
pTemp->pos.g += XXDJ;
break;
case p_rdown://右下
pTemp->pos.row++;
pTemp->pos.col++;
pTemp->pos.g += XXDJ;
break;
}
//判断他们能不能走,能走的计算h及f 入树 存储在buff数组
if (CanWalk(map, vis, pTemp->pos))
{//能走
//计算代价
pTemp->pos.GetH(pTemp->pos, Endpos);//计算h代价
pTemp->pos.GetF();//得到最后的f代价,f=g+h
//把能走的这个点存入树中
pCurrent->pChild.push_back(pTemp);//pTemp表示的就是下一个能走的点
pTemp->pParent = pCurrent;//父子关系确定
//存入数组
buff.push_back(pTemp);
//标记这个点走过
vis[pTemp->pos.row][pTemp->pos.col] = true;
}
else
{
//不能走则删除pTemp,继续遍历下一个方向的点
delete pTemp;
pTemp = nullptr;
}
}
/*
遍历完八个方向后,找到最小代价点,并且移动,然后删除
*/
auto itMin = min_element(buff.begin(), buff.end(), [&](TreeNode* p1, TreeNode* p2)
{
return p1->pos.f < p2->pos.f;
});
//当前点移动到这个最小代价点
pCurrent = *itMin;
//删除最小代价节点
buff.erase(itMin);
//有没有到达终点
if (pCurrent->pos == Endpos)
{
isFindEnd = true;
break;
}
//没有终点,自然一直删除节点,则buff为空
if (buff.size() == 0)
{
break;
}
}
if (isFindEnd)
{
cout << "找到终点了!\n";
while (pCurrent)
{
cout << "(" << pCurrent->pos.row << "," << pCurrent->pos.col << ")";
pCurrent = pCurrent->pParent;
}
}
else
{
cout << "没有找到终点!\n";
}
return 0;
}
2025年01月16日 00点01分 6
level 5
白芦花 楼主
启动寻路(X2 / 16, Y2 / 16, mx / 16, my / 16, 路径);
if (!路径.empty()) {
jb = false;
int px, py;
px = 路径.back();
路径.pop_back();
py = 路径.back();
路径.pop_back();
mx = px * 16; my = py * 16;
}
2025年01月16日 10点01分 7
[真棒]厉害
2025年01月16日 11点01分
@为什么学C 还是不太完美
2025年01月16日 23点01分
@白芦花 可以加个人物,2个人物用不同的寻路算法对比一下
2025年01月18日 10点01分
@为什么学C 好的,先找个能运行的别的算法
2025年01月19日 00点01分
level 15
如果你的角色可以走斜线的话,可以考虑对网格地图执行寻路后得到的所有途径点做简单的平滑处理,即:如果第 i 个点和第 i + 2 个点之间没有障碍的话,删去第 i + 1 个点,重复直到无点可删。(但这种方法得不到最优解。)更多的算法可参阅: https://theory.stanford.edu/~amitp/GameProgramming/Variations.html
2025年01月17日 01点01分 8
感谢你的提议,不能走斜线,原代码中八个方向已去掉四个
2025年01月17日 03点01分
看楼下 查找表
2025年01月17日 03点01分
level 5
白芦花 楼主
找到终点了!
(29,28)(29,27)(29,26)(29,25)(29,24)(29,23)(29,22)(29,21)(28,21)(27,21)(26,21)(25,21)(24,21)(23,21)(22,21)(21,21)(20,21)(20,22)(20,23)(20,24)(20,25)(20,26)(20,27)(20,28)(21,28)(22,28)(23,28)(24,28)(25,28)
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
011111111111111111000011111111111111111000000000111111110000
010000000000000000000010000000000000001000000000100000010000
010000000000000000000010100000000000101000000000100010010000
010010000000000000000010000000000000001000000000100000010000
010000000000000000000010000000000000001000000000100000010000
010000000000000000000010000000000000001000000000100000010000
010000000010000000000010000000000000001000000000100000010000
010000000010000000000000000000000000001111111111100000010000
010000000010000000000000000000000000000000000000000000000000
010000000010000000000000000000000000000000000000000000000000
010000000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000010000000
010010000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000010000000
010000000010000000000000000000000000000000000000000000000000
010000000010000000000555555550000000000000000000000000000000
010000000010000000000510000050000000001111111111100000010000
010000000000000000000510000050000000001000000000100000010000
010000000000000000000510000050000000001000000000100000010000
010010000000000000000510000050000000001000000000100000010000
010000000000000000000510100040000000101000000000100010010000
010000000000000000000510000000000000001000000000100000010000
011111111111111111000511111111111111111000000000111111110000
000000000000000000000500000000000000000000000000000000000000
000000000000000000000555555560000000000000000000000000000000
0:空,1:障碍,4:起点,5:路径,6:终点
查找表
2025年01月17日 03点01分 9
level 1
经典A星。或者给方格游戏来点小小的强化学习震撼。
2025年01月17日 04点01分 10
对对
2025年01月17日 05点01分
level 1
洪水算法或者A*[阴险]
不行就搞个Agent
2025年01月18日 08点01分 11
实现了一个A*算法
2025年01月19日 00点01分
level 5
白芦花 楼主
换个地图测试
2025年01月19日 00点01分 12
1