diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..dfaa897 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,56 @@ +{ + "files.associations": { + "iostream": "cpp", + "vector": "cpp", + "*.tcc": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "dfs.h": "c", + "eller.h": "c", + "stdio.h": "c", + "prim.h": "c", + "bfs.h": "c", + "water.h": "c", + "dijkstra.h": "c", + "labyrinth.h": "c" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3554a15 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +CC := gcc +SRC := src +OBJ := obj + +TARGET := a.out + +SRCS := $(shell find $(SRC) -name *.c) +FILES := $(notdir $(basename $(SRCS))) +OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(FILES))) + +FLAGS := -Werror -Wall + +all: clear build + +build: $(OBJS) + $(CC) $(FLAGS) $(OBJS) + ./$(TARGET) + +$(OBJ)/%.o: $(SRC)/%.c + $(CC) -Werror -Wall -c $< -o $@ + +only: build + +clean: clear + -rm -f $(OBJS) + + +clear: + clear diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..f14498f --- /dev/null +++ b/TODO.txt @@ -0,0 +1,2 @@ +- water +- emplace \ No newline at end of file diff --git a/a.out b/a.out new file mode 100755 index 0000000..a308670 Binary files /dev/null and b/a.out differ diff --git a/bakcup/.vscode/settings.json b/bakcup/.vscode/settings.json new file mode 100644 index 0000000..0947c0a --- /dev/null +++ b/bakcup/.vscode/settings.json @@ -0,0 +1,55 @@ +{ + "files.associations": { + "iostream": "cpp", + "vector": "cpp", + "*.tcc": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "dfs.h": "c", + "eller.h": "c", + "stdio.h": "c", + "prim.h": "c", + "bfs.h": "c", + "water.h": "c", + "dijkstra.h": "c" + } +} \ No newline at end of file diff --git a/bakcup/Makefile b/bakcup/Makefile new file mode 100644 index 0000000..3554a15 --- /dev/null +++ b/bakcup/Makefile @@ -0,0 +1,29 @@ +CC := gcc +SRC := src +OBJ := obj + +TARGET := a.out + +SRCS := $(shell find $(SRC) -name *.c) +FILES := $(notdir $(basename $(SRCS))) +OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(FILES))) + +FLAGS := -Werror -Wall + +all: clear build + +build: $(OBJS) + $(CC) $(FLAGS) $(OBJS) + ./$(TARGET) + +$(OBJ)/%.o: $(SRC)/%.c + $(CC) -Werror -Wall -c $< -o $@ + +only: build + +clean: clear + -rm -f $(OBJS) + + +clear: + clear diff --git a/bakcup/TODO.txt b/bakcup/TODO.txt new file mode 100644 index 0000000..f14498f --- /dev/null +++ b/bakcup/TODO.txt @@ -0,0 +1,2 @@ +- water +- emplace \ No newline at end of file diff --git a/bakcup/a.out b/bakcup/a.out new file mode 100755 index 0000000..5a6bad8 Binary files /dev/null and b/bakcup/a.out differ diff --git a/bakcup/include/bfs.h b/bakcup/include/bfs.h new file mode 100644 index 0000000..90818fb --- /dev/null +++ b/bakcup/include/bfs.h @@ -0,0 +1,6 @@ +#ifndef BFS_H +#define BFS_H + +void bfs(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/bakcup/include/binaryTree.h b/bakcup/include/binaryTree.h new file mode 100644 index 0000000..e8abbf1 --- /dev/null +++ b/bakcup/include/binaryTree.h @@ -0,0 +1,9 @@ +#ifndef BINARY_TREE_H +#define BINARY_TREE_H + +#include "labyrinth.h" + +Labyrinth* binaryTree(int n, int m); +Labyrinth* binaryTreeShow(int n, int m); + +#endif \ No newline at end of file diff --git a/bakcup/include/coor.h b/bakcup/include/coor.h new file mode 100644 index 0000000..95f801a --- /dev/null +++ b/bakcup/include/coor.h @@ -0,0 +1,9 @@ +#ifndef COOR_H +#define COOR_H + +typedef struct coor{ + int x; + int y; +} coor; + +#endif \ No newline at end of file diff --git a/bakcup/include/depthFirst.h b/bakcup/include/depthFirst.h new file mode 100644 index 0000000..97da0f7 --- /dev/null +++ b/bakcup/include/depthFirst.h @@ -0,0 +1,9 @@ +#ifndef DEPTH_FIRST_H +#define DEPTH_FIRST_H + +#include "labyrinth.h" + +Labyrinth* depthFirst(int n, int m); +Labyrinth* depthFirstShow(int n, int m); + +#endif \ No newline at end of file diff --git a/bakcup/include/dfs.h b/bakcup/include/dfs.h new file mode 100644 index 0000000..a9f8244 --- /dev/null +++ b/bakcup/include/dfs.h @@ -0,0 +1,6 @@ +#ifndef DFS_H +#define DFS_H + +void dfs(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/bakcup/include/dijkstra.h b/bakcup/include/dijkstra.h new file mode 100644 index 0000000..744fe8d --- /dev/null +++ b/bakcup/include/dijkstra.h @@ -0,0 +1,8 @@ +#ifndef DIJKSTRA_H +#define DIJKSTRA_H + +#include "labyrinth.h" + +void dijkstra(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/bakcup/include/eller.h b/bakcup/include/eller.h new file mode 100644 index 0000000..5b00125 --- /dev/null +++ b/bakcup/include/eller.h @@ -0,0 +1,9 @@ +#ifndef ELLER_H +#define ELLER_H + +#include "labyrinth.h" + +Labyrinth* eller(int n, int m); +Labyrinth* ellerShow(int n, int m); + +#endif \ No newline at end of file diff --git a/bakcup/include/labyrinth.h b/bakcup/include/labyrinth.h new file mode 100644 index 0000000..ba09439 --- /dev/null +++ b/bakcup/include/labyrinth.h @@ -0,0 +1,49 @@ +#ifndef LABYRINTH_H +#define LABYRINTH_H + +#include "coor.h" + +enum Color{ + WHITE, + GREEN, + ORANGE, + BLUE +}; + +enum Direction{ + UP, + RIGHT, + DOWN, + LEFT +}; + +typedef struct Node{ + short south; + short east; + + short visited; + int dp; + + enum Color color; + enum Direction direction; +} Node; + +typedef struct Labyrinth { + Node** at; + int x_size; + int y_size; + + coor start; + coor end; +} Labyrinth; + +Labyrinth* newLabyrinth(int n, int m); +void resetLabyrinth(Labyrinth* Labyrinth); +void removeLabyrinth(Labyrinth* labyrinth); + +void find_path(Labyrinth* labyrinth); + +void printLab(Labyrinth* labyrinth); +void printLabWith(Labyrinth* labyrinth, char wall, char floor, char corner); + +#endif \ No newline at end of file diff --git a/bakcup/include/prim.h b/bakcup/include/prim.h new file mode 100644 index 0000000..c70d30a --- /dev/null +++ b/bakcup/include/prim.h @@ -0,0 +1,9 @@ +#ifndef PRIM_H +#define PRIM_H + +#include "labyrinth.h" + +Labyrinth* prim(int n, int m); +Labyrinth* primShow(int n, int m); + +#endif \ No newline at end of file diff --git a/bakcup/include/priority_queue.h b/bakcup/include/priority_queue.h new file mode 100644 index 0000000..5f5c3e9 --- /dev/null +++ b/bakcup/include/priority_queue.h @@ -0,0 +1,40 @@ +#ifndef PRIORITY_QUEUE_H +#define PRIORITY_QUEUE_H + +#define PRIORITY_QUEUE_INIT_GROWTH_FACT 2 + +#define priority_queue(pq, compare) priority_queue* pq = newPriority_queue(compare); + +typedef struct priority_queue{ + void** at; + int capacity; + int size; + + int growthFactor; + + void (*toString)(); + bool (*compare)(); +} priority_queue; + + +priority_queue* newPriority_queue(bool (*compare)()); + +void priority_queueResize(priority_queue* v, int capacity); + +void priority_queueClear(priority_queue* pq); + +void priority_queuePush(priority_queue* pq, void* element); + +void priority_queueFree(priority_queue* pq); + +void priority_queueShrink_to_fit(priority_queue* pq); + +bool priority_queueIsEmpty(priority_queue* pq); + +void* priority_queueTop(priority_queue* pq); + +void priority_queuePop(priority_queue* pq); + +void priority_queuePrint(priority_queue* pq); + +#endif \ No newline at end of file diff --git a/bakcup/include/queue.h b/bakcup/include/queue.h new file mode 100644 index 0000000..3ab254e --- /dev/null +++ b/bakcup/include/queue.h @@ -0,0 +1,50 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include + +/* + * Macro to create a new queue. + */ +#define queue(q) queue* q = newQueue(); + +typedef struct queue_element{ + void* next; + void* element; +} queue_element; + +typedef struct queue{ + + int size; /* The number of at in use */ + queue_element* front; /* pointer to the first element of the queue */ + queue_element* back; /* pointer to the back element of the queue */ + + void (*toString)(); /* Pointer to toString function */ +} queue; + + +/* + * Creates new queue. + */ +queue* newQueue(); + +/* + * Adds a new element to the queue. + */ +void queuePush(queue* q, void* element); + +void queuePrint(queue* q); + +void queuePop(queue* q); + +bool queueIsEmpty(queue* q); + +void queueMerge(queue* q1, queue* q2); + +void queueClear(queue* q); + +void queueFree(queue* q); + +void queueEmplace(queue* q, void* element, size_t size); + +#endif \ No newline at end of file diff --git a/bakcup/include/water.h b/bakcup/include/water.h new file mode 100644 index 0000000..6f00882 --- /dev/null +++ b/bakcup/include/water.h @@ -0,0 +1,6 @@ +#ifndef WATER_H +#define WATHER_H + +void water(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/bakcup/obj/bfs.o b/bakcup/obj/bfs.o new file mode 100644 index 0000000..2250d82 Binary files /dev/null and b/bakcup/obj/bfs.o differ diff --git a/bakcup/obj/binaryTree.o b/bakcup/obj/binaryTree.o new file mode 100644 index 0000000..e26ee70 Binary files /dev/null and b/bakcup/obj/binaryTree.o differ diff --git a/bakcup/obj/depthFirst.o b/bakcup/obj/depthFirst.o new file mode 100644 index 0000000..e98d45b Binary files /dev/null and b/bakcup/obj/depthFirst.o differ diff --git a/bakcup/obj/dfs.o b/bakcup/obj/dfs.o new file mode 100644 index 0000000..3104ca8 Binary files /dev/null and b/bakcup/obj/dfs.o differ diff --git a/bakcup/obj/dijkstra.o b/bakcup/obj/dijkstra.o new file mode 100644 index 0000000..d814ac3 Binary files /dev/null and b/bakcup/obj/dijkstra.o differ diff --git a/bakcup/obj/eller.o b/bakcup/obj/eller.o new file mode 100644 index 0000000..3dc00fa Binary files /dev/null and b/bakcup/obj/eller.o differ diff --git a/bakcup/obj/labyrith.o b/bakcup/obj/labyrith.o new file mode 100644 index 0000000..a3be9b2 Binary files /dev/null and b/bakcup/obj/labyrith.o differ diff --git a/bakcup/obj/main.o b/bakcup/obj/main.o new file mode 100644 index 0000000..a76dc68 Binary files /dev/null and b/bakcup/obj/main.o differ diff --git a/bakcup/obj/prim.o b/bakcup/obj/prim.o new file mode 100644 index 0000000..5b3503f Binary files /dev/null and b/bakcup/obj/prim.o differ diff --git a/bakcup/obj/priorityQueuePP.o b/bakcup/obj/priorityQueuePP.o new file mode 100644 index 0000000..6c8d99e Binary files /dev/null and b/bakcup/obj/priorityQueuePP.o differ diff --git a/bakcup/obj/priority_queue.o b/bakcup/obj/priority_queue.o new file mode 100644 index 0000000..db216e4 Binary files /dev/null and b/bakcup/obj/priority_queue.o differ diff --git a/bakcup/obj/queue.o b/bakcup/obj/queue.o new file mode 100644 index 0000000..d90fd61 Binary files /dev/null and b/bakcup/obj/queue.o differ diff --git a/bakcup/obj/water.o b/bakcup/obj/water.o new file mode 100644 index 0000000..3bc6221 Binary files /dev/null and b/bakcup/obj/water.o differ diff --git a/bakcup/src/bfs.c b/bakcup/src/bfs.c new file mode 100644 index 0000000..52ca70c --- /dev/null +++ b/bakcup/src/bfs.c @@ -0,0 +1,87 @@ +#include +#include +#include "../include/labyrinth.h" +#include "../include/bfs.h" +#include "../include/queue.h" +#include "../include/coor.h" + +void bfs(Labyrinth* labyrinth){ + int i, j; + int arr[4] = {0, 1, 2, 3}, tmp, tp; + coor* cor = (coor*)malloc(sizeof(coor)); + coor* test; + cor->x = labyrinth->start.x; + cor->y = labyrinth->start.y; + queue(q); + queuePush(q, cor); + + while(!queueIsEmpty(q)){ + test = (coor*)q->front->element; + i = test->x; + j = test->y; + queuePop(q); + + if(i==labyrinth->end.x && j==labyrinth->end.y){ + queueFree(q); + find_path(labyrinth); + return; + } + + if(i!=labyrinth->start.x || j!=labyrinth->start.y) + labyrinth->at[i][j].color = GREEN; + + printLab(labyrinth); + + labyrinth->at[i][j].visited = true; + + + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + // goes in the direction if possible + for(int h=0; h<4; h++){ + coor* cor2 = (coor*)malloc(sizeof(coor)); + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].south && !labyrinth->at[i-1][j].visited){ + if(i-1!=labyrinth->end.x && j!=labyrinth->end.y) + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + cor2->x = i-1; + cor2->y = j; + queuePush(q, cor2); + } + }else if(arr[h]==1){ + if(jy_size-1 && labyrinth->at[i][j].east && !labyrinth->at[i][j+1].visited){ + if(i!=labyrinth->end.x && j+1!=labyrinth->end.y) + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + cor2->x = i; + cor2->y = j+1; + queuePush(q, cor2); + } + }else if(arr[h]==2){ + if(iy_size-1 && labyrinth->at[i][j].south && !labyrinth->at[i+1][j].visited){ + if(i+1!=labyrinth->end.x && j!=labyrinth->end.y) + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + cor2->x = i+1; + cor2->y = j; + queuePush(q, cor2); + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].east && !labyrinth->at[i][j-1].visited){ + if(i!=labyrinth->end.x && j-1!=labyrinth->end.y) + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + cor2->x = i; + cor2->y = j-1; + queuePush(q, cor2); + } + } + } + } +} \ No newline at end of file diff --git a/bakcup/src/binaryTree.c b/bakcup/src/binaryTree.c new file mode 100644 index 0000000..ce352cf --- /dev/null +++ b/bakcup/src/binaryTree.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "../include/binaryTree.h" +#include "../include/labyrinth.h" + +Labyrinth* binaryTree_r(int n, int m, bool show); + +Labyrinth* binaryTree(int n, int m){ + return binaryTree_r(n, m, false); +} + +Labyrinth* binaryTreeShow(int n, int m){ + return binaryTree_r(n, m, true); +} + +// creates a labyrinth using the binaryTree algorithm +Labyrinth* binaryTree_r(int n, int m, bool show){ + int i, j, tmp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + labyrinth->at[0][0].east = 1; + labyrinth->at[0][0].south = 1; + if(show){ + labyrinth->at[0][0].color = ORANGE; + printLab(labyrinth); + labyrinth->at[0][0].color = WHITE; + } + + for(i=1; iat[i-1][0].south = 1; + + if(show){ + labyrinth->at[i-1][0].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i-1][0].color = WHITE; + } + } + + for(j=1; jat[0][j-1].east = 1; + + if(show){ + labyrinth->at[0][j-1].color = ORANGE; + printLab(labyrinth); + labyrinth->at[0][j-1].color = WHITE; + } + + } + + for(i=1; iat[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + tmp = rand()%2; + if(tmp) + labyrinth->at[i-1][j].south = 1; + else + labyrinth->at[i][j-1].east = 1; + } + } + + resetLabyrinth(labyrinth); + + return labyrinth; +} \ No newline at end of file diff --git a/bakcup/src/depthFirst.c b/bakcup/src/depthFirst.c new file mode 100644 index 0000000..5080fdb --- /dev/null +++ b/bakcup/src/depthFirst.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include "../include/depthFirst.h" + +void depthFirst_r(int i, int j, Labyrinth* labyrinth, bool show); + +// dfs search algorithm +Labyrinth* depthFirst(int n, int m){ + Labyrinth* labyrinth = newLabyrinth(n, m); + + depthFirst_r(rand()%n, rand()%m, labyrinth, false); + + resetLabyrinth(labyrinth); + + return labyrinth; +} + +Labyrinth* depthFirstShow(int n, int m){ + Labyrinth* labyrinth = newLabyrinth(n, m); + + depthFirst_r(rand()%n, rand()%m, labyrinth, true); + + resetLabyrinth(labyrinth); + + return labyrinth; +} + +// ricursive function used by depthFirst +void depthFirst_r(int i, int j, Labyrinth* labyrinth, bool show){ + labyrinth->at[i][j].visited = 1; + labyrinth->at[i][j].dp = -1; + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + int arr[4] = {0, 1, 2, 3}, tmp, tp; + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + for(int h=0; h<4; h++){ + if(arr[h]==0){ + if(i>0 && !labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].south = 1; + depthFirst_r(i-1, j, labyrinth, show); + } + }else if(arr[h]==1){ + if(jy_size-1 && !labyrinth->at[i][j+1].visited){ + labyrinth->at[i][j].east = 1; + depthFirst_r(i, j+1, labyrinth, show); + } + }else if(arr[h]==2){ + if(ix_size-1 && !labyrinth->at[i+1][j].visited){ + labyrinth->at[i][j].south = 1; + depthFirst_r(i+1, j, labyrinth, show); + } + }else if(arr[h]==3){ + if(j>0 && !labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].east = 1; + depthFirst_r(i, j-1, labyrinth, show); + } + } + } + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } +} \ No newline at end of file diff --git a/bakcup/src/dfs.c b/bakcup/src/dfs.c new file mode 100644 index 0000000..b0ad722 --- /dev/null +++ b/bakcup/src/dfs.c @@ -0,0 +1,67 @@ +#include +#include +#include "../include/labyrinth.h" +#include "../include/dfs.h" + +short dfs_r(Labyrinth* labyrinth, int i, int j); + +void dfs(Labyrinth* labyrinth){ + dfs_r(labyrinth, labyrinth->start.x, labyrinth->start.y); + find_path(labyrinth); +} + +short dfs_r(Labyrinth* labyrinth, int i, int j){ + if(i==labyrinth->end.x && j==labyrinth->end.y) + return 1; + + if(i!=labyrinth->start.x || j!=labyrinth->start.y) + labyrinth->at[i][j].color = GREEN; + + printLab(labyrinth); + + labyrinth->at[i][j].visited = 1; + + // randomly generates order of direction to try + int arr[4] = {0, 1, 2, 3}, tmp, tp; + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + // goes in the direction if possible + for(int h=0; h<4; h++){ + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].south && !labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + if(dfs_r(labyrinth, i-1, j)) + return 1; + } + }else if(arr[h]==1){ + if(jy_size-1 && labyrinth->at[i][j].east && !labyrinth->at[i][j+1].visited){ + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + if(dfs_r(labyrinth, i, j+1)) + return 1; + } + }else if(arr[h]==2){ + if(iy_size-1 && labyrinth->at[i][j].south && !labyrinth->at[i+1][j].visited){ + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + if(dfs_r(labyrinth, i+1, j)) + return 1; + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].east && !labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + if(dfs_r(labyrinth, i, j-1)) + return 1; + } + } + } + + return 0; +} \ No newline at end of file diff --git a/bakcup/src/dijkstra.c b/bakcup/src/dijkstra.c new file mode 100644 index 0000000..defb96f --- /dev/null +++ b/bakcup/src/dijkstra.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include "../include/dijkstra.h" +#include "../include/priority_queue.h" + +typedef struct element{ + int dist; + int x; + int y; +} element; + +bool compare(element* e1, element* e2){ + return e1->dist > e2->dist; +} + +void toString(element* e){ + printf("(%d) %d %d\n", e->dist, e->x, e->y); +} + +void dijkstra_r(Labyrinth* labyrinth, int i, int j, int dist, priority_queue* queue); + +// dijkstra search algorithm +void dijkstra(Labyrinth* labyrinth){ + priority_queue(queue, compare); + queue->toString = toString; + + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = 0; + tmp->x = labyrinth->start.x; + tmp->y = labyrinth->start.y; + labyrinth->at[tmp->x][tmp->y].dp = 0; + priority_queuePush(queue, tmp); + + int a, b, c; + + while(!priority_queueIsEmpty(queue)){ + a = ((element*)priority_queueTop(queue))->dist; + b = ((element*)priority_queueTop(queue))->x; + c = ((element*)priority_queueTop(queue))->y; + + priority_queuePop(queue); + + dijkstra_r(labyrinth, b, c, a, queue); + printLab(labyrinth); + } + priority_queueFree(queue); + + find_path(labyrinth); + printf("test\n"); +} + +// ricursive function used by dijkstra +void dijkstra_r(Labyrinth* labyrinth, int i, int j, int dist, priority_queue* queue){ + + if(i==labyrinth->end.x && j==labyrinth->end.y){ + priority_queueClear(queue); + return; + } + + if(dist) + labyrinth->at[i][j].color = GREEN; + + // adds all four directions to the priority_queue + if(i>0 && labyrinth->at[i-1][j].south && labyrinth->at[i-1][j].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i-1; + tmp->y = j; + + priority_queuePush(queue, tmp); + + if(i-1!=labyrinth->end.x || j!=labyrinth->end.y) + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + labyrinth->at[i-1][j].dp = dist+1; + } + if(jy_size-1 && labyrinth->at[i][j].east && labyrinth->at[i][j+1].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i; + tmp->y = j+1; + + priority_queuePush(queue, tmp); + + if(i!=labyrinth->end.x || j+1!=labyrinth->end.y) + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + labyrinth->at[i][j+1].dp = dist+1; + } + if(ix_size-1 && labyrinth->at[i][j].south && labyrinth->at[i+1][j].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i+1; + tmp->y = j; + + priority_queuePush(queue, tmp); + + if(i+1!=labyrinth->end.x || j!=labyrinth->end.y) + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + labyrinth->at[i+1][j].dp = dist+1; + } + if(j>0 && labyrinth->at[i][j-1].east && labyrinth->at[i][j-1].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i; + tmp->y = j-1; + + priority_queuePush(queue, tmp); + + if(i!=labyrinth->end.x || j-1!=labyrinth->end.y) + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + labyrinth->at[i][j-1].dp = dist+1; + } +} \ No newline at end of file diff --git a/bakcup/src/eller.c b/bakcup/src/eller.c new file mode 100644 index 0000000..bbc9e01 --- /dev/null +++ b/bakcup/src/eller.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include "../include/eller.h" +#include "../include/queue.h" + +#define ELLER_COST 2 + +Labyrinth* eller_(int n, int m, bool show); + +Labyrinth* eller(int n, int m){ + return eller_(n, m, false); +} + +Labyrinth* ellerShow(int n, int m){ + return eller_(n, m, true); +} + +Labyrinth* eller_(int n, int m, bool show){ + int i, j, h, tmp, tp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + int sets[m][m]; + int setSizes[m]; + + queue(freeSets); + + int arr[m]; + for(i=0; iat[i][j].dp < 0){ + int* tmp = (int*)freeSets->front->element; + labyrinth->at[i][j].dp = *tmp; + queuePop(freeSets); + } + + tmp = labyrinth->at[i][j].dp; + sets[tmp][setSizes[tmp]] = j; + setSizes[tmp]++; + } + + // randomizes order + for(j=m; j>0; j--){ + tmp = rand() % j; + tp = arr[tmp]; + arr[tmp] = arr[j-1]; + arr[j-1] = tp; + } + + // randomly merge cells + for(j=0; jat[i][tmp].dp != labyrinth->at[i][tmp+1].dp && (rand()%ELLER_COST || i==n-1)){ + labyrinth->at[i][tmp].east = 1; + + tp = labyrinth->at[i][tmp].dp; + tmp = labyrinth->at[i][tmp+1].dp; + for(h=0; hat[i][sets[tmp][h]].dp = tp; + } + setSizes[tmp] = 0; + + int* s = (int*)malloc(sizeof(int)); + *s = tmp; + queuePush(freeSets, s); + + if(show){ + labyrinth->at[i][tmp].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][tmp].color = WHITE; + } + } + } + + // randomly makes cells go down + for(j=0; j1; h--){ + tmp = rand()%h; + tp = sets[j][tmp]; + sets[j][tmp] = sets[j][h-1]; + + if(rand()%ELLER_COST){ + labyrinth->at[i][tp].south = 1; + labyrinth->at[i+1][tp].dp = labyrinth->at[i][tp].dp; + down[j] = 1; + + if(show){ + labyrinth->at[i][tp].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][tp].color = WHITE; + } + } + } + + // last cell + if(setSizes[j] && (!down[j] || rand()%ELLER_COST)){ + labyrinth->at[i][sets[j][0]].south = 1; + labyrinth->at[i+1][sets[j][0]].dp = labyrinth->at[i][sets[j][0]].dp; + + if(show){ + labyrinth->at[i][sets[j][0]].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][sets[j][0]].color = WHITE; + } + } + } + } + + resetLabyrinth(labyrinth); + queueFree(freeSets); + + return labyrinth; +} \ No newline at end of file diff --git a/bakcup/src/labyrith.c b/bakcup/src/labyrith.c new file mode 100644 index 0000000..1eb5a71 --- /dev/null +++ b/bakcup/src/labyrith.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include "../include/labyrinth.h" + +void find_path_r(Labyrinth* labyrinth, int i, int j); + +Labyrinth* newLabyrinth(int n, int m){ + if(n<1 || m<1 || (n==1 && m==1)){ + printf("COGLIONE\n"); + exit(EXIT_FAILURE); + } + + Labyrinth* labyrinth = (Labyrinth* )malloc(sizeof(Labyrinth)); + labyrinth->x_size = n; + labyrinth->y_size = m; + + labyrinth->at = (Node** )malloc(n*sizeof(Node* )); + for(int i=0; iat[i] = (Node *)malloc(m*sizeof(Node)); + + for(int i=0; iat[i][j].dp = -1; + labyrinth->at[i][j].east = 0; + labyrinth->at[i][j].south = 0; + labyrinth->at[i][j].visited = 0; + } + } + + labyrinth->x_size = n; + labyrinth->y_size = m; + + labyrinth->start.x = rand()%n; + labyrinth->start.y = rand()%m; + + do{ + labyrinth->end.x = rand()%n; + labyrinth->end.y = rand()%m; + }while(labyrinth->start.x == labyrinth->end.x && labyrinth->start.y == labyrinth->end.y); + + return labyrinth; +} + +void resetLabyrinth(Labyrinth* labyrinth){ + for(int i=0; ix_size; i++){ + for(int j=0; jy_size; j++){ + labyrinth->at[i][j].color = WHITE; + labyrinth->at[i][j].visited = 0; + labyrinth->at[i][j].dp = -1; + } + } + + labyrinth->at[labyrinth->start.x][labyrinth->start.y].color = BLUE; + labyrinth->at[labyrinth->end.x][labyrinth->end.y].color = BLUE; +} + +void removeLabyrinth(Labyrinth* labyrinth){ + for(int i=0; ix_size; i++) + free(labyrinth->at[i]); + free(labyrinth->at); + free(labyrinth); +} + +void find_path(Labyrinth* labyrinth){ + find_path_r(labyrinth, labyrinth->end.x, labyrinth->end.y); +} + +void find_path_r(Labyrinth* labyrinth, int i, int j){ + labyrinth->at[i][j].color = BLUE; + // printLab(labyrinth); + + if(i==labyrinth->start.x && j==labyrinth->start.y) + return; + + if(labyrinth->at[i][j].direction == UP) + find_path_r(labyrinth, i+1, j); + else if(labyrinth->at[i][j].direction == RIGHT) + find_path_r(labyrinth, i, j-1); + else if(labyrinth->at[i][j].direction == DOWN) + find_path_r(labyrinth, i-1, j); + else if(labyrinth->at[i][j].direction == LEFT) + find_path_r(labyrinth, i, j+1); + else{ + printf("ERROR IN FIND_PATH\n"); + exit(EXIT_FAILURE); + } +} + +void printLab(Labyrinth* labyrinth){ + printLabWith(labyrinth, '|', '-', '+'); +} + +void printLabWith(Labyrinth* labyrinth, char wall, char floor, char corner){ + int i, j; + + system("clear"); + + for(j=0; jy_size; j++){ + printf("%c%c", corner, floor); + } + printf("%c\n", corner); + + for(i=0; ix_size; i++){ + printf("%c", wall); + + for(j=0; jy_size; j++){ + if(labyrinth->at[i][j].color == BLUE) + printf("\033[104m \033[49m"); + else if(labyrinth->at[i][j].color == GREEN) + printf("\033[102m \033[49m"); + else if(labyrinth->at[i][j].color == ORANGE) + printf("\033[103m \033[49m"); + else + printf(" "); + + if(labyrinth->at[i][j].east && jy_size-1){ + if(labyrinth->at[i][j+1].color == BLUE && labyrinth->at[i][j].color == BLUE) + printf("\033[104m \033[49m"); + else if((labyrinth->at[i][j+1].color == GREEN || labyrinth->at[i][j+1].color == BLUE) && (labyrinth->at[i][j].color == GREEN || labyrinth->at[i][j].color == BLUE)) + printf("\033[102m \033[49m"); + else if(!(labyrinth->at[i][j+1].color == WHITE) && !(labyrinth->at[i][j].color == WHITE)) + printf("\033[103m \033[49m"); + else + printf(" "); + }else + printf("%c", wall); + } + printf("\n"); + for(j=0; jy_size; j++){ + printf("%c", corner); + if(labyrinth->at[i][j].south && ix_size-1){ + if(labyrinth->at[i][j].color == BLUE && labyrinth->at[i+1][j].color == BLUE) + printf("\033[104m \033[49m"); + else if((labyrinth->at[i][j].color == GREEN || labyrinth->at[i][j].color == BLUE) && (labyrinth->at[i+1][j].color == GREEN || labyrinth->at[i+1][j].color == BLUE)) + printf("\033[102m \033[49m"); + else if(!(labyrinth->at[i][j].color == WHITE) && !(labyrinth->at[i+1][j].color == WHITE)) + printf("\033[103m \033[49m"); + else + printf(" "); + }else + printf("%c", floor); + } + printf("%c\n", corner); + } + printf("\n"); + + usleep(50000); +} \ No newline at end of file diff --git a/bakcup/src/main.c b/bakcup/src/main.c new file mode 100644 index 0000000..572d875 --- /dev/null +++ b/bakcup/src/main.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include "../include/dijkstra.h" +#include "../include/dfs.h" +#include "../include/labyrinth.h" +#include "../include/binaryTree.h" +#include "../include/depthFirst.h" +#include "../include/prim.h" +#include "../include/eller.h" +#include "../include/water.h" +#include "../include/bfs.h" + +#define N 15 +#define M 15 + +int main(){ + srand(time(0)); + + int n = N, m = M; + + Labyrinth* labyrinth1 = prim(n, m); + + dijkstra(labyrinth1); + printLab(labyrinth1); + resetLabyrinth(labyrinth1); + + + removeLabyrinth(labyrinth1); +} diff --git a/bakcup/src/prim.c b/bakcup/src/prim.c new file mode 100644 index 0000000..d608d41 --- /dev/null +++ b/bakcup/src/prim.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include "../include/coor.h" +#include "../include/prim.h" + +Labyrinth* prim_(int n, int m, bool show); + +Labyrinth* prim(int n, int m){ + return prim_(n, m, false); +} + +Labyrinth* primShow(int n, int m){ + return prim_(n, m, true); +} + +// creates a labyrinth using prim's algorithm +Labyrinth* prim_(int n, int m, bool show){ + int i, j, h, tmp, tp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + int arr[4] = {0, 1, 2, 3}; + + coor frontier[n*m]; + coor current = {.x = rand()%n, .y = rand()%m}; + i = current.x; + j = current.y; + int frontierSize = 0; + + do{ + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + + labyrinth->at[i][j].visited = 1; + + // adds frontier cells + if(i > 0 && labyrinth->at[i-1][j].dp < 0){ + frontier[frontierSize].x = i-1; + frontier[frontierSize].y = j; + frontierSize++; + labyrinth->at[i-1][j].dp = 1; + } + if(j < m-1 && labyrinth->at[i][j+1].dp < 0){ + frontier[frontierSize].x = i; + frontier[frontierSize].y = j+1; + frontierSize++; + labyrinth->at[i][j+1].dp = 1; + } + if(i < n-1 && labyrinth->at[i+1][j].dp < 0){ + frontier[frontierSize].x = i+1; + frontier[frontierSize].y = j; + frontierSize++; + labyrinth->at[i+1][j].dp = 1; + } + if(j > 0 && labyrinth->at[i][j-1].dp < 0){ + frontier[frontierSize].x = i; + frontier[frontierSize].y = j-1; + frontierSize++; + labyrinth->at[i][j-1].dp = 1; + } + + // randomly selects a frontier cell + tmp = rand()%frontierSize; + current = frontier[tmp]; + frontier[tmp] = frontier[frontierSize-1]; + frontierSize--; + + i = current.x; + j = current.y; + + // randomly joins the selected cell to another cell + for(h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + tmp = 1; + for(h=0; h<4 && tmp; h++){ + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].south = 1; + tmp = 0; + } + }else if(arr[h]==1){ + if(jat[i][j+1].visited){ + labyrinth->at[i][j].east = 1; + tmp = 0; + } + }else if(arr[h]==2){ + if(iat[i+1][j].visited){ + labyrinth->at[i][j].south = 1; + tmp = 0; + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].east = 1; + tmp = 0; + } + } + + } + + }while(frontierSize); + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + resetLabyrinth(labyrinth); + + return labyrinth; +} \ No newline at end of file diff --git a/bakcup/src/priority_queue.c b/bakcup/src/priority_queue.c new file mode 100644 index 0000000..6830fee --- /dev/null +++ b/bakcup/src/priority_queue.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include "../include/priority_queue.h" + + +void priority_queueFixheap(priority_queue* q, int i); +void priority_queueHeapify(priority_queue* queue, int i); +void priority_queueSwap(void** a, void** b); + +priority_queue* newPriority_queue(bool (*compare)()){ + priority_queue* pq = (priority_queue*)malloc(sizeof(priority_queue)); + pq->size = 0; + pq->capacity = 0; + pq->growthFactor = PRIORITY_QUEUE_INIT_GROWTH_FACT; + + pq->compare = compare; + pq->toString = NULL; + + return pq; +} + +void priority_queuePush(priority_queue* pq, void* element){ + if(pq->size == pq->capacity){ + if(pq->capacity) + priority_queueResize(pq, pq->capacity * pq->growthFactor); + else + priority_queueResize(pq, 1); + } + + pq->at[pq->size] = element; + pq->size++; + + priority_queueFixheap(pq, pq->size-1); +} + +void priority_queueFixheap(priority_queue* pq, int i){ + if(!i) + return; + if(pq->compare(pq->at[(i-1)/2], pq->at[i])) + priority_queueSwap(pq->at[i], pq->at[(i-1)/2]); + + priority_queueFixheap(pq, (i-1)/2); +} + +void priority_queuePop(priority_queue* pq){ + if(!pq->size){ + fprintf(stderr, "POP ON EMPTY PRIORITY_QUEUE\n"); + return; + } + + priority_queueSwap(&pq->at[0], &pq->at[pq->size-1]); + free(pq->at[pq->size-1]); + pq->size--; + priority_queueHeapify(pq, 0); +} + +void priority_queueHeapify(priority_queue* pq, int i){ + if(i >= (pq->size)/2) + return; + + int minson; + if(pq->size-1 == 2*i+1 || !pq->compare(pq->at[2*i+1], pq->at[2*i+2])) + minson = 2*i+1; + else + minson = 2*i+2; + + if(pq->compare(pq->at[i], pq->at[minson])){ + priority_queueSwap(&pq->at[i], &pq->at[minson]); + priority_queueHeapify(pq, minson); + } +} + +void priority_queueSwap(void** a, void** b){ + void* tmp = *a; + *a = *b; + *b = tmp; +} + +void priority_queueResize(priority_queue* pq, int capacity){ + for(int i=pq->size; i>capacity; i--) + free(pq->at[i-1]); + + void **at = realloc(pq->at, sizeof(void *) * capacity); + pq->at = at; + pq->capacity = capacity; +} + +void priority_queueClear(priority_queue* pq){ + priority_queueResize(pq, 0); + pq->size = 0; +} + +void priority_queueFree(priority_queue* pq){ + priority_queueClear(pq); + free(pq->at); + free(pq); +} + +void priority_queueShrink_to_fit(priority_queue* pq){ + priority_queueResize(pq, pq->size); +} + +bool priority_queueIsEmpty(priority_queue* pq){ + return pq->size > 0 ? false : true; +} + +void* priority_queueTop(priority_queue* pq){ + if(!pq->size){ + fprintf(stderr, "PRIORITY_QUEUE IS EMPTY\n"); + return NULL; + } + + return pq->at[0]; +} + +void priority_queuePrint(priority_queue* pq){ + if(pq->toString == NULL){ + fprintf(stderr, "TOSTRING NOT DEFINED\n"); + return; + } + + for(int i=0; isize; i++) + pq->toString(pq->at[i]); + + printf("\n"); +} \ No newline at end of file diff --git a/bakcup/src/queue.c b/bakcup/src/queue.c new file mode 100644 index 0000000..aa24f9e --- /dev/null +++ b/bakcup/src/queue.c @@ -0,0 +1,87 @@ +#include +#include +#include "../include/queue.h" + +queue* newQueue(){ + queue* tmp = (queue*)malloc(sizeof(queue)); + tmp->size = 0; + + tmp->toString = NULL; + tmp->front = NULL; + tmp->back = NULL; + + return tmp; +} + +void queuePush(queue* q, void* element){ + queue_element* qel = (queue_element*)malloc(sizeof(queue_element)); + qel->element = element; + qel->next = NULL; + + if(queueIsEmpty(q)){ + q->front = qel; + q->back = qel; + }else{ + q->back->next = qel; + q->back = qel; + } + + q->size++; +} + +void queuePrint(queue* q){ + if(q->toString == NULL){ + fprintf(stderr, "TOSTRING NOT DEFINED\n"); + return; + } + + queue_element* tmp = q->front; + while(tmp){ + q->toString(tmp->element); + tmp = tmp->next; + printf("\n"); + } + + printf("\n"); +} + +void queuePop(queue* q){ + if(queueIsEmpty(q)){ + fprintf(stderr, "QUEUE IS EMTPY\n"); + return; + } + + queue_element* tmp = q->front->next; + free(q->front->element); + free(q->front); + q->front = tmp; + q->size--; +} + +bool queueIsEmpty(queue* q){ + return q->size == 0; +} + +void queueMerge(queue* q1, queue* q2){ + q1->back->next = q2->front; + q1->size += q2->size; + q2->size = 0; +} + +void queueClear(queue* q){ + queue_element* tmp = q->front, *tp; + while(tmp){ + tp = tmp->next; + // free(tmp->element); + free(tmp); + tmp = tp; + } + + q->front = NULL; + q->size = 0; +} + +void queueFree(queue* q){ + queueClear(q); + free(q); +} \ No newline at end of file diff --git a/bakcup/src/water.c b/bakcup/src/water.c new file mode 100644 index 0000000..7ab4aae --- /dev/null +++ b/bakcup/src/water.c @@ -0,0 +1,17 @@ +#include +#include +#include "../include/labyrinth.h" +#include "../include/water.h" +#include "../include/priority_queue.h" + +bool compare(coor* c1, coor* c2){ + return c1->x < c2->x; +} + +void water(Labyrinth *labyrinth){ + int i, j, h, n = labyrinth->x_size, m = labyrinth->y_size; + + priority_queue(pq, compare); // DA METTERE RBTREE (mai) + + +} \ No newline at end of file diff --git a/include/bfs.h b/include/bfs.h new file mode 100644 index 0000000..90818fb --- /dev/null +++ b/include/bfs.h @@ -0,0 +1,6 @@ +#ifndef BFS_H +#define BFS_H + +void bfs(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/include/binaryTree.h b/include/binaryTree.h new file mode 100644 index 0000000..e8abbf1 --- /dev/null +++ b/include/binaryTree.h @@ -0,0 +1,9 @@ +#ifndef BINARY_TREE_H +#define BINARY_TREE_H + +#include "labyrinth.h" + +Labyrinth* binaryTree(int n, int m); +Labyrinth* binaryTreeShow(int n, int m); + +#endif \ No newline at end of file diff --git a/include/coor.h b/include/coor.h new file mode 100644 index 0000000..95f801a --- /dev/null +++ b/include/coor.h @@ -0,0 +1,9 @@ +#ifndef COOR_H +#define COOR_H + +typedef struct coor{ + int x; + int y; +} coor; + +#endif \ No newline at end of file diff --git a/include/depthFirst.h b/include/depthFirst.h new file mode 100644 index 0000000..97da0f7 --- /dev/null +++ b/include/depthFirst.h @@ -0,0 +1,9 @@ +#ifndef DEPTH_FIRST_H +#define DEPTH_FIRST_H + +#include "labyrinth.h" + +Labyrinth* depthFirst(int n, int m); +Labyrinth* depthFirstShow(int n, int m); + +#endif \ No newline at end of file diff --git a/include/dfs.h b/include/dfs.h new file mode 100644 index 0000000..a9f8244 --- /dev/null +++ b/include/dfs.h @@ -0,0 +1,6 @@ +#ifndef DFS_H +#define DFS_H + +void dfs(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/include/dijkstra.h b/include/dijkstra.h new file mode 100644 index 0000000..744fe8d --- /dev/null +++ b/include/dijkstra.h @@ -0,0 +1,8 @@ +#ifndef DIJKSTRA_H +#define DIJKSTRA_H + +#include "labyrinth.h" + +void dijkstra(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/include/eller.h b/include/eller.h new file mode 100644 index 0000000..5b00125 --- /dev/null +++ b/include/eller.h @@ -0,0 +1,9 @@ +#ifndef ELLER_H +#define ELLER_H + +#include "labyrinth.h" + +Labyrinth* eller(int n, int m); +Labyrinth* ellerShow(int n, int m); + +#endif \ No newline at end of file diff --git a/include/labyrinth.h b/include/labyrinth.h new file mode 100644 index 0000000..ba09439 --- /dev/null +++ b/include/labyrinth.h @@ -0,0 +1,49 @@ +#ifndef LABYRINTH_H +#define LABYRINTH_H + +#include "coor.h" + +enum Color{ + WHITE, + GREEN, + ORANGE, + BLUE +}; + +enum Direction{ + UP, + RIGHT, + DOWN, + LEFT +}; + +typedef struct Node{ + short south; + short east; + + short visited; + int dp; + + enum Color color; + enum Direction direction; +} Node; + +typedef struct Labyrinth { + Node** at; + int x_size; + int y_size; + + coor start; + coor end; +} Labyrinth; + +Labyrinth* newLabyrinth(int n, int m); +void resetLabyrinth(Labyrinth* Labyrinth); +void removeLabyrinth(Labyrinth* labyrinth); + +void find_path(Labyrinth* labyrinth); + +void printLab(Labyrinth* labyrinth); +void printLabWith(Labyrinth* labyrinth, char wall, char floor, char corner); + +#endif \ No newline at end of file diff --git a/include/prim.h b/include/prim.h new file mode 100644 index 0000000..c70d30a --- /dev/null +++ b/include/prim.h @@ -0,0 +1,9 @@ +#ifndef PRIM_H +#define PRIM_H + +#include "labyrinth.h" + +Labyrinth* prim(int n, int m); +Labyrinth* primShow(int n, int m); + +#endif \ No newline at end of file diff --git a/include/priority_queue.h b/include/priority_queue.h new file mode 100644 index 0000000..5f5c3e9 --- /dev/null +++ b/include/priority_queue.h @@ -0,0 +1,40 @@ +#ifndef PRIORITY_QUEUE_H +#define PRIORITY_QUEUE_H + +#define PRIORITY_QUEUE_INIT_GROWTH_FACT 2 + +#define priority_queue(pq, compare) priority_queue* pq = newPriority_queue(compare); + +typedef struct priority_queue{ + void** at; + int capacity; + int size; + + int growthFactor; + + void (*toString)(); + bool (*compare)(); +} priority_queue; + + +priority_queue* newPriority_queue(bool (*compare)()); + +void priority_queueResize(priority_queue* v, int capacity); + +void priority_queueClear(priority_queue* pq); + +void priority_queuePush(priority_queue* pq, void* element); + +void priority_queueFree(priority_queue* pq); + +void priority_queueShrink_to_fit(priority_queue* pq); + +bool priority_queueIsEmpty(priority_queue* pq); + +void* priority_queueTop(priority_queue* pq); + +void priority_queuePop(priority_queue* pq); + +void priority_queuePrint(priority_queue* pq); + +#endif \ No newline at end of file diff --git a/include/queue.h b/include/queue.h new file mode 100644 index 0000000..d399486 --- /dev/null +++ b/include/queue.h @@ -0,0 +1,50 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include + +/* + * Macro to create a new queue. + */ +#define queue(q) queue* q = newQueue(); + +typedef struct queue_element{ + void* next; + void* element; +} queue_element; + +typedef struct queue{ + + int size; /* The number of at in use */ + queue_element* front; /* pointer to the first element of the queue */ + queue_element* back; /* pointer to the back element of the queue */ + + void (*toString)(); /* Pointer to toString function */ +} queue; + + +/* + * Creates new queue. + */ +queue* newQueue(); + +/* + * Adds a new element to the queue. + */ +void queuePush(queue* q, void* element); + +void queuePrint(queue* q); + +void queuePop(queue* q); + +bool queueIsEmpty(queue* q); + +void queueMerge(queue* q1, queue* q2); + +void queueClear(queue* q); + +void queueFree(queue* q); + +void* queueTop(queue* q); + +#endif \ No newline at end of file diff --git a/include/water.h b/include/water.h new file mode 100644 index 0000000..6f00882 --- /dev/null +++ b/include/water.h @@ -0,0 +1,6 @@ +#ifndef WATER_H +#define WATHER_H + +void water(Labyrinth* labyrinth); + +#endif \ No newline at end of file diff --git a/obj/bfs.o b/obj/bfs.o new file mode 100644 index 0000000..2250d82 Binary files /dev/null and b/obj/bfs.o differ diff --git a/obj/binaryTree.o b/obj/binaryTree.o new file mode 100644 index 0000000..e26ee70 Binary files /dev/null and b/obj/binaryTree.o differ diff --git a/obj/depthFirst.o b/obj/depthFirst.o new file mode 100644 index 0000000..e98d45b Binary files /dev/null and b/obj/depthFirst.o differ diff --git a/obj/dfs.o b/obj/dfs.o new file mode 100644 index 0000000..3104ca8 Binary files /dev/null and b/obj/dfs.o differ diff --git a/obj/dijkstra.o b/obj/dijkstra.o new file mode 100644 index 0000000..68723c4 Binary files /dev/null and b/obj/dijkstra.o differ diff --git a/obj/eller.o b/obj/eller.o new file mode 100644 index 0000000..3dc00fa Binary files /dev/null and b/obj/eller.o differ diff --git a/obj/labyrith.o b/obj/labyrith.o new file mode 100644 index 0000000..a3be9b2 Binary files /dev/null and b/obj/labyrith.o differ diff --git a/obj/main.o b/obj/main.o new file mode 100644 index 0000000..998d501 Binary files /dev/null and b/obj/main.o differ diff --git a/obj/prim.o b/obj/prim.o new file mode 100644 index 0000000..5b3503f Binary files /dev/null and b/obj/prim.o differ diff --git a/obj/priorityQueuePP.o b/obj/priorityQueuePP.o new file mode 100644 index 0000000..6c8d99e Binary files /dev/null and b/obj/priorityQueuePP.o differ diff --git a/obj/priority_queue.o b/obj/priority_queue.o new file mode 100644 index 0000000..db216e4 Binary files /dev/null and b/obj/priority_queue.o differ diff --git a/obj/queue.o b/obj/queue.o new file mode 100644 index 0000000..db67099 Binary files /dev/null and b/obj/queue.o differ diff --git a/obj/water.o b/obj/water.o new file mode 100644 index 0000000..52371d7 Binary files /dev/null and b/obj/water.o differ diff --git a/src/bfs.c b/src/bfs.c new file mode 100644 index 0000000..52ca70c --- /dev/null +++ b/src/bfs.c @@ -0,0 +1,87 @@ +#include +#include +#include "../include/labyrinth.h" +#include "../include/bfs.h" +#include "../include/queue.h" +#include "../include/coor.h" + +void bfs(Labyrinth* labyrinth){ + int i, j; + int arr[4] = {0, 1, 2, 3}, tmp, tp; + coor* cor = (coor*)malloc(sizeof(coor)); + coor* test; + cor->x = labyrinth->start.x; + cor->y = labyrinth->start.y; + queue(q); + queuePush(q, cor); + + while(!queueIsEmpty(q)){ + test = (coor*)q->front->element; + i = test->x; + j = test->y; + queuePop(q); + + if(i==labyrinth->end.x && j==labyrinth->end.y){ + queueFree(q); + find_path(labyrinth); + return; + } + + if(i!=labyrinth->start.x || j!=labyrinth->start.y) + labyrinth->at[i][j].color = GREEN; + + printLab(labyrinth); + + labyrinth->at[i][j].visited = true; + + + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + // goes in the direction if possible + for(int h=0; h<4; h++){ + coor* cor2 = (coor*)malloc(sizeof(coor)); + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].south && !labyrinth->at[i-1][j].visited){ + if(i-1!=labyrinth->end.x && j!=labyrinth->end.y) + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + cor2->x = i-1; + cor2->y = j; + queuePush(q, cor2); + } + }else if(arr[h]==1){ + if(jy_size-1 && labyrinth->at[i][j].east && !labyrinth->at[i][j+1].visited){ + if(i!=labyrinth->end.x && j+1!=labyrinth->end.y) + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + cor2->x = i; + cor2->y = j+1; + queuePush(q, cor2); + } + }else if(arr[h]==2){ + if(iy_size-1 && labyrinth->at[i][j].south && !labyrinth->at[i+1][j].visited){ + if(i+1!=labyrinth->end.x && j!=labyrinth->end.y) + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + cor2->x = i+1; + cor2->y = j; + queuePush(q, cor2); + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].east && !labyrinth->at[i][j-1].visited){ + if(i!=labyrinth->end.x && j-1!=labyrinth->end.y) + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + cor2->x = i; + cor2->y = j-1; + queuePush(q, cor2); + } + } + } + } +} \ No newline at end of file diff --git a/src/binaryTree.c b/src/binaryTree.c new file mode 100644 index 0000000..ce352cf --- /dev/null +++ b/src/binaryTree.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "../include/binaryTree.h" +#include "../include/labyrinth.h" + +Labyrinth* binaryTree_r(int n, int m, bool show); + +Labyrinth* binaryTree(int n, int m){ + return binaryTree_r(n, m, false); +} + +Labyrinth* binaryTreeShow(int n, int m){ + return binaryTree_r(n, m, true); +} + +// creates a labyrinth using the binaryTree algorithm +Labyrinth* binaryTree_r(int n, int m, bool show){ + int i, j, tmp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + labyrinth->at[0][0].east = 1; + labyrinth->at[0][0].south = 1; + if(show){ + labyrinth->at[0][0].color = ORANGE; + printLab(labyrinth); + labyrinth->at[0][0].color = WHITE; + } + + for(i=1; iat[i-1][0].south = 1; + + if(show){ + labyrinth->at[i-1][0].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i-1][0].color = WHITE; + } + } + + for(j=1; jat[0][j-1].east = 1; + + if(show){ + labyrinth->at[0][j-1].color = ORANGE; + printLab(labyrinth); + labyrinth->at[0][j-1].color = WHITE; + } + + } + + for(i=1; iat[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + tmp = rand()%2; + if(tmp) + labyrinth->at[i-1][j].south = 1; + else + labyrinth->at[i][j-1].east = 1; + } + } + + resetLabyrinth(labyrinth); + + return labyrinth; +} \ No newline at end of file diff --git a/src/depthFirst.c b/src/depthFirst.c new file mode 100644 index 0000000..5080fdb --- /dev/null +++ b/src/depthFirst.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include "../include/depthFirst.h" + +void depthFirst_r(int i, int j, Labyrinth* labyrinth, bool show); + +// dfs search algorithm +Labyrinth* depthFirst(int n, int m){ + Labyrinth* labyrinth = newLabyrinth(n, m); + + depthFirst_r(rand()%n, rand()%m, labyrinth, false); + + resetLabyrinth(labyrinth); + + return labyrinth; +} + +Labyrinth* depthFirstShow(int n, int m){ + Labyrinth* labyrinth = newLabyrinth(n, m); + + depthFirst_r(rand()%n, rand()%m, labyrinth, true); + + resetLabyrinth(labyrinth); + + return labyrinth; +} + +// ricursive function used by depthFirst +void depthFirst_r(int i, int j, Labyrinth* labyrinth, bool show){ + labyrinth->at[i][j].visited = 1; + labyrinth->at[i][j].dp = -1; + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + int arr[4] = {0, 1, 2, 3}, tmp, tp; + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + for(int h=0; h<4; h++){ + if(arr[h]==0){ + if(i>0 && !labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].south = 1; + depthFirst_r(i-1, j, labyrinth, show); + } + }else if(arr[h]==1){ + if(jy_size-1 && !labyrinth->at[i][j+1].visited){ + labyrinth->at[i][j].east = 1; + depthFirst_r(i, j+1, labyrinth, show); + } + }else if(arr[h]==2){ + if(ix_size-1 && !labyrinth->at[i+1][j].visited){ + labyrinth->at[i][j].south = 1; + depthFirst_r(i+1, j, labyrinth, show); + } + }else if(arr[h]==3){ + if(j>0 && !labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].east = 1; + depthFirst_r(i, j-1, labyrinth, show); + } + } + } + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } +} \ No newline at end of file diff --git a/src/dfs.c b/src/dfs.c new file mode 100644 index 0000000..b0ad722 --- /dev/null +++ b/src/dfs.c @@ -0,0 +1,67 @@ +#include +#include +#include "../include/labyrinth.h" +#include "../include/dfs.h" + +short dfs_r(Labyrinth* labyrinth, int i, int j); + +void dfs(Labyrinth* labyrinth){ + dfs_r(labyrinth, labyrinth->start.x, labyrinth->start.y); + find_path(labyrinth); +} + +short dfs_r(Labyrinth* labyrinth, int i, int j){ + if(i==labyrinth->end.x && j==labyrinth->end.y) + return 1; + + if(i!=labyrinth->start.x || j!=labyrinth->start.y) + labyrinth->at[i][j].color = GREEN; + + printLab(labyrinth); + + labyrinth->at[i][j].visited = 1; + + // randomly generates order of direction to try + int arr[4] = {0, 1, 2, 3}, tmp, tp; + for(int h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + // goes in the direction if possible + for(int h=0; h<4; h++){ + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].south && !labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + if(dfs_r(labyrinth, i-1, j)) + return 1; + } + }else if(arr[h]==1){ + if(jy_size-1 && labyrinth->at[i][j].east && !labyrinth->at[i][j+1].visited){ + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + if(dfs_r(labyrinth, i, j+1)) + return 1; + } + }else if(arr[h]==2){ + if(iy_size-1 && labyrinth->at[i][j].south && !labyrinth->at[i+1][j].visited){ + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + if(dfs_r(labyrinth, i+1, j)) + return 1; + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].east && !labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + if(dfs_r(labyrinth, i, j-1)) + return 1; + } + } + } + + return 0; +} \ No newline at end of file diff --git a/src/dijkstra.c b/src/dijkstra.c new file mode 100644 index 0000000..c2e5b85 --- /dev/null +++ b/src/dijkstra.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include "../include/dijkstra.h" +#include "../include/priority_queue.h" + +typedef struct element{ + int dist; + int x; + int y; +} element; + +bool compare_element(element* e1, element* e2){ + return e1->dist > e2->dist; +} + +void toString(element* e){ + printf("(%d) %d %d\n", e->dist, e->x, e->y); +} + +void dijkstra_r(Labyrinth* labyrinth, int i, int j, int dist, priority_queue* queue); + +// dijkstra search algorithm +void dijkstra(Labyrinth* labyrinth){ + priority_queue(queue, compare_element); + queue->toString = toString; + + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = 0; + tmp->x = labyrinth->start.x; + tmp->y = labyrinth->start.y; + labyrinth->at[tmp->x][tmp->y].dp = 0; + priority_queuePush(queue, tmp); + + int a, b, c; + + while(!priority_queueIsEmpty(queue)){ + a = ((element*)priority_queueTop(queue))->dist; + b = ((element*)priority_queueTop(queue))->x; + c = ((element*)priority_queueTop(queue))->y; + + priority_queuePop(queue); + + dijkstra_r(labyrinth, b, c, a, queue); + printLab(labyrinth); + } + priority_queueFree(queue); + + find_path(labyrinth); + printf("test\n"); +} + +// ricursive function used by dijkstra +void dijkstra_r(Labyrinth* labyrinth, int i, int j, int dist, priority_queue* queue){ + + if(i==labyrinth->end.x && j==labyrinth->end.y){ + priority_queueClear(queue); + return; + } + + if(dist) + labyrinth->at[i][j].color = GREEN; + + // adds all four directions to the priority_queue + if(i>0 && labyrinth->at[i-1][j].south && labyrinth->at[i-1][j].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i-1; + tmp->y = j; + + priority_queuePush(queue, tmp); + + if(i-1!=labyrinth->end.x || j!=labyrinth->end.y) + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].direction = UP; + labyrinth->at[i-1][j].dp = dist+1; + } + if(jy_size-1 && labyrinth->at[i][j].east && labyrinth->at[i][j+1].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i; + tmp->y = j+1; + + priority_queuePush(queue, tmp); + + if(i!=labyrinth->end.x || j+1!=labyrinth->end.y) + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].direction = RIGHT; + labyrinth->at[i][j+1].dp = dist+1; + } + if(ix_size-1 && labyrinth->at[i][j].south && labyrinth->at[i+1][j].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i+1; + tmp->y = j; + + priority_queuePush(queue, tmp); + + if(i+1!=labyrinth->end.x || j!=labyrinth->end.y) + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].direction = DOWN; + labyrinth->at[i+1][j].dp = dist+1; + } + if(j>0 && labyrinth->at[i][j-1].east && labyrinth->at[i][j-1].dp<0){ + element* tmp = (element*)malloc(sizeof(element)); + tmp->dist = dist+1; + tmp->x = i; + tmp->y = j-1; + + priority_queuePush(queue, tmp); + + if(i!=labyrinth->end.x || j-1!=labyrinth->end.y) + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].direction = LEFT; + labyrinth->at[i][j-1].dp = dist+1; + } +} \ No newline at end of file diff --git a/src/eller.c b/src/eller.c new file mode 100644 index 0000000..bbc9e01 --- /dev/null +++ b/src/eller.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include "../include/eller.h" +#include "../include/queue.h" + +#define ELLER_COST 2 + +Labyrinth* eller_(int n, int m, bool show); + +Labyrinth* eller(int n, int m){ + return eller_(n, m, false); +} + +Labyrinth* ellerShow(int n, int m){ + return eller_(n, m, true); +} + +Labyrinth* eller_(int n, int m, bool show){ + int i, j, h, tmp, tp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + int sets[m][m]; + int setSizes[m]; + + queue(freeSets); + + int arr[m]; + for(i=0; iat[i][j].dp < 0){ + int* tmp = (int*)freeSets->front->element; + labyrinth->at[i][j].dp = *tmp; + queuePop(freeSets); + } + + tmp = labyrinth->at[i][j].dp; + sets[tmp][setSizes[tmp]] = j; + setSizes[tmp]++; + } + + // randomizes order + for(j=m; j>0; j--){ + tmp = rand() % j; + tp = arr[tmp]; + arr[tmp] = arr[j-1]; + arr[j-1] = tp; + } + + // randomly merge cells + for(j=0; jat[i][tmp].dp != labyrinth->at[i][tmp+1].dp && (rand()%ELLER_COST || i==n-1)){ + labyrinth->at[i][tmp].east = 1; + + tp = labyrinth->at[i][tmp].dp; + tmp = labyrinth->at[i][tmp+1].dp; + for(h=0; hat[i][sets[tmp][h]].dp = tp; + } + setSizes[tmp] = 0; + + int* s = (int*)malloc(sizeof(int)); + *s = tmp; + queuePush(freeSets, s); + + if(show){ + labyrinth->at[i][tmp].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][tmp].color = WHITE; + } + } + } + + // randomly makes cells go down + for(j=0; j1; h--){ + tmp = rand()%h; + tp = sets[j][tmp]; + sets[j][tmp] = sets[j][h-1]; + + if(rand()%ELLER_COST){ + labyrinth->at[i][tp].south = 1; + labyrinth->at[i+1][tp].dp = labyrinth->at[i][tp].dp; + down[j] = 1; + + if(show){ + labyrinth->at[i][tp].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][tp].color = WHITE; + } + } + } + + // last cell + if(setSizes[j] && (!down[j] || rand()%ELLER_COST)){ + labyrinth->at[i][sets[j][0]].south = 1; + labyrinth->at[i+1][sets[j][0]].dp = labyrinth->at[i][sets[j][0]].dp; + + if(show){ + labyrinth->at[i][sets[j][0]].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][sets[j][0]].color = WHITE; + } + } + } + } + + resetLabyrinth(labyrinth); + queueFree(freeSets); + + return labyrinth; +} \ No newline at end of file diff --git a/src/labyrith.c b/src/labyrith.c new file mode 100644 index 0000000..1eb5a71 --- /dev/null +++ b/src/labyrith.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include "../include/labyrinth.h" + +void find_path_r(Labyrinth* labyrinth, int i, int j); + +Labyrinth* newLabyrinth(int n, int m){ + if(n<1 || m<1 || (n==1 && m==1)){ + printf("COGLIONE\n"); + exit(EXIT_FAILURE); + } + + Labyrinth* labyrinth = (Labyrinth* )malloc(sizeof(Labyrinth)); + labyrinth->x_size = n; + labyrinth->y_size = m; + + labyrinth->at = (Node** )malloc(n*sizeof(Node* )); + for(int i=0; iat[i] = (Node *)malloc(m*sizeof(Node)); + + for(int i=0; iat[i][j].dp = -1; + labyrinth->at[i][j].east = 0; + labyrinth->at[i][j].south = 0; + labyrinth->at[i][j].visited = 0; + } + } + + labyrinth->x_size = n; + labyrinth->y_size = m; + + labyrinth->start.x = rand()%n; + labyrinth->start.y = rand()%m; + + do{ + labyrinth->end.x = rand()%n; + labyrinth->end.y = rand()%m; + }while(labyrinth->start.x == labyrinth->end.x && labyrinth->start.y == labyrinth->end.y); + + return labyrinth; +} + +void resetLabyrinth(Labyrinth* labyrinth){ + for(int i=0; ix_size; i++){ + for(int j=0; jy_size; j++){ + labyrinth->at[i][j].color = WHITE; + labyrinth->at[i][j].visited = 0; + labyrinth->at[i][j].dp = -1; + } + } + + labyrinth->at[labyrinth->start.x][labyrinth->start.y].color = BLUE; + labyrinth->at[labyrinth->end.x][labyrinth->end.y].color = BLUE; +} + +void removeLabyrinth(Labyrinth* labyrinth){ + for(int i=0; ix_size; i++) + free(labyrinth->at[i]); + free(labyrinth->at); + free(labyrinth); +} + +void find_path(Labyrinth* labyrinth){ + find_path_r(labyrinth, labyrinth->end.x, labyrinth->end.y); +} + +void find_path_r(Labyrinth* labyrinth, int i, int j){ + labyrinth->at[i][j].color = BLUE; + // printLab(labyrinth); + + if(i==labyrinth->start.x && j==labyrinth->start.y) + return; + + if(labyrinth->at[i][j].direction == UP) + find_path_r(labyrinth, i+1, j); + else if(labyrinth->at[i][j].direction == RIGHT) + find_path_r(labyrinth, i, j-1); + else if(labyrinth->at[i][j].direction == DOWN) + find_path_r(labyrinth, i-1, j); + else if(labyrinth->at[i][j].direction == LEFT) + find_path_r(labyrinth, i, j+1); + else{ + printf("ERROR IN FIND_PATH\n"); + exit(EXIT_FAILURE); + } +} + +void printLab(Labyrinth* labyrinth){ + printLabWith(labyrinth, '|', '-', '+'); +} + +void printLabWith(Labyrinth* labyrinth, char wall, char floor, char corner){ + int i, j; + + system("clear"); + + for(j=0; jy_size; j++){ + printf("%c%c", corner, floor); + } + printf("%c\n", corner); + + for(i=0; ix_size; i++){ + printf("%c", wall); + + for(j=0; jy_size; j++){ + if(labyrinth->at[i][j].color == BLUE) + printf("\033[104m \033[49m"); + else if(labyrinth->at[i][j].color == GREEN) + printf("\033[102m \033[49m"); + else if(labyrinth->at[i][j].color == ORANGE) + printf("\033[103m \033[49m"); + else + printf(" "); + + if(labyrinth->at[i][j].east && jy_size-1){ + if(labyrinth->at[i][j+1].color == BLUE && labyrinth->at[i][j].color == BLUE) + printf("\033[104m \033[49m"); + else if((labyrinth->at[i][j+1].color == GREEN || labyrinth->at[i][j+1].color == BLUE) && (labyrinth->at[i][j].color == GREEN || labyrinth->at[i][j].color == BLUE)) + printf("\033[102m \033[49m"); + else if(!(labyrinth->at[i][j+1].color == WHITE) && !(labyrinth->at[i][j].color == WHITE)) + printf("\033[103m \033[49m"); + else + printf(" "); + }else + printf("%c", wall); + } + printf("\n"); + for(j=0; jy_size; j++){ + printf("%c", corner); + if(labyrinth->at[i][j].south && ix_size-1){ + if(labyrinth->at[i][j].color == BLUE && labyrinth->at[i+1][j].color == BLUE) + printf("\033[104m \033[49m"); + else if((labyrinth->at[i][j].color == GREEN || labyrinth->at[i][j].color == BLUE) && (labyrinth->at[i+1][j].color == GREEN || labyrinth->at[i+1][j].color == BLUE)) + printf("\033[102m \033[49m"); + else if(!(labyrinth->at[i][j].color == WHITE) && !(labyrinth->at[i+1][j].color == WHITE)) + printf("\033[103m \033[49m"); + else + printf(" "); + }else + printf("%c", floor); + } + printf("%c\n", corner); + } + printf("\n"); + + usleep(50000); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2e4de9f --- /dev/null +++ b/src/main.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include "../include/dijkstra.h" +#include "../include/dfs.h" +#include "../include/labyrinth.h" +#include "../include/binaryTree.h" +#include "../include/depthFirst.h" +#include "../include/prim.h" +#include "../include/eller.h" +#include "../include/water.h" +#include "../include/bfs.h" + +#define N 15 +#define M 15 + +int main(){ + srand(time(0)); + + int n = N, m = M; + + Labyrinth* labyrinth1 = prim(n, m); + + water(labyrinth1); + printLab(labyrinth1); + resetLabyrinth(labyrinth1); + + + removeLabyrinth(labyrinth1); +} diff --git a/src/prim.c b/src/prim.c new file mode 100644 index 0000000..d608d41 --- /dev/null +++ b/src/prim.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include "../include/coor.h" +#include "../include/prim.h" + +Labyrinth* prim_(int n, int m, bool show); + +Labyrinth* prim(int n, int m){ + return prim_(n, m, false); +} + +Labyrinth* primShow(int n, int m){ + return prim_(n, m, true); +} + +// creates a labyrinth using prim's algorithm +Labyrinth* prim_(int n, int m, bool show){ + int i, j, h, tmp, tp; + Labyrinth* labyrinth = newLabyrinth(n, m); + + int arr[4] = {0, 1, 2, 3}; + + coor frontier[n*m]; + coor current = {.x = rand()%n, .y = rand()%m}; + i = current.x; + j = current.y; + int frontierSize = 0; + + do{ + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + + labyrinth->at[i][j].visited = 1; + + // adds frontier cells + if(i > 0 && labyrinth->at[i-1][j].dp < 0){ + frontier[frontierSize].x = i-1; + frontier[frontierSize].y = j; + frontierSize++; + labyrinth->at[i-1][j].dp = 1; + } + if(j < m-1 && labyrinth->at[i][j+1].dp < 0){ + frontier[frontierSize].x = i; + frontier[frontierSize].y = j+1; + frontierSize++; + labyrinth->at[i][j+1].dp = 1; + } + if(i < n-1 && labyrinth->at[i+1][j].dp < 0){ + frontier[frontierSize].x = i+1; + frontier[frontierSize].y = j; + frontierSize++; + labyrinth->at[i+1][j].dp = 1; + } + if(j > 0 && labyrinth->at[i][j-1].dp < 0){ + frontier[frontierSize].x = i; + frontier[frontierSize].y = j-1; + frontierSize++; + labyrinth->at[i][j-1].dp = 1; + } + + // randomly selects a frontier cell + tmp = rand()%frontierSize; + current = frontier[tmp]; + frontier[tmp] = frontier[frontierSize-1]; + frontierSize--; + + i = current.x; + j = current.y; + + // randomly joins the selected cell to another cell + for(h=3; h>0; h--){ + tmp = rand()%h; + tp = arr[h]; + arr[h] = arr[tmp]; + arr[tmp] = tp; + } + + tmp = 1; + for(h=0; h<4 && tmp; h++){ + if(arr[h]==0){ + if(i>0 && labyrinth->at[i-1][j].visited){ + labyrinth->at[i-1][j].south = 1; + tmp = 0; + } + }else if(arr[h]==1){ + if(jat[i][j+1].visited){ + labyrinth->at[i][j].east = 1; + tmp = 0; + } + }else if(arr[h]==2){ + if(iat[i+1][j].visited){ + labyrinth->at[i][j].south = 1; + tmp = 0; + } + }else if(arr[h]==3){ + if(j>0 && labyrinth->at[i][j-1].visited){ + labyrinth->at[i][j-1].east = 1; + tmp = 0; + } + } + + } + + }while(frontierSize); + + if(show){ + labyrinth->at[i][j].color = ORANGE; + printLab(labyrinth); + labyrinth->at[i][j].color = WHITE; + } + + resetLabyrinth(labyrinth); + + return labyrinth; +} \ No newline at end of file diff --git a/src/priority_queue.c b/src/priority_queue.c new file mode 100644 index 0000000..6830fee --- /dev/null +++ b/src/priority_queue.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include "../include/priority_queue.h" + + +void priority_queueFixheap(priority_queue* q, int i); +void priority_queueHeapify(priority_queue* queue, int i); +void priority_queueSwap(void** a, void** b); + +priority_queue* newPriority_queue(bool (*compare)()){ + priority_queue* pq = (priority_queue*)malloc(sizeof(priority_queue)); + pq->size = 0; + pq->capacity = 0; + pq->growthFactor = PRIORITY_QUEUE_INIT_GROWTH_FACT; + + pq->compare = compare; + pq->toString = NULL; + + return pq; +} + +void priority_queuePush(priority_queue* pq, void* element){ + if(pq->size == pq->capacity){ + if(pq->capacity) + priority_queueResize(pq, pq->capacity * pq->growthFactor); + else + priority_queueResize(pq, 1); + } + + pq->at[pq->size] = element; + pq->size++; + + priority_queueFixheap(pq, pq->size-1); +} + +void priority_queueFixheap(priority_queue* pq, int i){ + if(!i) + return; + if(pq->compare(pq->at[(i-1)/2], pq->at[i])) + priority_queueSwap(pq->at[i], pq->at[(i-1)/2]); + + priority_queueFixheap(pq, (i-1)/2); +} + +void priority_queuePop(priority_queue* pq){ + if(!pq->size){ + fprintf(stderr, "POP ON EMPTY PRIORITY_QUEUE\n"); + return; + } + + priority_queueSwap(&pq->at[0], &pq->at[pq->size-1]); + free(pq->at[pq->size-1]); + pq->size--; + priority_queueHeapify(pq, 0); +} + +void priority_queueHeapify(priority_queue* pq, int i){ + if(i >= (pq->size)/2) + return; + + int minson; + if(pq->size-1 == 2*i+1 || !pq->compare(pq->at[2*i+1], pq->at[2*i+2])) + minson = 2*i+1; + else + minson = 2*i+2; + + if(pq->compare(pq->at[i], pq->at[minson])){ + priority_queueSwap(&pq->at[i], &pq->at[minson]); + priority_queueHeapify(pq, minson); + } +} + +void priority_queueSwap(void** a, void** b){ + void* tmp = *a; + *a = *b; + *b = tmp; +} + +void priority_queueResize(priority_queue* pq, int capacity){ + for(int i=pq->size; i>capacity; i--) + free(pq->at[i-1]); + + void **at = realloc(pq->at, sizeof(void *) * capacity); + pq->at = at; + pq->capacity = capacity; +} + +void priority_queueClear(priority_queue* pq){ + priority_queueResize(pq, 0); + pq->size = 0; +} + +void priority_queueFree(priority_queue* pq){ + priority_queueClear(pq); + free(pq->at); + free(pq); +} + +void priority_queueShrink_to_fit(priority_queue* pq){ + priority_queueResize(pq, pq->size); +} + +bool priority_queueIsEmpty(priority_queue* pq){ + return pq->size > 0 ? false : true; +} + +void* priority_queueTop(priority_queue* pq){ + if(!pq->size){ + fprintf(stderr, "PRIORITY_QUEUE IS EMPTY\n"); + return NULL; + } + + return pq->at[0]; +} + +void priority_queuePrint(priority_queue* pq){ + if(pq->toString == NULL){ + fprintf(stderr, "TOSTRING NOT DEFINED\n"); + return; + } + + for(int i=0; isize; i++) + pq->toString(pq->at[i]); + + printf("\n"); +} \ No newline at end of file diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000..c28e747 --- /dev/null +++ b/src/queue.c @@ -0,0 +1,99 @@ +#include +#include +#include "../include/queue.h" + +queue* newQueue(){ + queue* tmp = (queue*)malloc(sizeof(queue)); + tmp->size = 0; + + tmp->toString = NULL; + tmp->front = NULL; + tmp->back = NULL; + + return tmp; +} + +void queuePush(queue* q, void* element){ + queue_element* qel = (queue_element*)malloc(sizeof(queue_element)); + qel->element = element; + qel->next = NULL; + + if(queueIsEmpty(q)){ + q->front = qel; + q->back = qel; + }else{ + q->back->next = qel; + q->back = qel; + } + + q->size++; +} + +void queuePrint(queue* q){ + if(q->toString == NULL){ + fprintf(stderr, "TOSTRING NOT DEFINED\n"); + return; + } + + queue_element* tmp = q->front; + while(tmp){ + q->toString(tmp->element); + tmp = tmp->next; + printf("\n"); + } + + printf("\n"); +} + +void queuePop(queue* q){ + if(queueIsEmpty(q)){ + fprintf(stderr, "QUEUE IS EMTPY\n"); + return; + } + + queue_element* tmp = q->front->next; + free(q->front->element); + free(q->front); + q->front = tmp; + q->size--; +} + +bool queueIsEmpty(queue* q){ + return q->size == 0; +} + +void queueMerge(queue* q1, queue* q2){ + if(queueIsEmpty(q1)) + q1->front = q2->front; + else + q1->back->next = q2->front; + + q1->back = q2->back; + q1->size += q2->size; + + q2->front = NULL; + q2->back = NULL; + q2->size = 0; +} + +void queueClear(queue* q){ + queue_element* tmp = q->front, *tp; + while(tmp){ + tp = tmp->next; + free(tmp->element); + free(tmp); + tmp = tp; + } + + q->front = NULL; + q->size = 0; +} + +void queueFree(queue* q){ + queueClear(q); + free(q); +} + +void* queueTop(queue* q){ + return q->front; +} \ No newline at end of file diff --git a/src/water.c b/src/water.c new file mode 100644 index 0000000..c2e2263 --- /dev/null +++ b/src/water.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include "../include/labyrinth.h" +#include "../include/water.h" +#include "../include/priority_queue.h" +#include "../include/queue.h" + +bool compare_water(coor* c1, coor* c2){ + return c1->x < c2->x; +} + +void pp(coor* c1){ + printf("%d %d", c1->x, c1->y); +} + +int qmin(queue* q); + +void expand(coor* c, Labyrinth* labyrinth, queue* pq); + +void water(Labyrinth *labyrinth){ + int i, min; + + queue(pq); // DA METTERE RBTREE (mai) + coor* tmp = (coor*)malloc(sizeof(coor)); + tmp->x = labyrinth->start.x; + tmp->y = labyrinth->start.y; + labyrinth->at[tmp->x][tmp->y].dp = 0; + + queuePush(pq, tmp); + pq->toString = pp; // TMP + + queue(q); + q->toString = pp; + + + while(!queueIsEmpty(pq)){ + printf("size: %d\n", pq->size); + queuePrint(pq); + + min = qmin(pq); + printf("min: %d\n", min); + queue_element* qelem = pq->front; + queue_element* prev = NULL; + + while(qelem){ + + printf("cons: "); + pp(qelem->element); + printf("\n"); + if(((coor*)qelem->element)->x == min){ + if(((coor*)(qelem->element))->x == labyrinth->end.x && ((coor*)(qelem->element))->y == labyrinth->end.y) + return; + + printf("in elem: "); + pp(qelem->element); + printf("\n"); + expand(qelem->element, labyrinth, q); + labyrinth->at[((coor*)qelem->element)->x][((coor*)qelem->element)->y].color = GREEN; + + if(prev) + prev->next = qelem->next; + else + pq->front = qelem->next; + + pq->size--; + + if(!qelem->next) + pq->back = prev; + + free(qelem->element); + free(qelem); + + }else{ + prev = qelem; + } + + if(prev) + qelem = prev->next; + else if(pq->front) + qelem = pq->front->next; + else + qelem = NULL; + + } + + printf("newqueue: %d\n", pq->size); + queuePrint(pq); + printf("p: %d\n", q->size); + queuePrint(q); + + queueMerge(pq, q); + printf("new: %d\n", pq->size); + queuePrint(pq); + + printLab(labyrinth); + scanf("%d", &i); + } +} + + +void expand(coor* c, Labyrinth* labyrinth, queue* q){ + int i = c->x, j = c->y; + + if(i>0 && labyrinth->at[i-1][j].south && labyrinth->at[i-1][j].dp<0){ + coor* tmp = (coor*)malloc(sizeof(coor)); + tmp->x = i-1; + tmp->y = j; + + queuePush(q, tmp); + + labyrinth->at[i-1][j].direction = UP; + labyrinth->at[i-1][j].color = ORANGE; + labyrinth->at[i-1][j].dp = 0; + } + if(jy_size-1 && labyrinth->at[i][j].east && labyrinth->at[i][j+1].dp<0){ + coor* tmp = (coor*)malloc(sizeof(coor)); + tmp->x = i; + tmp->y = j+1; + + queuePush(q, tmp); + + labyrinth->at[i][j+1].direction = UP; + labyrinth->at[i][j+1].color = ORANGE; + labyrinth->at[i][j+1].dp = 0; + } + if(ix_size-1 && labyrinth->at[i][j].south && labyrinth->at[i+1][j].dp<0){ + coor* tmp = (coor*)malloc(sizeof(coor)); + tmp->x = i+1; + tmp->y = j; + + queuePush(q, tmp); + + labyrinth->at[i+1][j].direction = UP; + labyrinth->at[i+1][j].color = ORANGE; + labyrinth->at[i+1][j].dp = 0; + } + if(j>0 && labyrinth->at[i][j-1].east && labyrinth->at[i][j-1].dp<0){ + coor* tmp = (coor*)malloc(sizeof(coor)); + tmp->x = i; + tmp->y = j-1; + + queuePush(q, tmp); + + labyrinth->at[i][j-1].direction = UP; + labyrinth->at[i][j-1].color = ORANGE; + labyrinth->at[i][j-1].dp = 0; + } +} + + +int qmin(queue* q){ + queue_element *tmp = q->front; + coor min = {.x = 0}; + while(tmp){ + if(compare_water(&min, tmp->element)) + min.x = ((coor*)tmp->element)->x; + + tmp = tmp->next; + } + + return min.x; +} \ No newline at end of file