Jump to content

Sokoban em Haskell


luis_gomes
 Share

Recommended Posts

Boas pessoal,

estou a inicar agora um projeto que consiste em fazer um programa em haskell com o código fonte do jogo sokoban (http://sokoban.info)

Nesta primeira fase o principal objetivo é verificar se um determinado mapa cumpre alguns requisitos. Os mapas que serão passados ao programa terao a seguinte estrutura:

(mapa)

(coordenadas do boneco e das caixas)

EX:

###################
#####   ###########
#####   ###########
#####   ###########
###      ##########
### # ## ##########
#   # ## #####  ..#
#               ..#
##### ### # ##  ..#
#####     #########
###################
11 2
5 8
7 7
5 6
7 6
2 3
5 3

Nota: 11 2 - coordenadas do boneco

restantes coord. - coord. das caixas

o mapa é um retangulo (ficou desformatado ao copiar)

tenho que fazer diferentes tipos de testes, por exemplo verificar se os limites exteriores sao cardinais, se as coordenadas estao dentro do mapa, se essas coordenadas coincidem com espaços em branco, etc. e caso esteja tudo bem tenho que dizer que esta tuo bem senao dar o numero da linha em que o erro ocorre.

Um desses testes era verificar se as coordenadas sao numeros inteiros positivos, mas nao estou a conseguir fazer esse teste.

Eu pretendo fazer duas funçoes: uma que me indique que sao numeros inteiros (por exemplo, se fornecer em vez de coordenadas uma letra terei que indicar a linha que o erro ocorre).

A segunda ja esta feita e verifica se eles sao positivos:


-- esta funçao dá-nos o mapa
mapa :: [string] -> [string]
mapa [] = []
mapa (h:t)= if head h == '#'
                  then h:(mapa t)
                  else []

--esta função da-nos as coordenadas
coord :: [string] -> [(Int,Int)]
coord [] = []
coord (h:t)= if head h /= '#'
                  then (coord_aux h):(coord t)
                  else coord t

--verifica se as coordenadas sao positivas
verifica_coord_posit :: [string] -> String
verifica_coord_posit m = coord_posit_aux (mapa m) (coord m) 1  

coord_posit_aux :: [string] -> [(Int,Int)] -> Int-> String
coord_posit_aux a [] n = "OK"
coord_posit_aux a ((x,y):t) n | x >=0 && y>=0 = coord_posit_aux a t (n+1)
                             | otherwise = show ((length a) + n )


Pedia ajuda porque é um trabalho com data de entrega e preciso disto urgentemente e tenho algumas duvidas noutras funçoes.

Edited by pwseo
code tags.
Link to comment
Share on other sites

Não é boa idea usar String para representar tudo! Deves começar por definir alguns tipos de dados para representar o problema. Sugestões

type Pos = (Int,Int)    -- posições (x,y)
type Walls = [Pos]    -- lista de posições das paredes
type Boxes = [Pos]  -- lista de posições das caixas

Para verificar se uma posição tem coordenadas positivas podes usar encaixe de padrões:

validPos :: Pos -> Bool
validPos (x,y) = x>=0 && y>=0

Para fazer o mesmo a uma lista de coordenadas podes fazer uma função recursiva; de novo aconselho encaixe de padrões em vez de funções como head/tail.

validList :: [Pos] -> Bool
validList [] = True
validList (p : ps) = validPos p && validList ps

Contudo, a forma mais idiomática em Haskell de definir esta função é usar funções de ordem superior em vez de estar sempre a definir recursões com o mesmo padrão; neste caso podemos usar a função 'all' definida no prelúdio:

-- usando a função all :: (a -> Bool) -> [a] -> Bool
validList :: [Pos] -> Bool
validList lista = all validPos lista

ou ainda mais curto (usando "conversão eta"):

validList = all validPos

Bom trabalho!

Edited by thoga31
Tags code + GeSHi
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.