From f4c030671700a191d10526780a42f88ebefbc637 Mon Sep 17 00:00:00 2001 From: Araozu Date: Sat, 26 Dec 2020 17:37:35 -0500 Subject: [PATCH] Empezar a modificar arquitectura para posteriormente implementar bots --- src/juego/Juego.kt | 62 +++++++++++++++++----------------- src/juego/Jugador.kt | 80 ++++++++++++++++++++++++++++++++++++++++++++ src/juego/Mano.kt | 4 +-- 3 files changed, 114 insertions(+), 32 deletions(-) create mode 100644 src/juego/Jugador.kt diff --git a/src/juego/Juego.kt b/src/juego/Juego.kt index cb722ef..70cd471 100644 --- a/src/juego/Juego.kt +++ b/src/juego/Juego.kt @@ -6,9 +6,10 @@ import io.ktor.http.cio.websocket.* class Juego(val usuarios: ArrayList>) { private val cartas: Array = GestorJuegos.generarCartas() - val conexiones: HashMap = HashMap() + + internal var jugadores = Array(4) { JugadorBot(this, "Bot $it") } + private val ordenJugadores = Array(4) { "" } - private val manos: HashMap = HashMap() private var gestorDora = GestorDora(cartas) private var estadoJuego = EstadoJuego.Espera private var posCartaActual = 10 @@ -63,42 +64,43 @@ class Juego(val usuarios: ArrayList>) { conexiones.clear() } - private suspend fun enviarDatos(idUsuario: String, ws: WebSocketSession) { - val manosS = HashMap() - - for ((idUsuarioAct, mano) in manos) { - if (idUsuarioAct == idUsuario) { - manosS[idUsuarioAct] = mano - } else { - manosS[idUsuarioAct] = mano.obtenerManoPrivada() - } - } - + private fun obtenerDatosJuegoActuales(): DatosJuego { val idJugadorTurnoActual = ordenJugadores[posJugadorActual] - val doraCerrado = gestorDora.dora - val datosJuego = DatosJuego( - doraCerrado, - manosS, - 108 - posCartaActual, - ordenJugadores, - idJugadorTurnoActual, - gestorDora.turnosRestantesDora, - dragonPartida, - oportunidadesRestantes + return DatosJuego( + dora = arrayListOf(), + manos = hashMapOf(), + cartasRestantes = 108 - posCartaActual, + ordenJugadores = ordenJugadores, + turnoActual = idJugadorTurnoActual, + turnosHastaDora = gestorDora.turnosRestantesDora, + dragonPartida = dragonPartida, + oportunidadesRestantes = oportunidadesRestantes ) - ws.send(Frame.Text("{\"operacion\": \"actualizar_datos\", \"datos\": ${gson.toJson(datosJuego)}}")) } private suspend fun enviarDatosATodos() { - for ((idUsuario, ws) in conexiones) { - enviarDatos(idUsuario, ws) - } + val datosJuego = obtenerDatosJuegoActuales() + + jugadores.forEach { it.enviarDatos(datosJuego) } } suspend fun agregarConexion(idUsuario: String, conexion: WebSocketSession) { - conexiones[idUsuario] = conexion - if (estadoJuego == EstadoJuego.Iniciado) { - enviarDatos(idUsuario, conexion) + // Buscar si el jugador ya existia + jugadores.forEach { + if (it.idUsuario == idUsuario) { + it.actualizarConexion(conexion) + it.enviarDatos(obtenerDatosJuegoActuales()) + return + } + } + + // El jugador es nuevo. Asignarlo. + val nuevoJugador = JugadorHumano(this, idUsuario, conexion) + for (i in 0 until 4) { + if (jugadores[i] !is JugadorBot) { + jugadores[i] = nuevoJugador + break + } } } diff --git a/src/juego/Jugador.kt b/src/juego/Jugador.kt new file mode 100644 index 0000000..9fc4f1c --- /dev/null +++ b/src/juego/Jugador.kt @@ -0,0 +1,80 @@ +package dev.araozu.juego + +import dev.araozu.gson +import io.ktor.http.cio.websocket.* +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +sealed class Jugador(val juego: Juego, val idUsuario: String) { + + abstract val isActive: Boolean + abstract suspend fun send(v: Frame.Text) + val mano = Mano() + + fun inicializarMano(cartas: ArrayList) { + mano.cartas = cartas + } + + abstract fun actualizarConexion(ws: WebSocketSession) + + abstract suspend fun enviarDatos(datos: DatosJuego) + +} + +class JugadorHumano(juego: Juego, idUsuario: String, private var ws: WebSocketSession) : Jugador(juego, idUsuario) { + + override val isActive: Boolean + get() = ws.isActive + + override suspend fun send(v: Frame.Text) { + ws.send(v) + } + + override fun actualizarConexion(ws: WebSocketSession) { + this.ws = ws + } + + override suspend fun enviarDatos(datos: DatosJuego) { + val manos = HashMap() + + juego.jugadores.forEach { + if (it === this) { + manos[idUsuario] = this.mano + } else { + manos[it.idUsuario] = it.mano + } + } + + val datosJuego = datos.copy( + manos = manos + ) + ws.send(Frame.Text("{\"operacion\": \"actualizar_datos\", \"datos\": ${gson.toJson(datosJuego)}}")) + } + +} + +class JugadorBot(juego: Juego, idUsuario: String) : Jugador(juego, idUsuario) { + + override val isActive: Boolean = true + + override suspend fun send(v: Frame.Text) { + println("Bot pensando...") + TODO("Bot no implementado D:") + } + + override fun actualizarConexion(ws: WebSocketSession) {} + + override suspend fun enviarDatos(datos: DatosJuego) { + // Si es turno del bot + GlobalScope.launch { + delay(1000) + } + + // Si el bot tiene una oportunidad + + + } + +} diff --git a/src/juego/Mano.kt b/src/juego/Mano.kt index 44836fb..847adde 100644 --- a/src/juego/Mano.kt +++ b/src/juego/Mano.kt @@ -1,12 +1,12 @@ package dev.araozu.juego data class Mano( - val cartas: ArrayList, + var cartas: ArrayList = arrayListOf(), val cartasReveladas: ArrayList> = arrayListOf(), val descartes: ArrayList = arrayListOf(), var sigCarta: Int = -1, var oportunidades: ArrayList = arrayListOf(), - val dragon: Dragon + val dragon: Dragon = Dragon.Negro ) { fun obtenerManoPrivada(): Mano {