4 Commits

4 changed files with 488 additions and 460 deletions
+158 -164
View File
@@ -7,17 +7,27 @@ class Partida
public $idPartida; public $idPartida;
public $nombrePartida; public $nombrePartida;
public $idUsuario; public $idUsuario;
public $fechaCreacion;
public $fechaInicio;
public $fechaFin;
public function __construct( public function __construct(
$idPartida = null, $idPartida = null,
$nombrePartida = null, $nombrePartida = null,
$idUsuario = null $idUsuario = null,
$fechaCreacion = null,
$fechaInicio = null,
$fechaFin = null
) { ) {
$this->idPartida = $idPartida; $this->idPartida = $idPartida;
$this->nombrePartida = $nombrePartida; $this->nombrePartida = $nombrePartida;
$this->idUsuario = $idUsuario; $this->idUsuario = $idUsuario;
$this->fechaCreacion = $fechaCreacion;
$this->fechaInicio = $fechaInicio;
$this->fechaFin = $fechaFin;
} }
public function insertar() public function insertar()
{ {
$conexion = conexionBD(); $conexion = conexionBD();
@@ -25,12 +35,7 @@ class Partida
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("INSERT INTO partida (nombrePartida,idUsuario) VALUES (:nombrePartida,:idUsuario)");
INSERT INTO partida
(nombrePartida,idUsuario)
VALUES
(:nombrePartida,:idUsuario)
");
$consulta->bindParam(":nombrePartida", $this->nombrePartida); $consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute(); $consulta->execute();
@@ -46,8 +51,7 @@ class Partida
} }
} }
public function listar() public function listar(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
@@ -64,18 +68,13 @@ class Partida
} }
} }
public function buscar() public function buscar(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("SELECT * FROM partida WHERE idPartida=:idPartida");
SELECT *
FROM partida
WHERE idPartida=:idPartida
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute(); $consulta->execute();
return $consulta->fetch(PDO::FETCH_ASSOC); return $consulta->fetch(PDO::FETCH_ASSOC);
@@ -87,20 +86,14 @@ class Partida
} }
} }
public function editar()
{ public function editar(){
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("UPDATE partida SET nombrePartida=:nombrePartida, idUsuario=:idUsuario WHERE idPartida=:idPartida");
UPDATE partida
SET
nombrePartida=:nombrePartida,
idUsuario=:idUsuario
WHERE idPartida=:idPartida
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":nombrePartida", $this->nombrePartida); $consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->bindParam(":idUsuario", $this->idUsuario);
@@ -117,17 +110,13 @@ class Partida
} }
} }
public function eliminar() public function eliminar(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("DELETE FROM partida WHERE idPartida=:idPartida");
DELETE FROM partida
WHERE idPartida=:idPartida
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute(); $consulta->execute();
return [ return [
@@ -142,27 +131,121 @@ class Partida
} }
} }
/**
* Devuelve las preguntas asignadas a la partida, junto con el public function iniciarPartida(){
* idPartidaxPregunta (necesario para guardar respuestas después). $conexion = conexionBD();
*/ if (is_array($conexion)){
public function getPreguntas() return $conexion;
{ }
try {
$consulta = $conexion->prepare("UPDATE partida SET fechaInicio=NOW() WHERE idPartida=:idPartida AND fechaInicio IS NULL");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
"exito" => "La partida ha comenzado.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al iniciar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function finalizar(){
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("UPDATE partida SET fechaFin=NOW() WHERE idPartida=:idPartida AND fechaFin IS NULL");
SELECT $consulta->bindParam(":idPartida", $this->idPartida);
pxp.idPartidaxPregunta, $consulta->execute();
p.* return [
FROM partidaxpregunta pxp "exito" => "La partida se finalizó correctamente.",
INNER JOIN pregunta p "exito_tecnico" => $this->idPartida
ON pxp.idPregunta=p.idPregunta ];
WHERE pxp.idPartida=:idPartida } catch (PDOException $error) {
ORDER BY pxp.idPartidaxPregunta return [
"); "error" => "Ocurrió un error al finalizar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
//true si la partida ya tiene fecha de fin (fechaFin no es NULL)
//Devuelve false si la partida no existe
public function estaFinalizada() {
$datos = $this->buscar();
if (is_array($datos) && isset($datos["error"])) {
return $datos;
}
if (!$datos) {
return false;
}
return $datos["fechaFin"] !== null;
}
//Devuelve la partida más reciente del usuario que aún no ha
//terminado (fechaFin NULL), o false si no tiene ninguna.
//Incluye también las salas que todavía no han empezado.
public function partidaEnCursoDeUsuario(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idUsuario=:idUsuario AND fechaFin IS NULL ORDER BY idPartida DESC LIMIT 1");
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return $consulta->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al buscar la partida en curso.",
'error_tecnico' => $error->getMessage()
];
}
}
public function listarSalasAbiertas() {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT p.idPartida, p.nombrePartida, e.idEquipo, e.nombreEquipo, u.idUsuario, u.nombreUsuario
FROM partida p INNER JOIN equipoxpartida exp ON exp.idPartida=p.idPartida INNER JOIN equipo e ON e.idEquipo=exp.idEquipo
LEFT JOIN equipoxusuario exu ON exu.idEquipo=e.idEquipo LEFT JOIN usuario u ON u.idUsuario=exu.idUsuario WHERE p.fechaInicio IS NULL
AND p.fechaFin IS NULL ORDER BY p.idPartida DESC, e.idEquipo ASC");
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al recuperar las salas abiertas.",
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Devuelve las preguntas asignadas a la partida, junto con el
* idPartidaxPregunta (necesario para guardar respuestas después).
*/
public function getPreguntas(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT pxp.idPartidaxPregunta, p.* FROM partidaxpregunta pxp INNER JOIN pregunta p ON pxp.idPregunta=p.idPregunta
WHERE pxp.idPartida=:idPartida ORDER BY pxp.idPartidaxPregunta");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute(); $consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC); return $consulta->fetchAll(PDO::FETCH_ASSOC);
@@ -174,22 +257,14 @@ class Partida
} }
} }
/**
* Asocia una pregunta ya existente a esta partida. public function asignarPregunta($idPregunta) {
*/
public function asignarPregunta($idPregunta)
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("INSERT INTO partidaxpregunta (idPartida,idPregunta) VALUES (:idPartida,:idPregunta)");
INSERT INTO partidaxpregunta
(idPartida,idPregunta)
VALUES
(:idPartida,:idPregunta)
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta); $consulta->bindParam(":idPregunta", $idPregunta);
$consulta->execute(); $consulta->execute();
@@ -205,18 +280,13 @@ class Partida
} }
} }
//Cuenta cuántas preguntas tiene la partida en total. Es la primera mitad de la comprobación "¿ha terminado el usuario de jugar?". //Cuenta cuántas preguntas tiene la partida en total. Es la primera mitad de la comprobación "¿ha terminado el usuario de jugar?".
public function contarPreguntasAsignadas() public function contarPreguntasAsignadas() {
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida");
SELECT COUNT(*) AS total
FROM partidaxpregunta
WHERE idPartida=:idPartida
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute(); $consulta->execute();
$fila = $consulta->fetch(PDO::FETCH_ASSOC); $fila = $consulta->fetch(PDO::FETCH_ASSOC);
@@ -229,21 +299,14 @@ class Partida
} }
} }
public function contarRespuestasUsuario($idUsuario) public function contarRespuestasUsuario($idUsuario){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM respuestaalmacenada ra INNER JOIN partidaxpregunta pxp
SELECT COUNT(*) AS total ON ra.idPartidaxPregunta=pxp.idPartidaxPregunta WHERE pxp.idPartida=:idPartida AND ra.idUsuario=:idUsuario");
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp
ON ra.idPartidaxPregunta=pxp.idPartidaxPregunta
WHERE pxp.idPartida=:idPartida
AND ra.idUsuario=:idUsuario
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idUsuario", $idUsuario); $consulta->bindParam(":idUsuario", $idUsuario);
$consulta->execute(); $consulta->execute();
@@ -258,11 +321,11 @@ class Partida
} }
/** /**
* Sustituye al antiguo campo `terminada`: compara cuántas preguntas * Indica si ESTE usuario ya ha respondido todas las preguntas:
* tiene la partida contra cuántas ha respondido este usuario. * compara cuántas preguntas tiene la partida contra cuántas ha
* respondido él. (La partida completa se marca con finalizar().)
*/ */
public function estaFinalizadaParaUsuario($idUsuario) public function estaFinalizadaParaUsuario($idUsuario){
{
$totalPreguntas = $this->contarPreguntasAsignadas(); $totalPreguntas = $this->contarPreguntasAsignadas();
if (is_array($totalPreguntas)) { if (is_array($totalPreguntas)) {
return $totalPreguntas; return $totalPreguntas;
@@ -277,19 +340,13 @@ class Partida
/** /**
* Partidas creadas por un usuario, de más reciente a más antigua. * Partidas creadas por un usuario, de más reciente a más antigua.
*/ */
public function listarDelUsuario() public function listarDelUsuario(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("SELECT * FROM partida WHERE idUsuario=:idUsuario ORDER BY idPartida DESC");
SELECT *
FROM partida
WHERE idUsuario=:idUsuario
ORDER BY idPartida DESC
");
$consulta->bindParam(":idUsuario", $this->idUsuario); $consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute(); $consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC); return $consulta->fetchAll(PDO::FETCH_ASSOC);
@@ -301,22 +358,13 @@ class Partida
} }
} }
public function preguntaAsignada($idPregunta) public function preguntaAsignada($idPregunta) {
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida AND idPregunta=:idPregunta");
SELECT COUNT(*) AS total
FROM partidaxpregunta
WHERE idPartida=:idPartida
AND idPregunta=:idPregunta
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta); $consulta->bindParam(":idPregunta", $idPregunta);
$consulta->execute(); $consulta->execute();
@@ -336,24 +384,13 @@ class Partida
* Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'. * Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'.
* Permite registrar qué grupos están participando en este torneo. * Permite registrar qué grupos están participando en este torneo.
*/ */
public function registrarEquipoEnPartida($idEquipo) public function registrarEquipoEnPartida($idEquipo){
{ $conexion = conexionBD();
$conexion = conexionBD(); // Obtenemos la conexión modular del proyecto
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; // Si hay error en la conexión, lo devuelve return $conexion;
} }
try { try {
// Preparamos la consulta para insertar la relación en la tabla intermedia real $consulta = $conexion->prepare("INSERT INTO equipoxpartida (idPartida, idEquipo) VALUES (:idPartida, :idEquipo)");
$consulta = $conexion->prepare("
INSERT INTO equipoxpartida
(idPartida, idEquipo)
VALUES
(:idPartida, :idEquipo)
");
// Vinculamos los parámetros con el objeto de la partida actual y el equipo recibido
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idEquipo", $idEquipo); $consulta->bindParam(":idEquipo", $idEquipo);
$consulta->execute(); $consulta->execute();
@@ -363,7 +400,6 @@ class Partida
"exito_tecnico" => $conexion->lastInsertId() "exito_tecnico" => $conexion->lastInsertId()
]; ];
} catch (PDOException $error) { } catch (PDOException $error) {
// Capturamos el error extrayendo solo el mensaje de texto limpio
return [ return [
"error" => "Ocurrió un error al asignar el equipo a la partida.", "error" => "Ocurrió un error al asignar el equipo a la partida.",
"error_tecnico" => $error->getMessage() "error_tecnico" => $error->getMessage()
@@ -375,28 +411,14 @@ class Partida
* Obtiene todos los equipos que están compitiendo en esta partida. * Obtiene todos los equipos que están compitiendo en esta partida.
* Es útil para mostrar la lista de rivales antes de empezar a responder. * Es útil para mostrar la lista de rivales antes de empezar a responder.
*/ */
public function getEquiposParticipantes() public function getEquiposParticipantes(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
// Hacemos un INNER JOIN para traer los nombres de los equipos desde la tabla intermedia $consulta = $conexion->prepare("SELECT exp.idEquipoxPartida, e.idEquipo, e.nombreEquipo FROM equipoxpartida exp
$consulta = $conexion->prepare(" INNER JOIN equipo e ON exp.idEquipo = e.idEquipo WHERE exp.idPartida = :idPartida ORDER BY e.nombreEquipo ASC");
SELECT
exp.idEquipoxPartida,
e.idEquipo,
e.nombreEquipo
FROM equipoxpartida exp
INNER JOIN equipo e
ON exp.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC
");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute(); $consulta->execute();
@@ -413,54 +435,26 @@ class Partida
* Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida. * Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida.
* Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos. * Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos.
*/ */
public function getJugadoresDeLaPartida() public function getJugadoresDeLaPartida(){
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} }
try { try {
$consulta = $conexion->prepare("SELECT DISTINCT u.idUsuario, u.nombreUsuario, u.email, e.idEquipo, e.nombreEquipo
$consulta = $conexion->prepare(" FROM equipoxpartida exp INNER JOIN equipoxusuario exu ON exp.idEquipo = exu.idEquipo INNER JOIN usuario u
SELECT DISTINCT ON exu.idUsuario = u.idUsuario INNER JOIN equipo e ON exu.idEquipo = e.idEquipo WHERE exp.idPartida = :idPartida
u.idUsuario, ORDER BY e.nombreEquipo ASC, u.nombreUsuario ASC");
u.nombreUsuario,
u.email,
e.idEquipo,
e.nombreEquipo
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu
ON exp.idEquipo = exu.idEquipo
INNER JOIN usuario u
ON exu.idUsuario = u.idUsuario
INNER JOIN equipo e
ON exu.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC,
u.nombreUsuario ASC
");
$consulta->bindParam( $consulta->bindParam(
":idPartida", ":idPartida",
$this->idPartida $this->idPartida
); );
$consulta->execute(); $consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC); return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) { } catch (PDOException $error) {
return [ return [
"error" => "error" =>
"Ocurrió un error al obtener la lista de jugadores.", "Ocurrió un error al obtener la lista de jugadores.",
"error_tecnico" => "error_tecnico" =>
$error->getMessage() $error->getMessage()
]; ];
+166
View File
@@ -0,0 +1,166 @@
<?php
session_start();
require_once $_SERVER['DOCUMENT_ROOT'] . '/triviagmatico/includes/conexionBD.php';
header('Content-Type: application/json; charset=utf-8');
if (!isset($_SESSION['idUsuario'])) {
echo json_encode(['error' => 'Sesión no iniciada']);
exit;
}
$idPartida = intval($_POST['idPartida'] ?? 0);
$orden = $_POST['orden'] ?? '';
if ($idPartida <= 0) {
echo json_encode(['error' => 'Partida no válida']);
exit;
}
$conexion = conexionBD();
if (is_array($conexion)) {
echo json_encode($conexion);
exit;
}
switch ($orden) {
case 'comprobarEstado':
try {
// Contar jugadores totales apuntados en los equipos de esta partida
$stmt = $conexion->prepare("
SELECT COUNT(exu.idUsuario) AS total_jugadores
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu ON exp.idEquipo = exu.idEquipo
WHERE exp.idPartida = :idPartida
");
$stmt->execute([':idPartida' => $idPartida]);
$totalJugadores = (int)$stmt->fetchColumn();
$preguntasTotalesEsperadas = $totalJugadores * 10;
// Contar respuestas dadas en la partida
$stmtRespuestas = $conexion->prepare("
SELECT COUNT(*)
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta
WHERE pxp.idPartida = :idPartida
");
$stmtRespuestas->execute([':idPartida' => $idPartida]);
$respuestasRespondidas = (int)$stmtRespuestas->fetchColumn();
$terminada = ($respuestasRespondidas >= $preguntasTotalesEsperadas && $preguntasTotalesEsperadas > 0);
// Cuando la partida finaliza, se actualizan los históricos
if ($terminada && !isset($_SESSION['partidas_procesadas'][$idPartida])) {
$conexion->beginTransaction();
// CÁLCULO DE VELOCIDAD PREGUNTA A PREGUNTA EN SESIÓN
if (!isset($_SESSION['primeros_en_acertar'][$idPartida])) {
$_SESSION['primeros_en_acertar'][$idPartida] = [];
}
// Vemos quién fue el primero
$stmtVelocidad = $conexion->prepare("
SELECT ra.idPartidaxPregunta, ra.idUsuario
FROM respuestaalmacenada ra
INNER JOIN respuesta r ON ra.idRespuesta = r.idRespuesta
INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta
WHERE pxp.idPartida = :idPartida AND r.correcta = 1
ORDER BY ra.idRespuestaAlmacenada ASC
");
$stmtVelocidad->execute([':idPartida' => $idPartida]);
$todosLosAciertos = $stmtVelocidad->fetchAll(PDO::FETCH_ASSOC);
foreach ($todosLosAciertos as $acierto) {
$idPxp = $acierto['idPartidaxPregunta'];
$idU = $acierto['idUsuario'];
if (!isset($_SESSION['primeros_en_acertar'][$idPartida][$idPxp])) {
$_SESSION['primeros_en_acertar'][$idPartida][$idPxp] = $idU;
}
}
// Actualizamos la base de datos
// Buscamos los aciertos de cada jugador en la partida actual
$stmtAciertos = $conexion->prepare("
SELECT ra.idUsuario, exu.idEquipo, COUNT(*) as aciertos_partida
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta
INNER JOIN respuesta r ON ra.idRespuesta = r.idRespuesta
INNER JOIN equipoxusuario exu ON ra.idUsuario = exu.idUsuario
WHERE pxp.idPartida = :idPartida AND r.correcta = 1
GROUP BY ra.idUsuario
");
$stmtAciertos->execute([':idPartida' => $idPartida]);
$jugadoresPartida = $stmtAciertos->fetchAll(PDO::FETCH_ASSOC);
$updateAciertosGlobales = $conexion->prepare("
UPDATE usuario
SET aciertos = aciertos + :nuevos_aciertos
WHERE idUsuario = :idUsuario
");
$puntosEquipos = [];
foreach ($jugadoresPartida as $jp) {
$idU = (int)$jp['idUsuario'];
$idE = (int)$jp['idEquipo'];
$nuevosAciertos = (int)$jp['aciertos_partida'];
// Sumamos los aciertos al perfil del usuario
$updateAciertos->execute([
':nuevos_aciertos' => $nuevosAciertos,
':idUsuario' => $idU
]);
if (!isset($puntosEquipos[$idE])) {
$puntosEquipos[$idE] = 0;
}
$puntosEquipos[$idE] += $nuevosAciertos;
}
// Determinamos qué equipo ha obtenido más aciertos en la partida
arsort($puntosEquipos);
$idEquipoGanador = key($puntosEquipos);
// Obtenemos todos los usuarios de la partida para asignar victorias/derrotas
$stmtMiembros = $conexion->prepare("
SELECT exu.idUsuario, exu.idEquipo
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu ON exp.idEquipo = exu.idEquipo
WHERE exp.idPartida = :idPartida
");
$stmtMiembros->execute([':idPartida' => $idPartida]);
$todosLosMiembros = $stmtMiembros->fetchAll(PDO::FETCH_ASSOC);
$updateVictoria = $conexion->prepare("UPDATE usuario SET victorias = victorias + 1 WHERE idUsuario = :idUsuario");
$updateDerrota = $conexion->prepare("UPDATE usuario SET derrotas = derrotas + 1 WHERE idUsuario = :idUsuario");
foreach ($todosLosMiembros as $miembro) {
$idU = (int)$miembro['idUsuario'];
$idE = (int)$miembro['idEquipo'];
if ($idE === $idEquipoGanador) {
$updateVictoria->execute([':idUsuario' => $idU]);
} else {
$updateDerrota->execute([':idUsuario' => $idU]);
}
}
$conexion->commit();
$_SESSION['partidas_procesadas'][$idPartida] = true;
}
echo json_encode(['terminada' => $terminada]);
} catch (PDOException $e) {
if ($conexion->inTransaction()) {
$conexion->rollBack();
}
echo json_encode(['error' => $e->getMessage()]);
}
break;
default:
echo json_encode(['error' => 'Acción no permitida']);
break;
}
+7 -4
View File
@@ -166,6 +166,9 @@ CREATE TABLE `partida` (
`idPartida` int(11) NOT NULL AUTO_INCREMENT, `idPartida` int(11) NOT NULL AUTO_INCREMENT,
`nombrePartida` varchar(100) NOT NULL, `nombrePartida` varchar(100) NOT NULL,
`idUsuario` int(11) NOT NULL, `idUsuario` int(11) NOT NULL,
`fechaCreacion` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`fechaInicio` DATETIME NULL,
`fechaFin` DATETIME NULL,
PRIMARY KEY (`idPartida`), PRIMARY KEY (`idPartida`),
KEY `FK idUsuario tabla usuario` (`idUsuario`), KEY `FK idUsuario tabla usuario` (`idUsuario`),
CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`)
@@ -178,10 +181,10 @@ CREATE TABLE `partida` (
LOCK TABLES `partida` WRITE; LOCK TABLES `partida` WRITE;
/*!40000 ALTER TABLE `partida` DISABLE KEYS */; /*!40000 ALTER TABLE `partida` DISABLE KEYS */;
INSERT INTO `partida` VALUES INSERT INTO `partida` (idPartida, nombrePartida, idUsuario, fechaInicio, fechaFin) VALUES
(1,'Partida de prueba 1',1), (1,'Partida de prueba 1',1, NULL, NULL),
(2,'Partida de prueba 2',4), (2,'Partida de prueba 2',4, NULL, NULL),
(3,'Partida de prueba 3',9); (3,'Partida de prueba 3',9, NULL, NULL);
/*!40000 ALTER TABLE `partida` ENABLE KEYS */; /*!40000 ALTER TABLE `partida` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
+141 -276
View File
@@ -1,291 +1,156 @@
<?php
session_start();
require_once $_SERVER['DOCUMENT_ROOT'] . '/triviagmatico/includes/conexionBD.php';
$idPartida = intval($_GET['idPartida'] ?? 0);
if ($idPartida <= 0) {
die("Partida no válida.");
}
$conexion = conexionBD();
if (is_array($conexion)) {
die("Error de conexión a la base de datos.");
}
// Obtener listado de jugadores y sus equipos en esta partida
$stmt = $conexion->prepare("
SELECT u.idUsuario, u.nombreUsuario, e.idEquipo, e.nombreEquipo
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu ON exp.idEquipo = exu.idEquipo
INNER JOIN usuario u ON exu.idUsuario = u.idUsuario
INNER JOIN equipo e ON exu.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
");
$stmt->execute([':idPartida' => $idPartida]);
$listaJugadoresRaw = $stmt->fetchAll(PDO::FETCH_ASSOC);
$primerosEnAcertar = $_SESSION['primeros_en_acertar'][$idPartida] ?? [];
$jugadoresFinales = [];
$equiposFinales = [];
// Respuestas de velocidad (+2 o +1)
foreach ($listaJugadoresRaw as $jugador) {
$idU = (int)$jugador['idUsuario'];
$idE = (int)$jugador['idEquipo'];
$stmtRespuestas = $conexion->prepare("
SELECT ra.idPartidaxPregunta, r.correcta
FROM respuestaalmacenada ra
INNER JOIN respuesta r ON ra.idRespuesta = r.idRespuesta
INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta
WHERE pxp.idPartida = :idPartida AND ra.idUsuario = :idUsuario
");
$stmtRespuestas->execute([':idPartida' => $idPartida, ':idUsuario' => $idU]);
$respuestasUsuario = $stmtRespuestas->fetchAll(PDO::FETCH_ASSOC);
$aciertos = 0;
$puntosTotalesJugador = 0;
foreach ($respuestasUsuario as $resp) {
if ((int)$resp['correcta'] === 1) {
$aciertos++;
$idPxp = $resp['idPartidaxPregunta'];
// Si el ID de usuario coincide con el primero guardado de esa pregunta se lleva 2 puntos
if (isset($primerosEnAcertar[$idPxp]) && $primerosEnAcertar[$idPxp] === $idU) {
$puntosTotalesJugador += 2;
} else {
$puntosTotalesJugador += 1;
}
}
}
$jugadoresFinales[] = [
'nombre' => $jugador['nombreUsuario'],
'equipo' => $jugador['nombreEquipo'],
'aciertos' => $aciertos,
'puntos' => $puntosTotalesJugador
];
if (!isset($equiposFinales[$idE])) {
$equiposFinales[$idE] = [
'nombre' => $jugador['nombreEquipo'],
'puntos' => 0
];
}
$equiposFinales[$idE]['puntos'] += $puntosTotalesJugador;
}
// Ordenar según la puntuación final de mayor a menor
usort($jugadoresFinales, function($a, $b) { return $b['puntos'] <=> $a['puntos']; });
usort($equiposFinales, function($a, $b) { return $b['puntos'] <=> $a['puntos']; });
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="es"> <html lang="es">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resultados - Trivial</title>
<title>Trivial - Resultado final</title> <link rel="stylesheet" href="css/resultados.css">
<script src="https://jquery.com"></script>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<!-- Bootstrap Icons -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link
href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="css/index.css">
</head> </head>
<body data-id-partida="<?php echo $idPartida; ?>">
<body> <div id="pantalla-espera" class="contenedor">
<h2>⌛ Esperando a que todos los jugadores terminen...</h2>
<?php <p>Calculando estadísticas de velocidad y actualizando perfiles históricos en el servidor.</p>
include_once("cabecera.php"); <div class="loader"></div>
?>
<main class="container py-5">
<!-- Título -->
<div class="text-center mb-5">
<div class="trophy-icon">
<i class="bi bi-trophy-fill"></i>
</div> </div>
<h1 class="fw-bold"> <div id="pantalla-resultados" class="contenedor" style="display:none;">
¡Trivial terminado! <h1>🏆 Resultados de la Partida 🏆</h1>
</h1>
<p class="text-muted fs-5 mb-0"> <h2>Clasificación por Equipos</h2>
Estos son los resultados finales <table class="tabla-ranking">
</p> <thead>
<tr>
<th>Posición</th>
<th>Equipo</th>
<th>Puntos Totales</th>
</tr>
</thead>
<tbody>
<?php foreach ($equiposFinales as $index => $eq): ?>
<tr class="<?php echo $index === 0 ? 'top-team' : ''; ?>">
<td>#<?php echo $index + 1; ?></td>
<td><?php echo htmlspecialchars($eq['nombre']); ?></td>
<td><strong><?php echo $eq['puntos']; ?> pts</strong></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h2>Rendimiento Individual</h2>
<table class="tabla-ranking">
<thead>
<tr>
<th>Posición</th>
<th>Jugador</th>
<th>Equipo</th>
<th>Aciertos</th>
<th>Puntos Logrados</th>
</tr>
</thead>
<tbody>
<?php foreach ($jugadoresFinales as $index => $jug): ?>
<tr class="<?php echo $index === 0 ? 'top-player' : ''; ?>">
<td>#<?php echo $index + 1; ?></td>
<td><?php echo htmlspecialchars($jug['nombre']); ?></td>
<td><?php echo htmlspecialchars($jug['equipo']); ?></td>
<td><?php echo $jug['aciertos']; ?> / 10</td>
<td><strong><?php echo $jug['puntos']; ?> pts</strong></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="contenedor-boton">
<a href="/triviagmatico/buscadorSala.php" class="btn-inicio">Volver al Inicio 🏠</a>
</div>
</div> </div>
<script src="js/resultados.js"></script>
<!-- Equipo ganador -->
<section class="row justify-content-center mb-5">
<div class="col-12 col-lg-8">
<div class="ranking-card">
<div class="ranking-header text-center">
<i class="bi bi-trophy-fill me-2"></i>
Equipo ganador
</div>
<div class="card-body text-center p-4">
<h2 class="fw-bold mb-2">
Los Cerebritos
</h2>
<div class="display-3 fw-bold mb-3">
850
<span class="fs-4 text-muted">
puntos
</span>
</div>
<p class="text-muted mb-0">
<i class="bi bi-stars me-1"></i>
¡Enhorabuena por la victoria!
</p>
</div>
</div>
</div>
</section>
<!-- Resultados de los dos equipos -->
<section class="row justify-content-center g-4">
<!-- EQUIPO GANADOR -->
<div class="col-12 col-lg-6">
<div class="ranking-card h-100">
<div class="ranking-header d-flex justify-content-between align-items-center">
<span>
Los Cerebritos
</span>
<span>
<i class="bi bi-trophy-fill"></i>
</span>
</div>
<div class="card-body p-4">
<div class="text-center mb-4">
<div class="fs-1 fw-bold">
850
</div>
<div class="text-muted">
puntos
</div>
</div>
<h5 class="fw-bold mb-3">
<i class="bi bi-people-fill me-2"></i>
Jugadores
</h5>
<ul class="list-group">
<li class="list-group-item">
1. Carlos
</li>
<li class="list-group-item">
2. Marta
</li>
<li class="list-group-item">
3. Pablo
</li>
<li class="list-group-item">
4. Laura
</li>
<li class="list-group-item">
5. David
</li>
<li class="list-group-item">
6. Ana
</li>
<li class="list-group-item">
7. Sergio
</li>
<li class="list-group-item">
8. Lucía
</li>
<li class="list-group-item">
9. Miguel
</li>
<li class="list-group-item">
10. Elena
</li>
</ul>
</div>
</div>
</div>
<!-- EQUIPO PERDEDOR -->
<div class="col-12 col-lg-6">
<div class="ranking-card h-100">
<!-- Cabecera plateada -->
<div
class="ranking-header d-flex justify-content-between align-items-center"
style="background-color: #c0c0c0;">
<span>
Los Campeones
</span>
<span>
<i class="bi bi-award-fill"></i>
</span>
</div>
<div class="card-body p-4">
<div class="text-center mb-4">
<div class="fs-1 fw-bold">
720
</div>
<div class="text-muted">
puntos
</div>
</div>
<h5 class="fw-bold mb-3">
<i class="bi bi-people-fill me-2"></i>
Jugadores
</h5>
<ul class="list-group">
<li class="list-group-item">
1. Javier
</li>
<li class="list-group-item">
2. Sofía
</li>
<li class="list-group-item">
3. Diego
</li>
<li class="list-group-item">
4. María
</li>
<li class="list-group-item">
5. Alejandro
</li>
<li class="list-group-item">
6. Paula
</li>
<li class="list-group-item">
7. Álvaro
</li>
<li class="list-group-item">
8. Carmen
</li>
</ul>
</div>
</div>
</div>
</section>
<!-- Volver al buscador -->
<div class="text-center mt-5">
<a
href="buscadorSala.php"
class="btn btn-play-kahoot">
<i class="bi bi-arrow-left-circle-fill"></i>
Volver al buscador de salas
</a>
</div>
</main>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
</body> </body>
</html> </html>