Dijkstra's algorithm
This commit is contained in:
parent
976b50308b
commit
67c85a4299
1 changed files with 85 additions and 1 deletions
86
src/vtr.c
86
src/vtr.c
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#define MONSTER_COUNT 10
|
#define MONSTER_COUNT 10
|
||||||
|
|
||||||
|
@ -31,6 +33,7 @@
|
||||||
#define INVENTORY "\U0000F187"
|
#define INVENTORY "\U0000F187"
|
||||||
#define PLAYER "\U0000EA67"
|
#define PLAYER "\U0000EA67"
|
||||||
#define MONSTER "\U0000F23C"
|
#define MONSTER "\U0000F23C"
|
||||||
|
#define PATH "\033[34mX\033[0m"
|
||||||
|
|
||||||
enum keys {
|
enum keys {
|
||||||
BACKSPACE = 127,
|
BACKSPACE = 127,
|
||||||
|
@ -79,6 +82,15 @@ typedef struct {
|
||||||
int slot;
|
int slot;
|
||||||
} player_t;
|
} player_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x, y;
|
||||||
|
int dist;
|
||||||
|
} node_t;
|
||||||
|
|
||||||
|
/* Directions for movement (up, down, left, right) */
|
||||||
|
int directions[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};
|
||||||
|
|
||||||
world_t world;
|
world_t world;
|
||||||
player_t player;
|
player_t player;
|
||||||
|
|
||||||
|
@ -93,7 +105,7 @@ void initialize_world()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < world.max_y; i++) {
|
for (int i = 0; i < world.max_y; i++) {
|
||||||
for (int j = 0; j < world.max_x; j++) {
|
for (int j = 0; j < world.max_x; j++) {
|
||||||
int rand_value = rand() % 100;
|
int rand_value = rand() % 10;
|
||||||
if (rand_value < 1) {
|
if (rand_value < 1) {
|
||||||
/* 1% chance for a tree */
|
/* 1% chance for a tree */
|
||||||
world.grid[i][j] = 'T';
|
world.grid[i][j] = 'T';
|
||||||
|
@ -192,6 +204,9 @@ void print_world()
|
||||||
case 'M':
|
case 'M':
|
||||||
printf("%s", MONSTER);
|
printf("%s", MONSTER);
|
||||||
break;
|
break;
|
||||||
|
case 'X':
|
||||||
|
printf("%s", PATH);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("%c", world.grid[i][j]);
|
printf("%c", world.grid[i][j]);
|
||||||
break;
|
break;
|
||||||
|
@ -207,6 +222,71 @@ void print_world()
|
||||||
pthread_mutex_unlock(&world_lock);
|
pthread_mutex_unlock(&world_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dijkstra(int start_x, int start_y, int end_x, int end_y)
|
||||||
|
{
|
||||||
|
int dist[world.max_y][world.max_x];
|
||||||
|
bool visited[world.max_y][world.max_x];
|
||||||
|
|
||||||
|
/* Initialize distances */
|
||||||
|
for (int i = 0; i < world.max_y; i++) {
|
||||||
|
for (int j = 0; j < world.max_x; j++) {
|
||||||
|
dist[i][j] = INT_MAX;
|
||||||
|
visited[i][j] = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Starting distance is zero */
|
||||||
|
dist[start_y][start_x] = 0;
|
||||||
|
|
||||||
|
/* Priority queue for Dijkstra */
|
||||||
|
node_t queue[world.max_x * world.max_y];
|
||||||
|
int front = 0, rear = 0;
|
||||||
|
|
||||||
|
queue[rear++] = (node_t){start_x, start_y, 0};
|
||||||
|
|
||||||
|
while (front < rear) {
|
||||||
|
node_t current = queue[front++];
|
||||||
|
int x = current.x, y = current.y;
|
||||||
|
|
||||||
|
if (visited[y][x]) continue;
|
||||||
|
visited[y][x] = true;
|
||||||
|
|
||||||
|
if (x == end_x && y == end_y) break;
|
||||||
|
|
||||||
|
/* Explore neighbors */
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int nx = x + directions[i][0];
|
||||||
|
int ny = y + directions[i][1];
|
||||||
|
|
||||||
|
if (nx >= 0 && ny >= 0 && nx < world.max_x && ny < world.max_y && world.grid[ny][nx] != 'T' && world.grid[ny][nx] != 'S' && world.grid[ny][nx] != 'D' && world.grid[ny][nx] != 'P' && world.grid[ny][nx] != 'M') {
|
||||||
|
int alt = dist[y][x] + 1;
|
||||||
|
if (alt < dist[ny][nx]) {
|
||||||
|
dist[ny][nx] = alt;
|
||||||
|
queue[rear++] = (node_t){nx, ny, alt};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backtrace from end to start to mark path */
|
||||||
|
int x = end_x, y = end_y;
|
||||||
|
while (!(x == start_x && y == start_y)) {
|
||||||
|
/* Mark path on grid */
|
||||||
|
world.grid[y][x] = 'X';
|
||||||
|
|
||||||
|
int min_dist = dist[y][x];
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int nx = x + directions[i][0];
|
||||||
|
int ny = y + directions[i][1];
|
||||||
|
if (nx >= 0 && ny >= 0 && nx < world.max_x && ny < world.max_y && dist[ny][nx] < min_dist) {
|
||||||
|
min_dist = dist[ny][nx];
|
||||||
|
x = nx;
|
||||||
|
y = ny;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int find_monster(int y)
|
int find_monster(int y)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MONSTER_COUNT; i++) {
|
for (int i = 0; i < MONSTER_COUNT; i++) {
|
||||||
|
@ -522,6 +602,10 @@ void *player_input(void *arg)
|
||||||
|
|
||||||
case RIGHT_CLICK:
|
case RIGHT_CLICK:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
dijkstra(0, 0, 168, 43);
|
||||||
|
break;
|
||||||
|
|
||||||
case '\033':
|
case '\033':
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue