• 类似于推箱子的小游戏 寻找 最短路径


    实现效果如下

    类似 推箱子小游戏 的变种 C/C++版本 BFS最短路径

    黑色代表墙壁 不能越过

    蓝色代表HOME点 灰色代表要找的小箱子

    绿色代表路径  

    最终目标是将灰色的小箱子移动到蓝色的HOME点 

    需要两次搜索 第一次是 出发点到灰色小箱子 

    第二次是灰色小箱子到蓝色HOME点

    BFS 搜索路径之后 找到一条最短路径 

    动画效果用的是JAVA的 一个jar包 

    完整的代码 包含动画效果已经上传点击这里下载

    C语言编译

    gcc box.c graphics.c -o box
    

    C++编译

    g++ box.cpp graphics.c -o box
    

    需要安装jdk 17版本  

    如下图 将 安装包里的所有文件放到 如下的jdk bin目录  

    执行如下代码  最后的jar包 用绝对路径就可以 

    ./box | ./java -jar /home/QMCY/robot/drawppp.jar
    

    代码很乱  临时记录下 

    C语言版本

    1. #include
    2. #include "graphics.h"
    3. #define GRID_SIZE_X 10
    4. #define GRID_SIZE_Y 10
    5. #define ROBOT 'R'
    6. #define HOME_X 9
    7. #define HOME_Y 2
    8. #define MARKER_X 7
    9. #define MARKER_Y 7
    10. #define ROBOT_X 6
    11. #define ROBOT_Y 5
    12. #define MAX_N 105
    13. int g_father[MAX_N][MAX_N];
    14. int dist[MAX_N][MAX_N];
    15. int last_dir[MAX_N][MAX_N];
    16. int dir[MAX_N*MAX_N];
    17. char g_has_visited[MAX_N][MAX_N]; //vis[x][y]表示xy点是否遍历过
    18. int Queue[MAX_N*MAX_N]; //用Q来模拟队列 给定两个下标 front和rear 那么入队则是Q[rear++]=u 出队是u=Q[front++]
    19. int coordinate[MAX_N*MAX_N];
    20. const int squareSize = 50;
    21. const int windowSize = 600;
    22. // Define the grid elements
    23. const char EMPTY = ' ';
    24. const char BLOCK = '#';
    25. const char MARKER = '*';
    26. const char HOME = 'H';
    27. // Define robot directions
    28. typedef enum { WEST , EAST, NORTH, SOUTH }Direction;
    29. // Define the robot struct
    30. typedef struct {
    31. int x;
    32. int y;
    33. Direction direction;
    34. char carryingMarker;
    35. }Robot;
    36. void drawStep(int homeX, int homeY)
    37. {
    38. background();
    39. setColour(pink);
    40. homeX = homeX*squareSize;
    41. homeY = homeY*squareSize;
    42. fillRect(homeX, homeY, squareSize, squareSize);
    43. }
    44. void drawMarker(int x,int y)
    45. {
    46. background();
    47. setColour(gray);
    48. x = x*squareSize;
    49. y = y*squareSize;
    50. fillRect(x, y, squareSize, squareSize);
    51. }
    52. void drawBlocks(int x,int y)
    53. {
    54. background();
    55. setColour(black);
    56. x = x*squareSize;
    57. y = y*squareSize;
    58. fillRect(x, y, squareSize, squareSize);
    59. }
    60. void drawEmpty(int x,int y)
    61. {
    62. foreground();
    63. setColour(white);
    64. x = x*squareSize;
    65. y = y*squareSize;
    66. fillRect(x, y, squareSize, squareSize);
    67. }
    68. // Function to initialize the grid
    69. void initializeGrid(char grid[][GRID_SIZE_Y]) {
    70. // Initialize the grid with empty spaces
    71. for (int i = 0; i < GRID_SIZE_X; ++i) {
    72. for (int j = 0; j < GRID_SIZE_X; ++j) {
    73. grid[i][j] = EMPTY;
    74. }
    75. }
    76. // Place blocks, markers, and home square
    77. grid[8][8] = BLOCK;
    78. grid[9][5] = BLOCK;
    79. grid[8][5] = BLOCK;
    80. grid[7][5] = BLOCK;
    81. grid[6][7] = BLOCK;
    82. grid[8][7] = BLOCK;
    83. grid[7][8] = BLOCK;
    84. grid[7][8] = BLOCK;
    85. grid[2][2] = BLOCK;
    86. grid[3][3] = BLOCK;
    87. grid[4][4] = BLOCK;
    88. grid[5][5] = BLOCK;
    89. grid[6][6] = BLOCK;
    90. grid[MARKER_X][MARKER_Y] = MARKER;
    91. grid[HOME_X][HOME_Y] = HOME;
    92. }
    93. // Function to display the grid
    94. void displayGrid(const char grid[][GRID_SIZE_X]) {
    95. setWindowSize(windowSize, windowSize);
    96. background(); // Must draw on the background layer.
    97. int x;
    98. int y;
    99. for (x=0; x
    100. {
    101. for (y=0; y
    102. {
    103. drawRect(x*squareSize, y*squareSize,
    104. squareSize, squareSize);
    105. }
    106. }
    107. }
    108. void draw_north(int x, int y)
    109. {
    110. int x_coords[] = {x, x+50, x+25};
    111. int y_coords[] = {y+50, y+50, y};
    112. fillPolygon(3, x_coords, y_coords);
    113. }
    114. void draw_east(int x, int y)
    115. {
    116. int x_coords[] = {x, x, x+50};
    117. int y_coords[] = {y, y+50, y+25};
    118. fillPolygon(3, x_coords, y_coords);
    119. }
    120. void draw_south(int x, int y)
    121. {
    122. int x_coords[] = {x, x+50, x+25};
    123. int y_coords[] = {y, y, y+50};
    124. fillPolygon(3, x_coords, y_coords);
    125. }
    126. void draw_west(int x, int y)
    127. {
    128. int x_coords[] = {x+50, x+50, x};
    129. int y_coords[] = {y, y+50, y+25};
    130. fillPolygon(3, x_coords, y_coords);
    131. }
    132. // Function to drop a marker
    133. void dropMarker(Robot *robot, char grid[][GRID_SIZE_X]) {
    134. if (!robot->carryingMarker) {
    135. return; // Robot is not carrying a marker
    136. }
    137. grid[robot->x][robot->y] = MARKER;
    138. robot->carryingMarker = 0;
    139. //drawRobot(robot.x, robot.y, (int)robot.direction);
    140. }
    141. void drawRobot(int x, int y, int direction)
    142. {
    143. foreground();
    144. clear();
    145. setColour(green);
    146. x = x*squareSize;
    147. y = y*squareSize;
    148. switch (direction)
    149. {
    150. case NORTH: draw_north(x, y); break;
    151. case EAST: draw_east(x, y); break;
    152. case SOUTH: draw_south(x, y); break;
    153. case WEST: draw_west(x, y); break;
    154. }
    155. }
    156. void drawRobotWithBg(int x, int y, int direction)
    157. {
    158. foreground();
    159. clear();
    160. setColour(gray);
    161. x = x*squareSize;
    162. y = y*squareSize;
    163. fillRect(x, y, squareSize, squareSize);
    164. setColour(green);
    165. switch (direction)
    166. {
    167. case NORTH: draw_north(x, y); break;
    168. case EAST: draw_east(x, y); break;
    169. case SOUTH: draw_south(x, y); break;
    170. case WEST: draw_west(x, y); break;
    171. }
    172. }
    173. void drawHome(int homeX, int homeY)
    174. {
    175. background();
    176. setColour(blue);
    177. homeX = homeX*squareSize;
    178. homeY = homeY*squareSize;
    179. fillRect(homeX, homeY, squareSize, squareSize);
    180. }
    181. void drawShort(int homeX, int homeY)
    182. {
    183. background();
    184. setColour(orange);
    185. homeX = homeX*squareSize;
    186. homeY = homeY*squareSize;
    187. fillRect(homeX, homeY, squareSize, squareSize);
    188. }
    189. void forward(Robot *robot, char grid[][GRID_SIZE_X]) {
    190. // Calculate the next position based on the direction
    191. int nextX = robot->x;
    192. int nextY = robot->y;
    193. if (robot->direction == NORTH) {
    194. --nextX;
    195. } else if (robot->direction == SOUTH) {
    196. ++nextX;
    197. } else if (robot->direction == EAST) {
    198. ++nextY;
    199. } else if (robot->direction == WEST) {
    200. --nextY;
    201. }
    202. // Check if the next position is valid
    203. if (nextX >= 0 && nextX < GRID_SIZE_X && nextY >= 0 && nextY < GRID_SIZE_X && grid[nextX][nextY] != BLOCK) {
    204. // Move the robot
    205. grid[robot->x][robot->y] = EMPTY;
    206. robot->x = nextX;
    207. robot->y = nextY;
    208. grid[robot->x][robot->y] = ROBOT;
    209. }
    210. drawRobot(robot->x, robot->y, robot->direction);
    211. }
    212. char markersLeft(char grid[][GRID_SIZE_X]) {
    213. for (int i = 0; i < GRID_SIZE_X; ++i) {
    214. for (int j = 0; j < GRID_SIZE_X; ++j) {
    215. if (grid[i][j] == MARKER) {
    216. return 1;
    217. }
    218. }
    219. }
    220. return 0;
    221. }
    222. void turn_left(Robot *robot) {
    223. if (robot->direction == NORTH) {
    224. robot->direction = WEST;
    225. } else if (robot->direction == SOUTH) {
    226. robot->direction = EAST;
    227. } else if (robot->direction == EAST) {
    228. robot->direction = NORTH;
    229. } else if (robot->direction == WEST) {
    230. robot->direction = SOUTH;
    231. }
    232. drawRobot(robot->x, robot->y, robot->direction);
    233. }
    234. void turn_right(Robot *robot) {
    235. if (robot->direction == NORTH) {
    236. robot->direction = EAST;
    237. } else if (robot->direction == SOUTH) {
    238. robot->direction = WEST;
    239. } else if (robot->direction == EAST) {
    240. robot->direction = SOUTH;
    241. } else if (robot->direction == WEST) {
    242. robot->direction = NORTH;
    243. }
    244. drawRobot(robot->x, robot->y, robot->direction);
    245. }
    246. // Function to pick up a marker
    247. void pickUpMarker(Robot *robot, char grid[][GRID_SIZE_Y]) {
    248. if (grid[robot->x][robot->y] == MARKER) {
    249. robot->carryingMarker = 1;
    250. grid[robot->x][robot->y] = EMPTY;
    251. }
    252. }
    253. void findAndCollectMarkers(Robot *robot, char grid[][GRID_SIZE_X]) {
    254. while (markersLeft(grid)) {
    255. int initialX = robot->x;
    256. int initialY = robot->y;
    257. Direction initialDirection = robot->direction;
    258. // Use the "right hand rule" to navigate
    259. if (robot->direction == NORTH) {
    260. if (grid[robot->x][robot->y + 1] != BLOCK) {
    261. turn_right(robot);
    262. } else if (grid[robot->x - 1][robot->y] != BLOCK) {
    263. forward(robot, grid);
    264. } else {
    265. turn_left(robot);
    266. }
    267. } else if (robot->direction == SOUTH) {
    268. if (grid[robot->x][robot->y - 1] != BLOCK) {
    269. turn_right(robot);
    270. } else if (grid[robot->x + 1][robot->y] != BLOCK) {
    271. forward(robot, grid);
    272. } else {
    273. turn_left(robot);
    274. }
    275. } else if (robot->direction == EAST) {
    276. if (grid[robot->x + 1][robot->y] != BLOCK) {
    277. turn_right(robot);
    278. } else if (grid[robot->x][robot->y + 1] != BLOCK) {
    279. forward(robot, grid);
    280. } else {
    281. turn_left(robot);
    282. }
    283. } else if (robot->direction == WEST) {
    284. if (grid[robot->x - 1][robot->y] != BLOCK) {
    285. turn_right(robot);
    286. } else if (grid[robot->x][robot->y - 1] != BLOCK) {
    287. forward(robot, grid);
    288. } else {
    289. turn_left(robot);
    290. }
    291. }
    292. if (initialX == robot->x && initialY == robot->y && initialDirection == robot->direction) {
    293. // Robot is stuck, rotate 180 degrees
    294. turn_left(robot);
    295. turn_left(robot);
    296. }
    297. forward(robot, grid);
    298. sleep(500); // Adjust sleep duration for animation speed
    299. pickUpMarker(robot, grid);
    300. }
    301. }
    302. int canMoveForward(Robot *robot, char grid[][GRID_SIZE_X])
    303. {
    304. int nextX = robot->x;
    305. int nextY = robot->y;
    306. if (robot->direction == NORTH) {
    307. --nextY;
    308. } else if (robot->direction == SOUTH) {
    309. ++nextY;
    310. } else if (robot->direction == EAST) {
    311. ++nextX;
    312. } else if (robot->direction == WEST) {
    313. --nextX;
    314. }
    315. // Check if the next position is valid
    316. if (nextX >=1 && nextX <= GRID_SIZE_X && nextY >= 1 && nextY <= GRID_SIZE_X && grid[nextX][nextY] != BLOCK) {
    317. // Move the robot
    318. //grid[robot->x][robot->y] = EMPTY;
    319. //robot->x = nextX;
    320. //robot->y = nextY;
    321. //grid[robot->x][robot->y] = 'R'; // Robot represented by 'R'
    322. return 1;
    323. }
    324. return 0;
    325. }
    326. // Function to turn the robot left (anti-clockwise)
    327. void left(Robot *robot) {
    328. if (robot->direction == NORTH) {
    329. robot->direction = WEST;
    330. } else if (robot->direction ==SOUTH) {
    331. robot->direction = EAST;
    332. } else if (robot->direction == EAST) {
    333. robot->direction =NORTH;
    334. } else if (robot->direction == WEST) {
    335. robot->direction = SOUTH;
    336. }
    337. drawRobot(robot->x, robot->y, robot->direction);
    338. }
    339. void right(Robot *robot) {
    340. if (robot->direction == NORTH) {
    341. robot->direction = EAST;
    342. } else if (robot->direction ==SOUTH) {
    343. robot->direction = WEST;
    344. } else if (robot->direction ==EAST) {
    345. robot->direction =SOUTH;
    346. } else if (robot->direction == WEST) {
    347. robot->direction =NORTH;
    348. }
    349. drawRobot(robot->x, robot->y, robot->direction);
    350. }
    351. #if 0
    352. bool findShortestPath(Robot &robot, char grid[][GRID_SIZE_X]) {
    353. // Use BFS to find the shortest path
    354. std::queueint, int>> q; // Queue for BFS
    355. std::vectorbool>> visited(GRID_SIZE_X, std::vector<bool>(GRID_SIZE_X, false));
    356. q.push({robot.x, robot.y});
    357. visited[robot.x][robot.y] = true;
    358. int u=robot.x*GRID_SIZE_X+robot.y;
    359. father[robot.x][robot.y]=u;
    360. sleep(2000);
    361. while (!q.empty()) {
    362. int x = q.front().first;
    363. int y = q.front().second;
    364. q.pop();
    365. //drawRobot(x, y, (int)robot.direction);
    366. if (grid[x][y] == MARKER) {
    367. // Found a marker, pick it up
    368. pickUpMarker(robot, grid);
    369. //dropMarker(robot, grid);
    370. //drawMarker(MARKER_X,MARKER_Y);
    371. //drawRobot(x, y, (int)robot.direction);
    372. return true;
    373. }
    374. // Explore neighboring cells
    375. int dx[] = {-1, 1, 0, 0};
    376. int dy[] = {0, 0, -1, 1};
    377. for (int i = 0; i < 4; ++i) {
    378. u=x*GRID_SIZE_X+y;
    379. int nx = x + dx[i];
    380. int ny = y + dy[i];
    381. if (nx >= 0 && nx < GRID_SIZE_X && ny >= 0 && ny < GRID_SIZE_X && !visited[nx][ny] && grid[nx][ny] != BLOCK) {
    382. q.push({nx, ny});
    383. //drawRobot(nx, ny, (int)robot.direction);
    384. //drawStep(nx, ny);
    385. //printf("x=%d y=%d \n",nx,ny);
    386. visited[nx][ny] = true;
    387. father[nx][ny]=u;
    388. //dist[nx][ny]=1+dist[x][y];
    389. last_dir[nx][ny]=i;
    390. }
    391. // printf("findShortestPath 2222\n");
    392. //sleep(200);
    393. }
    394. //drawRobot(robot.x, robot.y, (int)robot.direction);
    395. //sleep(10);
    396. }
    397. return false; // No markers found
    398. }
    399. #else
    400. char findShortestPath(int robot_x,int robot_y, char grid[][GRID_SIZE_X]) {
    401. // Use BFS to find the shortest path
    402. //std::queue> q; // Queue for BFS
    403. //std::vector> visited(GRID_SIZE_X, std::vector(GRID_SIZE_X, false));
    404. int front,rear;
    405. rear=front=0;
    406. Robot robot;
    407. robot.x = robot_x;
    408. robot.y = robot_y;
    409. //q.push({robot.x, robot.y});
    410. g_has_visited[robot.x][robot.y] = 1;
    411. int u=robot.x*GRID_SIZE_X+robot.y;
    412. g_father[robot.x][robot.y]=u;
    413. Queue[rear++]=u;
    414. sleep(1000);
    415. //while (!q.empty())
    416. while(rear>front)
    417. {
    418. u=Queue[front++];
    419. //int x = q.front().first;
    420. //int y = q.front().second;
    421. //q.pop();
    422. //drawRobot(x, y, (int)robot.direction);
    423. int x=u/GRID_SIZE_X;
    424. int y=u%GRID_SIZE_X;
    425. if (grid[x][y] == MARKER) {
    426. // Found a marker, pick it up
    427. pickUpMarker(&robot, grid);
    428. //dropMarker(robot, grid);
    429. //drawMarker(MARKER_X,MARKER_Y);
    430. //drawRobot(x, y, (int)robot.direction);
    431. return 1;
    432. }
    433. // Explore neighboring cells
    434. int dx[] = {-1, 1, 0, 0};
    435. int dy[] = {0, 0, -1, 1};
    436. for (int i = 0; i < 4; ++i) {
    437. //u=x*GRID_SIZE_X+y;
    438. int nx = x + dx[i];
    439. int ny = y + dy[i];
    440. if (nx >= 0 && nx < GRID_SIZE_X && ny >= 0 && ny < GRID_SIZE_X && !g_has_visited[nx][ny] && grid[nx][ny] != BLOCK) {
    441. #if 0
    442. q.push({nx, ny});
    443. //drawRobot(nx, ny, (int)robot.direction);
    444. //drawStep(nx, ny);
    445. //printf("x=%d y=%d \n",nx,ny);
    446. visited[nx][ny] = true;
    447. father[nx][ny]=u;
    448. //dist[nx][ny]=1+dist[x][y];
    449. last_dir[nx][ny]=i;
    450. #else
    451. int v=nx*GRID_SIZE_X+ny;
    452. Queue[rear++]=v;
    453. g_has_visited[nx][ny]=1;
    454. g_father[nx][ny]=u;
    455. dist[nx][ny]=1+dist[x][y];
    456. last_dir[nx][ny]=i;
    457. if (grid[nx][ny] == MARKER)
    458. {
    459. return 1;
    460. }
    461. #endif
    462. }
    463. // printf("findShortestPath 2222\n");
    464. //sleep(200);
    465. }
    466. //drawRobot(robot.x, robot.y, (int)robot.direction);
    467. //sleep(10);
    468. }
    469. return 0; // No markers found
    470. }
    471. #endif
    472. void print_path(int x,int y,char has_marker)
    473. {
    474. int steps=0;
    475. int pos_x,pos_y,direction;
    476. while(1)
    477. {
    478. int u=g_father[x][y];
    479. int fx=u/GRID_SIZE_X;
    480. int fy=u%GRID_SIZE_X;
    481. if (fx==x && fy==y)
    482. {
    483. break;
    484. }
    485. dir[steps]=last_dir[x][y];
    486. coordinate[steps++] = x*GRID_SIZE_X+y;
    487. x=fx;
    488. y=fy;
    489. }
    490. while(steps--)
    491. {
    492. pos_x = coordinate[steps]/GRID_SIZE_X;
    493. pos_y = coordinate[steps]%GRID_SIZE_X;
    494. direction = dir[steps];
    495. if(has_marker)
    496. {
    497. drawRobotWithBg(pos_x,pos_y,direction);
    498. }
    499. else
    500. {
    501. drawRobot(pos_x, pos_y,direction);
    502. }
    503. sleep(300);
    504. }
    505. }
    506. int main(int argc, char **argv) {
    507. char grid[GRID_SIZE_X][GRID_SIZE_X];
    508. initializeGrid(grid);
    509. Robot robot;
    510. robot.x = ROBOT_X; // Initial X position
    511. robot.y = ROBOT_Y; // Initial Y position
    512. robot.direction = EAST;
    513. robot.carryingMarker = 0;
    514. // Display the initial grid
    515. displayGrid(grid);
    516. drawHome(HOME_X, HOME_Y);
    517. drawMarker(MARKER_X,MARKER_Y);
    518. drawBlocks(8,8);
    519. drawBlocks(9,5);
    520. drawBlocks(8,5);
    521. drawBlocks(7,5);
    522. drawBlocks(6,7);
    523. drawBlocks(8,7);
    524. drawBlocks(7,8);
    525. drawBlocks(2,2);
    526. drawBlocks(3,3);
    527. drawBlocks(4,4);
    528. drawBlocks(5,5);
    529. drawBlocks(6,6);
    530. #if 0
    531. findAndCollectMarkers(&robot, grid);
    532. #elif 0
    533. while (!robot.carryingMarker) {
    534. if(canMoveForward(&robot, grid))
    535. {
    536. forward(robot, grid);
    537. }
    538. else
    539. {
    540. left(robot);
    541. }
    542. sleep(500);
    543. //printf("robot.x = %d y = %d dir = %d\n",robot.x,robot.y,robot.direction);
    544. }
    545. #else
    546. while (!findShortestPath(robot.x,robot.y, grid)) {
    547. forward(&robot, grid);
    548. sleep(500); // Adjust sleep duration for animation speed
    549. }
    550. print_path(MARKER_X,MARKER_Y,0);
    551. robot.x = MARKER_X;
    552. robot.y = MARKER_Y;
    553. grid[MARKER_X][MARKER_Y] = EMPTY;
    554. grid[HOME_X][HOME_Y] = MARKER;
    555. memset(g_has_visited,0,sizeof(g_has_visited));
    556. while (!findShortestPath(robot.x,robot.y, grid)) {
    557. forward(&robot, grid);
    558. sleep(500); // Adjust sleep duration for animation speed
    559. }
    560. print_path(HOME_X,HOME_Y,1);
    561. #endif
    562. return 0;
    563. }

    C++版本

    1. #include // For sleep function
    2. #include "graphics.h"
    3. #define GRID_SIZE_X 10
    4. #define GRID_SIZE_Y 10
    5. #define ROBOT 'R'
    6. const int maxn=105;
    7. #define HOME_X 0
    8. #define HOME_Y 0
    9. #define MARKER_X 7
    10. #define MARKER_Y 7
    11. #define ROBOT_X 9
    12. #define ROBOT_Y 0
    13. int father[maxn][maxn];
    14. int dist[maxn][maxn];
    15. int last_dir[maxn][maxn];
    16. int dir[maxn*maxn];
    17. bool visit_first[maxn][maxn]; //vis[x][y]表示xy点是否遍历过
    18. bool visit_second[maxn][maxn]; //vis[x][y]表示xy点是否遍历过
    19. int Queue[maxn*maxn]; //用Q来模拟队列 给定两个下标 front和rear 那么入队则是Q[rear++]=u 出队是u=Q[front++]
    20. int coordinate[maxn*maxn];
    21. const int squareSize = 50;
    22. const int windowSize = 600;
    23. // Define the grid elements
    24. const char EMPTY = ' ';
    25. const char BLOCK = '#';
    26. const char MARKER = '*';
    27. const char HOME = 'H';
    28. // Define robot directions
    29. enum Direction { WEST , EAST, NORTH, SOUTH };
    30. // Define the robot struct
    31. struct Robot {
    32. int x;
    33. int y;
    34. Direction direction;
    35. bool carryingMarker;
    36. };
    37. void drawStep(int homeX, int homeY)
    38. {
    39. background();
    40. setColour(pink);
    41. homeX = homeX*squareSize;
    42. homeY = homeY*squareSize;
    43. fillRect(homeX, homeY, squareSize, squareSize);
    44. }
    45. void drawMarker(int x,int y)
    46. {
    47. background();
    48. setColour(gray);
    49. x = x*squareSize;
    50. y = y*squareSize;
    51. fillRect(x, y, squareSize, squareSize);
    52. }
    53. void drawBlocks(int x,int y)
    54. {
    55. background();
    56. setColour(black);
    57. x = x*squareSize;
    58. y = y*squareSize;
    59. fillRect(x, y, squareSize, squareSize);
    60. }
    61. void drawEmpty(int x,int y)
    62. {
    63. foreground();
    64. setColour(white);
    65. x = x*squareSize;
    66. y = y*squareSize;
    67. fillRect(x, y, squareSize, squareSize);
    68. }
    69. // Function to initialize the grid
    70. void initializeGrid(char grid[][GRID_SIZE_Y]) {
    71. // Initialize the grid with empty spaces
    72. for (int i = 0; i < GRID_SIZE_X; ++i) {
    73. for (int j = 0; j < GRID_SIZE_X; ++j) {
    74. grid[i][j] = EMPTY;
    75. }
    76. }
    77. // Place blocks, markers, and home square
    78. grid[8][8] = BLOCK;
    79. grid[9][5] = BLOCK;
    80. grid[8][5] = BLOCK;
    81. grid[7][5] = BLOCK;
    82. grid[6][7] = BLOCK;
    83. grid[8][7] = BLOCK;
    84. grid[7][8] = BLOCK;
    85. grid[7][8] = BLOCK;
    86. grid[2][2] = BLOCK;
    87. grid[3][3] = BLOCK;
    88. grid[4][4] = BLOCK;
    89. grid[5][5] = BLOCK;
    90. grid[6][6] = BLOCK;
    91. grid[MARKER_X][MARKER_Y] = MARKER;
    92. grid[HOME_X][HOME_Y] = HOME;
    93. }
    94. // Function to display the grid
    95. void displayGrid(const char grid[][GRID_SIZE_X]) {
    96. setWindowSize(windowSize, windowSize);
    97. background(); // Must draw on the background layer.
    98. int x;
    99. int y;
    100. for (x=0; x
    101. {
    102. for (y=0; y
    103. {
    104. drawRect(x*squareSize, y*squareSize,
    105. squareSize, squareSize);
    106. }
    107. }
    108. }
    109. void draw_north(int x, int y)
    110. {
    111. int x_coords[] = {x, x+50, x+25};
    112. int y_coords[] = {y+50, y+50, y};
    113. fillPolygon(3, x_coords, y_coords);
    114. }
    115. void draw_east(int x, int y)
    116. {
    117. int x_coords[] = {x, x, x+50};
    118. int y_coords[] = {y, y+50, y+25};
    119. fillPolygon(3, x_coords, y_coords);
    120. }
    121. void draw_south(int x, int y)
    122. {
    123. int x_coords[] = {x, x+50, x+25};
    124. int y_coords[] = {y, y, y+50};
    125. fillPolygon(3, x_coords, y_coords);
    126. }
    127. void draw_west(int x, int y)
    128. {
    129. int x_coords[] = {x+50, x+50, x};
    130. int y_coords[] = {y, y+50, y+25};
    131. fillPolygon(3, x_coords, y_coords);
    132. }
    133. // Function to drop a marker
    134. void dropMarker(Robot &robot, char grid[][GRID_SIZE_X]) {
    135. if (!robot.carryingMarker) {
    136. return; // Robot is not carrying a marker
    137. }
    138. grid[robot.x][robot.y] = MARKER;
    139. robot.carryingMarker = false;
    140. //drawRobot(robot.x, robot.y, (int)robot.direction);
    141. }
    142. void drawRobot(int x, int y, int direction)
    143. {
    144. foreground();
    145. clear();
    146. setColour(green);
    147. x = x*squareSize;
    148. y = y*squareSize;
    149. switch (direction)
    150. {
    151. case Direction::NORTH: draw_north(x, y); break;
    152. case Direction::EAST: draw_east(x, y); break;
    153. case Direction::SOUTH: draw_south(x, y); break;
    154. case Direction::WEST: draw_west(x, y); break;
    155. }
    156. }
    157. void drawRobotWithBg(int x, int y, int direction)
    158. {
    159. foreground();
    160. clear();
    161. setColour(gray);
    162. x = x*squareSize;
    163. y = y*squareSize;
    164. fillRect(x, y, squareSize, squareSize);
    165. setColour(green);
    166. switch (direction)
    167. {
    168. case Direction::NORTH: draw_north(x, y); break;
    169. case Direction::EAST: draw_east(x, y); break;
    170. case Direction::SOUTH: draw_south(x, y); break;
    171. case Direction::WEST: draw_west(x, y); break;
    172. }
    173. }
    174. void drawHome(int homeX, int homeY)
    175. {
    176. background();
    177. setColour(blue);
    178. homeX = homeX*squareSize;
    179. homeY = homeY*squareSize;
    180. fillRect(homeX, homeY, squareSize, squareSize);
    181. }
    182. void drawShort(int homeX, int homeY)
    183. {
    184. background();
    185. setColour(orange);
    186. homeX = homeX*squareSize;
    187. homeY = homeY*squareSize;
    188. fillRect(homeX, homeY, squareSize, squareSize);
    189. }
    190. void forward(Robot *robot, char grid[][GRID_SIZE_X]) {
    191. // Calculate the next position based on the direction
    192. int nextX = robot->x;
    193. int nextY = robot->y;
    194. if (robot->direction == NORTH) {
    195. --nextX;
    196. } else if (robot->direction == SOUTH) {
    197. ++nextX;
    198. } else if (robot->direction == EAST) {
    199. ++nextY;
    200. } else if (robot->direction == WEST) {
    201. --nextY;
    202. }
    203. // Check if the next position is valid
    204. if (nextX >= 0 && nextX < GRID_SIZE_X && nextY >= 0 && nextY < GRID_SIZE_X && grid[nextX][nextY] != BLOCK) {
    205. // Move the robot
    206. grid[robot->x][robot->y] = EMPTY;
    207. robot->x = nextX;
    208. robot->y = nextY;
    209. grid[robot->x][robot->y] = ROBOT;
    210. }
    211. drawRobot(robot->x, robot->y, robot->direction);
    212. }
    213. bool markersLeft(char grid[][GRID_SIZE_X]) {
    214. for (int i = 0; i < GRID_SIZE_X; ++i) {
    215. for (int j = 0; j < GRID_SIZE_X; ++j) {
    216. if (grid[i][j] == MARKER) {
    217. return true;
    218. }
    219. }
    220. }
    221. return false;
    222. }
    223. void turn_left(Robot *robot) {
    224. if (robot->direction == NORTH) {
    225. robot->direction = WEST;
    226. } else if (robot->direction == SOUTH) {
    227. robot->direction = EAST;
    228. } else if (robot->direction == EAST) {
    229. robot->direction = NORTH;
    230. } else if (robot->direction == WEST) {
    231. robot->direction = SOUTH;
    232. }
    233. drawRobot(robot->x, robot->y, robot->direction);
    234. }
    235. void turn_right(Robot *robot) {
    236. if (robot->direction == NORTH) {
    237. robot->direction = EAST;
    238. } else if (robot->direction == SOUTH) {
    239. robot->direction = WEST;
    240. } else if (robot->direction == EAST) {
    241. robot->direction = SOUTH;
    242. } else if (robot->direction == WEST) {
    243. robot->direction = NORTH;
    244. }
    245. drawRobot(robot->x, robot->y, robot->direction);
    246. }
    247. // Function to pick up a marker
    248. void pickUpMarker(Robot *robot, char grid[][GRID_SIZE_Y]) {
    249. if (grid[robot->x][robot->y] == MARKER) {
    250. robot->carryingMarker = true;
    251. grid[robot->x][robot->y] = EMPTY;
    252. }
    253. }
    254. void findAndCollectMarkers(Robot *robot, char grid[][GRID_SIZE_X]) {
    255. while (markersLeft(grid)) {
    256. int initialX = robot->x;
    257. int initialY = robot->y;
    258. Direction initialDirection = robot->direction;
    259. // Use the "right hand rule" to navigate
    260. if (robot->direction == NORTH) {
    261. if (grid[robot->x][robot->y + 1] != BLOCK) {
    262. turn_right(robot);
    263. } else if (grid[robot->x - 1][robot->y] != BLOCK) {
    264. forward(robot, grid);
    265. } else {
    266. turn_left(robot);
    267. }
    268. } else if (robot->direction == SOUTH) {
    269. if (grid[robot->x][robot->y - 1] != BLOCK) {
    270. turn_right(robot);
    271. } else if (grid[robot->x + 1][robot->y] != BLOCK) {
    272. forward(robot, grid);
    273. } else {
    274. turn_left(robot);
    275. }
    276. } else if (robot->direction == EAST) {
    277. if (grid[robot->x + 1][robot->y] != BLOCK) {
    278. turn_right(robot);
    279. } else if (grid[robot->x][robot->y + 1] != BLOCK) {
    280. forward(robot, grid);
    281. } else {
    282. turn_left(robot);
    283. }
    284. } else if (robot->direction == WEST) {
    285. if (grid[robot->x - 1][robot->y] != BLOCK) {
    286. turn_right(robot);
    287. } else if (grid[robot->x][robot->y - 1] != BLOCK) {
    288. forward(robot, grid);
    289. } else {
    290. turn_left(robot);
    291. }
    292. }
    293. if (initialX == robot->x && initialY == robot->y && initialDirection == robot->direction) {
    294. // Robot is stuck, rotate 180 degrees
    295. turn_left(robot);
    296. turn_left(robot);
    297. }
    298. forward(robot, grid);
    299. sleep(500); // Adjust sleep duration for animation speed
    300. pickUpMarker(robot, grid);
    301. }
    302. }
    303. int canMoveForward(Robot *robot, char grid[][GRID_SIZE_X])
    304. {
    305. int nextX = robot->x;
    306. int nextY = robot->y;
    307. if (robot->direction == Direction::NORTH) {
    308. --nextY;
    309. } else if (robot->direction == Direction::SOUTH) {
    310. ++nextY;
    311. } else if (robot->direction == Direction::EAST) {
    312. ++nextX;
    313. } else if (robot->direction == Direction::WEST) {
    314. --nextX;
    315. }
    316. // Check if the next position is valid
    317. if (nextX >=1 && nextX <= GRID_SIZE_X && nextY >= 1 && nextY <= GRID_SIZE_X && grid[nextX][nextY] != BLOCK) {
    318. // Move the robot
    319. //grid[robot->x][robot->y] = EMPTY;
    320. //robot->x = nextX;
    321. //robot->y = nextY;
    322. //grid[robot->x][robot->y] = 'R'; // Robot represented by 'R'
    323. return 1;
    324. }
    325. return 0;
    326. }
    327. // Function to turn the robot left (anti-clockwise)
    328. void left(Robot *robot) {
    329. if (robot->direction == Direction::NORTH) {
    330. robot->direction = Direction::WEST;
    331. } else if (robot->direction == Direction::SOUTH) {
    332. robot->direction = Direction::EAST;
    333. } else if (robot->direction == Direction::EAST) {
    334. robot->direction = Direction::NORTH;
    335. } else if (robot->direction == Direction::WEST) {
    336. robot->direction = Direction::SOUTH;
    337. }
    338. drawRobot(robot->x, robot->y, robot->direction);
    339. }
    340. void right(Robot *robot) {
    341. if (robot->direction == Direction::NORTH) {
    342. robot->direction = Direction::EAST;
    343. } else if (robot->direction == Direction::SOUTH) {
    344. robot->direction = Direction::WEST;
    345. } else if (robot->direction == Direction::EAST) {
    346. robot->direction = Direction::SOUTH;
    347. } else if (robot->direction == Direction::WEST) {
    348. robot->direction = Direction::NORTH;
    349. }
    350. drawRobot(robot->x, robot->y, robot->direction);
    351. }
    352. // Function to pick up a marker
    353. void pickUpMarker(Robot &robot, char grid[][GRID_SIZE_X]) {
    354. if (grid[robot.x][robot.y] == MARKER) {
    355. robot.carryingMarker = true;
    356. grid[robot.x][robot.y] = EMPTY;
    357. //drawRobot(robot.x, robot.y, (int)robot.direction);
    358. }
    359. }
    360. #if 0
    361. bool findShortestPath(Robot &robot, char grid[][GRID_SIZE_X]) {
    362. // Use BFS to find the shortest path
    363. std::queueint, int>> q; // Queue for BFS
    364. std::vectorbool>> visited(GRID_SIZE_X, std::vector<bool>(GRID_SIZE_X, false));
    365. q.push({robot.x, robot.y});
    366. visited[robot.x][robot.y] = true;
    367. int u=robot.x*GRID_SIZE_X+robot.y;
    368. father[robot.x][robot.y]=u;
    369. sleep(2000);
    370. while (!q.empty()) {
    371. int x = q.front().first;
    372. int y = q.front().second;
    373. q.pop();
    374. //drawRobot(x, y, (int)robot.direction);
    375. if (grid[x][y] == MARKER) {
    376. // Found a marker, pick it up
    377. pickUpMarker(robot, grid);
    378. //dropMarker(robot, grid);
    379. //drawMarker(MARKER_X,MARKER_Y);
    380. //drawRobot(x, y, (int)robot.direction);
    381. return true;
    382. }
    383. // Explore neighboring cells
    384. int dx[] = {-1, 1, 0, 0};
    385. int dy[] = {0, 0, -1, 1};
    386. for (int i = 0; i < 4; ++i) {
    387. u=x*GRID_SIZE_X+y;
    388. int nx = x + dx[i];
    389. int ny = y + dy[i];
    390. if (nx >= 0 && nx < GRID_SIZE_X && ny >= 0 && ny < GRID_SIZE_X && !visited[nx][ny] && grid[nx][ny] != BLOCK) {
    391. q.push({nx, ny});
    392. //drawRobot(nx, ny, (int)robot.direction);
    393. //drawStep(nx, ny);
    394. //printf("x=%d y=%d \n",nx,ny);
    395. visited[nx][ny] = true;
    396. father[nx][ny]=u;
    397. //dist[nx][ny]=1+dist[x][y];
    398. last_dir[nx][ny]=i;
    399. }
    400. // printf("findShortestPath 2222\n");
    401. //sleep(200);
    402. }
    403. //drawRobot(robot.x, robot.y, (int)robot.direction);
    404. //sleep(10);
    405. }
    406. return false; // No markers found
    407. }
    408. #else
    409. bool findShortestPath(int robot_x,int robot_y, char grid[][GRID_SIZE_X],bool visit[][maxn]) {
    410. // Use BFS to find the shortest path
    411. //std::queue> q; // Queue for BFS
    412. //std::vector> visited(GRID_SIZE_X, std::vector(GRID_SIZE_X, false));
    413. int front,rear;
    414. rear=front=0;
    415. Robot robot;
    416. robot.x = robot_x;
    417. robot.y = robot_y;
    418. //q.push({robot.x, robot.y});
    419. bool **visited = NULL;
    420. visit[robot.x][robot.y] = true;
    421. int u=robot.x*GRID_SIZE_X+robot.y;
    422. father[robot.x][robot.y]=u;
    423. Queue[rear++]=u;
    424. sleep(1000);
    425. //while (!q.empty())
    426. while(rear>front)
    427. {
    428. u=Queue[front++];
    429. //int x = q.front().first;
    430. //int y = q.front().second;
    431. //q.pop();
    432. //drawRobot(x, y, (int)robot.direction);
    433. int x=u/GRID_SIZE_X;
    434. int y=u%GRID_SIZE_X;
    435. if (grid[x][y] == MARKER) {
    436. // Found a marker, pick it up
    437. pickUpMarker(robot, grid);
    438. //dropMarker(robot, grid);
    439. //drawMarker(MARKER_X,MARKER_Y);
    440. //drawRobot(x, y, (int)robot.direction);
    441. return true;
    442. }
    443. // Explore neighboring cells
    444. int dx[] = {-1, 1, 0, 0};
    445. int dy[] = {0, 0, -1, 1};
    446. for (int i = 0; i < 4; ++i) {
    447. //u=x*GRID_SIZE_X+y;
    448. int nx = x + dx[i];
    449. int ny = y + dy[i];
    450. if (nx >= 0 && nx < GRID_SIZE_X && ny >= 0 && ny < GRID_SIZE_X && !visit[nx][ny] && grid[nx][ny] != BLOCK) {
    451. #if 0
    452. q.push({nx, ny});
    453. //drawRobot(nx, ny, (int)robot.direction);
    454. //drawStep(nx, ny);
    455. //printf("x=%d y=%d \n",nx,ny);
    456. visited[nx][ny] = true;
    457. father[nx][ny]=u;
    458. //dist[nx][ny]=1+dist[x][y];
    459. last_dir[nx][ny]=i;
    460. #else
    461. int v=nx*GRID_SIZE_X+ny;
    462. Queue[rear++]=v;
    463. visit[nx][ny]=true;
    464. father[nx][ny]=u;
    465. dist[nx][ny]=1+dist[x][y];
    466. last_dir[nx][ny]=i;
    467. if (grid[nx][ny] == MARKER)
    468. {
    469. return true;
    470. }
    471. #endif
    472. }
    473. // printf("findShortestPath 2222\n");
    474. //sleep(200);
    475. }
    476. //drawRobot(robot.x, robot.y, (int)robot.direction);
    477. //sleep(10);
    478. }
    479. return false; // No markers found
    480. }
    481. #endif
    482. void print_path(int x,int y,bool has_marker)
    483. {
    484. int steps=0;
    485. int pos_x,pos_y,direction;
    486. while(true)
    487. {
    488. int u=father[x][y];
    489. int fx=u/GRID_SIZE_X;
    490. int fy=u%GRID_SIZE_X;
    491. if (fx==x && fy==y)
    492. {
    493. break;
    494. }
    495. dir[steps]=last_dir[x][y];
    496. coordinate[steps++] = x*GRID_SIZE_X+y;
    497. x=fx;
    498. y=fy;
    499. }
    500. while(steps--)
    501. {
    502. pos_x = coordinate[steps]/GRID_SIZE_X;
    503. pos_y = coordinate[steps]%GRID_SIZE_X;
    504. direction = dir[steps];
    505. if(has_marker)
    506. {
    507. drawRobotWithBg(pos_x,pos_y,direction);
    508. }
    509. else
    510. {
    511. drawRobot(pos_x, pos_y,direction);
    512. }
    513. sleep(300);
    514. }
    515. }
    516. int main(int argc, char **argv) {
    517. char grid[GRID_SIZE_X][GRID_SIZE_X];
    518. initializeGrid(grid);
    519. Robot robot;
    520. robot.x = ROBOT_X; // Initial X position
    521. robot.y = ROBOT_Y; // Initial Y position
    522. robot.direction = Direction::EAST;
    523. robot.carryingMarker = false;
    524. // Display the initial grid
    525. displayGrid(grid);
    526. drawHome(HOME_X, HOME_Y);
    527. drawMarker(MARKER_X,MARKER_Y);
    528. drawBlocks(8,8);
    529. drawBlocks(9,5);
    530. drawBlocks(8,5);
    531. drawBlocks(7,5);
    532. drawBlocks(6,7);
    533. drawBlocks(8,7);
    534. drawBlocks(7,8);
    535. drawBlocks(2,2);
    536. drawBlocks(3,3);
    537. drawBlocks(4,4);
    538. drawBlocks(5,5);
    539. drawBlocks(6,6);
    540. #if 0
    541. findAndCollectMarkers(&robot, grid);
    542. #elif 0
    543. while (!robot.carryingMarker) {
    544. if(canMoveForward(&robot, grid))
    545. {
    546. forward(robot, grid);
    547. }
    548. else
    549. {
    550. left(robot);
    551. }
    552. sleep(500);
    553. //printf("robot.x = %d y = %d dir = %d\n",robot.x,robot.y,robot.direction);
    554. }
    555. #else
    556. while (!findShortestPath(robot.x,robot.y, grid,visit_first)) {
    557. forward(&robot, grid);
    558. sleep(500); // Adjust sleep duration for animation speed
    559. }
    560. print_path(MARKER_X,MARKER_Y,false);
    561. robot.x = MARKER_X;
    562. robot.y = MARKER_Y;
    563. grid[MARKER_X][MARKER_Y] = EMPTY;
    564. grid[HOME_X][HOME_Y] = MARKER;
    565. while (!findShortestPath(robot.x,robot.y, grid,visit_second)) {
    566. forward(&robot, grid);
    567. sleep(500); // Adjust sleep duration for animation speed
    568. }
    569. print_path(HOME_X,HOME_Y,true);
    570. #endif
    571. return 0;
    572. }

  • 相关阅读:
    开源的远程桌面软件RustDesk
    线性同余方程( 数学知识 + 同余 + 扩展欧几里得算法 )
    入门ROS其实也没有那么难!
    确定Mac\Linux系统的架构类型是 x86-64(amd64),还是 arm64 架构
    20230909java面经整理
    win10 安装openssl并使用openssl创建自签名证书
    【题解】盛最多水的容器
    在pandas中使用query替代loc进行高效简洁的条件筛选
    sem_post
    Linux用户与权限管理命令
  • 原文地址:https://blog.csdn.net/baoecit/article/details/134426734