Last active
August 11, 2021 01:51
-
-
Save guille-acosta/5a97b7c0da406d449d857f912dbbae60 to your computer and use it in GitHub Desktop.
Recuperatorio PdeP Funcional 2021 Scarcella
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{----------------------------------- PdeP: Puños de Furia -------------------------------------------- | |
Queremos desarrollar un programa que analice y calcule el resultado de los enfrentamientos entre | |
peleadores de artes marciales, utilizando el paradigma funcional. | |
1) Necesitamos armar nuestro modelo base. | |
a. Modelar a los peleadores, de los cuales se conocen sus puntos de vida, su resistencia y el | |
conjunto de los ataques que conoce. | |
b. Implementar las siguientes operaciones sobre peleadores, basándonos en el modelo anterior: | |
-----------------------------------------------------------------------------------------------------} | |
type Vida = Int | |
type Resistencia = Int | |
type Ataque = Peleador -> Peleador | |
data Peleador = Peleador { | |
vida :: Vida, | |
resistencia :: Resistencia, | |
ataques :: [Ataque] | |
} | |
------------------------------------------------------------------------------------------------------ | |
-- i. estaMuerto: Un peleador está muerto si su vida es menor a 1. | |
------------------------------------------------------------------------------------------------------ | |
estaMuerto :: Peleador -> Bool | |
estaMuerto = ( 1 > ) . vida | |
------------------------------------------------------------------------------------------------------ | |
-- ii. esHabil: Un peleador es hábil cuando conoce más de 10 ataques. | |
------------------------------------------------------------------------------------------------------ | |
esHabil :: Peleador -> Bool | |
esHabil = ( 10 < ) . length . ataques | |
{----------------------------------------------------------------------------------------------------- | |
c. Modelar los ataques, e implementar los siguientes de forma tal que puedan ser incluidos | |
en el conjunto conocido por un peleador: | |
-----------------------------------------------------------------------------------------------------} | |
-- Funcion auxiliar para las funciones 'Ataque' | |
cambiarPuntosDeVida :: (Peleador -> Vida) -> Peleador -> Peleador | |
cambiarPuntosDeVida delta peleador = peleador{ vida = delta peleador } | |
{---------------------------------------------------------------------------------------------------- | |
i. golpe: Reduce la vida del peleador oponente en una cantidad igual a la intensidad del | |
golpe dividido la resistencia del oponente. (Por ejemplo, un golpe de intensidad 25 haría | |
perder 3 puntos de vida a un oponente con resistencia 7: 25 `div` 7 == 3). | |
-----------------------------------------------------------------------------------------------------} | |
type Intensidad = Int | |
golpe :: Intensidad -> Ataque | |
golpe intensidad = | |
cambiarPuntosDeVida (\oponente -> vida oponente - intensidad `div` resistencia oponente) | |
------------------------------------------------------------------------------------------------------ | |
--ii . toque de la muerte: El toque d la muerte hace que el oponente pierda toda su vida. | |
------------------------------------------------------------------------------------------------------ | |
toqueDeLaMuerte :: Ataque | |
toqueDeLaMuerte = cambiarPuntosDeVida ( ( 0 * ) . vida ) | |
{----------------------------------------------------------------------------------------------------- | |
iii. patada: Las patadas causan distintos efectos dependiendo en qué parte del cuerpo el oponente | |
las reciba: | |
- Una patada en el pecho hace que un oponente vivo pierda 10 puntos de vida, pero reanima el | |
corazón de un oponente muerto, haciéndole ganar 1 punto de vida. | |
- Una patada en la carita hace que cualquier oponente pierda la mitad de la vida que le queda. | |
- Una patada en la nuca no causa ningún daño, pero hace que el oponente olvide su primer ataque, | |
si es que conoce alguno. | |
- Una patada en cualquier otra parte del cuerpo no hace nada. Es necesario poder representar los | |
otros lugares aunque no causen ningún efecto. (Por ejemplo, una patada en la nuca haría que un | |
oponente que sólo sabe hacer el toque de la muerte se quede sin ataques, mientras que una patada | |
a, digamos, la pantorrilla o la axila, no le haría nada). | |
-----------------------------------------------------------------------------------------------------} | |
patada :: String -> Ataque | |
patada parteDelCuerpo peleador | |
| parteDelCuerpo == "pecho" && (not . estaMuerto $peleador) = | |
cambiarPuntosDeVida ( ( (-10) + ) . vida ) peleador | |
| parteDelCuerpo == "pecho" && estaMuerto peleador = | |
cambiarPuntosDeVida ( ( 1 + ) . vida ) peleador | |
| parteDelCuerpo == "carita" = cambiarPuntosDeVida ( ( `div` 2) . vida ) peleador | |
| parteDelCuerpo == "nuca" = peleador{ ataques = tail . ataques $peleador } | |
| otherwise = peleador | |
{----------------------------------------------------------------------------------------------------- | |
d . Escribir el código con el que crearía a Bruce Lee, un peleador con 200 de vida y 25 de | |
resistencia que tiene entre sus ataques el toque de la muerte, un golpe de intensidad 500 y | |
un ataque más que consiste en una secuencia de tres patadas a la carita. | |
-----------------------------------------------------------------------------------------------------} | |
bruceLee :: Peleador | |
bruceLee = Peleador { | |
vida = 200, | |
resistencia = 25, | |
ataques = [toqueDeLaMuerte, | |
golpe 500, | |
patada "carita" . patada "carita" . patada "carita"] | |
} | |
{----------------------------------------------------------------------------------------------------- | |
2) Dados un peleador y un enemigo, encontrar el mejor ataque del peleador contra ese | |
enemigo (es decir, encontrar el ataque del peleador que deja con menos vida al enemigo) | |
-----------------------------------------------------------------------------------------------------} | |
mejorAtaque :: Peleador -> Peleador -> Ataque | |
mejorAtaque peleador oponente = | |
foldl1 (ataqueMasDañino oponente) . ataques $peleador | |
ataqueMasDañino :: Peleador -> Ataque -> Ataque -> Ataque | |
ataqueMasDañino peleador ataque1 ataque2 | |
| (vida . ataque1 $peleador) < (vida . ataque2 $peleador) = ataque1 | |
| otherwise = ataque2 | |
{----------------------------------------------------------------------------------------------------- | |
Implementar las siguientes operaciones tratando de aprovechar al máximo los conceptos de | |
orden superior, composición y aplicación parcial: | |
-----------------------------------------------------------------------------------------------------} | |
{----------------------------------------------------------------------------------------------------- | |
a. terrible: un ataque es terrible para un conjunto de enemigos si, luego de realizarlo | |
contra todos ellos, quedan vivos menos de la mitad. | |
-----------------------------------------------------------------------------------------------------} | |
terrible :: Ataque -> [Peleador] -> Bool | |
terrible ataque enemigos = | |
(length enemigos `div` 2 > ) . length . filter (not . estaMuerto) . map ataque $enemigos | |
{----------------------------------------------------------------------------------------------------- | |
b. peligroso: un peleador es peligroso para un conjunto de enemigos si todos sus ataques son | |
terribles para los miembros del conjunto que son hábiles. | |
-----------------------------------------------------------------------------------------------------} | |
peligroso :: Peleador -> [Peleador] -> Bool | |
peligroso peleador enemigos = | |
all (flip terrible (filter esHabil enemigos)) . ataques $peleador | |
{----------------------------------------------------------------------------------------------------- | |
c. invencible: un peleador es invencible para un conjunto de enemigos si, luego de recibir | |
el mejor ataque de cada uno de ellos, sigue teniendo la misma vida que antes de ser atacado. | |
(No importa el orden en que se apliquen los ataques). | |
-----------------------------------------------------------------------------------------------------} | |
invencible :: Peleador -> [Peleador] -> Bool | |
invencible peleador = | |
(vida peleador == ) . vida . foldr ($) peleador . map (flip mejorAtaque peleador) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment