aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Petrashin <kirill8201@yandex.ru>2026-03-10 18:59:23 +0300
committerKirill Petrashin <kirill8201@yandex.ru>2026-03-10 18:59:23 +0300
commitfe40ce26ec975c2e2f89409913321064a7876d5c (patch)
tree143eccd14ef8270cf102aaf658abfadbe5f532dd
Initial commit
-rw-r--r--.gitignore1
-rw-r--r--Makefile11
-rw-r--r--config.h13
-rw-r--r--main.c40
-rw-r--r--map.c77
-rw-r--r--map.h37
-rw-r--r--stack.h1
-rw-r--r--structs.h11
8 files changed, 191 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cccee96
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+astar
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a8d80e2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+CC=gcc
+EXECUTABLE=astar
+
+astar: main.c map.c
+ $(CC) -Wall -Wpedantic -Wextra -Werror -O3 -o $(EXECUTABLE) map.c main.c -lncurses
+
+debug: main.c map.c
+ $(CC) -Wall -g -o $(EXECUTABLE) map.c main.c -lncurses
+
+clean:
+ rm ./$(EXECUTABLE)
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..3b3cd51
--- /dev/null
+++ b/config.h
@@ -0,0 +1,13 @@
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+// The characters that represent different tiles
+#define EMPTY_CHAR '.'
+#define GOAL_CHAR 'X'
+#define WALL_CHAR '#'
+#define PLAYER_CHAR '@'
+
+#define DRAW_MAP_OFFSET_X 1
+#define DRAW_MAP_OFFSET_Y 1
+
+#endif //CONFIG_H_
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..ee317c4
--- /dev/null
+++ b/main.c
@@ -0,0 +1,40 @@
+#include <curses.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "map.h"
+#include "structs.h"
+
+void sigint_handler(int sig) {
+ (void)sig; // We know it's a SIGINT
+ endwin();
+ printf("Received SIGINT\n");
+ exit(1);
+}
+
+void initialize_colors(void) {
+ start_color();
+ use_default_colors();
+ init_pair(EMPTY_COLOR, COLOR_BLACK, -1);
+ init_pair(GOAL_COLOR, COLOR_CYAN, -1);
+ init_pair(WALL_COLOR, COLOR_WHITE, -1);
+ init_pair(PLAYER_COLOR, COLOR_RED, -1);
+}
+
+int main(void) {
+ signal(SIGINT, sigint_handler);
+
+ initscr(); // Initialize the ncurses screen
+ cbreak(); // Process input one char at a time
+ curs_set(0); // Hide the cursor
+ noecho(); // Don't echo characters
+ initialize_colors();
+
+ Map map = rbt_maze_map(20, 10);
+ Position fake_player_position_to_pass_into_draw_map = {0, 0};
+ draw_map(map, 20*2-1, 10*2-1, fake_player_position_to_pass_into_draw_map);
+ getch();
+
+ endwin();
+ return 0;
+}
diff --git a/map.c b/map.c
new file mode 100644
index 0000000..21023f0
--- /dev/null
+++ b/map.c
@@ -0,0 +1,77 @@
+#include <string.h>
+#include <stdlib.h>
+#include <curses.h>
+#include <limits.h>
+#include "map.h"
+#include "config.h"
+#include "stack.h"
+
+Map empty_map(size_t width, size_t height) {
+ Map map = malloc(sizeof(MapTile*) * height);
+ if (map == NULL) return NULL;
+
+ for (size_t row = 0; row < height; row++) {
+ map[row] = malloc(sizeof(MapTile) * width);
+ if (map[row] == NULL) return NULL;
+ memset(map[row], 0, width*sizeof(MapTile));
+ }
+
+ return map;
+}
+
+Map rbt_maze_map(size_t width, size_t height) {
+ size_t map_width = width * 2 - 1,
+ map_height = height * 2 - 1;
+ Map map = empty_map(map_width, map_height);
+
+ // Vertical walls
+ for (size_t i = 1; i < map_width; i += 2) {
+ for (size_t j = 0; j < map_height; j += 1) {
+ map[j][i] = WALL;
+ }
+ }
+ // Horizontal walls
+ for (size_t i = 1; i < map_height; i += 2) {
+ for (size_t j = 0; j < map_width; j += 1) {
+ map[i][j] = WALL;
+ }
+ }
+
+ //TODO: Draw the rest of the owl
+
+ return map;
+}
+
+void draw_map(Map map, int width, int height, Position player_pos) {
+ // Draw field
+ char c; // The char for the current tile
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int color_pair = 0; // The color pair of the current char
+ switch (map[i][j]) {
+ case EMPTY:
+ color_pair = COLOR_PAIR(EMPTY_COLOR);
+ c = EMPTY_CHAR;
+ break;
+ case GOAL:
+ color_pair = COLOR_PAIR(GOAL_COLOR);
+ c = GOAL_CHAR;
+ break;
+ case WALL:
+ color_pair = COLOR_PAIR(WALL_COLOR);
+ c = WALL_CHAR;
+ break;
+
+ }
+ attron(color_pair);
+ mvaddch(i + DRAW_MAP_OFFSET_Y, j + DRAW_MAP_OFFSET_X, c);
+ attroff(color_pair);
+ }
+ }
+
+ // Draw the player
+ attron(COLOR_PAIR(PLAYER_COLOR));
+ mvaddch(player_pos.y + DRAW_MAP_OFFSET_Y, player_pos.x + DRAW_MAP_OFFSET_X, PLAYER_CHAR);
+ attroff(COLOR_PAIR(PLAYER_COLOR));
+}
+
diff --git a/map.h b/map.h
new file mode 100644
index 0000000..aa40652
--- /dev/null
+++ b/map.h
@@ -0,0 +1,37 @@
+#ifndef MAP_H_
+#define MAP_H_
+
+#include <stddef.h>
+#include "structs.h"
+
+enum MapTile_e {
+ EMPTY = 0,
+ GOAL,
+ WALL,
+};
+
+typedef enum MapTile_e MapTile;
+
+enum Colors_e {
+ EMPTY_COLOR = 1,
+ GOAL_COLOR = 2,
+ WALL_COLOR = 3,
+ PLAYER_COLOR = 4,
+};
+
+// A map is a 2D array of MapTiles.
+// Use as map[row][column]
+typedef MapTile** Map;
+
+// Returns an empty map of given size
+Map empty_map(size_t width, size_t height);
+
+// https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_depth-first_search
+// WARNING: width and height are not the width and height of the returned map!
+// TODO: formula for actual size
+Map rbt_maze_map(size_t width, size_t height);
+
+// Draw the map. Bet you didn't expect that.
+void draw_map(Map map, int width, int height, Position player_pos);
+
+#endif //MAP_H_
diff --git a/stack.h b/stack.h
new file mode 100644
index 0000000..72fd1f2
--- /dev/null
+++ b/stack.h
@@ -0,0 +1 @@
+// TODO: implement a stack
diff --git a/structs.h b/structs.h
new file mode 100644
index 0000000..a82975d
--- /dev/null
+++ b/structs.h
@@ -0,0 +1,11 @@
+#ifndef STRUCTS_H_
+#define STRUCTS_H_
+
+struct Position_s {
+ size_t x;
+ size_t y;
+};
+
+typedef struct Position_s Position;
+
+#endif /* STRUCTS_H_ */