Você está na página 1de 9

Relat´orio do Trabalho Pr´atico

Jo˜ao Pereira Francisco Mendes

3 de Janeiro de 2015

Conte´udo

1 Introdu¸c˜ao

1

2 Desenvolvimento do Projeto

 

1

2.1 Tarefa A .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

1

2.2 Tarefa B .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

2

2.3 Tarefa C .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

3

2.4 Tarefa D .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

5

2.5 Tarefa E

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

7

2.6 Makefile e runtests.sh

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

8

3 Conclus˜ao

9

1 Introdu¸c˜ao

Este relat´orio descreve o processo de desenvolvimento do trabalho pr´atico reali- zado no ˆambito da unidade curricular Laborat´orios de Inform´atica I. Neste pro- jeto, aplicamos os conhecimentos adquiridos ao longo do semestre, e evolu´ımos as nossas capacidades de programa¸c˜ao, gest˜ao de projetos, uso de comandos UNIX, uso de sistemas de controle de vers˜oes e capacidades de trabalho em grupo. Quanto ao projeto em si, este ´e inspirado no jogo LightBot facilmente acess´ıvel online e que consiste em criar sequˆencias de comandos que possibilitem ao robot ligar todas as luzes de um tabuleiro.

2 Desenvolvimento do Projeto

Neste cap´ıtulo, passamos ent˜ao a expor a forma como o nosso trabalho funciona.

2.1 Tarefa A

Nesta fase do projeto foi-nos pedido que fizessemos um programa que validasse o input fornecido. Para tal, criamos a fun¸c˜ao tarefa.

1

Caso o input passado fosse uma lista vazia, era devolvido 1, ou seja, havia um erro na primeira linha. Caso contr´ario, se o tabuleiro fosse uma lista va- zia, ou seja, se n˜ao houvesse nenhuma linha constitu´ıda apenas por caracteres alfab´eticos, ent˜ao daria erro na primeira linha. Se houvesse uma parte v´alida

correspondente ao tabuleiro, i.e. uma ou mais linhas com caracteres alfab´eticos, ent˜ao a fun¸c˜ao verificaLength iria verificar se as linhas do tabuleiro tinham todas o mesmo tamanho e se n˜ao tivessem, devolvia o Int correspondente `a primeira linha com comprimento diferente. Sen˜ao, esta fun¸c˜ao devolvia 0 e a fun¸c˜ao validaTab prosseguia.

A seguir, ia correr a fun¸c˜ao ver posInicial que verifica se linha da posi¸c˜ao

inicial ´e v´alida da seguinte forma: se o char que corresponde `a orienta¸c˜ao inicial for ou ’N’ ou ’S’ ou ’E’ ou ’O’ e se os dois primeiros elementos do resultado de words(posi¸c~aoInicial) aplicada ao tabuleiro em quest˜ao correspondem a duas coordenadas v´alidas, (i.e. se forem dois n´umeros inteiros e a posi¸c˜ao correspon- dente estiver dentro do tabuleiro) ent˜ao a linha correspondente `a posi¸c˜ao inicial ´e v´alida e vai passar para a verifica¸c˜ao da pr´oxima condi¸c˜ao. Caso contr´ario, d´a o n´umero da linha da posi¸c˜ao inicial.

A seguir, os comandos s˜ao verificados pela fun¸c˜ao valida linhaCom aplicada

ao tabuleiro. Esta fun¸c˜ao verifica se todos os elementos da linha de comandos s˜ao ou ’A’ ou ’S’ ou ’D’ ou ’E’ ou ’L’. Se n˜ao forem, ent˜ao ´e devolvido o Int que corresponde `a linha dos comandos. Caso contr´ario, esta fun¸c˜ao devolve 0 e chegamos `a ultima´ avalia¸c˜ao que verifica se h´a mais linhas depois dos comandos. Se houver, ent˜ao ´e devolvido o Int que corresponde `a primeira linha imediatam- nete a seguir `a lista de comandos. Caso contr´ario, ´e devolvido 0 e o tabuleiro ´e considerado v´alido.

2.2 Tarefa B

Nesta fase, tinhamos de criar um programa que dado um input v´alido, era devolvida a pr´oxima posi¸c˜ao do robot se o primeiro comando fosse v´alido e ERRO caso contr´ario. Este programa ´e constitu´ıdo pelas seguintes fun¸c˜oes principais:

estadoInicial que dado um tabuleiro, cria um tuplo com as coordenadas

e a orienta¸c˜ao com que o Robot come¸ca o jogo;

verPosicao que dado um tabuleiro e um estado, i.e., um tuplo constitu´ıdo

pela posi¸c˜ao em que o Robot se encontra e a orienta¸c˜ao do mesmo, devolve

a letra correspondente `a posi¸c˜ao;

converteEstado

guinte forma:

que dado um estado,

>>>

converteEstado

(1,1,’N’)

"1

1

N"

converte-o para uma string da se-

proxPosicao

que dado um tabuleiro e o

estado atual do Robot,

devolve

a pr´oxima posi¸c˜ao dependendo da orienta¸c˜ao;

2

Ent˜ao, a fun¸c˜ao tarefa funciona da seguinte forma:

1. Se o primeiro comando fˆor um ’L’ e se a letra correspondente `a posi¸c˜ao inicial fˆor mai´uscula, ent˜ao estamos perante uma luz que vai ser ligada e a posi¸c˜ao e orienta¸c˜ao do robot v˜ao-se manter inalteradas, pelo que vai ser devolvida a string correspondente `a posi¸c˜ao inicial, i.e. converteEstado

(estadoInicial

t) em que

t ´e o

input.

Sen˜ao passa-se `a pr´oxima fase;

2. Se o primeiro comando fˆor ’S’ e a pr´oxima posi¸c˜ao est´a dentro do tabuleiro

e se altura do tabuleiro no estado inicial fˆor superior `a da pr´oxima posi¸c˜ao

ou se fˆor igual `a altura da pr´oxima posi¸c˜ao subtra´ıda 1 ent˜ao ´e poss´ıvel o

robot saltar e ´e mostrada a string correspondente `a pr´oxima posi¸c˜ao.Caso contr´ario, passa-se `a pr´oxima condi¸c˜ao;

3. Caso o primeiro comando seja ’A’, se a pr´oxima posi¸c˜ao estiver dentro

do tabuleiro e a altura da posi¸c˜ao atual fˆor igual `a da pr´oxima, ent˜ao

´e poss´ıvel que o robot avance e ´e devolvida a string correspondente ao pr´oximo estado. Caso contr´ario, continua para o passo 4;

4. No caso do primeiro comando ser ’E’, ´e aplicada uma rota¸c˜ao no estado

inicial (a posi¸c˜ao mant´em-se, mudando apenas a orienta¸c˜ao) e ´e imprimida

a string correspondente ao segundo estado. Caso contr´ario passa-se para

a ultima´ verifica¸c˜ao;

5. Se o primeiro comando passado ao robot fˆor ’D’ ent˜ao aplica-se uma

rota¸c˜ao `a direita ao estado inicial e imprime-se esse estado. Caso contr´ario,

´e imprimida a string ERRO.

2.3 Tarefa C

Nesta tarefa, foi-nos pedido que cri´assemos um programa que dado um input constitu´ıdo pelo tabuleiro, pela posi¸c˜ao inicial e pelos comandos, verificasse se estes comandos ligavam as luzes todas do tabuleiro. Para tal, cri´amos a fun¸c˜ao tarefa que chama a fun¸c˜ao aux aplicada ao input, `a lista de comandos, ao n´umero de jogadas corretas (acumulador que come¸ca em 0), `a lista de luzes do tabuleiro e ao resultado da tarefa B aplicada ao tabuleiro e ao primeiro elemento da lista de comandos. A fun¸c˜ao tB faz o mesmo que faz a fun¸c˜ao tarefa na parte B mas sofreu algumas altera¸c˜oes para que quando fosse ligada uma luz, a string devolvida contivesse um ’L’ no ´ınicio e depois o estado do robot. Antes de passar `a descri¸c˜ao geral do programa, devem ser explicadas duas fun¸c˜oes muitos importantes ao funcionamento do mesmo:

fun¸c˜ao lampadas que dado um tabuleiro, calcula uma lista de strings cujos elementos correpondem `as posi¸c˜oes onde existem luzes. Esta fun¸c˜ao funci- ona recursivamente e n˜ao faz mais do que varrer o tabuleiro `a procura de letras mai´usculas e, caso as encontre, guarda as coordenadas da posi¸c˜ao correspondente.

3

fun¸c˜ao proxTab que dado uma lista de strings com o tabuleiro, estado inicial e lista de comandos, calcula a lista neste formato para o pr´oximo estado, i.e. se a lista de comandos fˆor vazia ent˜ao o resultado ´e igual `a lista passada `a fun¸c˜ao. Se o primeiro comando fˆor aplic´avel ent˜ao d´a a lista constitu´ıda pelo tabuleiro, pelo pr´oximo estado e pela tail da lista de comandos. Caso contr´ario, devolve a lista com o tabuleiro, estado inicial e a tail da lista de comandos.

A fun¸c˜ao aux aplicada aos parˆametros descritos acima funciona da seguinte forma:

1. Se a lista de luzes fˆor vazia, ent˜ao ´e devolvida a palavra FIM juntamente com o n´umero de jogadas corretas efetuadas.

2. Caso contr´ario, se a lista de comandos fˆor vazia, ou seja, se todos os comandos tiverem sido executados, ent˜ao significa que as luzes n˜ao foram todas ligadas e por isso ´e imprimido INCOMPLETO.

3. Se o primeiro elemento da string resultante da aplica¸c˜ao da fun¸c˜ao tB ao conjunto formado pelo tabuleiro e estado atual do robot e ao primeiro comando da lista de comandos fˆor um ’L’ (relembrando a altera¸c˜ao que fizemos `a fun¸c˜ao da tarefa B referida acima) ent˜ao:

Se essa luz estiver na lista de luzes ent˜ao ainda n˜ao foi ligada e por isso ´e devolvida a string correspondente `a posi¸c˜ao onde est´a o robot usando a fun¸c˜ao limpa que remove o ’L’ e a orienta¸c˜ao do resultado da fun¸c˜ao tB e de seguida calcula-se o resultado da fun¸c˜ao aux aplicada ao resultado de proxTab , `a tail da lista de comandos, ao n´umero de jogadas corretas mais 1, `a lista de luzes sem a luz que foi agora ligada e ao resultado de tB aplicada ao resultado da fun¸c˜ao proxTab

t em que t ´e o input.

Se essa luz n˜ao estiver na lista de luzes significa que j´a foi ligada e que agora vai ser desligada. Ent˜ao ´e imprimida uma string com as coordenadas da luz e calcula-se o resultado da fun¸c˜ao aux aplicada ao resultado de proxTab, `a tail da lista de comandos, ao n´umero de jogadas corretas mais 1, `a lista de luzes com a luz que foi agora des- ligada e ao resultado de tB aplicada ao resultado da fun¸c˜ao proxTab

t em que t ´e o input.

4. Se a condi¸c˜ao referida no ponto 3 n˜ao fˆor cumprida, verifica-se se a aplica¸c˜ao do primeiro comando da lista de comandos ´e poss´ıvel e se for, chama-se recursivamente a fun¸c˜ao aux aplicada ao proxTab da lista com o tabuleiro, estado atual e lista de comandos, `a tail da lista de comandos, ao n´umero de jogadas corretas mais um, `a lista de luzes por ligar e `a tB aplicada ao resultado de proxTab.

5. Se nenhuma das condi¸c˜oes anteriores ´e verificada, ent˜ao chama-se a fun¸c˜ao aux com os mesmos argumentos com que foi chamada mudando apenas a lista de comandos que passa a ser a tail dessa lista.

4

Esta fun¸c˜ao vai correr recursivamente at´e ligar todas as luzes ou at´e esgotar

os comandos.

2.4 Tarefa D

O objetivo desta tarefa era criar um programa que dado um input constitu´ıdo

pelo tabuleiro e pelo estado inicial, cria uma lista de comandos que liga todas as luzes. Com esse fim em vista, pr´ocuramos utilizar um algoritmo que funcionasse para todos os casos poss´ıveis, i.e. em que todas as lˆampadas s˜ao acess´ıveis ao

robot e acabamos por implementar uma solu¸c˜ao inspirada no algoritmo A*. Ent˜ao, a nossa tarefa funciona da seguinte forma:

1. Dado o input, a fun¸c˜ao tarefa chama a fun¸c˜ao lista comandos aplicada aos parˆametos tabuleiro, posi¸c˜ao inicial (passada como um par de inteiros), orienta¸c˜ao inicial e a lista de luzes do tabuleiro calculada pela fun¸c˜ao lista luzes, parecida com a que utilizamos anteriromente.

 

´

2.

E

ent˜ao calculado o resultado de lista comandos que ´e uma fun¸c˜ao re-

cursiva que calcula os comandos necess´arios para chegar da posi¸c˜ao inicial at´e `a posi¸c˜ao que ´e o primeiro elemento da lista de luzes e depois chama-se recursivamente para calcular os comandos a partir da primeira luz at´e `a segunda e assim sucessivamente at´e percorrer todas as luzes. Note-se que

o ultimo´ elemento da lista de comandos necess´arios para passar de uma

posi¸c˜ao `a outra ´e um ’L’, ou seja, quando chega aos destinos que s˜ao as luzes, estas s˜ao ligadas.

Esses comandos s˜ao calculados atrav´es de caminhos, i.e. uma lista de pares

de posi¸c˜oes em que a primeira posi¸c˜ao do par ´e a origem e a segunda ´e a pr´oxima

posi¸c˜ao. Note-se que a distˆancia do ponto de origem ao ponto seguinte ´e sempre 1 e o movimento entre os dois ´e sempre poss´ıvel. A fun¸c˜ao respons´avel por con- verter um caminho numa lista de comandos ´e a converte comandos que dado um caminho (do tipo [(Pos,Pos)]) e a orienta¸c˜ao inicial e o tabuleiro, converte em lista de comandos necess´arios a percorrer esse caminho.

Ent˜ao, dadas duas posi¸c˜oes como conseguimos obter um caminho v´alido entre as duas?

Os caminhos s˜ao criados a partir de listas de posi¸c˜oes consecutivas e acess´ıveis ao

robot atrav´es da fun¸c˜ao converte caminhos.

E nesta parte que entra em a¸c˜ao

a fun¸c˜ao a est’ inspirada no algoritmo A* que calcula a lista de posi¸c˜oes que formar˜ao o caminho. Esta fun¸c˜ao n˜ao faz mais que chamar a fun¸c˜ao a est aux com um parˆametro predefinido que vai ser explicada depois de explicar o funci- onamento da fun¸c˜ao a est (n˜ao confundir com a est’). A fun¸c˜ao a est, dado um tabuleiro, uma posi¸c˜ao inicial, uma posi¸c˜ao pre- tendida, uma lista de posi¸c˜oes percorridas pelo robot (que dever´a ser [ ] na primeira itera¸c˜ao da fun¸c˜ao), doravante conhecida como lista aberta, a lista de posi¸c˜oes que o robot tem de percorrer para chegar `a posi¸c˜ao atual, doravante

conhecida como lista fechada e que tamb´em dever´a ser [ ] na primeira itera¸c˜ao,

´

5

esta fun¸c˜ao calcula as posi¸c˜oes que o robot deve percorrer para chegar `a posi¸c˜ao pretendida a partir da inicial da seguinte forma:

1. Se a posi¸c˜ao pretendida estiver na lista fechada, ent˜ao significa que j´a se alcan¸cou a posi¸c˜ao pretendida e o algoritmo termina. Sen˜ao, passa-se para

o passo 2.

2. Se n˜ao existirem movimentos poss´ıveis a partir da posi¸c˜ao atual que n˜ao estejam na lista aberta e na lista fechada, i.e. se n˜ao existirem posi¸c˜oes acess´ıveis que ainda n˜ao tenham sido percorridas, ent˜ao devolve a lista com as posi¸c˜oes que o robot percorreu at´e chegar `a pois¸c˜ao onde est´a (esta ultima´ posi¸c˜ao est´a inclu´ıda na lista). Note-se que nestes casos, o resultado n˜ao ´e v´alido mas ser´a util´ para o c´aculo de um caminho v´alido atrav´es de outra fun¸c˜ao explicada mais `a frente.

3. Caso hajam posi¸c˜oes poss´ıveis que ainda n˜ao tenham sido percorridas, adiciona-se a posi¸c˜ao atual `a lista aberta e ´e escolhida a posi¸c˜ao poss´ıvel que tem menor distˆancia (valor absoluto da diferen¸ca dos valores das co- ordenadas) `a posi¸c˜ao objetivo para a nova posi¸c˜ao e adiciona-se `a lista fe-

´

chada.

nova posi¸c˜ao, `a posi¸c˜ao objetivo e `as listas aberta e fechada alteradas. Esta fun¸c˜ao vai correr recursivamente at´e ser encontrado um caminho poss´ıvel ou at´e chegar a um estado em que n˜ao existem movimentos poss´ıveis.

E ent˜ao chamada recursivamente a fun¸c˜ao aplicada ao tabuleiro, `a

>>>

Exemplo:

a_est

["BbbC","Cccb","aaba","aaaa"]

(3,0)

(0,3)

[]

[]

[(2,0),(1,0),(0,0),(0,1),(1,1),(2,1),(2,2),(1,2),(0,2),(0,3)]

>>>

a_est

[(1,0)]

["aaaa","acca","acca","acca","aaca"]

(0,0)

(3,0)

[]

[]

No primeiro caso, facilmente se observa que foi encontrado um caminho poss´ıvel. J´a no segundo, o resultado ter´a de ser tratado por uma fun¸c˜ao diferente para que um caminho v´alido seja obtido. Passo agora a explicar a fun¸c˜ao a est aux que dado um tabuleiro, a posi¸c˜ao inicial, a posi¸c˜ao pretendida e uma lista que corresponde `a lista aberta:

Se a fun¸c˜ao a est encontrou um caminho da posi¸c˜ao inicial at´e `a preten- dida (i.e. se a posi¸c˜ao pretendida faz parte da lista de posi¸c˜oes calculadas), insere a posi¸c˜ao inicial na primeira posi¸c˜ao da lista de posi¸c˜oes resultante da fun¸c˜ao a est e o algoritmo acaba, sendo que o resultado pode ser agora trabalhado pela fun¸c˜ao converte caminhos;

Caso contr´ario, vai ser calculado recursivamente, at´e obter uma solu¸c˜ao,

resultado da fun¸c˜ao a est aplicada aos mesmos pontos e tabuleiro mas

posi¸c˜ao do resultado anterior, fun-

cionando como uma restri¸c˜ao sobre os movimentos poss´ıveis na pr´oxima vez que executar a fun¸c˜ao.

o

em que a lista aberta contem a ultima´

6

Usando o algoritmo descrito em acima conseguimos resolver todos os casos de teste que concebemos e conseguimos tamb´em obter 20 pontos na avalia¸c˜ao do mooshak.

2.5 Tarefa E

Nesta tarefa, foi-nos proposto criar um programa que dado um input (cons- titu´ıdo pelo tabuleiro, estado inicial e lista de comandos), gera o c´odigo de um documento html onde ´e poss´ıvel visualizar o tabuleiro em 3D usando a fra- mework X3DOM. Para tal, definimos 3 listas de Strings que v˜ao ser comuns a todos os docu- mentos html:

cabecalho - Esta parte do c´odigo ´e respons´avel pela importa¸c˜ao das bibli- otecas necess´arias ao funcionamento do X3DOM e `a defini¸c˜ao de outras caracter´ısticas da p´agina html;

pontos - Parte do c´odigo respons´avel pela defini¸c˜ao das shapes que v˜ao formar o tabuleiro e da forma do robot;

fim - parte ”burocr´atica”necess´aria ao documento para que a estrutura da p´agina esteja correta;

Dado um input, a fun¸c˜ao tarefa vai juntar estas listas de strings comuns a todos os documentos com as partes var´aveis. Estas partes vari´aveis s˜ao geradas

pela fun¸c˜ao geraHtml, que cria o c´odigo referente ao tabuleiro, e pela gerAnim, que cria o c´odigo respons´avel pela anima¸c˜ao do robot.

A fun¸c˜ao geraHtml recebe uma lista de triplos em que os dois primeiros

elementos s˜ao do tipo Int e o terceiro ´e um Char. O formato desta lista coincide com o resultado da fun¸c˜ao processa que dado um tabuleiro , devolve uma lista de triplos em que os dois primeiros elementos s˜ao uma posi¸c˜ao do tabuleiro

e o terceiro ´e a letra correspondente `a posi¸c˜ao. Na fun¸c˜ao tarefa, a fun¸c˜ao geraHtml ´e passada com o argumento que ´e o resultado da fun¸c˜ao processa aplicada ao tabuleiro que est´a no input.

A fun¸c˜ao geraHtml aplicada a uma lista do tipo [(Int, Int, Char)] aplica

a todos os elementos da lista a fun¸c˜ao aux que funciona da seguinte forma:

1. Se a altura da posi¸c˜ao atual fˆor 0, se houver uma luz naquela posi¸c˜ao ent˜ao gera o c´odigo html respons´avel por criar um paralel´ıpipedo amarelo, que simboliza a existˆencia de luz. Se n˜ao houver uma luz, ent˜ao gera o c´odigo html respons´avel por criar um paralel´ıpipedo azul, que indica que n˜ao existe uma luz naquela posi¸c˜ao. Depois a fun¸c˜ao termina.

2. Caso contr´ario, se a posi¸c˜ao que queremos gerar corresponde a uma luz e est´a no topo do tabuleiro, i.e. n˜ao existem paralelip´ıpedos gerados acima do atual ent˜ao ´e gerado um paralel´ıpipedo amarelo e chama-se a fun¸c˜ao aux para gerar as shapes que dever˜ao ficar abaixo da que foi gerada agora.

7

3. Se nenhuma das condi¸c˜oes anteriores se verificar, ent˜ao gera-se a shape correspondente `a posi¸c˜ao sem luz para a altura atual e calcula-se as res- tantes shapes que dever˜ao ficar abaixo chamando recursivamente a fun¸c˜ao aux.

Desta forma, ´e criado o tabuleiro todo. Para gerar o robot e as anima¸c˜oes correspondentes, usamos a fun¸c˜ao gerAnim. Esta fun¸c˜ao recebe o input da fun¸c˜ao tarefa e devolve o c´odigo html com a estrutura necess´aria ao funciona- mento das anima¸c˜oes e define a dura¸c˜ao da anima¸c˜ao, as posi¸c˜oes por onde deve passar o robot, os tempos em que devem ser executadas anima¸c˜oes e rota¸c˜oes e de quantos graus devem ser essas rota¸c˜oes.

A dura¸c˜ao da anima¸c˜ao ´e diretamente proporcional ao n´umero de comandos

passados ao robot e os valores da key da PositionInterpolator (mecanismo respon´avel por gerar as transla¸c˜oes do robot) s˜ao obtidos adicionando sempre 1 dividido pelo comprimento da lista de comandos ao valor anterior, enquanto que este ´e menor que 1. As posi¸c˜oes para a keyValue s˜ao obtidas atrav´es da fun¸c˜ao posicoes que dado o estado inicial, a lista de comandos a execu- tar e o tabuleiro cria uma string com todas as posi¸c˜oes por onde o robot deve passar. Os valores para a key da orientationInterpolator (mecanismo res- pons´avel pelas rota¸c˜oes do robot) s˜ao obtidos filtrando os valores da key da PositionInterpolator em que ocorre uma rota¸c˜ao, i.e. ´e executado um co- mando ’D’ ou ’E’ e os valores para a keyValue s˜ao obtidos atrav´es da aplica¸c˜ao das rota¸c˜oes `a orienta¸c˜ao original atrav´es da fun¸c˜ao lista angulos. Desta forma, a fun¸c˜ao tarefa gera-se a representa¸c˜ao visual do tabuleiro. Note-se que o mooshak atribui Presentation Error `a nossa tarefa E, no en- tanto a estrutura do html ´e v´alida e a representa¸c˜ao gr´afica do tabuleiro funciona corretamente.

2.6 Makefile e runtests.sh

Quando ´e executado o programa make, os programas das diferentes tarefa v˜ao ser compilados e v˜ao ser corridos v´arios testes atrav´es do script runtests.sh que est´a na pasta tests. Depois ´e gerada a documenta¸c˜ao haddock na pasta doc

e o relat´orio ´e convertido para pdf.

O script runtests.sh verifica se existe um ficheiro com extens˜ao .out e se

houver, compara o conte´udo desse ficheiro com o output da tarefa a ser testada

e se forem iguais, ´e imprimida uma string que confirma que o teste teve um resultado correto. Caso contr´ario, ´e imprimida uma mensagem de erro.

Se n˜ao existir um ficheiro com extens˜ao .out ent˜ao, se o ficheiro corresponder

a um ficheiro de testes da tarefa E, ´e gerado o ficheiro html com a visualiza¸c˜ao

do tabuleiro. Se o ficheiro fˆor um teste da tarefa D ent˜ao ´e criado um ficheiro com extens˜ao .res que cont´em os dados do ficheiro original mais o resultado da tarefa D e calcula-se o output desse ficheiro pela tarefa C e guarda-se num ficheiro com extens˜ao .out. Se existir a palavra ”FIM”no ficheiro devolvido ent˜ao o teste ´e bem sucedido. Caso contr´ario d´a erro. No fim, os ficheiros com

extens˜ao .out e .res s˜ao eliminados.

8

Se o ficheiro de teste n˜ao for nem da tarefa D nem da E ent˜ao o teste ´e ignorado.

3

Conclus˜ao

Este projeto foi uma experiˆencia verdadeiramente enriquecedora uma vez que foi a primeira vˆes que fomos expostos ao desenvolvimento de um projeto de software do in´ıcio ao fim. Durante o desenvolvimento deste projeto utiliz´amos maioritariamente aquilo que nos foi lecionado nas aulas de Laborat´orios de Inform´atica e Programa¸c˜ao Funcional mas por vezes tivemos de recorrer a outras t´ecnicas e conhecimentos n˜ao lecionados principalmente na implementa¸c˜ao das anima¸c˜oes na tarefa E e no algoritmo de path-finding da tarefa D. Ao longo do trabalho encontramos v´arios obst´aculos e desafios, alguns deles bastante dificeis de superar, como por exemplo, alcan¸car os 20 pontos na tarefa D, mas conseguimos fazer tudo a que nos propusemos e consideramos que fizemos um bom trabalho, certamente acima da m´edia.

9