From eb23de0d41afa689722e932f3fa26a2bee551592 Mon Sep 17 00:00:00 2001
From: diegval <diego.valladolid@estudiantes.uva.es>
Date: Sat, 23 Nov 2024 13:55:52 +0100
Subject: [PATCH] =?UTF-8?q?Feature:=20algoritmo=20de=20generaci=C3=B3n=20d?=
 =?UTF-8?q?e=20eventos=20mejorado?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../model/GeneradorDeEventos.kt               | 73 ++++++++++++++++---
 .../exploradoresDePintia/model/TipoEvento.kt  |  2 +-
 .../model/eventoFactory/DescansoFactory.kt    | 38 ++++------
 .../model/eventoFactory/EventoDescanso.kt     | 15 +++-
 .../eventoFactory/EventoFactorySelector.kt    | 25 +------
 .../model/eventoFactory/RiesgoFactory.kt      |  2 +-
 6 files changed, 97 insertions(+), 58 deletions(-)

diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/GeneradorDeEventos.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/GeneradorDeEventos.kt
index 1c02b59..626d9a4 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/GeneradorDeEventos.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/GeneradorDeEventos.kt
@@ -8,29 +8,84 @@ import com.example.ellegadodepintia.exploradoresDePintia.model.GameState.context
 import com.example.ellegadodepintia.exploradoresDePintia.model.eventoFactory.Evento
 import com.example.ellegadodepintia.exploradoresDePintia.model.eventoFactory.EventoCombate
 import com.example.ellegadodepintia.exploradoresDePintia.model.eventoFactory.EventoFactorySelector
+import kotlin.random.Random
 
 
 object GeneradorDeEventos {
-    private const val CANTIDAD = 7 // Numero de eventos generados
+    private const val CANTIDAD = 10 // Numero de eventos generados
     private var eventos = ArrayList<Evento>()
 
-    private fun crearEvento(): Evento {
-        val factory = EventoFactorySelector.obtenerFactory()
-        return factory.generarEvento()
-    }
+    private val pesosBase = mutableMapOf(
+        TipoEvento.Reliquia to 0.25,
+        TipoEvento.Tienda to 0.1,
+        TipoEvento.Riesgo to 0.2,
+        TipoEvento.Trampa to 0.1,
+        TipoEvento.Combate to 0.25,
+        TipoEvento.Descanso to 0.0,
+        TipoEvento.Ladron to 0.1
+    )
+
+    private var historialTipos = mutableListOf<TipoEvento>()
+
 
     fun generarEventos() {
         val eventosGenerados = ArrayList<Evento>()
-        while (eventosGenerados.size < CANTIDAD) {
-            val nuevoEvento = crearEvento()
 
-            if (!eventosGenerados.contains(nuevoEvento)) {
-                eventosGenerados.add(nuevoEvento)
+        while (eventosGenerados.size < CANTIDAD) {
+            val tipoSeleccionado = seleccionarTipoEvento()
+            val nuevoEvento = EventoFactorySelector.obtenerFactory(tipoSeleccionado).generarEvento()
+
+            if (historialTipos.lastOrNull() != tipoSeleccionado || eventosGenerados.isEmpty()) {
+                if (!eventosGenerados.contains(nuevoEvento)) {
+                    eventosGenerados.add(nuevoEvento)
+                    historialTipos.add(tipoSeleccionado)
+                }
             }
         }
+
         eventos = eventosGenerados
     }
 
+    private fun seleccionarTipoEvento(): TipoEvento {
+        val pesosActuales = pesosBase.toMutableMap()
+
+        // 20% Descanso tras dos riegsos en los últimos 3 eventos
+        val recientes = historialTipos.takeLast(3)
+        if (recientes.count { it == TipoEvento.Riesgo } >= 2) {
+            pesosActuales[TipoEvento.Tienda] = pesosActuales[TipoEvento.Tienda]!! + 0.2
+        // 25% Ladron si 2 reliquias
+        }else if(recientes.count{it == TipoEvento.Reliquia} >= 2){
+            pesosActuales[TipoEvento.Ladron] = 0.25
+        }
+
+        // 35% Prob de descanso tras combate 20% Tienda 10% Combate
+        val ultimoTipo = historialTipos.lastOrNull()
+        if (ultimoTipo == TipoEvento.Combate) {
+            pesosActuales[TipoEvento.Descanso] = 0.35
+            pesosActuales[TipoEvento.Tienda] = 0.2
+            pesosActuales[TipoEvento.Combate] = 0.1
+        }
+
+        val totalPesos = pesosActuales.values.sum()
+        val probabilidadesNormalizadas = pesosActuales.mapValues { it.value / totalPesos }
+
+        val acumulado = probabilidadesNormalizadas.entries.fold(mutableListOf<Pair<Double, TipoEvento>>()) { acc, entry ->
+            val sumaAcumulada = acc.lastOrNull()?.first ?: 0.0
+            acc.add(Pair(sumaAcumulada + entry.value, entry.key))
+            acc
+        }
+
+        val random = Random.nextDouble()
+        val tipoSeleccionado = acumulado.first { random <= it.first }.second
+
+        val ultimosDos = historialTipos.takeLast(2)
+        if (tipoSeleccionado in ultimosDos) {
+            return seleccionarTipoEvento()
+        }
+
+        return tipoSeleccionado
+    }
+
     fun comprobarEventoDisponible() : Boolean{
         return eventos.size  >= 1
     }
diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/TipoEvento.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/TipoEvento.kt
index 26c05d2..2cf471a 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/TipoEvento.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/TipoEvento.kt
@@ -8,7 +8,7 @@ enum class TipoEvento {
     Riesgo,
     Descanso,
     Ladron,
-    /*Trampa,
+    /*
     Aliado,
     Misterio,
     Magia,
diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/DescansoFactory.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/DescansoFactory.kt
index 20f6e43..4876782 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/DescansoFactory.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/DescansoFactory.kt
@@ -7,40 +7,34 @@ import com.example.ellegadodepintia.exploradoresDePintia.model.efecto.EfectoIgno
 import com.example.ellegadodepintia.exploradoresDePintia.model.efecto.EfectoNubeVaccea
 
 class DescansoFactory : EventoFactory {
-    private val descansosMap = mapOf(
-        "Llegaste a un campamento vacceo, con un gran fuego en el centro y chozas hechas de madera y barro. Aquí puedes descansar, recuperar energía y estar listo para nuevas aventuras." to Pair(
-            R.drawable.asi_exploradores_campamento, listOf(
-                Opcion(
-                    descripcion = "Descansar",
-                    atributoRequerida = Atributo.Energia,
-                    EfectoNubeVaccea()
-
-                ), Opcion(
-                    descripcion = "Continuar",
-                    atributoRequerida = Atributo.Nula,
-                    EfectoIgnorar(100)
-                )
-            )
-        )
-    )
+    val descripcion = "Llegaste a un campamento vacceo, con un gran fuego en el centro y chozas hechas de madera y barro. Aquí puedes descansar, recuperar energía y estar listo para nuevas aventuras."
 
     override fun generarDescripcion(): String {
-        return descansosMap.keys.random()
+        return descripcion
     }
 
     override fun generarOpciones(descripcion: String): MutableList<Opcion> {
-        return descansosMap[descripcion]?.second?.toMutableList()
-            ?: mutableListOf()
+        return mutableListOf(
+            Opcion(
+                descripcion = "Descansar",
+                atributoRequerida = Atributo.Energia,
+                EfectoNubeVaccea()
+
+            ), Opcion(
+                descripcion = "Continuar",
+                atributoRequerida = Atributo.Nula,
+                EfectoIgnorar(100)
+            ))
     }
 
     override fun generarImagen(descripcion: String): Int {
-        return descansosMap[descripcion]?.first!!
+        return R.drawable.asi_exploradores_campamento
     }
 
     override fun generarEvento(): EventoDescanso {
-        val descripcion = generarDescripcion()
         return EventoDescanso(
-            descripcion = descripcion,
+            id = (0..Int.MAX_VALUE).random(),
+            descripcion = generarDescripcion(),
             dificultad = 0,
             opciones = generarOpciones(descripcion),
             imagen = generarImagen(descripcion),
diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoDescanso.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoDescanso.kt
index d30a839..dc510df 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoDescanso.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoDescanso.kt
@@ -3,9 +3,22 @@ package com.example.ellegadodepintia.exploradoresDePintia.model.eventoFactory
 import com.example.ellegadodepintia.exploradoresDePintia.model.Opcion
 
 class EventoDescanso(
+    val id: Int,
     override val descripcion: String,
     override val dificultad: Int,
     override val opciones: MutableList<Opcion>,
     override val imagen: Int, resistenciaMax: Int,
     override var finalizado: Boolean,
-) : Evento(descripcion, dificultad, opciones, imagen, resistenciaMax, resistenciaMax, finalizado)
\ No newline at end of file
+) : Evento(descripcion, dificultad, opciones, imagen, resistenciaMax, resistenciaMax, finalizado) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null || javaClass != other.javaClass) return false
+        other as EventoDescanso
+
+        return id == other.id
+    }
+
+    override fun hashCode(): Int {
+        return 31 * id.hashCode()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoFactorySelector.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoFactorySelector.kt
index 706bc85..1be2e5f 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoFactorySelector.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/EventoFactorySelector.kt
@@ -4,9 +4,7 @@ import com.example.ellegadodepintia.exploradoresDePintia.model.TipoEvento
 
 object EventoFactorySelector {
 
-    fun obtenerFactory(): EventoFactory {
-        val tipo = seleccionarTipoEventoConProbabilidades()
-
+    fun obtenerFactory(tipo: TipoEvento): EventoFactory {
         return when (tipo) {
             TipoEvento.Reliquia -> ReliquiaFactory()
             TipoEvento.Combate -> CombateFactory()
@@ -17,25 +15,4 @@ object EventoFactorySelector {
             TipoEvento.Ladron -> LadronFactory()
         }
     }
-
-    private fun seleccionarTipoEventoConProbabilidades(): TipoEvento {
-        val probabilidades = mapOf(
-            TipoEvento.Reliquia to 0.2,
-            TipoEvento.Tienda to 0.1,
-            TipoEvento.Riesgo to 0.2,
-            TipoEvento.Trampa to 0.1,
-            TipoEvento.Combate to 0.2,
-            TipoEvento.Descanso to 0.1,
-            TipoEvento.Ladron to 0.1
-        )
-
-        val acumulado = probabilidades.entries.fold(mutableListOf<Pair<Double, TipoEvento>>()) { acc, entry ->
-            val sumaAcumulada = acc.lastOrNull()?.first ?: 0.0
-            acc.add(Pair(sumaAcumulada + entry.value, entry.key))
-            acc
-        }
-
-        val random = Math.random()
-        return acumulado.first { random <= it.first }.second
-    }
 }
diff --git a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/RiesgoFactory.kt b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/RiesgoFactory.kt
index 26c410b..e205b26 100644
--- a/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/RiesgoFactory.kt
+++ b/app/src/main/java/com/example/ellegadodepintia/exploradoresDePintia/model/eventoFactory/RiesgoFactory.kt
@@ -76,7 +76,7 @@ class RiesgoFactory : EventoFactory {
 
         val evento = EventoRiesgo(
             id = id,
-            descripcion = descripcionComun,
+            descripcion = generarDescripcion(),
             dificultad = 0,
             opciones = eventoData.opciones.toMutableList(),
             imagen = eventoData.imagen,
-- 
GitLab