Universidade Federal de Minas Gerais Departamento de Ciência da Computação/ICEx Algoritmos e Estruturas de Dados II Prof. Jussara M. Almeida Trabalho Prático 1 Tipos Abstratos de Dados Data de entrega: 01 de setembro de 2008 Valor: 10 pontos Trabalho individual Objetivo: Explorar os conceitos de Tipos Abstratos de Dados (TADs), prática inicial de análise de algoritmos, prática de programação em linguagem C. Descrição do Trabalho Neste trabalho para entendermos os conceitos de TAD discutidos em sala, implementaremos três TADS e os usaremos na implementação de 2 programas diferentes: o jogo da forca e um tradutor. Para isso vocês deverão implementar: um TAD Palavra: este TAD deve representar uma palavra em uma língua específica (inglês ou português). Uma palavra é definida como um conjunto de até M caracteres do alfabeto (a-z, A-Z). um TAD Verbete: este TAD representa um par de palavras, uma em português e a sua tradução em inglês. um TAD Dicionário: este TAD contém um conjunto de verbetes. Algumas das funções que você deverá implementar no TAD Palavra são: int verificapalavra(palavra p); Verifica se p é realmente uma palavra, isto é, contém apenas caracteres do alfabeto. Retorna 1, caso p seja palavra, e 0, caso contrário. int verificalingua(palavra p); Retorna INGLES se a palavra p for em inglês e PORTUGUES, caso contrário. INGLES e PORTUGUES são constantes númericas que você deve definir. int retornaproxposletra(palavra p, char Letra, int inicio); Dada uma palavra p, identifica se ela possui a letra Letra a partir da posição início. Caso possua, retorna a posição da próxima instância (ocorrência) da letra. Caso contrário, retorne -1. Algumas das funções que você deverá implementar no TAD Verbete são: void inicializaverbete(verbete *v, Palavra p1, Palavra p2) Inicializa o Verbete v com as palavras p1 e p2, garantindo que elas estejam em línguas diferentes, uma em PORTUGUES, outra em INGLES.
Palavra obtemtraducao(verbete v, Palavra p) Dada a palavra p contida no verbete v, retorne a sua tradução. Palavra retornaport(verbete v) Dado um verbete v, retorna a tradução em português. Palavra retornaing(verbete v) Dado um verbete v, retorna a tradução em inglês. Algumas das funções que você deverá implementar no TAD Dicionário são: void InicializaDicionario(Dicionario *dic) Inicializa o dicionário dic como vazio. int CarregaDic(char *NomeArq, Dicionario *dic); Dado um string contendo o nome de um arquivo, abre o arquivo e carrega o dicionário em dic. Retorna 1, caso tenha conseguido carregar corretamente o dicionário e 0 se não conseguir. int InsereDic(Dicionario *dic, Verbete v); Dado um dicionário dic e um Verbete v, acrescenta-a no dicionário. Retorna 1, caso tenha conseguido acrescentá-la (caiba no dicionário) e 0 se não conseguir. void RetiraDic(Dicionario *dic, Palavra *p); Dado um dicionário dic e uma palavra p, retira o VERBETE que contenha p do dicionario dic. Retorna 1, caso tenha conseguido retirá-la e 0 se não conseguir (e.x. não a encontrar). int retornatraducaoport(palavra p, Palavra *p2); Dada uma palavra em inglês p, retorna 1, caso tenha conseguido traduzi-la para português, inserindo em p2 a sua tradução. Retorna 0 se não conseguir (e.x. não a encontrar). int retornatraducaoing(palavra p, Palavra *p2); Dada uma palavra em português p, retorna 1, caso tenha conseguido traduzi-la para inglês inserindo em p2 a sua tradução. Retorna 0 se não conseguir (e.x. não a encontrar). Palavra SorteiaPalavraPort(TipoDic dic); Dado um dicionário sorteia um verbete e retorna o seu significado em português. Palavra SorteiaPalavraIng(TipoDic dic); Dado um dicionário sorteia um verbete e retorna o seu significado em inglês.
Estas são as funções básicas necessárias. Algumas outras poderão ser úteis na implementação dos programas. Sinta-se à vontade para implementar outras funções que achar necessárias, seja para a interface dos TADs, seja para a implementação de outras funções definidas. Sinta-se à vontade também para alterar a passagem de parâmetros das funções definidas caso achar adequado. Lembre-se que (1) os tipos existentes no TAD só podem ser diretamente acessados pelas funções disponibilizadas na interface do TAD; e (2) as funções do TAD só devem ter conhecimento sobre o próprio TAD e não dos programas que fazem uso deste. Jogo da Forca O jogo da forca deverá funcionar da seguinte maneira: 1. O jogo primeiro deve pedir que o usuário escolha a língua do jogo (INGLES ou PORTUGUES) 2. O jogo selecionar aleatoriamente uma palavra na língua escolhida, que esteja disponível no dicionário e apresentar para o usuário o número de letras na palavra. 3. O usuário deverá indicar letras que acredita ter na palavra (1 por vez). 4. A cada letra, caso ela esteja presente na palavra todas as suas ocorrências deverão ser mostradas ao usuário nas posições corretas. 5. A cada jogada, as letras que já foram indicadas devem ser mostradas em ordem alfabética. 6. A partir do número de letras utilizadas para adivinhar a palavra o jogo, apresenta uma mensagem ao usuário. 7. Ao final o jogo deverá indicar a palavra, número de erros cometidos e uma mensagem ao usuário. Por exemplo, uma sugestão seria: 0 erros: Parabéns!!! Você está fera! 1 a 2 erros: Excelente, você está craque para adivinhar palavras. 3 a 5 erros: Muito bom, você acertou! 5 a 8 erros: Que palavra difícil! Será que consegue acertar com menos tentativas... mais de 8 erros: Você precisa praticar mais... Outra opção seria desenhar (com caracteres) o bonequinho da forca. O jogo deverá apresentar o modo JOGO em que o usuário interage para jogar, e o modo TESTE em que a palavra selecionada é apresentada no início do jogo para permitir o teste da corretude do jogo. Exemplo de jogo: Suponha que a língua escolhida tenha sido PORTUGUES e que a palavra sorteada tenha sido interessante. Assim, o jogo deverá começar mostrando ao usuário:
O usuário indica a letra A. O jogo então mostra: Bom palpite! A Letras indicadas: A Usuário indica a letra O. O jogo então mostra: Pena, mas esta letra não está na palavra. A Letras indicadas: A, O Usuário indica a letra C. O jogo então mostra: Pena, mas esta letra não está na palavra. A Letras indicadas: A, C, O Usuário indica a letra E. O jogo então mostra: Bom palpite! E E A E Letras indicadas: A, C, E, O Ao final, quando o usuário terminar, o jogo apresentaria:
Você acertou!!! Que palavra difícil! Será que consegue acertar com menos tentativas... I N T E R E S S A N T E Letras indicadas: A, C, E, I, L, M, N, O, R, S, T, U Número de palpites errados: 5 Quer jogar novamente (S/N)? Lembre-se que para que seu jogo agrade os usuários ele deve ter uma boa interface. A interface mostrada é um exemplo, fiquem à vontade para fazer uma interface com seu estilo (pode ser ASCII mesmo). De todo jeito, sua interface deverá apresentar as regras, status a cada jogada e mensagens claras. Além disso, ela deverá deixar o usuário interromper o jogo a qualquer momento. No fim de uma palavra o usuário deverá dizer se quer jogar novamente ou terminar o jogo. Tradutor Você deverá construir um tradutor que deverá fazer uso também dos TADs implementado para traduzir um texto. Para isso, o sistema deverá receber um arquivo texto (caracter ASCII) e traduzir palavra a palavra o texto de português para inglês ou de inglês para português. A mesma saída deverá ser impressa na tela e em um arquivo de saída. (Os arquivos de entrada e saída do tradutor deverão ser ambos arquivos ASCII.) Quando a palavra lida não existir no dicionário o tradutor deverá manter a palavra original. Os caracteres especiais (aqueles que não são letras, e.g. pontuação, aspas, etc.) também devem ser mantidos como no original. Você pode assumir que as palavras no arquivo de entrada e no dicionário não estarão acentuadas. Por exemplo, suponha o dicionário: aniversario - birthday bolo cake de of e is eu I festa party gosto like hoje today meu - my presente gift Neste caso, se o usuário entrar um arquivo contendo: Hoje e meu aniversario. Eu adoro bolo. O sistema vai gerar a saída:
Today is my birthday. I adoro cake. O usuário pode então interagir com o sistema para entrar uma nova palavra e acrescentar adoro love no dicionário. Fazendo a tradução do mesmo arquivo, então se obteria: Today is my birthday. I love cake. Considerações: O dicionário para ambos os sistemas deverá ser carregado a partir de um arquivo. Em outras palavras dado um arquivo em código ASCII no formato abaixo, o sistema deverá gerar na memória o dicionário. Formato <palavra português 1> <palavra inglês 1> <palavra português 2> <palavra inglês 2> <palavra português 3> <palavra inglês 3>... <palavra português n> <palavra inglês n> Exemplo aniversario birthday bolo cake de of e is eu I festa party gosto like hoje today meu my presente gift Observe que o arquivo contendo o dicionário deve ser carregado automaticamente a partir de um dicionário no mesmo diretório do programa principal de nome dicionario.txt. O diconário deverá conter apenas palavras simples, sem acento e sem hífen. Palavras compostas ou expressões não precisam ser consideradas. Requisitos obrigatórios do trabalho: 1. Cada TAD deverá ser implementado independentemente, em arquivos arquivos.c e.h 2. Os programas do Jogo da Forca e Tradutor devem fazer uso do TAD criado. Cada programa estará em um arquivo à parte. 3. O trabalho é individual. Trabalhos copiados serão penalizados conforme anunciado em sala. 4. O trabalho deve ser desenvolvido na linguagem C e compiladores devc ou gcc, conforme especificado no site da disciplina. 5. O programa não deve fazer uso dos comando goto ou break. 6. O programa não deve conter variáveis globais. 7. Caso apareçam números fixos no código, estes devem ser definidos como constantes.
Soluções que não correspondam a implementações de TADs Tipos Abstratos de Dados serão duramente penalizados por não atenderem à especificação. O que deve ser entregue: Além do que está descrito na página Regras para realização e entrega dos TPs, no site da disciplina, o seu relatório deve incluir, especificamente: 1. Capa: contendo o nome do trabalho, o nome do aluno, número de matrícula, turma e email. 2. Introdução: descrição do problema a ser resolvido e visão geral sobre o funcionamento do programa. 3. Implementação: descrição sobre a implementação do programa: a. Devem ser apresentados os TADs. Caso novas funções tenham sido incluídas, elas devem ser explicadas. juntamente com uma justificativa sobre sua necessidade. b. Deve ser apresentada também a estrutura de dados utilizada (de preferência com diagramas ilustrativos), o funcionamento das principais funções e procedimentos utilizados; c. Apresentar uma idéia geral do funcionamento do sistema (na linha de um manual do usuário); d. Apresentar decisões tomadas relativas aos casos e detalhes de especificação que porventura estejam omissos no enunciado. 4. Estudo de Complexidade: estudo da complexidade do tempo de execução dos procedimentos implementados e do programa como um todo (notação O). Para isso, considere que o tamanho do dicionário como sendo n e de cada palavra como sendo m. 5. Conclusão: comentários gerais sobre o trabalho, benefícios observados no uso do TAD e as principais dificuldades encontradas em sua implementação. 6. Bibliografia: bibliografia utilizada para o desenvolvimento do trabalho, incluindo sites da Internet se for o caso Obs: Consulte as dicas do Prof. Nívio Ziviani de como deve ser feita uma boa implementação e documentação de um trabalho prático: http://www.dcc.ufmg.br/~nivio/cursos/aed2/roteiro/ A entrega será realizada de forma eletrônica, conforme descrição no site da disciplina. Comentários Gerais: 1. Comece a fazer este trabalho logo, enquanto o problema está fresco na memória e o prazo para terminá-lo está tão longe quanto jamais poderá estar. 2. Clareza, indentação e comentários no programa também vão valer pontos. 3. Penalização por atraso: regra especificada no site da disciplina.