Page 1

Projecto de Laborat´orios de Inform´atica I Haskassonne Jos´e Cortez & Hugo Roriz 5 de Janeiro de 2014


Draw Para esta fun¸ca˜o, que desenha o tabuleiro no qual cada pe¸ca representa uma matriz em 5x5, foi usada a seguinte estrat´egia: Cria-se uma representa¸ca˜o simplificada de trˆes tabuleiros: um com o tipo de pe¸cas, outro com o tipo da orienta¸ca˜o e finalmente outro com os followers. De seguida, vai-se percorrendo os trˆes tabuleiros ao mesmo tempo, garantindo assim que s˜ao lidos os tipos,orienta¸co˜es e followers da mesma pe¸ca, e vai-se escrevendo o tabuleiro final. Fica aqui explicado em mais detalhe: O processo usado para o tabuleiro do tipo, orienta¸ca˜o e followers de cada pe¸ca ´e practicamente igual. Inicialmente cria-se uma lista na qual pares constitu´ıdos por uma abcissa e string (tipo de pe¸ca, orienta¸c˜ao e followers) est˜ao ordenadas pelas respectivas ordenadas. group tiles y :: [Element ] → [(Int, [(Int, String)])] group tiles y l = group tiles y aux (get y list l ) (get tiles geo l ) group tiles orientation :: [Element ] → [(Int, [(Int, String)])] group tiles orientation l = group tiles y aux (get y list l ) (get tiles orientation l ) group tiles meeples :: [Element ] → [(Int, [(Int, String)])] group tiles meeples l = group tiles y aux (get y list l ) (get tiles meeples l ) [(1,[(0,”E”),(1,”N”)]),(0,[(0,”E”)])] - Representa¸c˜ao de tipo/orienta¸c˜ao. [(0,[(0,”K1”),(1,” ”)])] - Representa¸c˜ao de followers.

Com estas fun¸c˜oes, fica armazenada nestas listas a informa¸c˜ao sobre as pe¸cas existentes do tabuleiro. O passo seguinte trata-se de representar os tabuleiros de forma mais realista, representando atrav´es de apenas uma string o tabuleiro. E aqui h´a uma diferencia¸ca˜o entre o tabuleiro dos followers e os demais. Para estes u ´ltimos, apenas ´e necess´ario um caract´er para representar uma pe¸ca. No entanto, para o caso dos followers, s˜ao necess´arios dois: um para o tipo de follower, o outro para o n´ umero do jogador que o colocou. Em suma, neste passo, s˜ao representadas as pe¸cas e as ausˆencias de pe¸cas de acordo com as coordenadas. 1


lista completa simplificada :: [Element ] → String lista completa simplificada l = lista completa (get x list l ) (group tiles y l ) lista completa orientacao :: [Element ] → String lista completa orientacao l = lista completa (get x list l ) (group tiles orientation l ) lista completa simplificada meeple :: [Element ] → String lista completa simplificada meeple l = lista completa meeple (get x list l ) (group tiles meeples l ) Ap´os a execu¸c˜ao destas trˆes fun¸co˜es, teremos as tais trˆes strings que representam os respectivos tabuleiros. ENE BC

SEN SE

K1K2 F1

Exemplo dos trˆes tabuleiros: Tipo, orienta¸c˜ao e followers de pe¸cas.

Agora que estes tabuleiros est˜ao dispon´ıveis, resta process´a-los. Para tal, o m´etodo utilizado ´e o seguinte: Os trˆes tabuleiros v˜ao sendo lidos ao mesmo tempo, caract´er a caract´er no caso do tipo e orienta¸ca˜o e dois a dois no caso dos followers. Ora, s˜ao essas as trˆes informa¸co˜es necess´arias para construir a pe¸ca na forma de matriz 5x5. transforma peca :: Char → Char → String → String transforma peca t o s@(x : xs) | t ≡ ’B’ ∧ s ≡ "__" = transforma peca b o | t ≡ ’C’ ∧ s ≡ "__" = transforma peca c o | t ≡ ’E’ ∧ s ≡ "__" = transforma peca e o | t ≡ ’N’ ∧ s ≡ "__" = transforma peca n o | t ≡ ’C’ ∧ x ≡ ’K’ = transforma peca knight c o s | t ≡ ’E’ ∧ x ≡ ’K’ = transforma peca knight e o s | t ≡ ’N’ ∧ x ≡ ’K’ = transforma peca knight n o s | t ≡ ’B’ ∧ x ≡ ’M’ = transforma peca monk b o s | t ≡ ’B’ ∧ x ≡ ’F’ = transforma peca farmer b o s | t ≡ ’E’ ∧ x ≡ ’F’ = transforma peca farmer e o s | t ≡ ’N’ ∧ x ≡ ’F’ = transforma peca farmer n o s | otherwise = " \n \n \n \n " Agora que se consegue desenhar pe¸cas em 5x5, pode-se representar uma pe¸ca como sendo uma lista de strings (cada linha representa uma string). Depois, mapeando a fun¸ca˜o para uma linha inteira, obt´em-se uma lista de listas (cada sub-lista representando uma pe¸ca).

2


transforma linha :: String → String → String → [[String ]] transforma linha [ ] [ ] [ ] = [ ] transforma linha (x : xs) (y : ys) (a : b : c) = (lines (transforma peca x y (a : b : [ ]))) : (transforma linha xs ys c) [[”1a linha 1a pe¸ca”,(...),”ultima linha 1a pe¸ca”],[”1a linha 2a pe¸ca”,(...)],(...)] Neste passo concatenam-se todas as primeiras linhas, depois as segundas, terceiras, quartas e por fim quintas com o caract´er newline entre elas. lista total :: [[String ]] → [String ] lista total [ ] = [ ] lista total [[ ], [ ]] = [ ] lista total (x : xs) = if ((length x ) ≡ 1) then (lista (x : xs)) : [ ] else (lista (x : xs) : (lista total (retira primeiros (x : xs)))) linha dum tabuleiro :: String → String → String → String linha dum tabuleiro t o m = intercalate "\n" (lista total (transforma linha t o m)) Visto que agora se consegue representar uma linha de tabuleiro, basta apenas mapear a fun¸ca˜o anterior para todas as linhas, intercalando-as com o caract´er newline entre elas. tabuleiro completo :: [String ] → [String ] → [String ] → String tabuleiro completo [ ] [ ] [ ] = [ ] tabuleiro completo (x : xs) (y : ys) (z : zs) = (linha dum tabuleiro x y z ) ++ "\n" ++ (tabuleiro completo xs ys zs) Desta forma representa-se um tabuleiro completo.

3


Play Para esta fun¸c˜ao, foi feito o seguinte (resumidamente): Procura-se sempre posi¸co˜es v´alidas na orla. Em primeiro lugar, procura-se em profundidade, ou seja, em coordenadas do tipo (x, ymin-1), depois, em largura, para a direita e depois esquerda, nas coordenadas (xmax+1, y) e (xmin-1,y), respectivamente. De real¸car que o objectivo ´e simplesmente colocar as pe¸cas em posi¸c˜oes v´alidas, ou seja, n˜ao visa a pontua¸c˜ao. O processo para a procura em profundidade e largura ´e e o mesmo, apenas mudam as regras de escolha de pe¸cas, por exemplo, na procura em profundidade evita-se encontrar a pe¸ca E virada para Sul, enquando que na profunda em largura na direita evita-se a pe¸ca E virada para Este. A primeira parte do processo consiste em encontrar o bloco no tabuleiro onde a pe¸ca ser´a colocada. Como referi, o processo ´e o mesmo para todas as procuras, fica ent˜ao s´o exemplificado aqui a pesquisa em profundidade e largura na parte direita do tabuleiro. procura x profundidade :: Int → [(Int, Int, String, String)] → (Int, String) procura x profundidade y [ ] = (−2500, "") procura x profundidade y ((a, b, c, d ) : xs) | (y ≡ b) ∧ (c ≡ "B" ∨ c ≡ "C") = (a, c) | (y ≡ b) ∧ (c ≡ "E") ∧ (d 6≡ "S") = (a, c) | (y ≡ b) ∧ (c ≡ "N") ∧ (d 6≡ "W" ∧ d 6≡ "S") = (a, c) | otherwise = procura x profundidade y xs procura x largura dir :: Int → [(Int, Int, String, String)] → (Int, String, String) procura x largura dir x [ ] = (−2500, "", "") procura x largura dir x ((a, b, c, d ) : ys) | (x ≡ a) ∧ (c ≡ "B" ∨ c ≡ "C") = (b, c, d ) | (x ≡ a) ∧ (c ≡ "N") ∧ (d 6≡ "S" ∧ d 6≡ "E") = (b, c, d ) | (x ≡ a) ∧ (c ≡ "E") ∧ (d 6≡ "E") = (b, c, d ) | otherwise = procura x largura dir x ys Come¸ca-se a procurar na lista das pe¸cas existentes uma que cumpra os requisitos, caso isso aconte¸ca, encontra-se o lugar para a nova pe¸ca, caso todas as pe¸cas sejam consideradas inv´alidias1 , ´e dado um c´odigo de erro. Ap´os a procura em profundidade, ´e ent˜ao executada a fun¸c˜ao que escreve em formato xml a nova pe¸ca.

1

De real¸car que a palavra inv´ alida, neste contexto, quer dizer que n˜ao cumpre as regras da fun¸c˜ ao

4


procura profundidade :: Element → String procura profundidade l = let lista y = get y list (get tiles l ) geo = get tiles info (get tiles l ) x = show (fst (procura x profundidade (last lista y) geo)) y = show ((last lista y) − 1) next = next tile l tipo = snd (procura x profundidade (last lista y) geo) in if (esta vazio l ) then "<tile type=\"E\" x=\"0\" y=\"0\" orientation=" ++ "\"N\"" ++ "/>" else if (x ≡ "-2500") then procura largura dir l else "<tile type=\"" ++ next ++ "\" x=\"" ++ x ++ "\" y=\"" ++ y ++ "\" orientation=\"S\"/>" procura largura dir :: Element → String procura largura dir l = let max x = last (get x list (get tiles l )) geo = get tiles info (get tiles l ) dir = show (first (procura x largura dir max x geo)) t = next tile l x dir = show (max x + 1) tipo dir = scnd (procura x largura dir max x geo) o = thr (procura x largura dir max x geo) in if (dir ≡ "-2500") then procura largura esq l + else "<tile type=\"" ++ t ++ "\" x=\"" ++ x dir ++ "\" y=\"" ++ dir + "\" orientation=\"E\"/>"

Se for encontrado uma posi¸ca˜o v´alida, ´e escrita a pe¸ca. Se for recebido o c´odigo de erro (neste caso a string -2500”), recome¸ca-se o processo de novo, desta vez para a pesquisa em largura na parte direita do tabuleiro que, por sua vez, se tamb´em n˜ao encontrar a´ı posi¸co˜es v´alidas, tamb´em recebe o c´odigo de erro e ´e feita a pesquisa em largura na parte esquerda do tabuleiro.

5


My report  
Advertisement
Read more
Read more
Similar to
Popular now
Just for you