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>>) {
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 manos: HashMap<String, Mano> = HashMap()
private var gestorDora = GestorDora(cartas)
private var estadoJuego = EstadoJuego.Espera
private var posCartaActual = 10
@ -63,42 +64,43 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
conexiones.clear()
}
private suspend fun enviarDatos(idUsuario: String, ws: WebSocketSession) {
val manosS = HashMap<String, Mano>()
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
}
}
}

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
data class Mano(
val cartas: ArrayList<Int>,
var cartas: ArrayList<Int> = arrayListOf(),
val cartasReveladas: ArrayList<ArrayList<Int>> = arrayListOf(),
val descartes: ArrayList<Int> = arrayListOf(),
var sigCarta: Int = -1,
var oportunidades: ArrayList<Oportunidad> = arrayListOf(),
val dragon: Dragon
val dragon: Dragon = Dragon.Negro
) {
fun obtenerManoPrivada(): Mano {