Last active
July 2, 2018 17:53
-
-
Save senapk/aa57b0e9cd59f543a53e8edae206d6c8 to your computer and use it in GitHub Desktop.
Create lab in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> //rand srand atoi | |
#include <time.h> //time | |
#include <stdbool.h> //bool true false | |
#define USEBLOCK 1 //para imprimir blocos ao invés de # para representar as Paredes do lab | |
#if USEBLOCK //para imprimir o unicode | |
#include <wchar.h> //to print full square | |
#include <locale.h> //to set locale | |
#endif | |
typedef struct{ //para representar um par linha e coluna | |
int l, c; | |
} LC; | |
#define WALL '#' | |
#define OPEN ' ' | |
//Macro generico para trocar duas coisas utilizando o recurso typeof do GCC | |
#define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0) //gcc only | |
void shuffle(LC vet[], int size){ //como embaralhar um vetor | |
for(int i = 0; i < size; i++){ | |
int pos = rand() % size; | |
SWAP(vet[i], vet[pos]); | |
} | |
} | |
//imprimir o lab, se a macro USEBLOCK for escolhida, a função vai usar wprintf | |
void show_lab(int nl, int nc, char mat[nl][nc]){ | |
for(int l = 0; l < nl; l++){ | |
#if USEBLOCK | |
for(int c = 0; c < nc; c++) | |
wprintf(L"%lc", (mat[l][c] == '#') ? 0x2588 : mat[l][c]); //troca o # por FULL SQUARE | |
wprintf(L"\n"); | |
#else | |
for(int c = 0; c < nc; c++) | |
printf("%c", mat[l][c]); | |
printf("\n"); | |
#endif | |
} | |
} | |
bool outside(int nl, int nc, int l, int c){ | |
return (c < 0) || (c >= nc) || (l < 0) || (l >= nl); | |
} | |
void make_lab(int nl, int nc, char mat[nl][nc], int l, int c){ | |
//se fora da matriz ou se não for parede | |
if(outside(nl, nc, l, c) || (mat[l][c] != WALL)) | |
return; | |
//contar vizinhos com paredes | |
int cont = 0; | |
//criando um vetor com a posição de todos os vizinhos Left, Up, Right, Down | |
LC neib[4] = {{l, c - 1}, {l - 1, c}, {l, c + 1}, {l + 1, c}}; | |
//verifica quantos vizinhos sao paredes e incrementa o contador | |
for(int i = 0; i < 4; i++) | |
if(!outside(nl, nc, neib[i].l, neib[i].c))//se existe | |
if(mat[neib[i].l][neib[i].c] == WALL)//e é uma parede | |
cont++; | |
if(cont < 3) //se tiver menos que 3 paredes não posso furar pra não abrir um caminho duplo | |
return; | |
//furando a posicao | |
mat[l][c] = OPEN; | |
//chamando aleatoriamente para todos os vizinhos a recursão | |
shuffle(neib, 4); | |
for(int i = 0; i < 4; i++) | |
make_lab(nl, nc, mat, neib[i].l, neib[i].c); | |
} | |
int main(int argc, char * argv[]){ | |
//se for utilizar unicode para imprimir os blocos, é necessário configura o LOCALE | |
#if USEBLOCK | |
setlocale(LC_CTYPE, ""); | |
#endif | |
int nl = 20, nc = 80; | |
//o primeiro parametro é o nome do programa | |
if(argc == 3){ //./lab nl nc | |
nl = atoi(argv[1]); //converter de string para inteiro | |
nc = atoi(argv[2]); | |
} | |
srand(time(NULL)); //inicializar o gerador de números aleatórios | |
char mat[nl][nc]; | |
for(int l = 0; l < nl; l++) //colocando parede em todas as posicoes da matriz | |
for(int c = 0; c < nc; c++) | |
mat[l][c] = WALL; | |
make_lab(nl, nc, mat, 1, 1); | |
show_lab(nl, nc, mat); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -Wall ./create_lab.c -o lab && ./lab 20 80 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment