PageRenderTime 17ms CodeModel.GetById 4ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/tp-1/codigo/Damas.hs

http://tps-paradigmas.googlecode.com/
Haskell | 198 lines | 119 code | 38 blank | 41 comment | 35 complexity | 582ab0d74492f7a269ad7e86c1529df6 MD5 | raw file
  1module Damas where
  2
  3import Char
  4import Tablero
  5import Maybe
  6
  7data Juego = J Color Tablero
  8data Movimiento = M Posicion Direccion
  9  deriving Show
 10
 11data Arbol a = Nodo a [Arbol a] deriving Show
 12type ArbolJugadas = Arbol ([Movimiento], Juego)
 13
 14type Valuacion = Juego -> Double
 15
 16---- Funciones de regalo ----
 17
 18instance Show Juego where
 19  show (J turno tablero) = "\n--Juegan las " ++ show turno ++ "s--\n" ++ show tablero
 20
 21arbolDeJugadas :: Juego -> ArbolJugadas
 22arbolDeJugadas j = Nodo ([], j) $ zipWith agmov movs hijos
 23  where agmov m (Nodo (ms, r) hs) = Nodo ((m:ms), r) (map (agmov m) hs)
 24        movsJuegos = movimientosPosibles j
 25        movs = map fst movsJuegos
 26        hijos = map (arbolDeJugadas . snd) movsJuegos
 27
 28---- Ejercicios ----
 29color :: Ficha -> Color
 30color (Simple c) = c
 31color (Reina c) = c
 32
 33isSimple :: Ficha -> Bool
 34isSimple (Simple c) = True
 35isSimple (Reina c) = False
 36
 37destino :: Movimiento -> Posicion
 38destino (M (i,j) BR) = (chr ((ord i) + 1), j-1)
 39destino (M (i,j) BL) = (chr ((ord i) - 1), j-1)
 40destino (M (i,j) TR) = (chr ((ord i) + 1), j+1)
 41destino (M (i,j) TL) = (chr ((ord i) - 1), j+1)
 42
 43destinoSiCaptura :: Movimiento -> Posicion
 44destinoSiCaptura (M (i,j) BR) = (chr ((ord i) + 2), j-2)
 45destinoSiCaptura (M (i,j) BL) = (chr ((ord i) - 2), j-2)
 46destinoSiCaptura (M (i,j) TR) = (chr ((ord i) + 2), j+2)
 47destinoSiCaptura (M (i,j) TL) = (chr ((ord i) - 2), j+2)
 48
 49
 50-- Ejercicio 3
 51
 52dentroDelTablero :: Posicion -> Bool
 53dentroDelTablero (i, j) = i `elem` ['a'..'h'] && j `elem` [1..8]
 54
 55-- se fija si hay ficha que comer y que sea del color contrario, detalle...
 56esCaptura :: Movimiento -> Tablero -> Color -> Bool
 57esCaptura (M (i, j) d) t c = not (isNothing (contenido (destino (M (i, j) d)) t)) && (color (dameFicha (contenido (destino (M (i, j) d)) t)) == (invertirColor c)) 
 58
 59puedeMover :: Ficha -> Direccion -> Bool
 60-- las reinas pueden mover en cualquier direccion
 61puedeMover (Reina _) _ = True
 62-- las simples blancas no pueden ir para el bottom
 63puedeMover (Simple Blanca) TL = True
 64puedeMover (Simple Blanca) TR = True
 65puedeMover (Simple Blanca) _ = False
 66-- las simples negras no pueden ir para el top
 67puedeMover (Simple Negra) BL = True
 68puedeMover (Simple Negra) BR = True
 69puedeMover (Simple Negra) _ = False
 70
 71invertirColor :: Color -> Color
 72invertirColor Blanca = Negra
 73invertirColor Negra = Blanca
 74
 75-- renombro la funcion para aclarar!
 76fichaAComer :: Movimiento -> Posicion
 77fichaAComer = destino
 78
 79-- funcion parcial!!
 80dameFicha :: Maybe Ficha -> Ficha
 81dameFicha (Just f) = f
 82
 83-- corona si debe, segun su posicion destino
 84coronarSiSeDebe :: Ficha -> Posicion -> Ficha
 85coronarSiSeDebe (Simple Blanca) (x,y) = if y == 8 then (Reina Blanca) else (Simple Blanca)
 86coronarSiSeDebe (Simple Negra) (x,y) = if y == 1 then (Reina Negra) else (Simple Negra)
 87coronarSiSeDebe (Reina Blanca) _ = (Reina Blanca)
 88coronarSiSeDebe (Reina Negra) _ = (Reina Negra)
 89
 90mover :: Movimiento -> Juego -> Maybe Juego
 91mover (M p d) (J c t) 
 92                -- la pos orig esta en el tablero
 93              | not (dentroDelTablero p) = Nothing 
 94                -- la posicion dest esta en el tablero (no captura)
 95              | not (dentroDelTablero (destino (M p d))) = Nothing               
 96                -- el contenido de la pos original no es vacio
 97              | contenido p t == Nothing = Nothing
 98                -- la posicion dest esta en el tablero (capturo)
 99              | (esCaptura (M p d) t c) && not (dentroDelTablero (destinoSiCaptura (M p d))) = Nothing 
100                -- el color de la ficha tiene que ser el mismo del que le toca jugar
101              | not (color (dameFicha (contenido p t)) == c) = Nothing
102                -- chequea que pueda mover depende de que ficha es (Blanca, Negra, Simple o Reina)
103              | not (puedeMover (dameFicha (contenido p t)) d) = Nothing
104                -- el destino esta vacio (captura)
105              | (esCaptura (M p d) t c) && not ((contenido (destinoSiCaptura (M p d)) t) == Nothing) = Nothing
106                -- el destino esta vacio (no captura)
107              | not (esCaptura (M p d) t c) && not ((contenido (destino (M p d)) t) == Nothing) = Nothing
108                -- la ficha que capturo es la del color del rival
109              | (esCaptura (M p d) t c) && (not (isNothing (contenido (destinoSiCaptura (M p d)) t))) && (color (dameFicha (contenido (destinoSiCaptura (M p d)) t)) == c) = Nothing
110                -- sino, hago la movida
111              | otherwise = 
112                    (Just (J (invertirColor c) (if (esCaptura (M p d) t c) then
113                    (sacar (fichaAComer (M p d)) (sacar p (poner (destinoSiCaptura (M p d))  (coronarSiSeDebe (dameFicha (contenido p t)) (destinoSiCaptura (M p d))) t)))
114                    else
115                    (sacar p (poner (destino (M p d)) (coronarSiSeDebe (dameFicha (contenido p t)) (destino (M p d))) t)))))
116
117
118-- Ejercicio 4
119movimientosPosibles :: Juego -> [(Movimiento, Juego)]
120movimientosPosibles (J c t) = map (\(m, Just j) -> (m,j))  
121					(filter (\(m, j1) -> not(isNothing j1))
122					[(m, mover m (J c t) ) | 
123					--itero todas las fichas de un color
124					p<-(fichas t c),	
125					--construyo un movimiento
126					m<- [M p TL,  M p TR,  M p BL,  M p BR]
127					]
128					)
129
130-- Ejercicio 5
131foldArbol :: (a -> c -> b) -> ([b] -> c) -> Arbol a -> b
132foldArbol g h (Nodo a xs) = g a (h (map (foldArbol g h) xs))
133
134-- Ejercicio 6
135podar :: Int -> Arbol a -> Arbol a
136podar i a = podarP a i
137
138podarP :: Arbol a -> Int -> Arbol a
139podarP = foldArbol (\a xs n -> if (n == 0) then (Nodo a []) else (Nodo a (map (\x -> x (n-1)) xs))) (id)
140
141-- Ejercicio 7
142mejorMovimiento :: Valuacion -> ArbolJugadas -> Movimiento
143mejorMovimiento v a = (head.snd) (minimax v a)
144
145-- chooseF devuelve el x en la lista que decide el criterio f
146chooseF :: (a -> a -> Bool) -> [a] -> a
147chooseF f = foldr1 (\x y -> if f x y then x else y)
148
149--Minimax con recursion explicita
150--minimax2 v (Nodo a hs) = auxMinimax v (Nodo a hs) True
151--
152--auxMinimax :: Valuacion -> ArbolJugadas -> Bool -> (Double, [Movimiento])
153--auxMinimax v (Nodo a []) _ = (v (snd a), fst a)
154--auxMinimax v (Nodo _ hs) True = min0 (map (\x -> auxMinimax v x False) hs) 
155--    where min0 = chooseF (\x y -> (fst x) < (fst y)) 
156--auxMinimax v (Nodo _ hs) False = max0 (map (\x -> auxMinimax v x True) hs)
157--    where max0 = chooseF (\x y -> (fst x) > (fst y))
158
159
160minimax :: Valuacion -> ArbolJugadas -> (Double, [Movimiento])
161minimax v = foldArbol f g
162    where
163        chooseMin = chooseF (\x y -> (fst x) < (fst y))
164        chooseMax = chooseF (\x y -> (fst x) >= (fst y))
165        g = \xs -> if (null xs) then Nothing else Just ( (chooseMin xs, chooseMax xs) )
166        f = \j rec -> case rec of
167            -- si es una hoja, devuelvo la jugada evaluada
168            Nothing -> (v (snd j), fst j)
169            -- sino elijo segun tengo que minimizar o maximizar la mejor jugada
170            Just (minVal, maxVal) -> if (length (fst j) `mod` 2 == 0) then maxVal else minVal
171
172-- Ejercicio 8
173ganador :: Juego -> Maybe Color
174ganador (J c t) | (length (movimientosPosibles (J c t)) == 0) = Just (invertirColor c)
175		| (length (fichas t (invertirColor c)) == 0) = Just c
176		| otherwise = Nothing
177
178-- Ejercicio 9
179valuacionDamas :: Juego -> Double
180valuacionDamas (J c t)	| (ganador (J c t) == (Just c)) = 1
181			| (ganador (J c t) == (Just (invertirColor c))) = -1
182			| otherwise = fromIntegral (2 * (2 * r + s)) / fromIntegral ((2 * rtot + 2 * stot) - 1)
183 where 	r = length (reinas t c)
184	s = length (simples t c)
185	rtot = r + (length (reinas t (invertirColor c)) )
186	stot = s + (length (simples t (invertirColor c)) )
187
188
189-- esta funcion se llama asi por que es corto el nombre pero devuelve todas las pocisiones ocupadas por un color
190fichas :: Tablero -> Color -> [Posicion]
191fichas t c = [ (i,j) | i <- ['a'..'h'], j <- [1..8], (not (isNothing (contenido (i,j) t))) && (color (dameFicha (contenido (i,j) t)) == c) ]
192
193simples :: Tablero -> Color -> [Posicion]
194simples t c = [ x | x <- (fichas t c), isSimple (dameFicha (contenido x t))]
195
196reinas :: Tablero -> Color -> [Posicion]
197reinas t c = [ x | x <- (fichas t c), not (isSimple (dameFicha (contenido x t)))]
198