feat: Implement multiplayer game session management
Some checks failed
Build & Deploy Farolero / Análisis de código (push) Has been cancelled
Build & Deploy Farolero / Build APK + AAB release (push) Has been cancelled

- Add models for managing player assignments and game session initialization in `inicio_partida_multijugador.dart`.
- Create a multiplayer room state management system in `sala_multijugador.dart`, including user registration, selection, and session validation.
- Develop a UI screen for displaying player words sequentially in `pantalla_palabras_cliente.dart`.
- Implement unit tests for the multiplayer session management and player assignment logic in `inicio_partida_multijugador_test.dart` and `sala_multijugador_test.dart`.
This commit is contained in:
Javier Bautista Fernández
2026-04-27 14:02:33 +02:00
parent 4a1abd0be0
commit a8d5b0f002
14 changed files with 1779 additions and 421 deletions

View File

@@ -0,0 +1,117 @@
class AsignacionJugador {
final String jugadorId;
final String nombre;
final String clientId;
final String? endpointId;
const AsignacionJugador({
required this.jugadorId,
required this.nombre,
required this.clientId,
required this.endpointId,
});
}
class JugadorInicioPartida {
final String jugadorId;
final String nombre;
final bool esImpostor;
final String? palabra;
const JugadorInicioPartida({
required this.jugadorId,
required this.nombre,
required this.esImpostor,
required this.palabra,
});
Map<String, dynamic> toJson() => {
'jugadorId': jugadorId,
'nombre': nombre,
'esImpostor': esImpostor,
if (palabra != null) 'palabra': palabra,
};
factory JugadorInicioPartida.fromJson(Map<String, dynamic> json) {
return JugadorInicioPartida(
jugadorId: json['jugadorId'] as String,
nombre: json['nombre'] as String,
esImpostor: json['esImpostor'] as bool? ?? false,
palabra: json['palabra'] as String?,
);
}
}
class InicioPartidaCliente {
final String clientId;
final String? endpointId;
final String categoria;
final List<JugadorInicioPartida> jugadores;
const InicioPartidaCliente({
required this.clientId,
required this.endpointId,
required this.categoria,
required this.jugadores,
});
Map<String, dynamic> toJson() => {
'clientId': clientId,
if (endpointId != null) 'endpointId': endpointId,
'categoria': categoria,
'jugadores': jugadores.map((jugador) => jugador.toJson()).toList(),
};
factory InicioPartidaCliente.fromJson(Map<String, dynamic> json) {
return InicioPartidaCliente(
clientId: json['clientId'] as String,
endpointId: json['endpointId'] as String?,
categoria: json['categoria'] as String,
jugadores: (json['jugadores'] as List<dynamic>? ?? [])
.map((jugadorJson) => JugadorInicioPartida.fromJson(
jugadorJson as Map<String, dynamic>,
))
.toList(),
);
}
}
class InicioPartidaMultijugador {
static Map<String, InicioPartidaCliente> crearPayloadsPorCliente({
required List<AsignacionJugador> asignaciones,
required String palabraSecreta,
required String categoria,
required Map<String, bool> impostoresPorJugadorId,
}) {
final payloads = <String, InicioPartidaCliente>{};
for (final asignacion in asignaciones) {
final esImpostor = impostoresPorJugadorId[asignacion.jugadorId] ?? false;
final payloadActual = payloads[asignacion.clientId];
final jugador = JugadorInicioPartida(
jugadorId: asignacion.jugadorId,
nombre: asignacion.nombre,
esImpostor: esImpostor,
palabra: esImpostor ? null : palabraSecreta,
);
if (payloadActual == null) {
payloads[asignacion.clientId] = InicioPartidaCliente(
clientId: asignacion.clientId,
endpointId: asignacion.endpointId,
categoria: categoria,
jugadores: [jugador],
);
} else {
payloads[asignacion.clientId] = InicioPartidaCliente(
clientId: payloadActual.clientId,
endpointId: payloadActual.endpointId,
categoria: payloadActual.categoria,
jugadores: [...payloadActual.jugadores, jugador],
);
}
}
return payloads;
}
}