/tuberia.hs
http://tpfuncional.googlecode.com/ · Haskell · 132 lines · 80 code · 37 blank · 15 comment · 37 complexity · 11c59b8dfc2d6462df4494fcf9790d3f MD5 · raw file
- type Pos= (Int, Int)
- data Card= N | S | E | O deriving (Show)
- data Tubo= Tub Pos Card Card | Ini Pos Card | Fin Pos Card deriving (Show)
- type Final= Tubo
- type Inicio= Tubo
- type Jugada= Tubo
- data Estrategia= AB | RAND | VEC deriving (Show)
- data Jugador= Jug String Estrategia [Jugada]
- data Tablero= T [Jugada] [Pos] Inicio Final Jugador
-
- -- Configuracion del juego
- confFil::Int
- confFil= 8
-
- confCol::Int
- confCol=8
-
- confIni::Tubo
- confIni= (Ini (3,2) N)
-
-
- confFin::Tubo
- confFin= (Fin (8,7) E)
- --confFin= (Fin (3,4) S)
-
- --------------------------
-
- generarTubos::Pos->[Tubo]
- generarTubos (x,y)= (Tub (x,y) N S):(Tub (x,y) E O):(Tub (x,y) S O):(Tub (x,y) N O):(Tub (x,y) E S):(Tub (x,y) E N):[]
-
- generarPos::Int->Int->[Pos]
- generarPos fil col=[(x,y) | x<-[0..fil], y<-[0..col]]
-
- sacarPos::Pos->[Pos]->[Pos]
- sacarPos xy xys= filter (\vw-> vw/=xy) xys
-
- --Recorre una tuberia y dice si esta completa
- tuberiaCompleta::Inicio->Final->[Jugada]->Bool
- tuberiaCompleta ini fin []= conectada ini fin
- tuberiaCompleta ini fin xs= if (conectada ini fin) then True
- else
- case siguienteTubo ini xs of
- Nothing-> conectada ini fin
- Just value->tuberiaCompleta value fin (sacarTubo value xs)
-
- --saca un tubo de una lista de tubos
- sacarTubo::Tubo->[Tubo]->[Tubo]
- sacarTubo (Ini xy _) vws= filter (\(Tub mn _ _)-> mn/=xy) vws
- sacarTubo (Tub xy _ _) vws= filter (\(Tub mn _ _)-> mn/=xy) vws
-
- -- Me dice si 2 tubos estan conectados
- conectada::Tubo->Final->Bool
- conectada (Ini xy card1) (Fin vw card)= if ((adjacentes xy vw) && (sentido card card1)) then True else False
- conectada (Tub xy card1 card2) (Fin vw card)= if ((adjacentes xy vw) && ((sentido card card1) || (sentido card card2))) then True else False
-
- sentido:: Card->Card->Bool
- sentido N S= True
- sentido S N= True
- sentido E O= True
- sentido O E= True
- sentido _ _= False
-
- adjacentes::Pos->Pos->Bool
- adjacentes (x,y) (v,w)= if ((x==v && abs(y-w)==1) || (y==w && abs(x-v)==1)) then True else False
-
- --Retorna el tubo q continua
- siguienteTubo::Inicio->[Tubo]->Maybe Inicio
- siguienteTubo (Ini xy card) tubos= case filter (\(Tub vw card1 card2)-> adjacentes xy vw) tubos of
- []-> Nothing
- value-> dameConectado (Ini xy card) value
-
-
- --Recibe una lista de tubos adjacentes
- dameConectado::Inicio->[Tubo]-> Maybe Inicio
- dameConectado (Ini xy card) []= Nothing
- dameConectado (Ini xy card) ((Tub vw card1 card2):vws)= if (sentido card card1) then Just (Ini vw card2)
- else if (sentido card card2) then Just (Ini vw card1)
- else dameConectado (Ini xy card) vws
-
-
- -- las posiciones se generan por unica vez cuando se crea el tablero
- jugadasPosibles :: Tablero -> [Jugada]
- jugadasPosibles (T vw pos ini fin _)= map (\x-> Tub x N S) pos
-
-
- -- El juego se da por terminado cuando si se conecta la tuberia completa o no hay mas posiciones disponibles
- juegoTerminado :: Tablero -> Bool
- juegoTerminado (T vw pos ini fin (Jug _ VEC []))= True
- juegoTerminado (T vw pos ini fin _)= if (tuberiaCompleta ini fin vw) || pos==[] then True else False
-
-
- -- El jugador resulta ganador cuando se completa la tuberia
- jugadorGanador :: Tablero -> Maybe Jugador
- jugadorGanador (T vw pos ini fin jug)= if (tuberiaCompleta ini fin vw) then Just jug else Nothing
-
-
- -- le llega un tablero y una jugada valida
- aplicar:: Tablero -> Jugada -> Tablero
- aplicar (T vw pos ini fin (Jug nom VEC xs)) (Tub xy card1 card2)= T ((Tub xy card1 card2):vw) (sacarPos xy pos) ini fin (Jug nom VEC (sacarTubo (Tub xy card1 card2) xs))
- aplicar (T vw pos ini fin jug) (Tub xy card1 card2)= T ((Tub xy card1 card2):vw) (sacarPos xy pos) ini fin jug
-
-
- elegirJugada :: Jugador -> [Jugada] -> Jugada
- elegirJugada (Jug nombre estr (x:[])) _= x
- elegirJugada (Jug nombre estr (x:xs)) _= case estr of
- -- AB ->
- -- RAND ->
- VEC -> x
-
- proxJugada:: Tablero->Jugada
- proxJugada (T vw pos ini fin jug)= elegirJugada jug (jugadasPosibles (T vw pos ini fin jug))
-
-
- nombre:: Jugador -> String
- nombre (Jug nombre _ _)= nombre
-
- -- Arma el tablero segun la configuracion
- tableroInicial :: [Jugador] -> Tablero
- tableroInicial (x:[])= (T [] (generarPos confFil confCol) confIni confFin x)
-
-
-
- jugar:: Tablero -> Maybe Jugador
- jugar tablero= if (juegoTerminado tablero) then jugadorGanador tablero
- else jugar (aplicar tablero (proxJugada tablero))
-
- resultado::Maybe Jugador->String
- resultado x= case x of
- Nothing-> "El jugador perdio"
- Just value-> "El ganador es: " ++ (nombre value)