diff --git a/src/baralho.c b/src/baralho.c
new file mode 100644
index 0000000000000000000000000000000000000000..c447040458bda14d6f3cd515034550dfdd029904
--- /dev/null
+++ b/src/baralho.c
@@ -0,0 +1,307 @@
+#include "baralho.h"
+#include "mesa.h"
+
+/* Inicia a  estrutura de dados para conter  as imagens individualizadas
+   de cartas. Os parâmetros indicam o nome do arquivo com a imagem original
+   em PPM, as dimensões de cada carta  na imagem original, o valor da carta
+   mais à esquerda, e a ordem dos naipes na imagem (de cima para baixo.) */
+Baralho init (char *imgFile, int cw,  int ch, char primCarta, char *ordNaipes) {
+	//                       largura  altura
+
+	/* Baralho é do tipo Carta**, o baralho é uma matriz de cartas.
+	   É a imagem original com "recortes" nas cartas. */
+	Baralho bar;
+	int i, j, aux;
+
+	/* Inicializa a variavel global ENTRADA com a imagem das cartas. */
+	ENTRADA = fopen(imgFile, "rb");
+
+	/* Inicializa cabeçalho das cartas. */
+	cabeca.magic[0] = 'P';
+	cabeca.magic[1] = '6';
+	cabeca.magic[2] = '\n';
+	cabeca.magic[3] = '\0';
+	cabeca.w = cw;
+	cabeca.h = ch;
+	cabeca.maxval = 255;
+
+	/* Ordena os vetores de valores e de naipes de modo que o
+	   primeiro elemento dos vetor de valores seja o valor
+	   que foi passado como parâmetro (primCarta) e o vetor de 
+	   naipes seja igual ao vetor de naipes passado como parâmetro
+	   (*ordNaipes). */
+	while (vals[0] != primCarta) {
+		aux = vals[0];
+		for (i = 0; i < 12; i++)
+			vals[i] = vals[i+1];
+		vals[i] = aux;
+	}
+	for (i = 0; i < NAIPES; i++)
+		naipes[i] = ordNaipes[i];
+
+	/* Aloca um vetor de quatro posições, uma para cada naipe. */
+	bar = (Baralho)malloc(sizeof(Carta*)*NAIPES);
+
+	/* Aloca 13 cartas para cada naipe. */
+	for (i = 0; i < NAIPES; i++)
+		bar[i] = (Carta*)malloc(sizeof(Carta)*CARTAS);
+
+	/* Aloca o espaço para a imagem de cada carta. */
+	for (i = 0; i < NAIPES; i++) {
+		for (j = 0; j < CARTAS; j++) {
+			bar[i][j].img = (Pixel*)malloc(sizeof(Pixel)*cw*ch);
+
+			/* Atribui o valor e o naipe de cada carta. */
+			bar[i][j].valor = vals[j];
+			bar[i][j].naipe = naipes[i];
+		}
+	}
+	return bar;
+}
+
+/* Lê  a  imagem  do  arquivo principal e preenche a estrutura de dados
+   gerada por \textsf{init()}. */
+/* Baralho de 52 cartas: cartas com 72 x 96 pixels. 
+   Intervalo entre cartas: 1 pixel. Intervalo entre naipes: 2 pixels. */
+Baralho geraBaralho (Baralho cartas) {
+	Pixel *p;
+	char s[4];
+	int col, lin, maxval;
+	int i, j, k, l, pos;
+
+	pos = 0;
+
+	/* É alocado o espaço do pixel a ser lido e são obtidas as informações
+	   da imagem original ("valor mágico", numero de colunas, numero de linhas
+	   e maxval). */
+	p = (Pixel*)malloc(sizeof(Pixel));
+	fgets(s, 4, ENTRADA);
+	fscanf(ENTRADA, "%d %d", &col, &lin);
+	fscanf(ENTRADA, "%d", &maxval);
+	fgetc(ENTRADA);
+
+	/* Dois lassos para pegar as cartas.
+	   Um lasso interno para a variação dos valores (horizontal)
+	   e um lasso externo para a variação dos naipes (vertical). */
+	for (i = 0; i < NAIPES; i++) {
+		for (j = 0; j < CARTAS; j++) {
+
+			/* Dois lassos para pegar os pixels da carta.
+			   Um lasso interno para a variação horizontal e um lasso
+			   externo para a variação vertical. */
+			for (k = 0; k < cabeca.h; k++) {
+				for (l = 0; l < cabeca.w; l++, pos++) {
+					fread(p, sizeof(Pixel), 1, ENTRADA);
+					cartas[i][j].img[pos] = *p;
+				}
+				fseek(ENTRADA, (col - cabeca.w) * (sizeof(Pixel)), SEEK_CUR);
+			}
+			fseek(ENTRADA, sizeof(Pixel) + (cabeca.w * sizeof(Pixel)) - (col * (sizeof(Pixel)) * cabeca.h), SEEK_CUR);
+			fseek(ENTRADA, sizeof(Pixel), SEEK_CUR);
+			pos = 0;
+		}
+		fseek(ENTRADA, col * sizeof(Pixel), SEEK_CUR);
+		fseek(ENTRADA, col * cabeca.h * sizeof(Pixel), SEEK_CUR);
+		fseek(ENTRADA, -sizeof(Pixel), SEEK_CUR);
+	}
+	return cartas;
+}
+
+/* Gera a imagem PPM de uma carta individual, pronta para uso. */
+Carta getCarta (char naipe, char valor, Baralho cartas) {
+	int i, j;
+
+	if ((naipe != 'P' && naipe != 'E' && naipe != 'C' && naipe != 'O') ||
+		(valor != 'A' && valor != '2' && valor != '3' && valor != '4' && 
+		 valor != '5' && valor != '6' && valor != '7' && valor != '8' &&
+		 valor != '9' && valor != 'D' && valor != 'J' && valor != 'Q' && 
+		 valor != 'K')) {
+		fprintf(stderr, "erro. carta inexistente.\n");
+		return;
+	}
+
+	/* Dois contadores para encontrar a posição do naipe e do valor desejados. */
+	for (i = 0; naipes[i] != naipe; i++);
+	for (j = 0; vals[j] != valor; j++);
+	return cartas[i][j];
+}
+
+/* Gera arquivo com imagem de  uma carta individual em formato PPM. Nome
+   do   arquivo  tem   formato   ``valor-naipe.ppm''  (e.g.,   ``A-C.ppm'',
+   ``2-P.ppm'', etc.). */
+void geraCarta (char naipe, char valor, Baralho cartas) {
+	int i, j;
+	char nome[8];
+	FILE *SAIDA;
+	Carta card;
+
+	if ((naipe != 'P' && naipe != 'E' && naipe != 'C' && naipe != 'O') ||
+		(valor != 'A' && valor != '2' && valor != '3' && valor != '4' && 
+		 valor != '5' && valor != '6' && valor != '7' && valor != '8' &&
+		 valor != '9' && valor != 'D' && valor != 'J' && valor != 'Q' && 
+		 valor != 'K')) {
+		fprintf(stderr, "erro. carta inexistente.\n");
+		return;
+	}
+
+	/* Atribui à string "nome" o nome do arquivo de saida desejado. */
+	nome[0] = valor;
+	nome[1] = '-';
+	nome[2] = naipe;
+	nome[3] = '.';
+	nome[4] = 'p';
+	nome[5] = 'p';
+	nome[6] = 'm';
+	nome[7] = '\0';
+	SAIDA = fopen(nome, "wb+");
+
+	card = getCarta(naipe, valor, cartas);
+
+	/* Imprime no arquivo os dados contidos no cabeçalho. */
+	fprintf(SAIDA, "%c%c%c\n", cabeca.magic[0], cabeca.magic[1], cabeca.magic[2]);
+	fprintf(SAIDA, "%d %d\n", cabeca.w, cabeca.h);
+	fprintf(SAIDA, "%d\n", cabeca.maxval);
+
+	/* Imprime no arquivo todos os pixels contidos na carta desejada. */
+	fwrite(card.img, sizeof(Pixel), cabeca.w * cabeca.h, SAIDA);
+	fclose(SAIDA);
+}
+
+/* Cria um monte vazio (sem cartas), que pode ser preenchido usando colocaCarta()
+   e esvaziado com tiraCarta(). */
+Monte criaMonte (int n) {
+	Monte deck;
+	int i;
+
+	/* Aloca memória para o monte.
+	   O número de espaços de memória alocados será o número de baralhos (n)
+	   vezes o numero de valores (CARTAS) vezes o número de naipes (NAIPES)
+	   mais 1. Esse último espaço de memória alocado servirá como uma barreira
+	   para não acessar memória inválida.
+	   Como CARTAS e NAIPES são constantes:
+	    	caso n = 0: memória alocada = 1
+	    	caso n = 1: memória alocada = 53
+	    	caso n = 2: memória alocada = 105
+	    	(...)
+	   E para cada um desses espaços são alocados mais 3 espaços de memória
+	   (valor, naipe e '\0') */
+	deck = (Monte)malloc(sizeof(char*) * (n * CARTAS * NAIPES + 1));
+	for (i = 0; i < n * CARTAS * NAIPES + 1; i++) {
+		deck[i] = (char*)malloc(sizeof(char) * 3);
+
+		/* Inicializa a memória alocada com o char '0'. */
+		deck[i][0] = '0';
+		deck[i][1] = '0';
+		deck[i][2] = '\0';
+	}
+	return deck;
+}
+
+/* Retorna a primeira carta de um monte, que é retirada do topo deste. */
+Carta tiraCarta (Monte deck, Baralho bar) {
+	int i, j;
+	char valor, naipe;
+
+	i = 0;
+	valor = deck[0][0];
+	naipe = deck[0][1];
+	while (deck[i][0] != '0' && deck[i][1] != '0') {
+		deck[i][0] = deck[i+1][0];
+		deck[i][1] = deck[i+1][1];
+		i++;
+	}
+
+	if (valor == '0' && naipe == '0') {
+		fprintf(stderr, "erro. o monte esta vazio.\n");
+		return;
+	}
+
+	/* Encontra dentro do baralho a carta que possui o valor e o naipe que foram
+	   retirados do monte.
+	   Essa rotina é necessária pois a imagem da carta está armazenada no Baralho, e não
+	   no Monte. */
+	i = 0;
+	j = 0;
+	while (bar[i][j].naipe != naipe) i++;
+	while (bar[i][j].valor != valor) j++;
+	return bar[i][j];
+}
+
+/* Coloca uma carta no topo de um monte. Retorna o Monte com a nova carta no topo. */
+Monte colocaCarta (int n, Carta c, Monte deck) {
+	unsigned int i = 0;
+	unsigned int cont = 0;
+
+	/* A mensagem de erro é mostrada caso seja tentado empilhar uma carta inexistente */
+	if ((c.naipe != 'P' && c.naipe != 'E' && c.naipe != 'C' && c.naipe != 'O') ||
+		(c.valor != 'A' && c.valor != '2' && c.valor != '3' && c.valor != '4' && 
+		 c.valor != '5' && c.valor != '6' && c.valor != '7' && c.valor != '8' &&
+		 c.valor != '9' && c.valor != 'D' && c.valor != 'J' && c.valor != 'Q' && 
+		 c.valor != 'K')) {
+		fprintf(stderr, "erro. carta inexistente.\n");
+		return;
+	}
+
+	while (deck[i][0] != '0' && deck[i][1] != '0') i++;
+	if (i == 0) {
+		deck[0][0] = c.valor;
+		deck[0][1] = c.naipe;
+		return deck;
+	}
+
+	/* A mensagem de erro é mostrada caso seja tentado empilhar uma carta em uma
+	   pilha cheia. */
+	if (i >= (n * NAIPES * CARTAS) - 1) {
+		fprintf(stderr, "erro. monte lotado, impossivel de empilhar.\n");
+		return;
+	}
+
+	for(; i > 0; i--) {
+		deck[i][0] = deck[i-1][0];
+		deck[i][1] = deck[i-1][1];
+	}
+	deck[0][0] = c.valor;
+	deck[0][1] = c.naipe;
+
+	return deck;
+}
+
+/* Rotina para trocar a carta em deck[i] com a carta em deck[ir].
+   i é a posição atual e ir é a posição que foi randomizada. */
+void troca (Monte deck, int i, int ir) {
+	Monte aux;
+
+	aux = (Monte)malloc(sizeof(char*));
+	aux[0] = (char*)malloc(sizeof(char) * 3);
+	
+	aux[0][0] = deck[i][0];
+	aux[0][1] = deck[i][1];
+	aux[0][2] = deck[i][2];
+
+	deck[i][0] = deck[ir][0];
+	deck[i][1] = deck[ir][1];
+	deck[i][2] = deck[ir][2];
+
+	deck[ir][0] = aux[0][0];
+	deck[ir][1] = aux[0][1];
+	deck[ir][2] = aux[0][2];
+}
+
+/* Gera um monte contendo todas as n*52 cartas embaralhadas em ordem aleatória */
+Monte embaralha (Monte deck) {
+	int i, ir;
+	int numCartas;
+
+	i = 0;
+	while (deck[i][0] != '0' && deck[i][1] != '0') i++;
+	i--;
+	numCartas = i;
+
+	/* As cartas do monte são embaralhadas. */
+	srand(time(0));
+	for (i = 0; i < numCartas; i++) {
+		ir = rand() % (numCartas);
+		troca(deck, i, ir);
+	}
+	return deck;
+}
\ No newline at end of file