Você está na página 1de 17

Relatório

Jogo da Memória

Programação I

30 de Janeiro de 2007

Elaborado Por:

André Lourenço (N.º 60350)


Paulo Mendonça (N.º 60351)
Índice

1. Introdução................................................................................................................. 3
2. Descrição do Jogo..................................................................................................... 3
2.1 Instruções.......................................................................................................... 3
2.2 Compilador utilizado ........................................................................................ 3
2.3 Código Fonte .................................................................................................... 3
2.4 Dificuldades...................................................................................................... 3
3. Conclusão ................................................................................................................. 3
4. Autoria ...................................................................................................................... 3

Página 2 de 17
1. Introdução

O objectivo deste trabalho era por em prática todos os conhecimentos adquiridos ao


longo do semestre na cadeira de Programação I.
O projecto desenvolvido foi o Jogo da Memória em linguagem de programação C.
O jogo consiste em adivinhar os pares das cartas visualizadas no ecrã.

Página 3 de 17
2. Descrição do Jogo
2.1 Instruções

O objectivo no Jogo da Memória é tentar adivinhar os pares possíveis nas cartas, no


menor numero possível de movimentos.
Para melhor percebermos o jogo, o melhor será mesmo colocar algumas imagens:

Imagem Nº1

Os símbolos “|-|” correspondem às cartas. Depois de uma carta virada o símbolo “|-|“
retorna a letra escondida (por exemplo “|A|”). Teremos que ir introduzindo o número da
linha a virar, bem como o numero da coluna a virar. Na imagem 1, que corresponde ao
nível 1, existem 3 linhas e 4 colunas, que dá um total de 6 combinações possíveis.
O numero de níveis disponível neste jogo é 3. Sendo o nível 1 composto por 3 linhas e 4
colunas, o nível 2 por 4 linhas e 6 colunas e o nível 3 por 5 linhas e 8 colunas.

Quando o jogo é executado, aparece o menu principal (Imagem 2) com as opções de “1-
Jogar”, “2- Instruções”, “3- Acerca”, “4- Pontuações” e “9- Sair”.
Para escolher a opção desejada, insira o numero correspondente e prima a tecla ENTER.
A opção 1, após inserir o nome do jogador, é levado para o primeiro nível do jogo (nível
de dificuldade fácil).
A opção 2, descreve resumidamente as instruções do jogo.
A opção 3, mostra informações sobre o jogo (elaboração).

Página 4 de 17
A opção 4, mostra as pontuações dos 5 melhores jogadores (jogares que acabaram o
ultimo nível, com o menor numero de movimentos).
A opção 9, tal como o nome indica sai do jogo.

Imagem Nº2

2.2 Compilador utilizado

O projecto foi inicialmente concebido no compilador “Pelles C”. Após alguns


problemas encontrados com o compilador, utilizamos o “Dev C++”. Note-se que o
projecto foi feito em 2 computadores exactamente iguais, com instalações iguais
(imagem) e o comportamento do compilador “Pelles C” era bem diferente de
computador para computador.

Página 5 de 17
2.3 Código Fonte

O jogo tem um ficheiro principal (JMem.c) onde existe a função main e outras, e
também por uma livraria (jmemlib.h) elaborada por nós, onde se encontram todas as
declarações de outras livrarias a incluir, variáveis globais e funções sobre o jogo.

Código fonte livraria jmemlib.h


/*
nº60350: André Lourenço
nº60351: Paulo Mendonça

Trabalho de Prog1.
30-01-2007
* Ficheiro de congregação das LIBs a incluír.
* Declaração das funções.
* Variàveis globais.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// definição dos niveis


int iNiv1L = 2; // nº de linhas no nivel 1
int iNiv2L = 3; // nº de linhas no nivel 2
int iNiv3L = 4; // nº de linhas no nivel 3
int iNiv1C = 3; // nº de colunas no nivel 1. Tem que ser par
int iNiv2C = 5; // nº de colunas no nivel 2. Tem que ser par
int iNiv3C = 7; // nº de colunas no nivel 3. Tem que ser par

// array de controlo. marca se já foi virada ou não.


int arContr[20][20];

// array de letras. contém as letras.


char arLetra[20][20];

int iLevel = 0; // Variável que marca o Nivel actual do jogo


int iSAIR = 0; // Variável para controlar a saída do jogo.
int bInitArray = 1; // Variável que marca o 1º preenchimento do array
para o jogo.

// variável com o nome utilizador


char cUserName[255];
// variável com nº de movimentos
int iMyScore = 0;

// Funções explicativas sobre o jogo


void cls_ecran(void);
void ajuda(void);
void sobre(void);
int preencher_array(void);
void imprime_array();
void PedirLinhaColuna();

Página 6 de 17
Código fonte JMem.c
/*
nº60350: André Lourenço
nº60351: Paulo Mendonça

Trabalho de Prog1.
30-01-2007
* Main
* limpar ecran
* PedirLinhaColuna
*/

#include <jmemlib.h> //lib a incluir para que o programa funcione

int main()
{
int menu = 0, n = 0;
char cBatota[50], cConteudo[255];

// Menu Principal e suas opções


MenuPrincipal:

fflush(stdin);
system("cls");

printf("Bem-vindo ao Jogo da Memoria!


v1.00 build 505\n\n\n");
printf("Menu Principal (escolha uma das seguintes opcoes):");
printf("\n\n1- Jogar");
printf("\n2- Instrucoes");
printf("\n3- Acerca");
printf("\n4- Ver pontuacoes");
printf("\n9- Para sair\n:>");
OpcaoInvalida:
scanf("%i", &menu);
fflush(stdin);

do
if (menu==9)
return 0;

else if (menu==1){ //pede o nome do jogador


fflush(stdin);
printf("Insira o nome! ");
fgets(cUserName,255,stdin);
iSAIR = 0;
PedirLinhaColuna();
goto MenuPrincipal;
}

else if (menu==2){ //mostra as instruções


system("cls");
printf("Jogo da Memoria\n\nInstrucoes:\n");
printf("O objectivo do jogo e adivinhar os pares das cartas.
Tem de inserir o numero da linha e da coluna que quer virar e depois
tentar virar a carta igual correspondente.");
printf("\nInsira o numero de linha e o numero de coluna que
dseja virar e de seguida pressione ENTER.");
printf("O melhor e mesmo experimentar jogar para praticar!\n");

Página 7 de 17
printf("\nPara voltar ao Menu Principal prima qualquer
tecla.");
system("pause >null");
system("cls");
goto MenuPrincipal;
}

else if (menu==3){ //mostra as informações sobre o jogo


system("cls");
printf("Jogo da Memoria\n\nAcerca:\n");
printf("Este estampantastico, magnifico e espectacular jogo
(programa) foi elaborado\npor:");
printf("\nAndre Lourenco N 60350");
printf("\nPaulo Mendonca N 60351");
printf("\n\n1 Ano - Turma C1");
printf("\nUnI - Engenharia Informatica");
printf("\n\nPara voltar ao Menu Principal prima qualquer
tecla.");
system("pause >null");
system("cls");
goto MenuPrincipal;
}

else if (menu==4){ // mostra as melhores 5 pontuações


system("sort /+1 fMem.txt /O fMemf.txt ");
FILE *fMemf;
fMemf = fopen("fMemf.txt","r+");
system("cls");
// se o ficheiro de pontos nao existir ele mostra a mensagem de que
nao existe
if (fMemf == NULL){
printf("\n\nNao existem pontuacoes\nO melhor e jogar para
ver o seu nome nesta lista!\n\nPara voltar ao Menu Principal, prima
qualquer tecla.");
system("pause>null");
}
else {
printf("Melhores Pontuacoes\n\n");

for (n=1; n < 6; n++){


rewind(fMemf+n);
fgets(cConteudo,sizeof(cConteudo),fMemf);
printf("%s", cConteudo);
}
fclose(fMemf);
printf("\n\nPara voltar ao Menu Principal, prima qualquer
tecla.");
system("pause >null");
}
goto MenuPrincipal;
}

else if (menu==2007){ // opção de batota: esta opção não está


visivel no menu principal mas se introduzida é aceite e serve para
gravar a pontuação e o nome desejado para o ficheiro das pontuações
printf("Parabens! Entrou para o Guiness! Insira
pontuacao e nome no formato xxxx - Nome\n(x sao numeros)\n(ENTER para
terminar): ");
fflush(stdin);
FILE *fMem;

Página 8 de 17
fMem = fopen("fMem.txt", "a+");
fgets(cBatota,50,stdin);
fprintf(fMem, "%s", cBatota);
fclose(fMem);
goto MenuPrincipal;
}
else{
printf("\nA opcao que escolheu nao e valida. Insira a
opcao 1, 2, 3, 4 ou 9!\n:>");
goto OpcaoInvalida;
}
while (menu<=1 || menu>=9);

return 0;
}

int preencher_array(void)
{
int iCountL = 0, iCountC = 0, iTotalCartas = 0, i = 0, x = 0, z
= 0;
int iLinha = 0, iColuna = 0, iL, iC;
char cLetra[51];

fflush(NULL);
srand(time(NULL));
//Definição das strings dos niveis
if (iLevel == 1)
{
strncpy(cLetra,
"AABBCCDDEEFFGGHHJJKKLLMMNNOOPPQQRRSSTTUUVVXXZZWWFF",50);
iL = iNiv1L;
iC = iNiv1C;
} else if (iLevel == 2)
{
strncpy(cLetra,
"ABCDEFGHJKLMNOPQRSTUVXZWABCDEFGHJKLMNOPQRSTUVXZWGS", 50);
iL = iNiv2L;
iC = iNiv2C;
} else
{
strncpy(cLetra,
"AaBbCcDdEeFfGgHhJKkLMmNnOoPpQqRrSsTtUuVvXxWwZzKhCv", 50);
iL = iNiv3L;
iC = iNiv3C;
}

int iPointerContr[iL+1][iC+1];
char iPointerLetra[iL+1][iC+1];

iTotalCartas = ((iL+1) * (iC+1));

for (iCountL = 0; iCountL <= iL; iCountL++){


for (iCountC = 0; iCountC <= iC; iCountC++){
iPointerContr[iCountL][iCountC] = -1;
}
}

for (iCountL = 0; iCountL <= iL; iCountL++){


for (iCountC = 0; iCountC <= iC; iCountC++){

Página 9 de 17
z = 0;
i = rand() % 50; // Rand para escolher uma letra ao
calhas, evita que o array seja preenchido sempre da mesma forma jogo
apôs jogo...
for (x = 1; x <= 2; x++){
iLinha = rand() % iL; // Rand para escolher uma celula
do array aleatoria.
iColuna = rand() % iC; // Rand para escolher uma
celula do array aleatoria.
do{
z++;
iColuna++;
if (iColuna > iC){
iColuna = 0;
iLinha++;
}
if (iLinha > iL) iLinha = 0;
if (iTotalCartas*3 <= z) goto ExitThisCicle;
} while (iPointerContr[iLinha][iColuna] != -1);

iPointerContr[iLinha][iColuna] = 0;
iPointerLetra[iLinha][iColuna] = cLetra[i];
}
}
}

ExitThisCicle:

for (iCountL = 0; iCountL <= iL; iCountL++){


for (iCountC = 0; iCountC <= iC; iCountC++){
arContr[iCountL][iCountC] =
iPointerContr[iCountL][iCountC];
arLetra[iCountL][iCountC] =
iPointerLetra[iCountL][iCountC];

//printf(" %c", arLetra[iCountL][iCountC]); //Batota: Para mostrar as


solucoes quando se escolhe a opcao de jogar

}
printf("\n");
}

fflush(stdin);
//system("pause >null");

return 0;
}

void cls_ecran(void){
fflush(stdin);
system("cls");
}

Página 10 de 17
void PedirLinhaColuna(void){
// Variáveis para a linha e coluna inserida pelo utilizador.
int l1 = 0, c1 = 0, l2 = 0, c2 = 0;

int iCountL = 0, iCountC = 0;


int iL = 0, iC = 0;
int bJogoCompleto = 1;
char xget;

//ciclo dos niveis


Init_Again:
if (iLevel == 1)
{
iL = iNiv1L;
iC = iNiv1C;
} else if (iLevel == 2)
{
iL = iNiv2L;
iC = iNiv2C;
} else
{
iL = iNiv3L;
iC = iNiv3C;
}

if (iSAIR != 0) return;

bJogoCompleto = 1;
for (iCountL = 0; iCountL <= iL; iCountL++){
for (iCountC = 0; iCountC <= iC; iCountC++){
if (arContr[iCountL][iCountC] == 0) bJogoCompleto = 0;
}
}
//mensagem a aparecer se o jogador chegar ao fim do ultimo nivel
(nivel 3)
if (bJogoCompleto == 1 || bInitArray == 1)
{
bInitArray = 0;
iLevel++;
if (iLevel == 4) {
FILE *fMem;
fMem = fopen("fMem.txt","a");
fprintf(fMem, "%04d - %s", iMyScore, cUserName);
fclose(fMem);
system("cls");
printf("Parabens pela pontuacao!\n");
printf("Nunca pensamos que alguem fosse capaz de jogar
isto ate ao fim.\n\n");
printf("Se quiser jogar mais, compre a versao completa!
Sao mais de 40 niveis, com graficos e sons espectaculares!\n");
system("pause >null");
printf("Se ainda esta a ler! Nao se esqueca de fazer o
donativo\n\n");
system("pause >null");
printf("\n\npssst! o donativosito?!! hum?\n\n");
system("pause >null");
return;
}
preencher_array();
goto Init_Again;

Página 11 de 17
}

iMyScore++;

l1 = c1 = l2 = c2 = -1;

Refresh_Jogo:
if (iSAIR != 0) return;

// Limpar ecran e imprimir o array do jogo


cls_ecran();

//quadro de pontuações a aparecer durante o jogo


printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("+-------------------------+\n");
printf("| |\n");
printf("| Nivel - %i |\n", iLevel);
printf("| Movimentos - %04d |\n", iMyScore);
printf("| |\n");
printf("+-------------------------+\n");
printf("\n");
printf("Jogador - %s\n", cUserName);
printf("\n");
printf("'S' para Sair!\n");

// para mostrar no ecran. durante o teste dá jeito para avançar nos


niveis.
for (iCountL = 0; iCountL <= iL; iCountL++){
for (iCountC = 0; iCountC <= iC; iCountC++){
//printf(" %c", arLetra[iCountL][iCountC]); // Batota 2:
para mostrar as solucoes durante o jogo
}
printf("\n");
}
// printf("\n");
// printf("\n");

for (iCountL = 0; iCountL <= iL; iCountL++)


{
for (iCountC = 0; iCountC <= iC; iCountC++)
{
if (arContr[iCountL][iCountC] == 1) printf("|%c| ",
arLetra[iCountL][iCountC]); // Já foi encontrado o par
else if ((iCountL == l1) && (iCountC == c1))
printf("|%c| ", arLetra[iCountL][iCountC]); // Carta escolhida,
portanto mostra a letra...
else if ((iCountL == l2) && (iCountC == c2))
printf("|%c| ", arLetra[iCountL][iCountC]); // Carta escolhida,
portanto mostra a letra...
else printf("|-| ");
// esconder a letra.
}
printf("\n");
}

Página 12 de 17
//pedir coordenadas para a 1ª carta (linha nº X, coluna nº Y)
printf("\n");
if (l1 == -1){
printf("Inserir linha primeira carta.
");
fflush(stdin);
scanf("%c", &xget);
l1 = xget;
if (l1 == 115 || l1 == 83){
iSAIR = 1;
return;
}

l1 = l1 - 49;
if (l1 < 0 || l1 > iL){
printf("\nNumero invalido. Tem que ser entre (1-%i).
", iL+1);
system("pause >null");
l1 = -1;
}
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

if (c1 == -1){
printf("Inserir coluna primeira carta.
");
fflush(stdin);
scanf("%c", &xget);
c1 = xget;
if (c1 == 115 || c1 == 83){
iSAIR = 1;
return;
}

c1 = c1 - 49;
if (c1 < 0 || c1 > iC){
printf("\nNumero invalido. Tem que ser entre (1-%i).
", iC+1);
system("pause >null");
c1 = -1;
}
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

// verificar se a carta já tinha sido escolhida


if (arContr[l1][c1] == 1){
printf("Carta nao disponível. Tente novamente.\n");
system("pause >null");
l1 = c1 = -1;
iMyScore++; // penalizar esta situação no score.
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

//pedir coordenadas para a 2ª carta (linha nº X, coluna nº Y)


if (l2 == -1){

Página 13 de 17
printf("Inserir linha segunda carta.
");
fflush(stdin);
scanf("%c", &xget);
l2 = xget;
if (l2 == 115 || l2 == 83){
iSAIR = 1;
return;
}

l2 = l2 - 49;
if (l2 < 0 || l2 > iL){
printf("\nNumero invalido. Tem que ser entre (1-%i).
", iL+1);
system("pause >null");
l2 = -1;
}
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

if (c2 == -1){
printf("Inserir coluna segunda carta.
");
fflush(stdin);
scanf("%c", &xget);
c2 = xget;
if (c2 == 115 || c2 == 83){
iSAIR = 1;
return;
}

c2 = c2 - 49;
if (c2 < 0 || c2 > iC){
printf("\nNumero invalido. Tem que ser entre (1-%i).
", iC+1);
system("pause >null");
c2 = -1;
}
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

// verificar se a carta já tinha sido escolhida


if (arContr[l2][c2] == 1 || (l1 == l2 && c1 == c2)){
printf("Carta nao disponível. Tente novamente.\n");
system("pause >null");
l2 = c2 = -1;
iMyScore++; // penalizar esta situação no score.
goto Refresh_Jogo; // Refresh para mostrar o conteúdo da
carta.
}

// Marcar no array as cartas escolhidas


if (arLetra[l1][c1] == arLetra[l2][c2]){
arContr[l1][c1] = 1;
arContr[l2][c2] = 1;
printf("MUITO BEM!!!!\n
");

Página 14 de 17
} else {
// as cartas escolhidas são diferentes
printf("As cartas não fazem par!\n");
}

system("pause >null");
goto Init_Again;

return;

2.4 Dificuldades

A nossa maior dificuldade foi lidar com ponteiros. Inicialmente, algumas das variáveis
foram desenhadas para serem apontadores. Com estas variáveis, o programa deixava de
executar da forma pretendida o que nos levou a desistir de utilizar apontadores.
Uma outra dificuldade, foi fazer o sort no ficheiro das pontuações. O pretendido era
colocar as pontuações por ordem crescente baseado no número de movimentos. Depois
de tentar, sem sucesso utilizar apenas comandos em C para fazer o sort, resolvemos
utilizar o comando sort incluído no sistema operativo (system(“sort xxxxx....”);).

Página 15 de 17
3. Conclusão
De forma geral, a elaboração do programa correu como o pretendido (excepto a
utilização de ponteiros e a utilização do sort em ficheiros). Aplicamos todos os
conhecimentos adquiridos nas aulas e complementamos todos esses conhecimentos com
algum estudo de “background”.
Apesar dos problemas encontrados durante a elaboração do programa, este faz
exactamente o que foi inicialmente planeado.

Página 16 de 17
4. Autoria
André Lourenço (N.º 60350)
Paulo Mendonça (N.º 60351)

Alunos do
1º ano do curso de Engenharia Informática
Turma C1
2006 - 2007

Página 17 de 17

Você também pode gostar