Cursosā€Ž > ā€ŽSĆ”bados MaƱana - Anualā€Ž > ā€Ž

TP3 Funcional

Plantas Vs. Ā Zombies

Ā 

En todo jardín nos encontramos con una situación en común: el ataque de los zombies. Es nuestro deber defender nuestros hogares de estos comedores de cerebros.

La forma mas efectiva de repeler el ataque de zombies, claro estĆ”, es con plantas, como todos sabemos.
Para afrontar la situación en nuestros jardines se necesita de la codificación de un programa Haskell que modele esta problemÔtica.
Ā 

Primero debemos saber que las plantas se modelan con una 5-upla con los siguientes datos: (cantidad de disparos, cantidad de mordisco que se banca, soles que da, daño, frecuencia de acción). Por ejemplo:


peaShooter = (1,5,0,10,3)
sunflower = (0,7,1,0,6)
nut = (0,100,0,0,0)
puffShroom = (5,1,0,1,1)


Para que sea mas fĆ”cil de acceder, nuestro vecino ā€œCrazy Daveā€ nos regaló estas funciones:


cantidadDeDisparos(d,_,_,_,_) = d

cantidadDeMordiscos(_,m,_,_,_) = m
cantidadDeSoles(_,_,s,_,_) = s
daƱo(_,_,_,d,_) = d
frecuencia (_,_,_,_,f) = f



Para defendernos de los ataques zombies, se plantean lĆ­neas de defensa, cada lĆ­nea es una lista de plantas, por ejemplo podrĆ­amos plantear las siguientes lĆ­neas:


linea1 = [sunflower,sunflower,sunflower,sunflower]
linea2 = [sunflower,peaShooter,peaShooter,sunflower]
linea3 = [puffShroom,puffShroom,puffShroom,peaShooter]
linea4 = [nut,puffShroom,puffShroom,nut]

Puede venir bien recordar las siguientes funciones del prelude:

  • head --> devuelve la cabeza de una lista
  • tail --> devuelve la cola de una lista (complemento de head)
  • last --> devuelve el Ćŗltimo elemento de una lista
  • init --> devuelve la lista desde el primero hasta el penĆŗltimo elemento de una lista (complemento de last)
  • div --> división entera

Nota: Se debe aplicar, en el desarrollo de los distintos puntos, al menos una vez cada uno de los siguientes conceptos:
  • Listas por comprensión
  • Recursividad
  • Orden superior
  • Composición de funciones
  • Pattern matching
  • Aplicación parcial

Se pide:

  1. Poder determinar de quƩ especialidad es una planta. Tener en cuenta para esto que:
    1. Las plantas que dan soles son de especialidad ā€œProveedoraā€
    2. Las plantas cuyo daƱo potencial (que se calcula como la cantidad de disparos multiplicado por su daƱo) es Ā mayor o igual que la cantidad de mordiscos que se banca, son de especialidad ā€œAtaqueā€.
    3. Si no cumplen con ninguna de las anteriores son de especialidad ā€œDefensaā€.

      Por ejemplo:


      > especialidadĀ sunflower
      ā€œProveedoraā€


  2. Poder determinar si una lĆ­nea necesita ser defendida, esto pasa cuando todas las plantas de esa linea son proveedoras. Por ejemplo:

    > necesitaSerDefendida linea1
    True


    > necesitaSerDefendida linea3

    False



    1. Poder saber la potencia de ataque que tiene una planta, que se calcula como: la cantidad de disparos multiplicada por el daño dividido por la frecuencia (división entera) (si la frecuencia es 0, su potencia también lo es). Por ejemplo:

      > potencia nut
      0

      > potencia puffShroom
      5

    2. Saber la potencia total de una lĆ­nea de plantas.

      > potenciaTotal linea4
      10


  3. a) Realizar una función que reciba dos parÔmetros:
                   1- una condición sobre una planta
    Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā 2- una lista de plantas
    y devuelva un numero, que representa la cantidad de plantas de esa linea que cumplen con esa condición.
    b) Realizar las consultas (
    sin codificar funciones auxiliares) que permitan saber:
    1. La cantidad de plantas que dan al menos un sol en la linea1
    2. La cantidad de plantas que tienen potencia de ataque mayor a 3 en la linea2
    3. La cantidad de plantas que se bancan mƔs de 5 mordiscos en la linea2
    4. La cantidad de plantas para las cuales el daño menos la frecuencia da un número par en linea3

  4. Saber si una lƭnea es mixta, que es cuando ninguna de las plantas de la lƭnea tiene la misma especialidad que su inmediata siguiente. AdemƔs, la lƭnea debe tener al menos dos plantas.
    Nota: No usar length (ni ninguna función que tenga el mismo propósito).

    > lineaMixta linea2
    False


    Ahora se agregan (”finalmente!) los zombies, que se representan por tuplas (mordiscosPorTurno, defensa).

    balloonZombie = (1, 11)
    newspaperZombie = (2, 16)
    gargantuar = (30, 150)

    Y las hordas de zombies correspondientes:

    septimoRegimiento = [newspaperZombie, balloonZombie, balloonZombie]
    legion = [gargantuar, gargantuar, gargantuar, gargantuar, gargantuar, gargantuar]

    Para estos, tenemos las funciones:

    mordiscosPorTurno = fst
    defensa = snd

  5. Saber cómo seria el resultado de una ronda de ataque para una planta y un zombie. El resultado de esta funcion debe ser una dupla (planta, zombie) con el resultado del ā€œfuego cruzadoā€, es decir, como quedarian el zombie y la planta luego de enfrentarse. Los ataques son simples:

    1. El zombie muerde a la planta tantas veces como indique su valor de mordiscosPorTurno, disminuyendo el valor de cantidadDeMordiscos en igual cantidad.

    2. La planta le baja la defensa al zombie de igual forma, segĆŗn su potencia de ataque.

    En ambos casos, el valor mínimo de cantidadDeMordiscos/defensa resultante debe ser 0, en cuyo caso la planta muere o el zombie es destruido (lo cual no es relevante para esta función, pero sí mÔs adelante).

    > rondaDeAtaque puffShroom gargantuar

    ((1,0,0,1,1), (30,145))

    El gargantuar es atacado con una potencia de 5, mientras que el puffShroom es atacado con una potencia de 30 (detalle: el puffShroom muere, pero dijimos que acĆ” eso no afecta).


  6. Conocer el resultado de un ataque masivo en una linea de plantas. Se pide lo mismo que para la anterior (una única ronda de ataque), pero para una lista de plantas y una lista de zombies. La diferencia con la anterior es que si una planta muere o un zombie es destruido, la lista resultante no deberÔ incluirlos, y ademÔs se debe considerar que siempre los que pelean son la última planta contra el primer zombie.
    Ejemplo, para la consulta:

    > resultadoDeAtaque linea3 septimoRegimiento
    ([(5,1,0,1,1),(5,1,0,1,1),(5,1,0,1,1),(1,3,0,10,3)],
    [(2,13),(1,11),(1,11)])


    los que pelean son el peaShooter y el newspaperZombie.

  7. Desarrollar la función theZombiesAteYourBrains, que nos dice si, para una línea de plantas y una lista de zombies que atacan, luego de un ataque en serie de los zombies nos quedamos sin plantas. Un ataque en serie es una sucesión de ataques que termina cuando nos quedamos sin plantas (y nos comen el cerebro) o destruimos a todos los zombies. Las plantas y zombies en cada nuevo ataque son los que correspondan al resultado del ataque anterior.
    Nota: Si al mismo tiempo que nos quedamos sin plantas, también se acaban los zombies... ”zafamos!
    Ayuda: Recursividad.

    > theZombiesAteYourBrains linea1 legion
    True