Empezar a modificar arquitectura para posteriormente implementar bots

master
Araozu 2020-12-26 17:37:35 -05:00
parent d07651c28b
commit f4c0306717
3 changed files with 114 additions and 32 deletions

View File

@ -6,9 +6,10 @@ import io.ktor.http.cio.websocket.*
class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) { class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
private val cartas: Array<Int> = GestorJuegos.generarCartas() private val cartas: Array<Int> = GestorJuegos.generarCartas()
val conexiones: HashMap<String, WebSocketSession> = HashMap()
internal var jugadores = Array<Jugador>(4) { JugadorBot(this, "Bot $it") }
private val ordenJugadores = Array(4) { "" } private val ordenJugadores = Array(4) { "" }
private val manos: HashMap<String, Mano> = HashMap()
private var gestorDora = GestorDora(cartas) private var gestorDora = GestorDora(cartas)
private var estadoJuego = EstadoJuego.Espera private var estadoJuego = EstadoJuego.Espera
private var posCartaActual = 10 private var posCartaActual = 10
@ -63,42 +64,43 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
conexiones.clear() conexiones.clear()
} }
private suspend fun enviarDatos(idUsuario: String, ws: WebSocketSession) { private fun obtenerDatosJuegoActuales(): DatosJuego {
val manosS = HashMap<String, Mano>()
for ((idUsuarioAct, mano) in manos) {
if (idUsuarioAct == idUsuario) {
manosS[idUsuarioAct] = mano
} else {
manosS[idUsuarioAct] = mano.obtenerManoPrivada()
}
}
val idJugadorTurnoActual = ordenJugadores[posJugadorActual] val idJugadorTurnoActual = ordenJugadores[posJugadorActual]
val doraCerrado = gestorDora.dora return DatosJuego(
val datosJuego = DatosJuego( dora = arrayListOf(),
doraCerrado, manos = hashMapOf(),
manosS, cartasRestantes = 108 - posCartaActual,
108 - posCartaActual, ordenJugadores = ordenJugadores,
ordenJugadores, turnoActual = idJugadorTurnoActual,
idJugadorTurnoActual, turnosHastaDora = gestorDora.turnosRestantesDora,
gestorDora.turnosRestantesDora, dragonPartida = dragonPartida,
dragonPartida, oportunidadesRestantes = oportunidadesRestantes
oportunidadesRestantes
) )
ws.send(Frame.Text("{\"operacion\": \"actualizar_datos\", \"datos\": ${gson.toJson(datosJuego)}}"))
} }
private suspend fun enviarDatosATodos() { private suspend fun enviarDatosATodos() {
for ((idUsuario, ws) in conexiones) { val datosJuego = obtenerDatosJuegoActuales()
enviarDatos(idUsuario, ws)
} jugadores.forEach { it.enviarDatos(datosJuego) }
} }
suspend fun agregarConexion(idUsuario: String, conexion: WebSocketSession) { suspend fun agregarConexion(idUsuario: String, conexion: WebSocketSession) {
conexiones[idUsuario] = conexion // Buscar si el jugador ya existia
if (estadoJuego == EstadoJuego.Iniciado) { jugadores.forEach {
enviarDatos(idUsuario, conexion) 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
}
} }
} }

80
src/juego/Jugador.kt Normal file
View File

@ -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<Int>) {
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<String, Mano>()
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
}
}

View File

@ -1,12 +1,12 @@
package dev.araozu.juego package dev.araozu.juego
data class Mano( data class Mano(
val cartas: ArrayList<Int>, var cartas: ArrayList<Int> = arrayListOf(),
val cartasReveladas: ArrayList<ArrayList<Int>> = arrayListOf(), val cartasReveladas: ArrayList<ArrayList<Int>> = arrayListOf(),
val descartes: ArrayList<Int> = arrayListOf(), val descartes: ArrayList<Int> = arrayListOf(),
var sigCarta: Int = -1, var sigCarta: Int = -1,
var oportunidades: ArrayList<Oportunidad> = arrayListOf(), var oportunidades: ArrayList<Oportunidad> = arrayListOf(),
val dragon: Dragon val dragon: Dragon = Dragon.Negro
) { ) {
fun obtenerManoPrivada(): Mano { fun obtenerManoPrivada(): Mano {