Skip to content

Instantly share code, notes, and snippets.

@senapk
Last active July 2, 2018 17:53
Show Gist options
  • Save senapk/aa57b0e9cd59f543a53e8edae206d6c8 to your computer and use it in GitHub Desktop.
Save senapk/aa57b0e9cd59f543a53e8edae206d6c8 to your computer and use it in GitHub Desktop.
Create lab in C
#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;
}
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