/tuberia.hs

http://tpfuncional.googlecode.com/ · Haskell · 132 lines · 80 code · 37 blank · 15 comment · 37 complexity · 11c59b8dfc2d6462df4494fcf9790d3f MD5 · raw file

  1. type Pos= (Int, Int)
  2. data Card= N | S | E | O deriving (Show)
  3. data Tubo= Tub Pos Card Card | Ini Pos Card | Fin Pos Card deriving (Show)
  4. type Final= Tubo
  5. type Inicio= Tubo
  6. type Jugada= Tubo
  7. data Estrategia= AB | RAND | VEC deriving (Show)
  8. data Jugador= Jug String Estrategia [Jugada]
  9. data Tablero= T [Jugada] [Pos] Inicio Final Jugador
  10. -- Configuracion del juego
  11. confFil::Int
  12. confFil= 8
  13. confCol::Int
  14. confCol=8
  15. confIni::Tubo
  16. confIni= (Ini (3,2) N)
  17. confFin::Tubo
  18. confFin= (Fin (8,7) E)
  19. --confFin= (Fin (3,4) S)
  20. --------------------------
  21. generarTubos::Pos->[Tubo]
  22. 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):[]
  23. generarPos::Int->Int->[Pos]
  24. generarPos fil col=[(x,y) | x<-[0..fil], y<-[0..col]]
  25. sacarPos::Pos->[Pos]->[Pos]
  26. sacarPos xy xys= filter (\vw-> vw/=xy) xys
  27. --Recorre una tuberia y dice si esta completa
  28. tuberiaCompleta::Inicio->Final->[Jugada]->Bool
  29. tuberiaCompleta ini fin []= conectada ini fin
  30. tuberiaCompleta ini fin xs= if (conectada ini fin) then True
  31. else
  32. case siguienteTubo ini xs of
  33. Nothing-> conectada ini fin
  34. Just value->tuberiaCompleta value fin (sacarTubo value xs)
  35. --saca un tubo de una lista de tubos
  36. sacarTubo::Tubo->[Tubo]->[Tubo]
  37. sacarTubo (Ini xy _) vws= filter (\(Tub mn _ _)-> mn/=xy) vws
  38. sacarTubo (Tub xy _ _) vws= filter (\(Tub mn _ _)-> mn/=xy) vws
  39. -- Me dice si 2 tubos estan conectados
  40. conectada::Tubo->Final->Bool
  41. conectada (Ini xy card1) (Fin vw card)= if ((adjacentes xy vw) && (sentido card card1)) then True else False
  42. conectada (Tub xy card1 card2) (Fin vw card)= if ((adjacentes xy vw) && ((sentido card card1) || (sentido card card2))) then True else False
  43. sentido:: Card->Card->Bool
  44. sentido N S= True
  45. sentido S N= True
  46. sentido E O= True
  47. sentido O E= True
  48. sentido _ _= False
  49. adjacentes::Pos->Pos->Bool
  50. adjacentes (x,y) (v,w)= if ((x==v && abs(y-w)==1) || (y==w && abs(x-v)==1)) then True else False
  51. --Retorna el tubo q continua
  52. siguienteTubo::Inicio->[Tubo]->Maybe Inicio
  53. siguienteTubo (Ini xy card) tubos= case filter (\(Tub vw card1 card2)-> adjacentes xy vw) tubos of
  54. []-> Nothing
  55. value-> dameConectado (Ini xy card) value
  56. --Recibe una lista de tubos adjacentes
  57. dameConectado::Inicio->[Tubo]-> Maybe Inicio
  58. dameConectado (Ini xy card) []= Nothing
  59. dameConectado (Ini xy card) ((Tub vw card1 card2):vws)= if (sentido card card1) then Just (Ini vw card2)
  60. else if (sentido card card2) then Just (Ini vw card1)
  61. else dameConectado (Ini xy card) vws
  62. -- las posiciones se generan por unica vez cuando se crea el tablero
  63. jugadasPosibles :: Tablero -> [Jugada]
  64. jugadasPosibles (T vw pos ini fin _)= map (\x-> Tub x N S) pos
  65. -- El juego se da por terminado cuando si se conecta la tuberia completa o no hay mas posiciones disponibles
  66. juegoTerminado :: Tablero -> Bool
  67. juegoTerminado (T vw pos ini fin (Jug _ VEC []))= True
  68. juegoTerminado (T vw pos ini fin _)= if (tuberiaCompleta ini fin vw) || pos==[] then True else False
  69. -- El jugador resulta ganador cuando se completa la tuberia
  70. jugadorGanador :: Tablero -> Maybe Jugador
  71. jugadorGanador (T vw pos ini fin jug)= if (tuberiaCompleta ini fin vw) then Just jug else Nothing
  72. -- le llega un tablero y una jugada valida
  73. aplicar:: Tablero -> Jugada -> Tablero
  74. 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))
  75. aplicar (T vw pos ini fin jug) (Tub xy card1 card2)= T ((Tub xy card1 card2):vw) (sacarPos xy pos) ini fin jug
  76. elegirJugada :: Jugador -> [Jugada] -> Jugada
  77. elegirJugada (Jug nombre estr (x:[])) _= x
  78. elegirJugada (Jug nombre estr (x:xs)) _= case estr of
  79. -- AB ->
  80. -- RAND ->
  81. VEC -> x
  82. proxJugada:: Tablero->Jugada
  83. proxJugada (T vw pos ini fin jug)= elegirJugada jug (jugadasPosibles (T vw pos ini fin jug))
  84. nombre:: Jugador -> String
  85. nombre (Jug nombre _ _)= nombre
  86. -- Arma el tablero segun la configuracion
  87. tableroInicial :: [Jugador] -> Tablero
  88. tableroInicial (x:[])= (T [] (generarPos confFil confCol) confIni confFin x)
  89. jugar:: Tablero -> Maybe Jugador
  90. jugar tablero= if (juegoTerminado tablero) then jugadorGanador tablero
  91. else jugar (aplicar tablero (proxJugada tablero))
  92. resultado::Maybe Jugador->String
  93. resultado x= case x of
  94. Nothing-> "El jugador perdio"
  95. Just value-> "El ganador es: " ++ (nombre value)