Actualizar la funcion que maneja descartes
This commit is contained in:
parent
f4c0306717
commit
f325a586d3
@ -8,8 +8,8 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
|
|||||||
private val cartas: Array<Int> = GestorJuegos.generarCartas()
|
private val cartas: Array<Int> = GestorJuegos.generarCartas()
|
||||||
|
|
||||||
internal var jugadores = Array<Jugador>(4) { JugadorBot(this, "Bot $it") }
|
internal var jugadores = Array<Jugador>(4) { JugadorBot(this, "Bot $it") }
|
||||||
|
private var ordenJugadores = Array(4) { jugadores[it].idUsuario }
|
||||||
|
|
||||||
private val ordenJugadores = Array(4) { "" }
|
|
||||||
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
|
||||||
@ -17,55 +17,40 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
|
|||||||
private var dragonPartida = Dragon.Negro
|
private var dragonPartida = Dragon.Negro
|
||||||
private var oportunidadesRestantes = 0
|
private var oportunidadesRestantes = 0
|
||||||
|
|
||||||
suspend fun iniciarJuego(ws: WebSocketSession) {
|
suspend fun iniciarJuego() {
|
||||||
if (estadoJuego != EstadoJuego.Espera) return
|
if (estadoJuego != EstadoJuego.Espera) return
|
||||||
|
|
||||||
if (conexiones.size < 4) {
|
|
||||||
ws.send(Frame.Text("{\"operacion\": \"error\", \"razon\": \"Usuarios insuficientes\"}"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
estadoJuego = EstadoJuego.Iniciado
|
estadoJuego = EstadoJuego.Iniciado
|
||||||
|
|
||||||
// Asignar orden de jugadores
|
val nuevoArrJugadores = Array<Jugador>(4) { JugadorBot(this, "-") }
|
||||||
var i = 0
|
val jugadoresRestantes = arrayListOf(0, 1, 2, 3)
|
||||||
val posInicio = (Math.random() * 4).toInt()
|
|
||||||
conexiones.forEach { (idUsuario, _) ->
|
|
||||||
ordenJugadores[i] = idUsuario
|
|
||||||
val dragonActual = Dragon.get(i)
|
|
||||||
|
|
||||||
|
for (i in 0 until 4) {
|
||||||
|
val nuevoIndice = (Math.random() * jugadoresRestantes.size).toInt()
|
||||||
|
nuevoArrJugadores[i] = jugadores[nuevoIndice]
|
||||||
|
jugadoresRestantes.remove(nuevoIndice)
|
||||||
|
}
|
||||||
|
|
||||||
|
dragonPartida = Dragon.get((Math.random() * 4).toInt())
|
||||||
|
|
||||||
|
for ((i, jugador) in nuevoArrJugadores.withIndex()) {
|
||||||
val cartasL = arrayListOf<Int>()
|
val cartasL = arrayListOf<Int>()
|
||||||
|
|
||||||
for (j in posCartaActual until (posCartaActual + 10)) {
|
for (j in posCartaActual until (posCartaActual + 10)) {
|
||||||
cartasL.add(cartas[j])
|
cartasL.add(cartas[j])
|
||||||
}
|
}
|
||||||
posCartaActual += 10
|
posCartaActual += 10
|
||||||
|
|
||||||
val mano = if (i == posInicio) {
|
jugador.inicializarCartas(cartasL)
|
||||||
val sigCarta = cartas[posCartaActual]
|
jugador.inicializarDragon(Dragon.get(i))
|
||||||
posCartaActual++
|
jugador.send(Frame.Text("{\"operacion\": \"juego_iniciado\"}"))
|
||||||
gestorDora.actualizarDora()
|
|
||||||
dragonPartida = dragonActual
|
|
||||||
posJugadorActual = i
|
|
||||||
|
|
||||||
Mano(cartasL, sigCarta = sigCarta, dragon = dragonActual)
|
|
||||||
} else {
|
|
||||||
Mano(cartasL, dragon = dragonActual)
|
|
||||||
}
|
|
||||||
|
|
||||||
manos[idUsuario] = mano
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conexiones.forEach { (_, socket) ->
|
jugadores = nuevoArrJugadores
|
||||||
socket.send(Frame.Text("{\"operacion\": \"juego_iniciado\"}"))
|
ordenJugadores = Array(4) { jugadores[it].idUsuario }
|
||||||
}
|
|
||||||
|
|
||||||
conexiones.clear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun obtenerDatosJuegoActuales(): DatosJuego {
|
private fun obtenerDatosJuegoActuales(): DatosJuego {
|
||||||
val idJugadorTurnoActual = ordenJugadores[posJugadorActual]
|
val idJugadorTurnoActual = jugadores[posJugadorActual].idUsuario
|
||||||
return DatosJuego(
|
return DatosJuego(
|
||||||
dora = arrayListOf(),
|
dora = arrayListOf(),
|
||||||
manos = hashMapOf(),
|
manos = hashMapOf(),
|
||||||
@ -85,6 +70,8 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun agregarConexion(idUsuario: String, conexion: WebSocketSession) {
|
suspend fun agregarConexion(idUsuario: String, conexion: WebSocketSession) {
|
||||||
|
if (estadoJuego != EstadoJuego.Espera) return
|
||||||
|
|
||||||
// Buscar si el jugador ya existia
|
// Buscar si el jugador ya existia
|
||||||
jugadores.forEach {
|
jugadores.forEach {
|
||||||
if (it.idUsuario == idUsuario) {
|
if (it.idUsuario == idUsuario) {
|
||||||
@ -113,95 +100,33 @@ class Juego(val usuarios: ArrayList<Pair<String, Boolean>>) {
|
|||||||
posJugadorActual = (posJugadorActual + 1) % 4
|
posJugadorActual = (posJugadorActual + 1) % 4
|
||||||
oportunidadesRestantes = 0
|
oportunidadesRestantes = 0
|
||||||
|
|
||||||
val idSigUsuario = ordenJugadores[posJugadorActual]
|
// Si se acabaron las cartas
|
||||||
|
if (posCartaActual >= cartas.size) {
|
||||||
|
estadoJuego = EstadoJuego.Terminado
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Extraer sig carta. TODO: Verificar que no quedan cartas y establecer empate
|
// Sino
|
||||||
val sigCarta = cartas[posCartaActual]
|
val sigCarta = cartas[posCartaActual]
|
||||||
posCartaActual++
|
posCartaActual++
|
||||||
|
|
||||||
// Asignar nueva carta
|
// Asignar carta
|
||||||
val manoSigJugador = manos[idSigUsuario]!!
|
jugadores[posJugadorActual].recibirCarta(sigCarta)
|
||||||
manoSigJugador.sigCarta = sigCarta
|
// Verificar Tsumo
|
||||||
|
jugadores[posJugadorActual].verificarTsumo()
|
||||||
// TODO: Arreglar. Roto.
|
|
||||||
val oportunidadWin = OportunidadWin.verificar(sigCarta, manoSigJugador.cartas, manoSigJugador.cartasReveladas)
|
|
||||||
if (oportunidadWin != null) {
|
|
||||||
manoSigJugador.oportunidades.add(oportunidadWin)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun esUsuarioIzq(idUsuarioIzq: String, idUsuario1: String): Boolean {
|
suspend fun manejarDescarte(idUsuario: String, cartaDescartada: Int) {
|
||||||
var posUsuario1 = 0
|
// Si un jugador del que no es turno intenta descartar
|
||||||
var posUsuarioIzq = 0
|
if (jugadores[posJugadorActual].idUsuario != idUsuario) return
|
||||||
for ((posActual, idUsuario) in ordenJugadores.withIndex()) {
|
|
||||||
if (idUsuario == idUsuario1) posUsuario1 = posActual
|
|
||||||
if (idUsuario == idUsuarioIzq) posUsuarioIzq = posActual
|
|
||||||
}
|
|
||||||
return (posUsuarioIzq + 1) % 4 == posUsuario1
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun manejarDescarte(idUsuario: String, carta: Int) {
|
|
||||||
if (ordenJugadores[posJugadorActual] != idUsuario) return
|
|
||||||
|
|
||||||
// Si el jugador del turno actual ya descarto, otros jugadores tienen oportunidades
|
// Si el jugador del turno actual ya descarto, otros jugadores tienen oportunidades
|
||||||
// e intento descartar de nuevo
|
// e intento descartar de nuevo
|
||||||
if (oportunidadesRestantes > 0) return
|
if (oportunidadesRestantes > 0) return
|
||||||
|
|
||||||
val m = manos[idUsuario]!!
|
val cantidadOportunidades = jugadores[posJugadorActual].descartarCarta(cartaDescartada)
|
||||||
|
|
||||||
if (m.sigCarta == carta) {
|
if (cantidadOportunidades > 0) {
|
||||||
m.sigCarta = -1
|
|
||||||
} else {
|
|
||||||
val posCarta = m.cartas.indexOf(carta)
|
|
||||||
if (posCarta != -1) {
|
|
||||||
m.cartas.removeAt(posCarta)
|
|
||||||
|
|
||||||
// Tras llamar un Seq/Tri el jugador no tiene una carta adicional en su mano.
|
|
||||||
if (m.sigCarta != -1) m.cartas.add(m.sigCarta)
|
|
||||||
|
|
||||||
m.sigCarta = -1
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.descartes.add(carta)
|
|
||||||
|
|
||||||
// Verificar seq/tri/win
|
|
||||||
var hayOportunidades = false
|
|
||||||
for ((idUsuarioActual, mano) in manos) {
|
|
||||||
// No buscar oportunidades en el usuario que acaba de descartar.
|
|
||||||
if (idUsuarioActual == idUsuario) continue
|
|
||||||
|
|
||||||
// Solo verificar seq en el jugador a la derecha del que descarto
|
|
||||||
if (esUsuarioIzq(idUsuario, idUsuarioActual)) {
|
|
||||||
val oportunidadSeq = OportunidadSeq.verificar(carta, mano.cartas)
|
|
||||||
if (oportunidadSeq != null) {
|
|
||||||
hayOportunidades = true
|
|
||||||
oportunidadesRestantes++
|
|
||||||
mano.oportunidades.add(oportunidadSeq)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Oportunidades tri
|
|
||||||
val oportunidadTri = OportunidadTri.verificar(carta, mano.cartas)
|
|
||||||
if (oportunidadTri != null) {
|
|
||||||
hayOportunidades = true
|
|
||||||
oportunidadesRestantes++
|
|
||||||
mano.oportunidades.add(oportunidadTri)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Oportunidades win (ron)
|
|
||||||
val oportunidadWin = OportunidadWin.verificar(carta, mano.cartas, mano.cartasReveladas)
|
|
||||||
if (oportunidadWin != null) {
|
|
||||||
hayOportunidades = true
|
|
||||||
oportunidadesRestantes++
|
|
||||||
mano.oportunidades.add(oportunidadWin)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hayOportunidades) {
|
|
||||||
// Enviar datos
|
// Enviar datos
|
||||||
enviarDatosATodos()
|
enviarDatosATodos()
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,14 +13,75 @@ sealed class Jugador(val juego: Juego, val idUsuario: String) {
|
|||||||
abstract suspend fun send(v: Frame.Text)
|
abstract suspend fun send(v: Frame.Text)
|
||||||
val mano = Mano()
|
val mano = Mano()
|
||||||
|
|
||||||
fun inicializarMano(cartas: ArrayList<Int>) {
|
fun inicializarCartas(cartas: ArrayList<Int>) {
|
||||||
mano.cartas = cartas
|
mano.cartas = cartas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun inicializarDragon(dragon: Dragon) {
|
||||||
|
mano.dragon = dragon
|
||||||
|
}
|
||||||
|
|
||||||
abstract fun actualizarConexion(ws: WebSocketSession)
|
abstract fun actualizarConexion(ws: WebSocketSession)
|
||||||
|
|
||||||
abstract suspend fun enviarDatos(datos: DatosJuego)
|
abstract suspend fun enviarDatos(datos: DatosJuego)
|
||||||
|
|
||||||
|
fun recibirCarta(carta: Int) {
|
||||||
|
mano.sigCarta = carta
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intenta descartar una carta de la mano y devuelve si dicho descarte
|
||||||
|
* brinda oportunidades a otros jugadores
|
||||||
|
* @param cartaDescartada La carta a remover de la mano
|
||||||
|
* @return La cantidad de oportunidades
|
||||||
|
*/
|
||||||
|
fun descartarCarta(cartaDescartada: Int): Int {
|
||||||
|
val cartaFueDescartada = mano.descartarCarta(cartaDescartada)
|
||||||
|
|
||||||
|
if (!cartaFueDescartada) return -1
|
||||||
|
|
||||||
|
var oportunidadesRestantes = 0
|
||||||
|
var posicionJugadorActual = -1
|
||||||
|
for ((i, jugador) in juego.jugadores.withIndex()) {
|
||||||
|
if (this === jugador) {
|
||||||
|
posicionJugadorActual = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var hayOportunidad = false
|
||||||
|
val mano = jugador.mano
|
||||||
|
|
||||||
|
// Verificar seq en jugador a la derecha
|
||||||
|
if ((posicionJugadorActual + 1) % 4 == i) {
|
||||||
|
val oportunidadSeq = OportunidadSeq.verificar(cartaDescartada, mano.cartas)
|
||||||
|
if (oportunidadSeq != null) {
|
||||||
|
hayOportunidad = true
|
||||||
|
mano.oportunidades.add(oportunidadSeq)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Oportunidades tri
|
||||||
|
val oportunidadTri = OportunidadTri.verificar(cartaDescartada, mano.cartas)
|
||||||
|
if (oportunidadTri != null) {
|
||||||
|
hayOportunidad = true
|
||||||
|
mano.oportunidades.add(oportunidadTri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Oportunidades win (ron)
|
||||||
|
val oportunidadWin = OportunidadWin.verificar(cartaDescartada, mano.cartas, mano.cartasReveladas)
|
||||||
|
if (oportunidadWin != null) {
|
||||||
|
hayOportunidad = true
|
||||||
|
mano.oportunidades.add(oportunidadWin)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hayOportunidad) oportunidadesRestantes++
|
||||||
|
}
|
||||||
|
|
||||||
|
return oportunidadesRestantes
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun verificarTsumo()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JugadorHumano(juego: Juego, idUsuario: String, private var ws: WebSocketSession) : Jugador(juego, idUsuario) {
|
class JugadorHumano(juego: Juego, idUsuario: String, private var ws: WebSocketSession) : Jugador(juego, idUsuario) {
|
||||||
@ -53,6 +114,10 @@ class JugadorHumano(juego: Juego, idUsuario: String, private var ws: WebSocketSe
|
|||||||
ws.send(Frame.Text("{\"operacion\": \"actualizar_datos\", \"datos\": ${gson.toJson(datosJuego)}}"))
|
ws.send(Frame.Text("{\"operacion\": \"actualizar_datos\", \"datos\": ${gson.toJson(datosJuego)}}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun verificarTsumo() {
|
||||||
|
System.err.println("Tsumo no implementado D:")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JugadorBot(juego: Juego, idUsuario: String) : Jugador(juego, idUsuario) {
|
class JugadorBot(juego: Juego, idUsuario: String) : Jugador(juego, idUsuario) {
|
||||||
@ -77,4 +142,8 @@ class JugadorBot(juego: Juego, idUsuario: String) : Jugador(juego, idUsuario) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun verificarTsumo() {
|
||||||
|
System.err.println("Tsumo no implementado D:")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ data class Mano(
|
|||||||
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 = Dragon.Negro
|
var dragon: Dragon = Dragon.Negro
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun obtenerManoPrivada(): Mano {
|
fun obtenerManoPrivada(): Mano {
|
||||||
@ -19,6 +19,41 @@ data class Mano(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validarHay10Cartas(): Boolean =
|
||||||
|
cartas.size + (cartasReveladas.size * 3) + (if (sigCarta != -1) 1 else 0) - 1 == 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intenta descartar una carta de la mano y devuelve si fue correcto
|
||||||
|
* @param cartaDescartada La carta a remover de la mano
|
||||||
|
* @return true si se descarto la carta, false sino
|
||||||
|
*/
|
||||||
|
fun descartarCarta(cartaDescartada: Int): Boolean {
|
||||||
|
if (!validarHay10Cartas()) {
|
||||||
|
System.err.println("Error al descartar carta: Hacerlo dejaria al jugador con menos de 10 cartas")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigCarta == cartaDescartada) {
|
||||||
|
sigCarta = -1
|
||||||
|
} else {
|
||||||
|
val posCarta = cartas.indexOf(cartaDescartada)
|
||||||
|
if (posCarta != -1) {
|
||||||
|
cartas.removeAt(posCarta)
|
||||||
|
|
||||||
|
// Incluir la carta entrante a la mano del jugador
|
||||||
|
if (sigCarta != -1) {
|
||||||
|
cartas.add(sigCarta)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.err.println("Error al descartar carta: El jugador no tiene dicha carta.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
descartes.add(cartaDescartada)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Cachear la mano privada y actualizarla solo cuando se llama tri/seq
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user