33 Commits

Author SHA1 Message Date
profesor 1980f7582f Actualizar clases/ClasePartida.php 2026-09-29 14:25:52 +02:00
Isaac d8837484b0 Arreglado el buscadorSala 2026-09-29 14:05:19 +02:00
profesor d5cd07b135 Actualizar README.md 2026-09-29 13:44:16 +02:00
jorge fc7629143d Actualizar cabecera.php 2026-09-29 13:43:35 +02:00
jorge d22a642cca Actualizada cabecera js (evitar conflicto con check de alexis) 2026-09-29 13:42:16 +02:00
jorge 7969685d02 Merge branch 'cookies' 2026-09-29 13:35:39 +02:00
jorge d8c8cea558 Merge pull request 'añadir funcion iniciar y finalizar en la ClasePartida' (#14) from control_inicio into main
Reviewed-on: #14
2026-09-29 13:27:18 +02:00
jorge de19ea1861 Merge pull request 'Resultadophp' (#13) from resultadophp into main
Reviewed-on: #13
2026-09-29 13:23:03 +02:00
jorge 30dd4a0e2f Merge pull request 'Add funcionamiento del juego' (#12) from juegophp into main
Reviewed-on: #12
Reviewed-by: jorge <jdavidnunez@gmail.com>
2026-09-29 13:20:15 +02:00
dbvictor2002 7ae1b14e6e Subir archivos a "js" 2026-09-29 13:19:26 +02:00
dbvictor2002 e64761400d Subir archivos a "css" 2026-09-29 13:18:57 +02:00
dbvictor2002 00e1c04868 Subir archivos a "controladores" 2026-09-29 13:18:33 +02:00
dbvictor2002 8e1ccc6718 Subir archivos a "/" 2026-09-29 13:18:16 +02:00
jorge bdebd32f80 Merge pull request 'Host2' (#11) from host2 into main
Reviewed-on: #11
2026-09-29 13:12:04 +02:00
jorge 49f950bbd0 Merge pull request 'Toast de confirmacion de pregunta creada' (#10) from toast into main
Reviewed-on: #10
Reviewed-by: jorge <jdavidnunez@gmail.com>
2026-09-29 13:04:21 +02:00
jorge b8f977e437 Merge pull request 'archivo .env + conexionBD' (#2) from archivo_env into main
Reviewed-on: #2
2026-09-29 12:19:14 +02:00
Isaac c8c0792bd7 Más funcionalidades de host 2026-09-29 11:27:18 +02:00
jorge 02c109662d Manejo de cookies 2026-09-29 11:26:42 +02:00
Isaac 534c20a45d Eliminar Sala (Se ejecuta cuando el host abandona la sala)
He modificado salirDeSala() de ClaseEquipoxUsuario.php
2026-09-29 11:25:56 +02:00
jorge c8199aa261 Añadida BD definitiva 2.0
Añadido a main la base de datos (modificada por Víctor Díaz)
2026-09-29 11:25:26 +02:00
v.rodriguezcamacho f5a354025e Toast de confirmacion de pregunta creada 2026-09-29 11:24:42 +02:00
margarita 04fe80946f añadir funcion iniciar y finalizar en la ClasePartida 2026-09-29 11:06:35 +02:00
alexis 449cb1d976 Add funcionamiento del juego 2026-09-29 10:50:58 +02:00
Isaac 94bfe480cb Arreglado iconos bootstrap 2026-09-29 10:11:25 +02:00
profesor 7661343572 Merge pull request 'Se asignan 10 preguntas a la partida al crearse' (#3) from asignar_preguntas into main
Reviewed-on: #3
2026-09-29 09:56:06 +02:00
profesor e97586b033 Se asignan 10 preguntas a la partida al crearse
La clase Pregunta tiene un nuevo método getTodosIds() que devuelve un array con todos los id de las preguntas
2026-09-29 09:42:57 +02:00
Juanjo 14e2fd48a1 archivo .env + conexionBD 2026-09-29 09:41:40 +02:00
Isaac 42cc1489e9 Arreglado CSS (Alguien™ estaba usando modo oscuro) 2026-09-29 09:10:30 +02:00
Isaac a694f19667 Funcionalidades del host 2026-09-28 14:17:54 +02:00
jorge 3cc0dfb122 Corregido cambiar avatar en cabecera 2026-09-28 13:29:57 +02:00
jorge 4efb831b7a Reparado inicio y registro de momento 2026-09-28 13:13:05 +02:00
jorge 22f38f924f Merge branch 'pruebasJorge' 2026-09-28 12:37:07 +02:00
jorge 01aa2643f6 Actualizando a 12:24 2026-09-28 12:23:45 +02:00
35 changed files with 2349 additions and 4659 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ Configuración de acceso al servidor de producción:
- SSH/SCP/SFTP:
- Host: desarrolloalcala.com
- Puerto: 2222
- Usuario: alumnado
- Usuario: my_webapp
- Contraseña: epdsrntr\*\*
- Acceso WEB al panel de control:
- URL: http://desarrolloalcala.com
+59 -164
View File
@@ -4,208 +4,103 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trivial - Lobby</title>
<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">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/buscadorSala.css">
</head>
<body>
<?php
include_once("cabecera.php");
?>
<?php include_once("cabecera.php"); ?>
<main class="container py-5">
<!-- Botón Volver -->
<div class="mb-4">
<a href="index.php" class="btn btn-outline-secondary d-inline-flex align-items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
</svg>
Volver al Inicio
</a>
</div>
<div id="contenedorCrearSala" class="text-center mb-5">
<button
type="button"
class="btn btn-play-kahoot btn-crear-sala"
data-bs-toggle="modal"
data-bs-target="#modalCrearSala">
<span>+</span>
Crear sala
</button>
<main class="container py-4">
<!-- Botón Volver -->
<div class="mb-4">
<a href="index.php" class="btn btn-outline-secondary d-inline-flex align-items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
</svg>
Volver al Inicio
</a>
</div>
<div
id="contenedorSalas"
class="row justify-content-center g-4">
<div
id="cargandoSalas"
class="col-12 text-center">
<div
class="spinner-border text-primary"
role="status">
<span class="visually-hidden">
Cargando...
</span>
<!-- Botón Crear Sala -->
<div id="contenedorCrearSala" class="text-center mb-5">
<button type="button" class="btn btn-play-kahoot btn-crear-sala" data-bs-toggle="modal" data-bs-target="#modalCrearSala">
<span>+</span> Crear sala
</button>
</div>
<!-- Contenedor Principal de Salas -->
<div id="contenedorSalas" class="row justify-content-center g-4">
<div id="cargandoSalas" class="col-12 text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
<p class="mt-3 text-muted">
Cargando salas...
</p>
<p class="mt-3 text-muted">Cargando salas...</p>
</div>
</div>
</main>
<!-- Modal Crear Sala -->
<div
class="modal fade"
id="modalCrearSala"
tabindex="-1"
aria-labelledby="modalCrearSalaLabel"
aria-hidden="true">
<div class="modal fade" id="modalCrearSala" tabindex="-1" aria-labelledby="modalCrearSalaLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot">
<div class="modal-header modal-kahoot-header">
<h5
class="modal-title"
id="modalCrearSalaLabel">
Crear sala
</h5>
<button
type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
</button>
<h5 class="modal-title" id="modalCrearSalaLabel">Crear sala</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Cerrar"></button>
</div>
<div class="modal-body p-4">
<div class="mb-3">
<label
for="nombreSala"
class="form-label">
Nombre de la sala
</label>
<input
type="text"
id="nombreSala"
class="form-control input-kahoot"
name="nombreSala"
placeholder="Ej. Noche de Trivial"
maxlength="100">
<label for="nombreSala" class="form-label">Nombre de la sala</label>
<input type="text" id="nombreSala" class="form-control input-kahoot" name="nombreSala" placeholder="Ej. Noche de Trivial" maxlength="100">
</div>
<div class="mb-3">
<label
for="nombreEquipo1"
class="form-label">
Nombre del equipo 1
</label>
<input
type="text"
id="nombreEquipo1"
name="nombreEquipo1"
class="form-control input-kahoot"
placeholder="Ej. Los cerebritos"
maxlength="50">
<label for="nombreEquipo1" class="form-label">Nombre del equipo 1</label>
<input type="text" id="nombreEquipo1" name="nombreEquipo1" class="form-control input-kahoot" placeholder="Ej. Los cerebritos" maxlength="50">
</div>
<div class="mb-3">
<label
for="nombreEquipo2"
class="form-label">
Nombre del equipo 2
</label>
<input
type="text"
id="nombreEquipo2"
name="nombreEquipo2"
class="form-control input-kahoot"
placeholder="Ej. Los campeones"
maxlength="50">
<label for="nombreEquipo2" class="form-label">Nombre del equipo 2</label>
<input type="text" id="nombreEquipo2" name="nombreEquipo2" class="form-control input-kahoot" placeholder="Ej. Los campeones" maxlength="50">
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal">
Cancelar
</button>
<button
type="button"
class="btn btn-kahoot-login"
id="btnCrearSala">
Crear sala
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-kahoot-login" id="btnCrearSala">Crear sala</button>
</div>
</div>
</div>
</div>
<!--MODAL ABANDONAR SALA -->
<!-- Modal Confirmar Abandonar Sala -->
<div class="modal fade" id="modalAbandonarSala" tabindex="-1" aria-labelledby="modalAbandonarSalaLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot text-center p-3">
<div class="modal-body">
<div class="mb-3 fs-1">⚠️</div>
<h4 class="modal-title mb-2 fw-bold" id="modalAbandonarSalaLabel">¿Abandonar la sala?</h4>
<p class="text-dark-50" id="modalAbandonarSalaMensaje">Si sales de la sala, perderás tu lugar en el equipo.</p>
</div>
<div class="modal-footer justify-content-center border-0 gap-2">
<button type="button" class="btn btn-secondary px-4 py-2" data-bs-dismiss="modal">
Cancelar
</button>
<button type="button" id="btnConfirmarAbandonar" class="btn btn-danger px-4 py-2">
Sí, salir
</button>
</div>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
<script src="js/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/jquery-4.0.0.min.js"></script>
<script src="js/buscadorSala.js"></script>
</body>
</html>
</html>
+2 -2
View File
@@ -21,9 +21,9 @@
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
<!-- Adtoy ti pagianan ti botones / dropdown a patulaon ti JS -->
<!-- Contenedor dinámico de usuario/botones -->
<div class="d-flex align-items-center gap-3" id="contenedorUsuarioCabecera">
<!-- Ikapit ti JS ti HTML dita -->
</div>
</div>
</div>
+159 -42
View File
@@ -60,17 +60,18 @@ class EquipoxUsuario
];
}
}
public function obtenerSalaUsuario($idUsuario)
{
$conexion = conexionBD();
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
if (is_array($conexion)) {
return $conexion;
}
try {
try {
$sql = "
$sql = "
SELECT
exu.idEquipo,
exp.idPartida
@@ -84,43 +85,40 @@ class EquipoxUsuario
LIMIT 1
";
$consulta = $conexion->prepare($sql);
$consulta = $conexion->prepare($sql);
$consulta->bindParam(
':idUsuario',
$idUsuario,
PDO::PARAM_INT
);
$consulta->bindParam(
':idUsuario',
$idUsuario,
PDO::PARAM_INT
);
$consulta->execute();
$consulta->execute();
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
if (!$resultado) {
if (!$resultado) {
return [
'asociado' => false
];
}
return [
'asociado' => false
'asociado' => true,
'idEquipo' => $resultado['idEquipo'],
'idPartida' => $resultado['idPartida']
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al obtener la sala del usuario.',
'error_tecnico' => $error->getMessage()
];
}
return [
'asociado' => true,
'idEquipo' => $resultado['idEquipo'],
'idPartida' => $resultado['idPartida']
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al obtener la sala del usuario.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function salirDeSala($idUsuario)
public static function salirDeSala($idUsuario)
{
$conexion = conexionBD();
@@ -129,24 +127,143 @@ public static function salirDeSala($idUsuario)
}
try {
$sql = "DELETE FROM equipoxusuario WHERE idUsuario = :idUsuario";
// 1. Averiguamos el equipo y la partida del usuario
$sql = "SELECT exu.idEquipo, exp.idPartida, p.idUsuario AS idHost FROM equipoxusuario exu INNER JOIN equipoxpartida exp ON exu.idEquipo = exp.idEquipo INNER JOIN partida p ON exp.idPartida = p.idPartida WHERE exu.idUsuario = :idUsuario LIMIT 1";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idUsuario', $idUsuario, PDO::PARAM_INT);
$consulta->bindParam(':idUsuario',$idUsuario, PDO::PARAM_INT);
$consulta->execute();
$datosSala = $consulta->fetch(PDO::FETCH_ASSOC);
// El usuario no pertenece a ninguna sala
if (!$datosSala) {
return [
'error' => 'No perteneces a ninguna sala.'
];
}
$idEquipo = (int)$datosSala['idEquipo'];
$idPartida = (int)$datosSala['idPartida'];
$idHost = (int)$datosSala['idHost'];
// Comenzamos una transacción
$conexion->beginTransaction();
/*
* 2. Comprobamos si quien abandona es el HOST
*/
if ($idUsuario === $idHost) {
/*
* Obtenemos todos los equipos pertenecientes
* a esta partida.
*/
$sqlEquipos = "SELECT idEquipo FROM equipoxpartida WHERE idPartida = :idPartida";
$consultaEquipos = $conexion->prepare($sqlEquipos);
$consultaEquipos->bindParam(':idPartida', $idPartida, PDO::PARAM_INT);
$consultaEquipos->execute();
$equipos = $consultaEquipos->fetchAll(PDO::FETCH_COLUMN);
/*
* 3. Eliminamos los jugadores de esos equipos
* de la tabla equipoxusuario.
*/
if (!empty($equipos)) {
$placeholders = implode(',', array_fill(0, count($equipos), '?'));
$sqlUsuarios = "DELETE FROM equipoxusuario WHERE idEquipo IN ($placeholders)";
$consultaUsuarios = $conexion->prepare($sqlUsuarios);
$consultaUsuarios->execute($equipos);
}
/*
* 4. Eliminamos las relaciones
* entre equipos y partida.
*/
$sqlEquipoxPartida = "DELETE FROM equipoxpartida WHERE idPartida = :idPartida";
$consultaEquipoxPartida = $conexion->prepare($sqlEquipoxPartida);
$consultaEquipoxPartida->bindParam(':idPartida', $idPartida,PDO::PARAM_INT);
$consultaEquipoxPartida->execute();
/*
* 5. Eliminamos los equipos.
*
* Los equipos ya no tienen relaciones con
* usuarios ni con la partida.
*/
if (!empty($equipos)) {
$placeholders = implode(',', array_fill(0, count($equipos), '?'));
$sqlEliminarEquipos = "DELETE FROM equipo WHERE idEquipo IN ($placeholders)";
$consultaEliminarEquipos = $conexion->prepare($sqlEliminarEquipos);
$consultaEliminarEquipos->execute($equipos);
}
/*
* 6. Eliminamos las relaciones
* entre preguntas y partida.
*/
$sqlPartidaxPregunta = "DELETE FROM partidaxpregunta WHERE idPartida = :idPartida";
$consultaPartidaxPregunta = $conexion->prepare($sqlPartidaxPregunta);
$consultaPartidaxPregunta->bindParam(':idPartida', $idPartida, PDO::PARAM_INT);
$consultaPartidaxPregunta->execute();
/*
* 7. Finalmente eliminamos la partida.
*/
$sqlPartida = "DELETE FROM partida WHERE idPartida = :idPartida";
$consultaPartida = $conexion->prepare($sqlPartida);
$consultaPartida->bindParam(':idPartida', $idPartida, PDO::PARAM_INT);
$consultaPartida->execute();
// Todo ha ido correctamente
$conexion->commit();
return [
'exito' => true,
'salaEliminada' => true,
'mensaje' => 'La sala ha sido eliminada correctamente.'
];
}
/*
* 7. Si NO es el host, simplemente abandona
* su relación con el equipo.
*/
$sqlSalir = "DELETE FROM equipoxusuario WHERE idUsuario = :idUsuario";
$consultaSalir = $conexion->prepare($sqlSalir);
$consultaSalir->bindParam(':idUsuario', $idUsuario, PDO::PARAM_INT);
$consultaSalir->execute();
$conexion->commit();
return [
'exito' => true,
'mensaje' => 'Usuario eliminado de la sala correctamente.'
'salaEliminada' => false,
'mensaje' => 'Has abandonado la sala correctamente.'
];
} catch (PDOException $error) {
// Si había una transacción activa, la deshacemos
if ($conexion->inTransaction()) {
$conexion->rollBack();
}
return [
'error' => 'Ocurrió un error al salir de la sala.',
'error' => 'Ocurrió un error al abandonar la sala.',
'error_tecnico' => $error->getMessage()
];
}
}
}
+348
View File
@@ -0,0 +1,348 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
require_once __DIR__ . '/ClaseRespuestaAlmacenada.php';
/**
* Lógica de la dinámica de juego (la usa juego.php a través de ControladorJuego.php):
* - deja preparadas las 10 preguntas de la partida
* - se las devuelve al jugador con sus respuestas SIN decir cuál es la correcta
* - guarda la respuesta de cada jugador y le dice si ha acertado
*
* Todos los métodos devuelven un array con la clave 'error' si algo falla,
* igual que el resto de clases del proyecto.
*/
class Juego
{
const NUM_PREGUNTAS = 10;
/**
* Comprueba que el usuario pertenece a alguno de los equipos de la partida.
* Devuelve true/false (o el array de error si falla la BD).
*/
public static function usuarioEnPartida($idPartida, $idUsuario)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT COUNT(*) AS total
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu
ON exu.idEquipo = exp.idEquipo
WHERE exp.idPartida = :idPartida
AND exu.idUsuario = :idUsuario
");
$consulta->execute([
':idPartida' => $idPartida,
':idUsuario' => $idUsuario
]);
return (int)$consulta->fetchColumn() > 0;
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al comprobar si perteneces a la partida.',
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Si la partida todavía no tiene preguntas, le asigna 10 al azar.
* Se hace dentro de una transacción con la fila de la partida bloqueada
* para que, si varios jugadores entran a la vez, las preguntas se
* asignen una sola vez.
* Devuelve null si todo va bien, o un array de error.
*/
private static function asegurarPreguntas($conexion, $idPartida)
{
try {
$conexion->beginTransaction();
$bloqueo = $conexion->prepare("
SELECT idPartida FROM partida
WHERE idPartida = :idPartida
FOR UPDATE
");
$bloqueo->execute([':idPartida' => $idPartida]);
if (!$bloqueo->fetch()) {
$conexion->rollBack();
return ['error' => 'La partida no existe.'];
}
$cuenta = $conexion->prepare("
SELECT COUNT(*) FROM partidaxpregunta
WHERE idPartida = :idPartida
");
$cuenta->execute([':idPartida' => $idPartida]);
if ((int)$cuenta->fetchColumn() === 0) {
// Solo preguntas que tengan alguna respuesta marcada como correcta
$elegidas = $conexion->query("
SELECT p.idPregunta
FROM pregunta p
WHERE EXISTS (
SELECT 1 FROM respuesta r
WHERE r.idPregunta = p.idPregunta
AND r.correcta = 1
)
ORDER BY RAND()
LIMIT " . self::NUM_PREGUNTAS
)->fetchAll(PDO::FETCH_COLUMN);
$insertar = $conexion->prepare("
INSERT INTO partidaxpregunta (idPartida, idPregunta)
VALUES (:idPartida, :idPregunta)
");
foreach ($elegidas as $idPregunta) {
$insertar->execute([
':idPartida' => $idPartida,
':idPregunta' => $idPregunta
]);
}
}
$conexion->commit();
return null;
} catch (PDOException $error) {
if ($conexion->inTransaction()) {
$conexion->rollBack();
}
return [
'error' => 'Ocurrió un error al preparar las preguntas de la partida.',
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Devuelve las preguntas de la partida (máximo 10) con sus respuestas
* mezcladas. NO incluye el campo 'correcta' para que no se pueda hacer
* trampa mirando la respuesta del servidor.
* Cada pregunta indica si este usuario ya la ha respondido, para poder
* retomar la partida si recarga la página.
*/
public static function cargarPreguntas($idPartida, $idUsuario)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
$error = self::asegurarPreguntas($conexion, $idPartida);
if ($error !== null) {
return $error;
}
try {
// 1. Las preguntas, siempre en el mismo orden para todos los jugadores
$consulta = $conexion->prepare("
SELECT
pxp.idPartidaxPregunta,
p.idPregunta,
p.nombrePregunta
FROM partidaxpregunta pxp
INNER JOIN pregunta p
ON p.idPregunta = pxp.idPregunta
WHERE pxp.idPartida = :idPartida
ORDER BY pxp.idPartidaxPregunta
LIMIT " . self::NUM_PREGUNTAS
);
$consulta->execute([':idPartida' => $idPartida]);
$preguntas = $consulta->fetchAll(PDO::FETCH_ASSOC);
// 2. Las respuestas de todas esas preguntas, agrupadas por pregunta
$consulta = $conexion->prepare("
SELECT DISTINCT
r.idRespuesta,
r.idPregunta,
r.nombreRespuesta
FROM respuesta r
INNER JOIN partidaxpregunta pxp
ON pxp.idPregunta = r.idPregunta
WHERE pxp.idPartida = :idPartida
");
$consulta->execute([':idPartida' => $idPartida]);
$respuestasPorPregunta = [];
foreach ($consulta->fetchAll(PDO::FETCH_ASSOC) as $fila) {
$respuestasPorPregunta[(int)$fila['idPregunta']][] = [
'idRespuesta' => (int)$fila['idRespuesta'],
'nombreRespuesta' => $fila['nombreRespuesta']
];
}
// 3. Qué preguntas ha respondido ya este usuario
$consulta = $conexion->prepare("
SELECT ra.idPartidaxPregunta
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp
ON pxp.idPartidaxPregunta = ra.idPartidaxPregunta
WHERE pxp.idPartida = :idPartida
AND ra.idUsuario = :idUsuario
");
$consulta->execute([
':idPartida' => $idPartida,
':idUsuario' => $idUsuario
]);
$respondidas = array_flip($consulta->fetchAll(PDO::FETCH_COLUMN));
// 4. Montamos la respuesta final
$resultado = [];
foreach ($preguntas as $pregunta) {
$idPregunta = (int)$pregunta['idPregunta'];
$idPxp = (int)$pregunta['idPartidaxPregunta'];
$respuestas = $respuestasPorPregunta[$idPregunta] ?? [];
shuffle($respuestas);
$resultado[] = [
'idPartidaxPregunta' => $idPxp,
'idPregunta' => $idPregunta,
'nombrePregunta' => $pregunta['nombrePregunta'],
'respondida' => isset($respondidas[$idPxp]),
'respuestas' => $respuestas
];
}
return [
'total' => count($resultado),
'respondidas' => count($respondidas),
'preguntas' => $resultado
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al cargar las preguntas.',
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Guarda la respuesta que ha elegido el usuario en una pregunta y
* devuelve si ha acertado y cuál era la correcta (para el feedback).
* Comprueba en el servidor que:
* - la pregunta pertenece a la partida
* - la respuesta pertenece a esa pregunta
* - el usuario no ha respondido ya esa pregunta
*/
public static function registrarRespuesta($idPartida, $idUsuario, $idPartidaxPregunta, $idRespuesta)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
// 1. La pregunta tiene que ser de esta partida
$consulta = $conexion->prepare("
SELECT idPregunta
FROM partidaxpregunta
WHERE idPartidaxPregunta = :idPxp
AND idPartida = :idPartida
");
$consulta->execute([
':idPxp' => $idPartidaxPregunta,
':idPartida' => $idPartida
]);
$idPregunta = $consulta->fetchColumn();
if ($idPregunta === false) {
return ['error' => 'Esa pregunta no pertenece a esta partida.'];
}
// 2. La respuesta tiene que ser una de las de esa pregunta
$consulta = $conexion->prepare("
SELECT idRespuesta, correcta
FROM respuesta
WHERE idPregunta = :idPregunta
");
$consulta->execute([':idPregunta' => $idPregunta]);
$elegida = null;
$primeraCorrecta = null;
foreach ($consulta->fetchAll(PDO::FETCH_ASSOC) as $fila) {
if ((int)$fila['correcta'] === 1 && $primeraCorrecta === null) {
$primeraCorrecta = (int)$fila['idRespuesta'];
}
if ((int)$fila['idRespuesta'] === $idRespuesta) {
$elegida = $fila;
}
}
if ($elegida === null) {
return ['error' => 'Esa respuesta no pertenece a la pregunta.'];
}
// 3. Solo se puede responder una vez a cada pregunta
$consulta = $conexion->prepare("
SELECT COUNT(*)
FROM respuestaalmacenada
WHERE idPartidaxPregunta = :idPxp
AND idUsuario = :idUsuario
");
$consulta->execute([
':idPxp' => $idPartidaxPregunta,
':idUsuario' => $idUsuario
]);
if ((int)$consulta->fetchColumn() > 0) {
return ['error' => 'Ya has respondido a esta pregunta.'];
}
// 4. Guardamos la respuesta con la clase que ya existía
$almacenada = new RespuestaAlmacenada(
null,
$idPartidaxPregunta,
$idUsuario,
$idRespuesta
);
$guardado = $almacenada->guardarRespuesta();
if (isset($guardado['error'])) {
return $guardado;
}
// 5. Progreso del usuario en la partida
$consulta = $conexion->prepare("
SELECT COUNT(*)
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp
ON pxp.idPartidaxPregunta = ra.idPartidaxPregunta
WHERE pxp.idPartida = :idPartida
AND ra.idUsuario = :idUsuario
");
$consulta->execute([
':idPartida' => $idPartida,
':idUsuario' => $idUsuario
]);
$respondidas = (int)$consulta->fetchColumn();
$consulta = $conexion->prepare("
SELECT COUNT(*) FROM partidaxpregunta
WHERE idPartida = :idPartida
");
$consulta->execute([':idPartida' => $idPartida]);
$total = min((int)$consulta->fetchColumn(), self::NUM_PREGUNTAS);
$acierto = (int)$elegida['correcta'] === 1;
return [
'exito' => 'Respuesta guardada.',
'acierto' => $acierto,
'idRespuestaCorrecta' => $acierto ? $idRespuesta : $primeraCorrecta,
'respondidas' => $respondidas,
'total' => $total,
'terminada' => $respondidas >= $total
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al guardar la respuesta.',
'error_tecnico' => $error->getMessage()
];
}
}
}
+160 -166
View File
@@ -7,17 +7,27 @@ class Partida
public $idPartida;
public $nombrePartida;
public $idUsuario;
public $fechaCreacion;
public $fechaInicio;
public $fechaFin;
public function __construct(
$idPartida = null,
$nombrePartida = null,
$idUsuario = null
$idUsuario = null,
$fechaCreacion = null,
$fechaInicio = null,
$fechaFin = null
) {
$this->idPartida = $idPartida;
$this->nombrePartida = $nombrePartida;
$this->idUsuario = $idUsuario;
$this->fechaCreacion = $fechaCreacion;
$this->fechaInicio = $fechaInicio;
$this->fechaFin = $fechaFin;
}
public function insertar()
{
$conexion = conexionBD();
@@ -25,12 +35,7 @@ class Partida
return $conexion;
}
try {
$consulta = $conexion->prepare("
INSERT INTO partida
(nombrePartida,idUsuario)
VALUES
(:nombrePartida,:idUsuario)
");
$consulta = $conexion->prepare("INSERT INTO partida (nombrePartida,idUsuario) VALUES (:nombrePartida,:idUsuario)");
$consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
@@ -46,8 +51,7 @@ class Partida
}
}
public function listar()
{
public function listar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
@@ -64,18 +68,13 @@ class Partida
}
}
public function buscar()
{
public function buscar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT *
FROM partida
WHERE idPartida=:idPartida
");
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return $consulta->fetch(PDO::FETCH_ASSOC);
@@ -87,20 +86,14 @@ class Partida
}
}
public function editar()
{
public function editar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
UPDATE partida
SET
nombrePartida=:nombrePartida,
idUsuario=:idUsuario
WHERE idPartida=:idPartida
");
$consulta = $conexion->prepare("UPDATE partida SET nombrePartida=:nombrePartida, idUsuario=:idUsuario WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario);
@@ -117,17 +110,13 @@ class Partida
}
}
public function eliminar()
{
public function eliminar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
DELETE FROM partida
WHERE idPartida=:idPartida
");
$consulta = $conexion->prepare("DELETE FROM partida WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
@@ -142,27 +131,121 @@ class Partida
}
}
/**
* Devuelve las preguntas asignadas a la partida, junto con el
* idPartidaxPregunta (necesario para guardar respuestas después).
*/
public function getPreguntas()
{
public function iniciarPartida(){
$conexion = conexionBD();
if (is_array($conexion)){
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();
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 = $conexion->prepare("UPDATE partida SET fechaFin=NOW() WHERE idPartida=:idPartida AND fechaFin IS NULL");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
"exito" => "La partida se finalizó correctamente.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
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->execute();
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();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
INSERT INTO partidaxpregunta
(idPartida,idPregunta)
VALUES
(:idPartida,:idPregunta)
");
$consulta = $conexion->prepare("INSERT INTO partidaxpregunta (idPartida,idPregunta) VALUES (:idPartida,:idPregunta)");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta);
$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?".
public function contarPreguntasAsignadas()
{
public function contarPreguntasAsignadas() {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT COUNT(*) AS total
FROM partidaxpregunta
WHERE idPartida=:idPartida
");
$consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
$fila = $consulta->fetch(PDO::FETCH_ASSOC);
@@ -229,21 +299,14 @@ class Partida
}
}
public function contarRespuestasUsuario($idUsuario)
{
public function contarRespuestasUsuario($idUsuario){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT COUNT(*) AS total
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp
ON ra.idPartidaxPregunta=pxp.idPartidaxPregunta
WHERE pxp.idPartida=:idPartida
AND ra.idUsuario=:idUsuario
");
$consulta = $conexion->prepare("SELECT COUNT(*) AS total 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(":idUsuario", $idUsuario);
$consulta->execute();
@@ -258,11 +321,11 @@ class Partida
}
/**
* Sustituye al antiguo campo `terminada`: compara cuántas preguntas
* tiene la partida contra cuántas ha respondido este usuario.
* Indica si ESTE usuario ya ha respondido todas las preguntas:
* 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();
if (is_array($totalPreguntas)) {
return $totalPreguntas;
@@ -277,19 +340,13 @@ class Partida
/**
* Partidas creadas por un usuario, de más reciente a más antigua.
*/
public function listarDelUsuario()
{
public function listarDelUsuario(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT *
FROM partida
WHERE idUsuario=:idUsuario
ORDER BY idPartida DESC
");
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idUsuario=:idUsuario ORDER BY idPartida DESC");
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
@@ -301,22 +358,13 @@ class Partida
}
}
public function preguntaAsignada($idPregunta)
{
public function preguntaAsignada($idPregunta) {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT COUNT(*) AS total
FROM partidaxpregunta
WHERE idPartida=:idPartida
AND idPregunta=:idPregunta
");
$consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida AND idPregunta=:idPregunta");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta);
$consulta->execute();
@@ -336,24 +384,13 @@ class Partida
* Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'.
* Permite registrar qué grupos están participando en este torneo.
*/
public function registrarEquipoEnPartida($idEquipo)
{
$conexion = conexionBD(); // Obtenemos la conexión modular del proyecto
public function registrarEquipoEnPartida($idEquipo){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion; // Si hay error en la conexión, lo devuelve
return $conexion;
}
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)
");
// Vinculamos los parámetros con el objeto de la partida actual y el equipo recibido
$consulta = $conexion->prepare("INSERT INTO equipoxpartida (idPartida, idEquipo) VALUES (:idPartida, :idEquipo)");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idEquipo", $idEquipo);
$consulta->execute();
@@ -363,7 +400,6 @@ class Partida
"exito_tecnico" => $conexion->lastInsertId()
];
} catch (PDOException $error) {
// Capturamos el error extrayendo solo el mensaje de texto limpio
return [
"error" => "Ocurrió un error al asignar el equipo a la partida.",
"error_tecnico" => $error->getMessage()
@@ -375,28 +411,14 @@ class 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.
*/
public function getEquiposParticipantes()
{
public function getEquiposParticipantes(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
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
INNER JOIN equipo e
ON exp.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC
");
try {
$consulta = $conexion->prepare("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->execute();
@@ -413,57 +435,29 @@ class Partida
* Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida.
* Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos.
*/
public function getJugadoresDeLaPartida()
{
public function getJugadoresDeLaPartida(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("
SELECT DISTINCT
u.idUsuario,
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 = $conexion->prepare("SELECT DISTINCT u.idUsuario, 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(
":idPartida",
$this->idPartida
);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" =>
"Ocurrió un error al obtener la lista de jugadores.",
"error_tecnico" =>
$error->getMessage()
];
}
}
}
}
+19
View File
@@ -1,3 +1,4 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
@@ -110,4 +111,22 @@ class Pregunta {
];
}
}
public static function getTodosIds()//devuelve solamente los id de todas las preguntas
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT idPregunta FROM pregunta");
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_COLUMN);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al obtener el listado.",
'error_tecnico' => $error->getMessage()
];
}
}
}
+71 -16
View File
@@ -269,6 +269,60 @@ class Usuario
return null;
}
// Cookies
public static function guardarCookieToken($idUsuario, $token)
{
$conexion = conexionBD();
if (is_array($conexion)) return false;
try {
$sql = "UPDATE usuario SET cookie = :token WHERE idUsuario = :id";
$stmt = $conexion->prepare($sql);
return $stmt->execute([
':token' => $token,
':id' => $idUsuario
]);
} catch (PDOException $e) {
return false;
}
}
public static function buscarPorCookie($token)
{
if (empty($token)) return null;
$conexion = conexionBD();
if (is_array($conexion)) return null;
try {
$sql = "SELECT * FROM usuario WHERE cookie = :token AND cookie IS NOT NULL";
$stmt = $conexion->prepare($sql);
$stmt->execute([':token' => $token]);
$datos = $stmt->fetch(PDO::FETCH_ASSOC);
if ($datos) {
return new Usuario(
$datos['nombreUsuario'],
$datos['contrasena'],
$datos['email'],
$datos['avatar'],
$datos['cookie'],
(int)$datos['aciertos'],
(int)$datos['victorias'],
(int)$datos['derrotas'],
(int)$datos['idUsuario']
);
}
return null;
} catch (PDOException $e) {
return null;
}
}
public function cambiarNombre($nuevoNombre)
{
$conexion = conexionBD();
@@ -384,16 +438,17 @@ class Usuario
}
}
public static function obtenerRanking($limite = 10) {
try {
$conexion = conexionBD();
public static function obtenerRanking($limite = 10)
{
try {
$conexion = conexionBD();
if (is_array($conexion)) {
return [];
}
if (is_array($conexion)) {
return [];
}
$sql = "SELECT
$sql = "SELECT
idUsuario,
nombreUsuario,
avatar,
@@ -408,12 +463,12 @@ class Usuario
FROM usuario
ORDER BY victorias DESC, aciertos DESC
LIMIT " . (int)$limite;
$stmt = $conexion->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
return [];
$stmt = $conexion->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
return [];
}
}
}
}
}
+1 -1
View File
@@ -75,6 +75,7 @@ switch ($_POST['orden']) {
break;
case 'salirDeSala':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode(['error' => 'Usuario no autenticado']);
@@ -86,5 +87,4 @@ switch ($_POST['orden']) {
echo json_encode($respuesta);
break;
}
+96
View File
@@ -0,0 +1,96 @@
<?php
session_start();
require_once '../clases/ClaseJuego.php';
header('Content-Type: application/json; charset=utf-8');
// Hay que estar logueado y decir de qué partida se trata
if (!isset($_SESSION['idUsuario'])) {
echo json_encode(['error' => 'Debes iniciar sesión para jugar.']);
exit;
}
$idUsuario = (int)$_SESSION['idUsuario'];
$idPartida = intval($_POST['idPartida'] ?? 0);
if ($idPartida <= 0) {
echo json_encode(['error' => 'No se ha indicado la partida.']);
exit;
}
// Solo pueden jugar los usuarios que están en uno de los equipos de la partida
$perteneceAPartida = Juego::usuarioEnPartida($idPartida, $idUsuario);
if (is_array($perteneceAPartida)) {
echo json_encode($perteneceAPartida);
exit;
}
if (!$perteneceAPartida) {
echo json_encode(['error' => 'No formas parte de esta partida.']);
exit;
}
switch ($_POST['orden'] ?? '') {
// Devuelve las 10 preguntas con sus respuestas (sin marcar la correcta)
case 'cargarPreguntas':
echo json_encode(Juego::cargarPreguntas($idPartida, $idUsuario));
break;
// Guarda la respuesta del usuario y dice si ha acertado
case 'responder':
$idPartidaxPregunta = intval($_POST['idPartidaxPregunta'] ?? 0);
$idRespuesta = intval($_POST['idRespuesta'] ?? 0);
if ($idPartidaxPregunta <= 0 || $idRespuesta <= 0) {
echo json_encode(['error' => 'Faltan datos para registrar la respuesta.']);
break;
}
echo json_encode(
Juego::registrarRespuesta(
$idPartida,
$idUsuario,
$idPartidaxPregunta,
$idRespuesta
)
);
break;
// Recibe los aciertos del jugador al terminar sus 10 preguntas,
// para que resultados.php los pueda usar al montar la hoja de resultados
case 'finalizarPartida':
$aciertos = intval($_POST['aciertos'] ?? 0);
if (!isset($_SESSION['aciertosPorPartida'])) {
$_SESSION['aciertosPorPartida'] = [];
}
$_SESSION['aciertosPorPartida'][$idPartida] = $aciertos;
echo json_encode([
'exito' => 'Aciertos registrados correctamente.',
'idPartida' => $idPartida,
'aciertos' => $aciertos
]);
break;
default:
echo json_encode(['error' => 'La orden indicada no existe.']);
break;
}
+39 -1
View File
@@ -6,6 +6,7 @@ require_once '../clases/ClasePartida.php';
require_once '../clases/ClaseEquipo.php';
require_once '../clases/ClaseEquipoxUsuario.php';
require_once '../clases/ClaseEquipoxPartida.php';
require_once '../clases/ClasePregunta.php';
switch ($_POST['orden']) {
@@ -119,6 +120,7 @@ switch ($_POST['orden']) {
}
$idPartida = (int)$resultadoPartida['exito_tecnico'];
$partida->idPartida = $idPartida;
/*
@@ -211,6 +213,42 @@ switch ($_POST['orden']) {
}
/*
* ==========================================
* 5. ASIGNAMOS 10 PREGUNTAS ALEATORIAS A LA PARTIDA
* ==========================================
*/
// Obtenemos todos los IDs de las preguntas
$listaPreguntas = Pregunta::getTodosIds();
$totalPreguntas = count($listaPreguntas);
// Guardamos las preguntas que ya hemos asignado
$preguntasAsignadas = [];
// Generamos 10 posiciones aleatorias sin repetir
while (count($preguntasAsignadas) < 10) {
// Generamos una posición aleatoria del array
$posicionAleatoria = rand(0, $totalPreguntas - 1);
// Obtenemos el ID real de la pregunta
$idPreguntaAleatoria = $listaPreguntas[$posicionAleatoria];
// Comprobamos que esa pregunta no haya sido asignada ya
if (!in_array($idPreguntaAleatoria, $preguntasAsignadas)) {
$preguntasAsignadas[] = $idPreguntaAleatoria;
// Asignamos el ID real de la pregunta a la partida
$partida->asignarPregunta($idPreguntaAleatoria);
}
}//fin shile
/*
* ==========================================
* TODO CORRECTO
@@ -218,7 +256,7 @@ switch ($_POST['orden']) {
*/
echo json_encode([
'exito' => 'Sala creada correctamente.',
'exito' => 'Sala creada correctamente. Preguntas preparadas.',
'idPartida' => $resultadoPartida['exito_tecnico'],
'idEquipo1' => $equipo1->idEquipo,
'idEquipo2' => $equipo2->idEquipo
+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;
}
+79 -24
View File
@@ -50,21 +50,37 @@ switch ($_POST['orden']) {
$email = trim($_POST['email'] ?? '');
$contrasena = $_POST['contrasena'] ?? '';
$recuerdame = isset($_POST['recuerdame']) && ($_POST['recuerdame'] === 'true' || $_POST['recuerdame'] === true);
$resultado = Usuario::login($email, $contrasena);
if ($resultado instanceof Usuario) {
// === AÑADIR ESTAS LÍNEAS PARA GUARDAR EN SESIÓN ===
// Guardamos la sesión
$_SESSION['idUsuario'] = $resultado->getIdUsuario();
$_SESSION['nombreUsuario'] = $resultado->getNombreUsuario();
$_SESSION['email'] = $resultado->getEmail();
// =================================================
$_SESSION['avatar'] = $resultado->getAvatar();
// Si ha marcado "Recuérdame durante 10 días"
if ($recuerdame) {
$token = bin2hex(random_bytes(32)); // Token único de 64 caracteres
$duracion = time() + (10 * 24 * 60 * 60); // 10 días
setcookie('recuerdame_token', $token, $duracion, "/");
Usuario::guardarCookieToken($resultado->getIdUsuario(), $token);
} else {
// Si entra sin marcar recuérdame, limpiamos la cookie
if (isset($_COOKIE['recuerdame_token'])) {
setcookie('recuerdame_token', '', time() - 3600, "/");
}
Usuario::guardarCookieToken($resultado->getIdUsuario(), null);
}
echo json_encode([
'exito' => 'Login correcto',
'idUsuario' => $resultado->getIdUsuario(),
'nombreUsuario' => $resultado->getNombreUsuario()
'nombreUsuario' => $resultado->getNombreUsuario(),
'avatar' => $resultado->getAvatar()
]);
} else {
@@ -76,13 +92,23 @@ switch ($_POST['orden']) {
break;
case 'cerrarSesion':
// Si el usuario tenía token en la BD, lo eliminamos
if (isset($_SESSION['idUsuario'])) {
Usuario::guardarCookieToken($_SESSION['idUsuario'], null);
}
// Borramos la cookie del navegador
if (isset($_COOKIE['recuerdame_token'])) {
setcookie('recuerdame_token', '', time() - 3600, "/");
}
// Limpiamos las variables de sesión
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
// Destruimos la sesión
session_destroy();
@@ -92,7 +118,6 @@ switch ($_POST['orden']) {
]);
break;
case 'mostrarEstadisticas':
$usuario = Usuario::buscarPorId($_SESSION['idUsuario']);
@@ -228,25 +253,55 @@ switch ($_POST['orden']) {
break;
case 'obtenerRanking':
$ranking = Usuario::obtenerRanking(5); //Cambiar para mostrar X jugadores en index
echo json_encode([
'exito' => true,
'ranking' => $ranking
]);
break;
case 'obtenerRanking':
$ranking = Usuario::obtenerRanking(5); //Cambiar para mostrar X jugadores en index
echo json_encode([
'exito' => true,
'ranking' => $ranking
]);
break;
case 'comprobarSesion':
if (isset($_SESSION['idUsuario']) && !empty($_SESSION['idUsuario'])) {
echo json_encode([
'activa' => true,
'usuario' => [
'idUsuario' => $_SESSION['idUsuario'],
'nombreUsuario' => $_SESSION['nombreUsuario'] ?? ''
]
]);
} else {
//Si hay sesión:
if (isset($_SESSION['idUsuario']) && !empty($_SESSION['idUsuario'])) {
echo json_encode([
'activa' => true,
'usuario' => [
'idUsuario' => $_SESSION['idUsuario'],
'nombreUsuario' => $_SESSION['nombreUsuario'] ?? '',
'avatar' => $_SESSION['avatar'] ?? ''
]
]);
break;
}
// Si no hay sesión, comprobamos si hay cookie:
if (isset($_COOKIE['recuerdame_token'])) {
$usuarioCookie = Usuario::buscarPorCookie($_COOKIE['recuerdame_token']);
if ($usuarioCookie instanceof Usuario) {
$_SESSION['idUsuario'] = $usuarioCookie->getIdUsuario();
$_SESSION['email'] = $usuarioCookie->getEmail();
$_SESSION['nombreUsuario'] = $usuarioCookie->getNombreUsuario();
$_SESSION['avatar'] = $usuarioCookie->getAvatar();
echo json_encode([
'activa' => true,
'usuario' => [
'idUsuario' => $usuarioCookie->getIdUsuario(),
'nombreUsuario' => $usuarioCookie->getNombreUsuario(),
'avatar' => $usuarioCookie->getAvatar()
]
]);
break;
}
}
//No hay sesión ni hay cookie:
echo json_encode(['activa' => false]);
}
break;
}
break;
}
+10 -2
View File
@@ -68,8 +68,8 @@
.btn-unirse {
border: none;
border-bottom: 3px solid #0c4891;
background-color: var(--kahoot-blue);
border-bottom: 3px solid #1f6f09;
background-color: #26890c;
color: white;
font-weight: 600;
border-radius: 8px;
@@ -105,3 +105,11 @@
border-color: var(--kahoot-purple);
box-shadow: 0 0 0 3px rgba(70, 23, 143, 0.15);
}
.jugador-host {
background-color: #fff3cd;
border: 1px solid #ffc107;
border-radius: 8px;
padding: 6px 10px;
font-weight: 600;
}
+63 -1
View File
@@ -116,4 +116,66 @@
.btn-answer {
font-size: 18px;
}
}
}
/* ===== Lógica de juego (js/juego.js) ===== */
.game-header {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.progress-track {
height: 8px;
background-color: #ddd;
border-radius: 4px;
overflow: hidden;
margin-bottom: 16px;
}
.progress-fill {
height: 100%;
width: 0;
background-color: #1368ce;
transition: width 0.3s ease;
}
.feedback {
min-height: 1.5em;
margin-top: 12px;
font-size: 18px;
font-weight: 600;
}
.feedback.ok { color: #26890c; }
.feedback.ko { color: #e21b3c; }
/* Mientras se envía la respuesta o se ve el feedback no se puede volver a pulsar */
.answers-grid.bloqueado .btn-answer {
pointer-events: none;
}
.btn-answer.correcta {
box-shadow: 0 0 0 6px #fff, 0 0 0 10px #26890c;
}
.btn-answer.incorrecta,
.btn-answer.atenuada {
opacity: 0.45;
}
.btn-answer:focus-visible {
outline: 4px solid #333;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.progress-fill,
.btn-answer {
transition: none;
}
}
+179
View File
@@ -0,0 +1,179 @@
/* ==========================================================================
ESTILOS GENERALES Y FONDO
========================================================================== */
* {
margin: 0;
padding: 0;
box-shadow: none;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
background-color: #f0f4f8;
color: #2c3e50;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
/* Contenedor principal estilo tarjeta */
.contenedor {
width: 100%;
max-width: 900px;
background: #ffffff;
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
text-align: center;
animation: fadeIn 0.5s ease-in-out;
}
h1 {
font-size: 2.5rem;
color: #1a365d;
margin-bottom: 30px;
}
h2 {
font-size: 1.6rem;
color: #2b6cb0;
margin-top: 30px;
margin-bottom: 15px;
text-align: left;
border-bottom: 2px solid #e2e8f0;
padding-bottom: 8px;
}
p {
font-size: 1.1rem;
color: #718096;
margin-bottom: 30px;
}
/* ==========================================================================
PANTALLA DE ESPERA Y ANIMACIÓN DE CARGA (LOADER)
========================================================================== */
#pantalla-espera {
padding: 60px 20px;
}
.loader {
width: 60px;
height: 60px;
border: 6px solid #e2e8f0;
border-top: 6px solid #3182ce;
border-radius: 50%;
margin: 0 auto;
animation: spin 1.2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* ==========================================================================
TABLAS DE CLASIFICACIÓN (RANKING)
========================================================================== */
.tabla-ranking {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
font-size: 1.05rem;
}
.tabla-ranking th,
.tabla-ranking td {
padding: 16px 20px;
text-align: left;
}
.tabla-ranking th {
background-color: #2d3748;
color: #ffffff;
font-weight: 600;
text-transform: uppercase;
font-size: 0.9rem;
letter-spacing: 0.5px;
}
/* Alinear los puntos y aciertos a la derecha para mejor lectura numérica */
.tabla-ranking th:last-child,
.tabla-ranking td:last-child {
text-align: right;
}
.tabla-ranking tr {
border-bottom: 1px solid #e2e8f0;
transition: background-color 0.2s;
}
.tabla-ranking tbody tr:hover {
background-color: #f7fafc;
}
/* ==========================================================================
RESALTADO DE GANADORES (1º PUESTO)
========================================================================== */
/* Fila del Equipo Ganador y Jugador Ganador */
.tabla-ranking tr.top-team,
.tabla-ranking tr.top-player {
background-color: #fefcbf !important; /* Amarillo suave */
font-weight: bold;
}
/* Cambiar el color del texto del puesto #1 a dorado/corona */
.tabla-ranking tr.top-team td:first-child,
.tabla-ranking tr.top-player td:first-child {
color: #b7791f;
font-size: 1.2rem;
}
.tabla-ranking td strong {
color: #2f855a; /* Verde para destacar los aciertos conseguidos */
font-size: 1.1rem;
}
/* ==========================================================================
EFECTOS VISUALES SUAVES
========================================================================== */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* ==========================================================================
ESTILOS DEL BOTÓN DE RETORNO A INICIO
========================================================================== */
.contenedor-boton {
margin-top: 40px;
padding-top: 20px;
text-align: center;
}
.btn-inicio {
display: inline-block;
background-color: #3182ce; /* Azul corporativo */
color: #ffffff;
padding: 14px 28px;
font-size: 1.1rem;
font-weight: 600;
text-decoration: none;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(49, 130, 206, 0.2);
transition: background-color 0.2s, transform 0.2s, box-shadow 0.2s;
}
.btn-inicio:hover {
background-color: #2b6cb0; /* Azul ligeramente más oscuro al pasar el cursor */
box-shadow: 0 6px 12px rgba(43, 108, 176, 0.3);
transform: translateY(-2px); /* Pequeño salto hacia arriba */
}
.btn-inicio:active {
transform: translateY(0); /* Vuelve a su posición normal al pulsar */
box-shadow: 0 2px 4px rgba(43, 108, 176, 0.2);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+23 -26
View File
@@ -1,29 +1,26 @@
<?php
//CARGA DE ARCHIVOS .ENV CON PHPDOTENV
require('c:/laragon/vendor/autoload.php');//Se carga el módulo instalado con composer
$dotenv = Dotenv\Dotenv::createImmutable('c:/laragon/', 'triviagmatico.env');//leemos el archivo. El primer parámetro es la ruta para llegar y el segundo el nombre del archivo .env
$dotenv->load();
function conexionBD() {
// Configuración para Laragon
$servidor = "localhost";
$bd = "triviagmatico"; // Asegúrate de que este sea el nombre de tu BD en HeidiSQL / phpMyAdmin
$usuario = "root";
$pass = ""; // Laragon deja la contraseña de root vacía por defecto
$puerto = "3306";
try {
$dsn = "mysql:host=$servidor;port=$puerto;dbname=$bd;charset=utf8mb4";
$opciones = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
return new PDO($dsn, $usuario, $pass, $opciones);
} catch (PDOException $error) {
return [
'error' => 'No se pudo conectar a la base de datos.',
'error_tecnico' => $error->getMessage()
];
function conexionBD (){
try{
$servidor = 'mysql:host='.$_ENV['bDatosServer'].';dbname='.$_ENV['bDatos'];
$user=$_ENV['bDatosUser'];
$password=$_ENV['bDatosPass'];
$options=array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
);
//Creamos la conexión PDO a la base de datos
$pdo = new PDO($servidor, $user, $password, $options);
}
}
?>
catch(PDOException $e){
//$resultado = ['error' => $e->getMessage()];
$resultado = ['error' => 'Error Temporal: No se puede conectar con la base de datos.'];
return $resultado;
}
return $pdo;
}
+3 -6
View File
@@ -1,7 +1,3 @@
<?php
include 'cabecera.php';
?>
<!DOCTYPE html>
<html lang="es-ES">
@@ -9,16 +5,17 @@ include 'cabecera.php';
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Triviagmático</title>
<script src="js/jquery-4.0.0.min.js"></script>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head>
<body>
<?php include 'cabecera.php'; ?>
<div class="container my-5">
<div class="row justify-content-center align-items-center g-4">
<!-- Botón Jugar (oculto por defecto, JS lo muestra si hay sesión) -->
<!-- Botón Jugar (oculto por defecto, JS lo muestra si hay sesión activa) -->
<div class="col-12 col-lg-5 col-xl-4 d-none" id="colBotonJugar">
<a href="buscadorSala.php" class="btn btn-play-kahoot" id="btnJugar">
<i class="fa-solid fa-play"></i>
+186 -239
View File
@@ -4,6 +4,7 @@ $(document).ready(function () {
comprobarSalaUsuario();
});
// 1. Comprobar si el usuario actual ya pertenece a una sala
function comprobarSalaUsuario() {
$("#cargandoSalas").remove();
@@ -11,101 +12,64 @@ function comprobarSalaUsuario() {
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: {
orden: "obtenerSalaUsuario",
},
data: { orden: "obtenerSalaUsuario" },
success: function (respuesta) {
console.log("Sala del usuario:", respuesta);
if (respuesta.error) {
console.error(respuesta.error);
if (respuesta.error || !respuesta.asociado) {
usuarioYaEstaEnEquipo = false;
$("#contenedorCrearSala").show();
cargarSalas();
return;
}
if (respuesta.asociado) {
usuarioYaEstaEnEquipo = true;
$("#contenedorCrearSala").hide();
cargarSalaUsuario(respuesta.idPartida);
} else {
usuarioYaEstaEnEquipo = false;
cargarSalas();
usuarioYaEstaEnEquipo = true;
$("#contenedorCrearSala").hide(); // Ocultar "Crear Sala" si ya pertenece a una
cargarSalaUsuario(respuesta.idPartida);
}
},
error: function (xhr, status, error) {
console.error("Error al comprobar la sala del usuario:", error);
usuarioYaEstaEnEquipo = false;
cargarSalas();
},
});
}
// 2. Cargar únicamente la sala en la que está metido el usuario
function cargarSalaUsuario(idPartida) {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
orden: "buscar",
idPartida: idPartida,
},
data: { orden: "buscar", idPartida: idPartida },
success: function (partida) {
if (partida.error) {
console.error(partida.error);
return;
}
$("#contenedorSalas").empty();
cargarInformacionSala(partida);
},
error: function (xhr, status, error) {
console.error("Error al obtener la sala del usuario:", error);
},
});
}
// 3. Cargar la lista completa de todas las salas
function cargarSalas() {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
orden: "listar",
},
data: { orden: "listar" },
success: function (partidas) {
const contenedor = $("#contenedorSalas");
contenedor.empty();
contenedor.empty();
if (!Array.isArray(partidas) || partidas.length === 0) {
contenedor.html(`
<div class="col-12 text-center">
<p class="text-muted">
No hay salas disponibles.
</p>
</div>
`);
<div class="col-12 text-center">
<p class="text-muted">No hay salas disponibles actualmente.</p>
</div>
`);
return;
}
@@ -113,54 +77,42 @@ function cargarSalas() {
cargarInformacionSala(partida);
});
},
error: function (xhr, status, error) {
console.error("Error al obtener las partidas:", error);
},
});
}
// 4. Obtener equipos y jugadores asociados a una sala concreta
function cargarInformacionSala(partida) {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
orden: "getEquipos",
idPartida: partida.idPartida,
},
data: { orden: "getEquipos", idPartida: partida.idPartida },
success: function (equipos) {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
orden: "getJugadores",
idPartida: partida.idPartida,
},
data: { orden: "getJugadores", idPartida: partida.idPartida },
success: function (jugadores) {
mostrarSala(partida, equipos, jugadores);
},
error: function (xhr, status, error) {
console.error("Error al obtener jugadores:", error);
},
});
},
error: function (xhr, status, error) {
console.error("Error al obtener equipos:", error);
},
});
}
// 5. Renderizar el HTML de la sala y botones según estado
function mostrarSala(partida, equipos, jugadores) {
const contenedor = $("#contenedorSalas");
let equiposHTML = "";
equipos.forEach(function (equipo) {
@@ -168,230 +120,250 @@ function mostrarSala(partida, equipos, jugadores) {
return jugador.idEquipo == equipo.idEquipo;
});
let jugadoresHTML = "";
let jugadoresHTML = "";
if (jugadoresEquipo.length > 0) {
jugadoresEquipo.forEach(function (jugador) {
const esHost = jugador.idUsuario == partida.idUsuario;
jugadoresHTML += `
<div class="jugador">
<div class="jugador border border-2 d-flex align-items-center justify-content-between ${
esHost ? "jugador-host" : ""
}">
<div>
<span class="avatar">${esHost ? '<i class="bi bi-award-fill"></i>' : '<i class="bi bi-person-fill"></i>'}</span>
${escapeHTML(jugador.nombreUsuario)}
</div>
<span class="avatar">
👤
</span>
${escapeHTML(jugador.nombreUsuario)}
</div>
`;
${
esHost
? `<span class="badge bg-warning text-dark ms-2">HOST</span>`
: ""
}
</div>
`;
});
} else {
jugadoresHTML = `
<div class="text-muted small">
Sin jugadores
</div>
`;
jugadoresHTML = `<div class="text-muted small">Sin jugadores</div>`;
}
let botonUnirseHTML = "";
// Botón "Unirse" solo visible si NO pertenece a ningún equipo
let botonUnirseHTML = "";
if (!usuarioYaEstaEnEquipo) {
botonUnirseHTML = `
<button
type="button"
class="btn btn-unirse w-100 btn-unirse-equipo"
<button type="button" class="btn-unirse w-100 btn-unirse-equipo mt-2"
data-id-partida="${partida.idPartida}"
data-id-equipo="${equipo.idEquipo}">
Unirse
</button>
`;
Unirse
</button>
`;
}
equiposHTML += `
<div class="equipo">
<h6>
${escapeHTML(equipo.nombreEquipo)}
</h6>
<div class="jugadores">
${jugadoresHTML}
</div>
${botonUnirseHTML}
<div class="equipo me-2 ms-2 p-3 border rounded">
<h6>${escapeHTML(equipo.nombreEquipo)}</h6>
<div class="jugadores mb-2">
${jugadoresHTML}
</div>
${botonUnirseHTML}
</div>
`;
});
const salaHTML = `
<div class="col-12 col-md-10 col-lg-8">
// Acciones disponibles si el usuario YA ESTÁ dentro de esta sala
// Acciones disponibles si el usuario YA ESTÁ dentro de esta sala
let accionesSalaHTML = "";
<div class="sala">
if (usuarioYaEstaEnEquipo) {
const esHost = partida.idUsuario == idUsuarioSesion;
let botonIniciarHTML = "";
<div class="sala-header">
// Solo el host puede iniciar la partida
if (esHost) {
botonIniciarHTML = `
<a href="juego.php?idPartida=${partida.idPartida}"
class="btn btn-success btn-lg px-4">
<i class="bi bi-controller"></i> ¡Iniciar Partida!
</a>
`;
}
${escapeHTML(partida.nombrePartida)}
accionesSalaHTML = `
<div class="sala-acciones text-center mt-4 pt-3 border-top d-flex justify-content-center gap-3">
</div>
<button type="button"
class="btn btn-outline-danger btn-abandonar-sala"
data-id-partida="${partida.idPartida}"
data-es-host="${esHost}">
Abandonar sala
</button>
<div class="sala-body">
<div class="equipos">
${equiposHTML}
</div>
</div>
</div>
${botonIniciarHTML}
</div>
`;
`;
}
const salaHTML = `
<div class="col-12 col-md-10 col-lg-8">
<div class="sala card p-3 shadow-sm mb-4">
<div class="sala-header h4 text-center mb-3 text-white">
${escapeHTML(partida.nombrePartida)}
</div>
<div class="sala-body">
<div class="equipos d-flex justify-content-around">
${equiposHTML}
</div>
${accionesSalaHTML}
</div>
</div>
</div>
`;
contenedor.append(salaHTML);
}
// ======================================================
// UNIRSE A UN EQUIPO
// ======================================================
// 6. Evento: Unirse a un Equipo
$(document).on("click", ".btn-unirse-equipo", function () {
const boton = $(this);
const idEquipo = boton.data("id-equipo");
const idPartida = boton.data("id-partida");
boton.prop("disabled", true);
boton.text("Uniéndose...");
boton.prop("disabled", true).text("Uniéndose...");
$.ajax({
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: {
orden: "registrarUsuarioEnEquipo",
idEquipo: idEquipo,
},
success: function (respuesta) {
console.log("Respuesta al unirse:", respuesta);
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false);
boton.text("Unirse");
boton.prop("disabled", false).text("Unirse");
return;
}
// ==========================================
// UNIÓN CORRECTA
// ==========================================
usuarioYaEstaEnEquipo = true;
// Ocultamos el botón "Crear sala"
$("#contenedorCrearSala").hide();
// Eliminamos las salas actuales
$("#contenedorSalas").empty();
// Cargamos directamente la sala
// donde acaba de entrar el usuario
cargarSalaUsuario(idPartida);
},
error: function (xhr, status, error) {
console.error("Error al unirse al equipo:", error);
console.error("Respuesta del servidor:", xhr.responseText);
alert("No se ha podido unir al equipo.");
boton.prop("disabled", false);
boton.text("Unirse");
boton.prop("disabled", false).text("Unirse");
},
});
});
// ======================================================
// ESCAPAR HTML
// ======================================================
// 7. Evento: Abandonar Sala
// Guardamos temporalmente el botón presionado
let botonAbandonarReferencia = null;
function escapeHTML(texto) {
return $("<div>")
.text(texto ?? "")
.html();
}
// A. Al hacer clic en el botón "Abandonar sala" de la tarjeta, abrimos el modal
$(document).on("click", ".btn-abandonar-sala", function () {
botonAbandonarReferencia = $(this);
// ======================================================
// CREAR SALA
// ======================================================
const esHost = $(this).data("es-host") === true || $(this).data("es-host") === "true";
const titulo = $("#modalAbandonarSalaLabel");
const mensaje = $("#modalAbandonarSalaMensaje");
const botonConfirmar = $("#btnConfirmarAbandonar");
if (esHost) {
titulo.text("¿Abandonar la sala?");
mensaje.text(
"Si abandonas la sala como anfitrión, la partida terminará para todos los jugadores.",
);
botonConfirmar.text("Sí, abandonar");
} else {
titulo.text("¿Abandonar la sala?");
mensaje.text(
"Si sales de la sala, perderás tu lugar en el equipo.",
);
botonConfirmar.text("Sí, salir");
}
const modal = new bootstrap.Modal(
document.getElementById("modalAbandonarSala"),
);
modal.show();
});
// B. Al hacer clic en "Sí, salir" dentro del modal Kahoot
$(document).on("click", "#btnConfirmarAbandonar", function () {
const modalEl = document.getElementById("modalAbandonarSala");
const modalInstance = bootstrap.Modal.getInstance(modalEl);
const btnConfirmar = $(this);
btnConfirmar.prop("disabled", true).text("Saliendo...");
$.ajax({
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: { orden: "salirDeSala" },
success: function (respuesta) {
btnConfirmar.prop("disabled", false).text("Sí, salir");
if (modalInstance) {
modalInstance.hide();
}
if (respuesta.error) {
alert(respuesta.error);
return;
}
// Restablecemos la interfaz a la lista completa de salas
usuarioYaEstaEnEquipo = false;
$("#contenedorCrearSala").show();
cargarSalas();
},
error: function (xhr, status, error) {
console.error("Error al salir de la sala:", error);
alert("No se pudo salir de la sala.");
btnConfirmar.prop("disabled", false).text("Sí, salir");
if (modalInstance) {
modalInstance.hide();
}
},
});
});
// 8. Evento: Crear Sala
$("#btnCrearSala").on("click", function () {
const nombreSala = $("#nombreSala").val().trim();
const nombreEquipo1 = $("#nombreEquipo1").val().trim();
const nombreEquipo2 = $("#nombreEquipo2").val().trim();
let valido = true;
$(".mensaje-error-sala").remove();
$(".input-kahoot").removeClass("is-invalid");
if (nombreSala === "") {
mostrarError("#nombreSala", "El nombre de la sala es obligatorio.");
valido = false;
} else if (nombreSala.length < 3) {
if (nombreSala === "" || nombreSala.length < 3) {
mostrarError(
"#nombreSala",
"El nombre de la sala debe tener al menos 3 caracteres.",
);
valido = false;
}
if (nombreEquipo1 === "") {
mostrarError("#nombreEquipo1", "El nombre del equipo 1 es obligatorio.");
valido = false;
} else if (nombreEquipo1.length < 2) {
if (nombreEquipo1 === "" || nombreEquipo1.length < 2) {
mostrarError(
"#nombreEquipo1",
"El nombre del equipo debe tener al menos 2 caracteres.",
);
valido = false;
}
if (nombreEquipo2 === "") {
mostrarError("#nombreEquipo2", "El nombre del equipo 2 es obligatorio.");
valido = false;
} else if (nombreEquipo2.length < 2) {
if (nombreEquipo2 === "" || nombreEquipo2.length < 2) {
mostrarError(
"#nombreEquipo2",
"El nombre del equipo debe tener al menos 2 caracteres.",
);
valido = false;
}
@@ -404,22 +376,16 @@ $("#btnCrearSala").on("click", function () {
"#nombreEquipo2",
"Los dos equipos deben tener nombres diferentes.",
);
valido = false;
}
if (!valido) {
return;
}
if (!valido) return;
// Deshabilitamos el botón mientras se crea la sala
const boton = $("#btnCrearSala");
boton.prop("disabled", true);
boton.text("Creando sala...");
boton.prop("disabled", true).text("Creando sala...");
$.ajax({
url: "controladores/controladorPartida.php", // <-- cambia esto por la ruta de tu controlador
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
@@ -428,16 +394,10 @@ $("#btnCrearSala").on("click", function () {
nombreEquipo1: nombreEquipo1,
nombreEquipo2: nombreEquipo2,
},
success: function (respuesta) {
console.log("Respuesta del servidor:", respuesta);
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false);
boton.text("Crear sala");
boton.prop("disabled", false).text("Crear sala");
return;
}
@@ -446,43 +406,30 @@ $("#btnCrearSala").on("click", function () {
location.reload();
}
},
error: function (xhr, status, error) {
console.error("Error al crear la sala:", error);
console.error("Respuesta:", xhr.responseText);
alert("No se ha podido crear la sala.");
boton.prop("disabled", false);
boton.text("Crear sala");
boton.prop("disabled", false).text("Crear sala");
},
});
});
// ======================================================
// MOSTRAR ERROR
// ======================================================
// Auxiliares
function escapeHTML(texto) {
return $("<div>")
.text(texto ?? "")
.html();
}
function mostrarError(selector, mensaje) {
const input = $(selector);
input.addClass("is-invalid");
input.after(`
<div class="mensaje-error-sala text-danger mt-1 small">
${mensaje}
</div>
`);
input.after(
`<div class="mensaje-error-sala text-danger mt-1 small">${mensaje}</div>`,
);
}
// ======================================================
// QUITAR ERROR AL ESCRIBIR
// ======================================================
$(".input-kahoot").on("input", function () {
$(document).on("input", ".input-kahoot", function () {
$(this).removeClass("is-invalid");
$(this).next(".mensaje-error-sala").remove();
});
+37 -130
View File
@@ -1,13 +1,15 @@
// Función de escape colocada arriba para evitar el ReferenceError
function escapeHTML(str) {
return $("<div>").text(str ?? "").html();
}
let idUsuarioSesion = null;
// Comprobar estado de sesión al cargar la página
$(document).ready(function () {
comprobarSesion();
});
// Función auxiliar para escapar texto HTML
function escapeHTML(str) {
return $("<div>")
.text(str ?? "")
.html();
}
// Comprobar estado de sesión al cargar la página
function comprobarSesion() {
@@ -20,17 +22,23 @@ function comprobarSesion() {
if (typeof respuesta === "string") {
respuesta = JSON.parse(respuesta);
}
const contenedor = $("#contenedorUsuarioCabecera");
contenedor.empty();
if (respuesta.activa && respuesta.usuario) {
// 1. Renderizar Menú de Usuario en la Cabecera
// Recogemos el idUsuario de la sesion en una variable para usarlo (no me lo volváis a borrar por favor os lo pido)
idUsuarioSesion = respuesta.usuario.idUsuario;
// Obtenemos la ruta del avatar o la de por defecto
const avatarUrl =
respuesta.usuario.avatar || "img/avatars/defaultProfile.jpeg";
// Usuario autenticado: Mostrar Menú Dropdown con el avatar
const htmlUsuario = `
<div class="dropdown">
<button class="btn user-dropdown-btn dropdown-toggle d-flex align-items-center gap-2"
type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-circle-user fa-lg text-warning"></i>
<img src="${escapeHTML(avatarUrl)}" alt="Avatar" class="rounded-circle" style="width: 32px; height: 32px; object-fit: cover;">
<span>${escapeHTML(respuesta.usuario.nombreUsuario)}</span>
</button>
<ul class="dropdown-menu dropdown-menu-end user-dropdown-menu" aria-labelledby="userDropdown">
@@ -50,12 +58,15 @@ function comprobarSesion() {
`;
contenedor.html(htmlUsuario);
// 2. Muestra el botón JUGAR y ajusta columnas
$("#colBotonJugar").removeClass("d-none");
$("#colRanking").removeClass("col-lg-8").addClass("col-lg-7 col-xl-8");
// Si estamos en la página principal, mostramos el botón JUGAR
if ($("#colBotonJugar").length) {
$("#colBotonJugar").removeClass("d-none");
$("#colRanking")
.removeClass("col-lg-8")
.addClass("col-lg-7 col-xl-8");
}
} else {
// 1. Renderizar Botones de Invitado
// No hay sesión: Mostrar botones de Login y Registro
const htmlInvitado = `
<button type="button" class="btn btn-kahoot-login rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#modalLogin">
<i class="fa-solid fa-right-to-bracket me-1"></i> Iniciar Sesión
@@ -66,9 +77,13 @@ function comprobarSesion() {
`;
contenedor.html(htmlInvitado);
// 2. Ocultar el botón JUGAR y expandir ranking
$("#colBotonJugar").addClass("d-none");
$("#colRanking").removeClass("col-lg-7 col-xl-8").addClass("col-lg-8");
// Si estamos en la página principal, ocultamos el botón JUGAR
if ($("#colBotonJugar").length) {
$("#colBotonJugar").addClass("d-none");
$("#colRanking")
.removeClass("col-lg-7 col-xl-8")
.addClass("col-lg-8");
}
}
} catch (e) {
console.error("Error al procesar la respuesta de la sesión:", e);
@@ -76,9 +91,10 @@ function comprobarSesion() {
});
}
// Registro
// Registro
$("#botonAceptarRegistro").click(function (event) {
event.preventDefault();
let nombreUsuario = $("#regNombre").val().trim();
let email = $("#regEmail").val().trim();
let contrasena = $("#regPassword").val();
@@ -128,12 +144,13 @@ $("#botonAceptarRegistro").click(function (event) {
});
});
// Login
// Login
$("#botonAceptarLogin").click(function (event) {
event.preventDefault();
let email = $("#loginEmail").val().trim();
let contrasena = $("#loginPassword").val();
let recuerdame = $("#recordar").is(":checked");
$("#loginEmail").removeClass("is-invalid");
$("#loginPassword").removeClass("is-invalid");
@@ -152,6 +169,7 @@ $("#botonAceptarLogin").click(function (event) {
data: {
email: email,
contrasena: contrasena,
recuerdame: recuerdame,
orden: "comprobarUsuario",
},
}).done(function (respuesta) {
@@ -167,7 +185,7 @@ $("#botonAceptarLogin").click(function (event) {
});
});
// Cerrar sesión
// Cerrar sesión
$(document).on("click", "#botonCerrarSesion", function (event) {
event.preventDefault();
@@ -186,114 +204,3 @@ $(document).on("click", "#botonCerrarSesion", function (event) {
});
});
// Registro
$("#botonAceptarRegistro").click(function (event) {
event.preventDefault();
let nombreUsuario = $("#regNombre").val().trim();
let email = $("#regEmail").val().trim();
let contrasena = $("#regPassword").val();
let contrasenaConfirmacion = $("#regPasswordConfirm").val();
$("#regNombre").removeClass("is-invalid");
$("#regEmail").removeClass("is-invalid");
$("#regPassword").removeClass("is-invalid");
$("#regPasswordConfirm").removeClass("is-invalid");
$("#errorRegistro").text("");
if (contrasena !== contrasenaConfirmacion) {
$("#regPassword").addClass("is-invalid");
$("#regPasswordConfirm").addClass("is-invalid");
$("#errorRegistro").text("Las contraseñas no coinciden.");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
nombreUsuario: nombreUsuario,
email: email,
contrasena: contrasena,
orden: "registrarUsuario",
},
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$("#errorRegistro").text(respuesta.error);
$("#regNombre").addClass("is-invalid");
$("#regEmail").addClass("is-invalid");
} else {
$("#errorRegistro")
.removeClass("text-danger")
.addClass("text-success")
.text(respuesta.exito);
$("#formRegistro")[0].reset();
setTimeout(function () {
location.reload();
}, 1000);
}
});
});
// Login
$("#botonAceptarLogin").click(function (event) {
event.preventDefault();
let email = $("#loginEmail").val().trim();
let contrasena = $("#loginPassword").val();
$("#loginEmail").removeClass("is-invalid");
$("#loginPassword").removeClass("is-invalid");
$("#errorLogin").text("");
if (email === "" || contrasena === "") {
$("#errorLogin").text("Todos los campos son obligatorios.");
if (email === "") $("#loginEmail").addClass("is-invalid");
if (contrasena === "") $("#loginPassword").addClass("is-invalid");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
email: email,
contrasena: contrasena,
orden: "comprobarUsuario",
},
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$("#loginEmail").addClass("is-invalid");
$("#loginPassword").addClass("is-invalid");
$("#errorLogin").text(respuesta.error);
} else {
location.reload();
}
});
});
// Cerrar sesión (Usa delegación de eventos por si el botón se crea dinámicamente)
$(document).on("click", "#botonCerrarSesion", function (event) {
event.preventDefault();
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: { orden: "cerrarSesion" },
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
window.location.href = "index.php";
}
});
});
+45 -39
View File
@@ -1,36 +1,36 @@
$(document).ready(function () {
cargarRanking();
cargarRanking();
});
function cargarRanking() {
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
data: { orden: 'obtenerRanking' },
dataType: 'json',
success: function (response) {
if (response.exito && response.ranking.length > 0) {
renderizarTablaRanking(response.ranking);
} else {
$('#ranking-container').html(`
$.ajax({
url: "controladores/controladorUsuario.php",
type: "POST",
data: { orden: "obtenerRanking" },
dataType: "json",
success: function (response) {
if (response.exito && response.ranking.length > 0) {
renderizarTablaRanking(response.ranking);
} else {
$("#ranking-container").html(`
<div class="alert alert-info my-3">
<i class="fa-solid fa-info-circle me-2"></i>Aún no hay partidas registradas para mostrar el ranking.
</div>
`);
}
},
error: function () {
$('#ranking-container').html(`
}
},
error: function () {
$("#ranking-container").html(`
<div class="alert alert-danger my-3">
<i class="fa-solid fa-exclamation-triangle me-2"></i>Error al cargar la clasificación.
</div>
`);
}
});
},
});
}
function renderizarTablaRanking(jugadores) {
let html = `
let html = `
<div class="table-responsive">
<table class="table table-striped table-hover align-middle mb-0 text-center">
<thead class="table-dark">
@@ -46,24 +46,29 @@ function renderizarTablaRanking(jugadores) {
<tbody>
`;
jugadores.forEach((jugador, index) => {
let posicion = index + 1;
let medalla = '';
jugadores.forEach((jugador, index) => {
let posicion = index + 1;
let medalla = "";
// Medallas para el Top 3
if (posicion === 1) {
medalla = '<i class="fa-solid fa-medal text-warning fa-lg" title="1º Puesto"></i>';
} else if (posicion === 2) {
medalla = '<i class="fa-solid fa-medal text-secondary fa-lg" title="2º Puesto"></i>';
} else if (posicion === 3) {
medalla = '<i class="fa-solid fa-medal text-brown fa-lg" style="color: #cd7f32;" title="3º Puesto"></i>';
} else {
medalla = `<span class="fw-bold text-muted">${posicion}</span>`;
}
// Medallas para el Top 3
if (posicion === 1) {
medalla =
'<i class="fa-solid fa-medal text-warning fa-lg" title="1º Puesto"></i>';
} else if (posicion === 2) {
medalla =
'<i class="fa-solid fa-medal text-secondary fa-lg" title="2º Puesto"></i>';
} else if (posicion === 3) {
medalla =
'<i class="fa-solid fa-medal text-brown fa-lg" style="color: #cd7f32;" title="3º Puesto"></i>';
} else {
medalla = `<span class="fw-bold text-muted">${posicion}</span>`;
}
let avatarImg = jugador.avatar ? jugador.avatar : 'img/avatars/defaultProfile.jpeg';
let avatarImg = jugador.avatar
? jugador.avatar
: "img/avatars/defaultProfile.jpeg";
html += `
html += `
<tr>
<td class="fw-bold fs-5">${medalla}</td>
<td class="text-start fw-bold">
@@ -78,18 +83,19 @@ function renderizarTablaRanking(jugadores) {
</td>
</tr>
`;
});
});
html += `
html += `
</tbody>
</table>
</div>
`;
$('#ranking-container').removeClass('text-center p-4 ranking-placeholder').html(html);
$("#ranking-container")
.removeClass("text-center p-4 ranking-placeholder")
.html(html);
}
function escapeHtml(texto) {
return $('<div>').text(texto).html();
}
return $("<div>").text(texto).html();
}
+219
View File
@@ -0,0 +1,219 @@
// Lógica de juego.php
// Carga las preguntas de la partida, las muestra de una en una,
// guarda cada respuesta en el servidor y al terminar lleva a resultados.php
const URL_CONTROLADOR = "controladores/ControladorJuego.php";
const PAUSA_FEEDBACK = 1800; // ms que se ve si has acertado o fallado
// Colores y formas de los botones (estilo Kahoot, definidos en juego.css)
const ESTILOS_BOTON = [
{ color: "red", forma: "triangle" },
{ color: "blue", forma: "diamond" },
{ color: "yellow", forma: "circle" },
{ color: "green", forma: "square" },
];
let idPartida = 0;
let preguntas = [];
let indice = 0; // pregunta que se está mostrando
let bloqueado = false; // true mientras se envía una respuesta o se ve el feedback
let numeroAciertos = 0; // número de aciertos del jugador
$(document).ready(function () {
idPartida = parseInt($("body").data("id-partida"), 10);
// Un solo listener para todos los botones de respuesta
$("#respuestas").on("click", ".btn-answer", function () {
responder($(this));
});
cargarPreguntas();
});
// 1. Pedir las preguntas al servidor
function cargarPreguntas() {
$.ajax({
url: URL_CONTROLADOR,
type: "POST",
dataType: "json",
data: { orden: "cargarPreguntas", idPartida: idPartida },
success: function (datos) {
if (datos.error) {
mostrarError(datos.error);
return;
}
preguntas = datos.preguntas;
if (preguntas.length === 0) {
mostrarError("Esta partida no tiene preguntas.");
return;
}
// Retomamos por la primera pregunta sin responder (por si recarga la página)
indice = preguntas.findIndex(function (p) {
return !p.respondida;
});
if (indice === -1) {
irAResultados();
return;
}
mostrarPregunta();
},
error: function () {
mostrarError("No se pudo conectar con el servidor.");
},
});
}
// 2. Pintar la pregunta actual y sus respuestas
function mostrarPregunta() {
const pregunta = preguntas[indice];
bloqueado = false;
$("#textoPregunta").text(pregunta.nombrePregunta);
$("#feedback").text("").removeClass("ok ko");
$("#contadorPregunta").text(
"Pregunta " + (indice + 1) + " de " + preguntas.length,
);
$("#barraProgreso").css("width", (indice / preguntas.length) * 100 + "%");
const $respuestas = $("#respuestas").empty();
pregunta.respuestas.forEach(function (respuesta, i) {
const estilo = ESTILOS_BOTON[i % ESTILOS_BOTON.length];
// .text() y createTextNode evitan que el texto de la BD se interprete como HTML
const $boton = $("<button>")
.attr("type", "button")
.addClass("btn-answer " + estilo.color)
.attr("data-id-respuesta", respuesta.idRespuesta)
.append($("<span>").addClass("shape " + estilo.forma))
.append(document.createTextNode(respuesta.nombreRespuesta));
$respuestas.append($boton);
});
}
// 3. El usuario pulsa una respuesta: se guarda y se enseña si ha acertado
function responder($botonPulsado) {
if (bloqueado) {
return;
}
bloqueado = true;
const pregunta = preguntas[indice];
const idRespuesta = parseInt($botonPulsado.attr("data-id-respuesta"), 10);
$("#respuestas").addClass("bloqueado");
$.ajax({
url: URL_CONTROLADOR,
type: "POST",
dataType: "json",
data: {
orden: "responder",
idPartida: idPartida,
idPartidaxPregunta: pregunta.idPartidaxPregunta,
idRespuesta: idRespuesta,
},
success: function (datos) {
if (datos.error) {
// No se guardó: dejamos que vuelva a intentarlo
$("#feedback").text(datos.error).removeClass("ok").addClass("ko");
$("#respuestas").removeClass("bloqueado");
bloqueado = false;
return;
}
pregunta.respondida = true;
mostrarFeedback($botonPulsado, datos);
setTimeout(function () {
if (datos.terminada || indice >= preguntas.length - 1) {
terminar();
} else {
indice++;
$("#respuestas").removeClass("bloqueado");
mostrarPregunta();
}
}, PAUSA_FEEDBACK);
},
error: function () {
$("#feedback")
.text("No se pudo guardar la respuesta. Inténtalo de nuevo.")
.removeClass("ok")
.addClass("ko");
$("#respuestas").removeClass("bloqueado");
bloqueado = false;
},
});
}
// Marca la respuesta correcta en verde y atenúa el resto
function mostrarFeedback($botonPulsado, datos) {
$("#respuestas .btn-answer").each(function () {
const $boton = $(this);
const esLaCorrecta =
parseInt($boton.attr("data-id-respuesta"), 10) ===
datos.idRespuestaCorrecta;
if (esLaCorrecta) {
$boton.addClass("correcta");
} else {
$boton.addClass("atenuada");
}
});
if (datos.acierto) {
$("#feedback").text("¡Correcto!").removeClass("ko").addClass("ok");
numeroAciertos++;
} else {
$botonPulsado.addClass("incorrecta");
$("#feedback")
.text("Respuesta incorrecta. La correcta está marcada.")
.removeClass("ok")
.addClass("ko");
}
}
// 4. Última pregunta respondida: se avisa al backend con los aciertos y luego se va a resultados
function terminar() {
$("#barraProgreso").css("width", "100%");
$("#respuestas").empty();
$("#contadorPregunta").text("Partida terminada");
$("#textoPregunta").text("¡Has terminado! Cargando resultados…");
$("#feedback").text("").removeClass("ok ko");
setTimeout(function () {
$.ajax({
url: URL_CONTROLADOR,
type: "POST",
dataType: "json",
data: {
orden: "finalizarPartida",
idPartida: idPartida,
aciertos: numeroAciertos,
},
complete: function () {
// Se va a resultados tanto si el AJAX ha ido bien como si ha fallado
irAResultados();
},
});
}, 1200);
}
function irAResultados() {
window.location.href = "resultados.php?idPartida=" + idPartida;
}
function mostrarError(mensaje) {
$("#respuestas").empty();
$("#textoPregunta").text(mensaje);
$("#feedback").html(
'<a href="buscadorSala.php">Volver al buscador de salas</a>',
);
}
+30 -27
View File
@@ -26,6 +26,10 @@ $.ajax({
function cambiarNombre() {
let nuevoNombre = $("#nuevoNombre").val().trim();
if (nuevoNombre === "") {
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
@@ -42,8 +46,13 @@ function cambiarNombre() {
// Actualizamos el nombre mostrado en la página
$("#nombre").text(respuesta.nombreUsuario);
// Limpiamos el input
$("#nuevoNombre").val("");
if (typeof comprobarEstadoSesion === "function") {
comprobarEstadoSesion();
}
}
});
}
@@ -74,14 +83,11 @@ $("#inputFoto").change(function () {
// Comprobamos que sea una imagen
if (!archivo.type.startsWith("image/")) {
alert("El archivo seleccionado no es una imagen.");
$("#inputFoto").val("");
return;
}
let datos = new FormData();
datos.append("avatar", archivo);
datos.append("orden", "cambiarAvatar");
@@ -97,18 +103,23 @@ $("#inputFoto").change(function () {
if (respuesta.error) {
alert(respuesta.error);
} else {
// Actualizamos la imagen sin recargar la página
// Actualizamos la imagen en la página de perfil sin recargar
$("#fotoPerfil").attr(
"src",
respuesta.avatar + "?t=" + new Date().getTime(),
respuesta.avatar + "?t=" + new Date().getTime()
);
// Actualizamos también el avatar superior en la cabecera
if (typeof comprobarEstadoSesion === "function") {
comprobarEstadoSesion();
}
}
});
});
// =========================
// RECOGER CATEGORIAS
// ====
// =========================
$("#modalCrearPregunta").on("show.bs.modal", function () {
const selectCategoria = $("#idCategoria");
@@ -141,16 +152,14 @@ $("#modalCrearPregunta").on("show.bs.modal", function () {
$("<option>", {
value: categoria.idCategoria,
text: categoria.nombreCategoria,
}),
})
);
});
},
error: function (xhr, status, error) {
console.error("Error al cargar las categorías:", error);
console.error("Respuesta del servidor:", xhr.responseText);
alert("No se han podido cargar las categorías.");
},
});
@@ -158,7 +167,7 @@ $("#modalCrearPregunta").on("show.bs.modal", function () {
// =========================
// CREAR PREGUNTA
// ====
// =========================
$("#formCrearPregunta").on("submit", function (e) {
e.preventDefault();
@@ -188,24 +197,15 @@ $("#formCrearPregunta").on("submit", function (e) {
$.ajax({
url: "controladores/controladorPregunta.php",
type: "POST",
dataType: "json",
data: {
orden: "crearPregunta",
idCategoria: $("#idCategoria").val(),
nombrePregunta: pregunta,
respuestaCorrecta: respuestaCorrecta,
respuestaIncorrecta1: respuestaIncorrecta1,
respuestaIncorrecta2: respuestaIncorrecta2,
respuestaIncorrecta3: respuestaIncorrecta3,
},
@@ -214,10 +214,8 @@ $("#formCrearPregunta").on("submit", function (e) {
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false);
boton.text("Crear pregunta");
return;
}
@@ -233,17 +231,14 @@ $("#formCrearPregunta").on("submit", function (e) {
// Volvemos a activar el botón
boton.prop("disabled", false);
boton.text("Crear pregunta");
// Si tienes que actualizar la lista de preguntas:
// cargarPreguntas();
// Toast exito
mostrarToast()
}
},
error: function (xhr, status, error) {
console.error("Error al crear la pregunta:", error);
console.error("Respuesta del servidor:", xhr.responseText);
alert("No se ha podido crear la pregunta.");
boton.prop("disabled", false);
@@ -251,3 +246,11 @@ $("#formCrearPregunta").on("submit", function (e) {
},
});
});
function mostrarToast() {
const toastMensaje = document.getElementById("ToastCrearPregunta");
if (toastMensaje) {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastMensaje);
toastBootstrap.show();
}
}
+38
View File
@@ -0,0 +1,38 @@
$(document).ready(function () {
const idPartida = $("body").data("id-partida");
comprobarEstadoPartida(idPartida);
const intervalo = setInterval(function () {
comprobarEstadoPartida(idPartida, intervalo);
}, 3000);
});
function comprobarEstadoPartida(idPartida, intervalo = null) {
$.ajax({
url: "controladores/ControladorResultados.php",
type: "POST",
dataType: "json",
data: {
orden: "comprobarEstado",
idPartida: idPartida
},
success: function (respuesta) {
if (respuesta.error) {
console.error("Error:", respuesta.error);
return;
}
if (respuesta.terminada) {
if (intervalo !== null) clearInterval(intervalo);
$("#pantalla-espera").fadeOut(400, function() {
location.reload();
});
}
},
error: function () {
console.log("Error de comunicación con el controlador.");
}
});
}
+34 -29
View File
@@ -1,3 +1,20 @@
<?php
session_start();
// Hay que estar logueado para jugar
if (!isset($_SESSION['idUsuario'])) {
header('Location: index.php');
exit;
}
// La partida llega por la URL: juego.php?idPartida=3
$idPartida = filter_input(INPUT_GET, 'idPartida', FILTER_VALIDATE_INT);
if (!$idPartida || $idPartida < 1) {
header('Location: buscadorSala.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
@@ -8,39 +25,27 @@
<link rel="stylesheet" href="css/juego.css">
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head>
<body>
<body data-id-partida="<?= (int)$idPartida ?>">
<!-- Contenedor de la Pregunta -->
<!-- Progreso: "Pregunta 3 de 10" + barra -->
<div class="game-header">
<span id="contadorPregunta">Cargando…</span>
</div>
<div class="progress-track">
<div class="progress-fill" id="barraProgreso"></div>
</div>
<!-- Contenedor de la Pregunta (lo rellena js/juego.js) -->
<div class="question-container">
¿Cuál es el planeta más grande de nuestro sistema solar?
<div id="textoPregunta">Cargando preguntas…</div>
<div id="feedback" class="feedback" aria-live="polite"></div>
</div>
<!-- Contenedor de Respuestas (Estilo Kahoot) -->
<div class="answers-grid">
<button class="btn-answer red" onclick="checkAnswer('Marte')">
<span class="shape triangle"></span>
Marte
</button>
<button class="btn-answer blue" onclick="checkAnswer('Júpiter')">
<span class="shape diamond"></span>
Júpiter
</button>
<button class="btn-answer yellow" onclick="checkAnswer('Saturno')">
<span class="shape circle"></span>
Saturno
</button>
<button class="btn-answer green" onclick="checkAnswer('Tierra')">
<span class="shape square"></span>
Tierra
</button>
</div>
<!-- Contenedor de Respuestas (Estilo Kahoot, lo rellena js/juego.js) -->
<div class="answers-grid" id="respuestas"></div>
<script>
</script>
<script src="js/jquery-4.0.0.min.js"></script>
<script src="js/juego.js"></script>
</body>
</html>
</html>
-471
View File
@@ -1,471 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3307
-- Generation Time: Sep 18, 2026 at 11:39 AM
-- Server version: 8.4.3
-- PHP Version: 8.3.30
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `trivial`
--
-- --------------------------------------------------------
--
-- Table structure for table `preguntas`
--
CREATE TABLE `pregunta` (
`idPregunta` int NOT NULL,
`idCategoria` int DEFAULT NULL,
`nombrePregunta` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
--
-- Dumping data for table `preguntas`
--
INSERT INTO `pregunta` (`idPregunta`, `idCategoria`, `nombrePregunta`) VALUES
(2140, 1, 4, '¿En qué año llegó Cristóbal Colón a América?'),
(2141, 1, 5, '¿Cuál es la capital de Francia?'),
(2142, 1, 6, '¿Qué planeta es conocido como el planeta rojo?'),
(2143, 1, 7, '¿Quién pintó la Mona Lisa?'),
(2144, 1, 5, '¿Cuál es el océano más grande del planeta?'),
(2145, 1, 6, '¿Cuál es el símbolo químico del oro?'),
(2146, 1, 8, '¿Quién escribió Don Quijote de la Mancha?'),
(2147, 1, 9, '¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2148, 1, 10, '¿Cuál es la estrella más cercana a la Tierra?'),
(2149, 1, 11, '¿Cuál es el animal terrestre más grande?'),
(2150, 2, 4, '¿Quién fue el primer emperador romano?'),
(2151, 1, 5, '¿Cuál es la capital de España?'),
(2152, 1, 6, '¿Qué gas es imprescindible para la respiración humana?'),
(2153, 1, 12, '¿Cómo se llama el protagonista de la saga cinematográfica Indiana Jones?'),
(2154, 1, 13, '¿Qué instrumento musical tiene teclas blancas y negras?'),
(2155, 2, 5, '¿Cuál es la montaña más alta del mundo?'),
(2156, 1, 4, '¿Qué civilización construyó las pirámides de Egipto?'),
(2157, 2, 6, '¿Cuál es la fórmula química del agua?'),
(2158, 2, 8, '¿Quién escribió Cien años de soledad?'),
(2159, 1, 9, '¿Cada cuántos años se celebran los Juegos Olímpicos?'),
(2160, 1, 14, '¿Qué significan las siglas CPU?'),
(2161, 1, 10, '¿Cuántos planetas tiene actualmente el sistema solar?'),
(2162, 1, 11, '¿Cuál es el animal más grande del planeta?'),
(2163, 2, 7, '¿Qué movimiento artístico fue desarrollado por Picasso y Braque?'),
(2164, 1, 15, '¿Cuántos días tiene un año bisiesto?'),
(2165, 2, 5, '¿Cuál es el país más grande del mundo por superficie?'),
(2166, 2, 4, '¿Quién fue conocido como el Libertador de gran parte de Sudamérica?'),
(2167, 2, 6, '¿Cuál es la unidad básica de la vida?'),
(2168, 2, 13, '¿Quién compuso la Novena Sinfonía?'),
(2169, 1, 9, '¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2170, 2, 4, '¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2171, 1, 5, '¿Cuál es la capital de Japón?'),
(2172, 1, 6, '¿Qué órgano humano se encarga principalmente de bombear la sangre?'),
(2173, 1, 8, '¿Quién escribió Romeo y Julieta?'),
(2174, 2, 12, '¿Qué película incluye al personaje Darth Vader?'),
(2175, 1, 5, '¿Cuál es la capital de Italia?'),
(2176, 1, 6, '¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2177, 2, 4, '¿Qué imperio construyó Machu Picchu?'),
(2178, 1, 11, '¿Cuál es el felino más grande del mundo?'),
(2179, 1, 14, '¿Qué dispositivo se utiliza para mover el cursor en un ordenador?'),
(2180, 2, 10, '¿Cuál es el planeta más grande del sistema solar?'),
(2181, 1, 13, '¿Qué cantante es conocido como el Rey del Pop?'),
(2182, 2, 9, '¿En qué deporte destacó Michael Jordan?'),
(2183, 2, 8, '¿Quién escribió La Odisea?'),
(2184, 2, 7, '¿Quién pintó La noche estrellada?'),
(2185, 2, 5, '¿En qué continente se encuentra Egipto?'),
(2186, 2, 6, '¿Qué científico formuló la teoría de la relatividad?'),
(2187, 1, 4, '¿Dónde nació la democracia antigua?'),
(2188, 1, 16, '¿Cuál es el ingrediente principal del guacamole?'),
(2189, 1, 15, '¿Cuántos continentes se reconocen habitualmente?'),
(2190, 2, 4, '¿En qué país se encuentra la ciudad antigua de Petra?'),
(2191, 1, 5, '¿Cuál es la capital de Portugal?'),
(2192, 1, 6, '¿Qué parte de la planta realiza principalmente la fotosíntesis?'),
(2193, 2, 12, '¿Quién dirigió la película Titanic?'),
(2194, 2, 13, '¿Qué grupo británico lanzó la canción Bohemian Rhapsody?'),
(2195, 1, 9, '¿En qué deporte se disputa el torneo de Wimbledon?'),
(2196, 2, 14, '¿Qué lenguaje se utiliza principalmente para estructurar páginas web?'),
(2197, 2, 10, '¿Cómo se llama nuestra galaxia?'),
(2198, 2, 11, '¿Cuál es el animal terrestre más rápido?'),
(2199, 1, 16, '¿De qué país es originaria la pizza moderna?'),
(2200, 2, 4, '¿Quién fue el primer presidente de Estados Unidos?'),
(2201, 2, 5, '¿Cuál es el desierto cálido más grande del mundo?'),
(2202, 2, 6, '¿Qué científico propuso las leyes del movimiento y la gravitación universal?'),
(2203, 2, 8, '¿Quién escribió El principito?'),
(2204, 1, 7, '¿Qué artista pintó los frescos de la Capilla Sixtina?'),
(2205, 1, 5, '¿Cuál es la capital de Alemania?'),
(2206, 1, 6, '¿Qué vitamina produce principalmente el cuerpo con la exposición al sol?'),
(2207, 2, 4, '¿Qué civilización desarrolló un calendario muy avanzado en Mesoamérica?'),
(2208, 1, 12, '¿Qué personaje vive en una piña bajo el mar?'),
(2209, 1, 13, '¿Qué instrumento toca normalmente un baterista?'),
(2210, 2, 9, '¿En qué país nació el fútbol moderno?'),
(2211, 1, 14, '¿Qué empresa creó el sistema operativo Windows?'),
(2212, 1, 10, '¿Qué planeta es famoso por sus anillos?'),
(2213, 1, 11, '¿Qué animal es conocido como el rey de la selva?'),
(2214, 1, 16, '¿Cuál es el ingrediente principal del sushi tradicional?'),
(2215, 2, 4, '¿Quién fue Napoleón Bonaparte?'),
(2216, 1, 5, '¿Cuál es la capital de Argentina?'),
(2217, 2, 6, '¿Qué elemento químico tiene el símbolo Fe?'),
(2218, 2, 8, '¿Quién escribió La metamorfosis?'),
(2219, 2, 7, '¿Qué artista español creó el personaje Don Quijote en ilustraciones famosas?'),
(2220, 2, 5, '¿Cuál es la capital de Canadá?'),
(2221, 1, 6, '¿Qué órgano del cuerpo humano permite respirar?'),
(2222, 2, 4, '¿Qué famoso faraón fue enterrado en una tumba encontrada casi intacta en 1922?'),
(2223, 1, 12, '¿Cómo se llama el ogro protagonista de una famosa saga de películas de animación?'),
(2224, 2, 13, '¿Qué compositor creó la ópera La flauta mágica?'),
(2225, 1, 9, '¿Cuántos puntos vale un triple en baloncesto?'),
(2226, 2, 14, '¿Qué significa la sigla WWW?'),
(2227, 2, 10, '¿Cuál es el planeta más cercano al Sol?'),
(2228, 1, 11, '¿Qué animal produce lana?'),
(2229, 2, 16, '¿Cuál es el ingrediente principal del hummus?'),
(2230, 2, 4, '¿Qué pueblo antiguo creó la democracia ateniense?'),
(2231, 1, 5, '¿Cuál es la capital de México?'),
(2232, 2, 6, '¿Qué científico desarrolló la teoría de la evolución por selección natural?'),
(2233, 2, 8, '¿Quién escribió Los viajes de Gulliver?'),
(2234, 2, 7, '¿Qué pintor español creó el cuadro Guernica?'),
(2235, 2, 5, '¿Cuál es la isla más grande del mundo?'),
(2236, 1, 6, '¿Cuántos huesos tiene aproximadamente un adulto?'),
(2237, 1, 4, '¿Quién fue Julio César?'),
(2238, 2, 12, '¿Qué actor interpretó a Jack en Titanic?'),
(2239, 1, 13, '¿Qué grupo musical formaron John Lennon y Paul McCartney?'),
(2240, 1, 5, '¿Cuál es la capital de Brasil?'),
(2241, 2, 6, '¿Qué parte del átomo tiene carga negativa?'),
(2242, 2, 4, '¿En qué país surgió la Revolución Industrial?'),
(2243, 1, 12, '¿Cómo se llama el ratón protagonista de Disney?'),
(2244, 2, 13, '¿Qué cantante española es conocida por la canción Despechá?'),
(2245, 2, 9, '¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2246, 1, 14, '¿Qué empresa desarrolló el buscador Google?'),
(2247, 2, 10, '¿Cómo se llama el satélite natural de la Tierra?'),
(2248, 1, 11, '¿Qué animal es conocido por cambiar de color?'),
(2249, 1, 16, '¿Qué bebida se obtiene principalmente de la fermentación de la uva?'),
(2250, 2, 4, '¿Qué reina egipcia tuvo relación con Julio César y Marco Antonio?'),
(2251, 1, 5, '¿Cuál es la capital de Grecia?'),
(2252, 2, 6, '¿Qué científico descubrió la radiactividad junto con Pierre Curie?'),
(2253, 2, 8, '¿Quién escribió La Divina Comedia?'),
(2254, 2, 7, '¿Qué artista español creó el surrealismo con obras como La persistencia de la memoria?'),
(2255, 2, 5, '¿Cuál es el río que atraviesa Egipto?'),
(2256, 1, 6, '¿Qué planeta habitamos los seres humanos?'),
(2257, 2, 4, '¿Qué guerra enfrentó principalmente a Atenas y Esparta?'),
(2258, 2, 14, '¿Qué significa la sigla USB?'),
(2259, 1, 9, '¿En qué deporte se utiliza una portería y un balón con las manos?'),
(2260, 2, 5, '¿Cuál es la capital de Australia?'),
(2261, 2, 6, '¿Qué sangre circula por las arterias desde el corazón hacia el cuerpo?'),
(2262, 2, 4, '¿Qué pueblo construyó el Coliseo de Roma?'),
(2263, 2, 12, '¿Qué película cuenta la historia de un barco que choca contra un iceberg?'),
(2264, 1, 13, '¿Qué instrumento tiene seis cuerdas normalmente?'),
(2265, 2, 9, '¿En qué deporte se utiliza un bate y una pelota?'),
(2266, 2, 14, '¿Qué empresa creó el iPhone?'),
(2267, 2, 10, '¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2268, 1, 11, '¿Qué animal es conocido por tener una trompa larga?'),
(2269, 1, 16, '¿Cuál es el ingrediente principal de las tortillas mexicanas tradicionales?'),
(2270, 2, 4, '¿Qué explorador llegó a América en 1492?'),
(2271, 1, 5, '¿Cuál es la capital de Francia?'),
(2272, 2, 6, '¿Qué científico descubrió la penicilina?'),
(2273, 2, 8, '¿Quién escribió El Quijote?'),
(2274, 1, 7, '¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2275, 2, 5, '¿Cuál es el río más largo del mundo según muchas mediciones?'),
(2276, 1, 6, '¿Qué sentido permite percibir los sonidos?'),
(2277, 2, 4, '¿Qué civilización construyó las ciudades de Tikal y Palenque?'),
(2278, 2, 12, '¿Qué director creó la trilogía de El Señor de los Anillos en cine?'),
(2279, 1, 13, '¿Qué instrumento pertenece a la familia de viento?'),
(2280, 2, 9, '¿Qué país ganó el Mundial de fútbol de 2022?'),
(2281, 1, 14, '¿Qué dispositivo permite realizar llamadas y conectarse a internet?'),
(2282, 2, 10, '¿Qué nombre recibe el conjunto formado por una estrella y los cuerpos que orbitan a su alrededor?'),
(2283, 2, 11, '¿Cuál es el árbol que produce bellotas?'),
(2284, 2, 16, '¿Cuál es el ingrediente principal del gazpacho tradicional?'),
(2285, 2, 4, '¿Qué antigua ciudad fue sepultada por el volcán Vesubio?'),
(2286, 1, 5, '¿En qué continente está España?'),
(2287, 2, 6, '¿Qué parte del cerebro coordina principalmente el equilibrio?'),
(2288, 1, 8, '¿Qué personaje literario vive en una casa de Baker Street?'),
(2289, 2, 7, '¿Qué arquitecto diseñó la Sagrada Familia de Barcelona?'),
(2290, 2, 5, '¿Cuál es el país más poblado del mundo actualmente?'),
(2291, 1, 6, '¿Qué gas absorben las plantas durante la fotosíntesis?'),
(2292, 2, 4, '¿Quién fue conocido como el Gran Alejandro?'),
(2293, 1, 12, '¿Qué superhéroe tiene como identidad a Bruce Wayne?'),
(2294, 2, 13, '¿Qué compositor perdió la audición al final de su vida?'),
(2295, 1, 9, '¿Cuántos anillos tiene el símbolo olímpico?'),
(2296, 2, 14, '¿Qué empresa creó el sistema operativo Android?'),
(2297, 1, 10, '¿Qué estrella está en el centro del sistema solar?'),
(2298, 2, 11, '¿Qué mamífero es capaz de volar?'),
(2299, 1, 16, '¿Qué fruta se utiliza para hacer aceite de oliva?'),
(2300, 2, 4, '¿Qué tratado puso fin oficialmente a la Primera Guerra Mundial?'),
(2301, 2, 5, '¿Cuál es la capital de Turquía?'),
(2302, 1, 6, '¿Qué parte de la célula contiene el material genético?'),
(2303, 2, 8, '¿Quién escribió Frankenstein?'),
(2304, 1, 12, '¿Qué personaje dice la frase \'Hasta la vista, baby\'?'),
(2305, 2, 13, '¿Qué compositor creó Las cuatro estaciones?'),
(2306, 2, 9, '¿En qué deporte se utiliza un volante o pluma?'),
(2307, 2, 14, '¿Qué significa la sigla IA?'),
(2308, 2, 10, '¿Cómo se llama la explosión final de una estrella masiva?'),
(2309, 1, 11, '¿Qué animal es famoso por construir presas?'),
(2310, 2, 16, '¿Qué país es famoso por el plato llamado paella?'),
(2311, 2, 4, '¿Qué civilización utilizaba jeroglíficos?'),
(2312, 1, 5, '¿Cuál es la capital de Italia?'),
(2313, 2, 6, '¿Qué instrumento se utiliza para medir la temperatura?'),
(2314, 2, 8, '¿Quién creó al personaje de Harry Potter?'),
(2315, 2, 7, '¿Qué estilo artístico predominó en muchas catedrales medievales?'),
(2316, 2, 5, '¿Cuál es la montaña más alta de África?'),
(2317, 1, 6, '¿Cuántos sentidos tradicionales tiene el ser humano?'),
(2318, 2, 4, '¿Quién fue conocido como el rey del Imperio francés?'),
(2319, 1, 12, '¿Qué personaje es un ogro verde?'),
(2320, 1, 13, '¿Qué cantante es conocido como el Rey del Rock and Roll?'),
(2321, 2, 9, '¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2322, 1, 14, '¿Qué aparato se usa para imprimir documentos?'),
(2323, 2, 10, '¿Qué es un cometa?'),
(2324, 1, 11, '¿Cuál es el animal terrestre más grande?'),
(2325, 2, 16, '¿Qué país es famoso por el sushi?'),
(2326, 2, 4, '¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2327, 2, 5, '¿Cuál es la capital de Japón?'),
(2328, 2, 6, '¿Qué científico formuló la teoría de la evolución?'),
(2329, 2, 8, '¿Quién escribió Romeo y Julieta?'),
(2330, 2, 7, '¿Qué pintor creó la Mona Lisa?'),
(2331, 1, 5, '¿Cuál es el océano más grande del planeta?'),
(2332, 1, 6, '¿Qué planeta es conocido como el planeta rojo?'),
(2333, 2, 4, '¿Qué civilización construyó las pirámides de Guiza?'),
(2334, 2, 12, '¿Qué película de animación tiene personajes llamados Woody y Buzz Lightyear?'),
(2335, 2, 13, '¿Qué instrumento tiene teclas blancas y negras?'),
(2336, 2, 9, '¿En qué deporte destacó Rafael Nadal?'),
(2337, 2, 14, '¿Qué red conecta ordenadores a nivel mundial?'),
(2338, 2, 10, '¿Qué instrumento permite observar objetos lejanos en el espacio?'),
(2339, 1, 11, '¿Qué ave no puede volar y vive en la Antártida?'),
(2340, 1, 16, '¿Qué ingrediente se obtiene de la leche y se usa en muchos postres?'),
(2341, 2, 4, '¿Quién fue el primer ser humano en pisar la Luna?'),
(2342, 2, 5, '¿Cuál es la capital de Rusia?'),
(2343, 2, 6, '¿Qué científico es considerado el padre de la física moderna?'),
(2344, 1, 8, '¿Qué detective fue creado por Arthur Conan Doyle?'),
(2345, 2, 7, '¿Qué movimiento artístico inició Pablo Picasso junto con Braque?'),
(2346, 2, 5, '¿Cuál es el país más grande del mundo por superficie?'),
(2347, 1, 6, '¿Qué órgano bombea la sangre por el cuerpo?'),
(2348, 2, 4, '¿Qué antigua ciudad griega fue famosa por sus guerreros?'),
(2349, 2, 12, '¿Qué saga cinematográfica incluye al personaje Darth Vader?'),
(2350, 2, 13, '¿Qué cantante interpretó la canción Thriller?'),
(2351, 2, 9, '¿Qué país ganó el Mundial de fútbol de 2010?'),
(2352, 1, 14, '¿Qué aparato convierte documentos físicos en archivos digitales?'),
(2353, 2, 10, '¿Cómo se llama la galaxia vecina más cercana a la Vía Láctea?'),
(2354, 1, 11, '¿Qué insecto produce miel?'),
(2355, 2, 16, '¿Qué especia es conocida como azafrán?'),
(2356, 2, 4, '¿Qué imperio tuvo su capital en Constantinopla?'),
(2357, 2, 5, '¿Cuál es la capital de Egipto?'),
(2358, 2, 6, '¿Qué unidad se utiliza para medir la fuerza?'),
(2359, 2, 8, '¿Qué escritor creó a Don Quijote de la Mancha?'),
(2360, 1, 7, '¿Qué color se obtiene al mezclar azul y amarillo?'),
(2361, 2, 5, '¿Cuál es la capital de Noruega?'),
(2362, 2, 6, '¿Cuál es el símbolo químico del oro?'),
(2363, 2, 4, '¿Qué faraón ordenó construir una de las mayores pirámides de Guiza?'),
(2364, 2, 12, '¿Qué actor interpretó a Iron Man en el Universo Marvel?'),
(2365, 2, 13, '¿Qué banda lanzó el álbum The Dark Side of the Moon?'),
(2366, 1, 9, '¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2367, 2, 14, '¿Qué significa la sigla CPU?'),
(2368, 2, 10, '¿Qué planeta tiene la Gran Mancha Roja?'),
(2369, 2, 11, '¿Cuál es el animal terrestre más alto?'),
(2370, 1, 16, '¿Qué bebida se prepara con granos tostados y molidos?'),
(2371, 2, 4, '¿Quién fue conocido como el Libertador de varios países sudamericanos?'),
(2372, 2, 5, '¿Cuál es la capital de Irlanda?'),
(2373, 1, 6, '¿Qué planeta está más cerca de la Tierra?'),
(2374, 2, 8, '¿Quién escribió La isla del tesoro?'),
(2375, 2, 7, '¿Qué artista pintó Las meninas?'),
(2376, 1, 5, '¿Qué país tiene forma alargada en la costa oeste de Sudamérica?'),
(2377, 2, 6, '¿Qué vitamina se asocia con los cítricos como la naranja?'),
(2378, 2, 4, '¿Qué acontecimiento comenzó en 1939?'),
(2379, 1, 12, '¿Cómo se llama el león protagonista de El Rey León?'),
(2380, 2, 13, '¿Qué instrumento toca un violinista?'),
(2381, 2, 9, '¿Qué piloto español ganó varios campeonatos de Fórmula 1?'),
(2382, 2, 14, '¿Qué empresa creó la consola PlayStation?'),
(2383, 1, 10, '¿Cuántos planetas tiene el sistema solar?'),
(2384, 2, 11, '¿Qué animal es conocido por su gran inteligencia marina?'),
(2385, 2, 16, '¿De qué país procede tradicionalmente el curry?'),
(2386, 2, 4, '¿Qué reina española apoyó el viaje de Colón?'),
(2387, 1, 5, '¿Cuál es la capital de España?'),
(2388, 2, 6, '¿Qué instrumento permite ver objetos muy pequeños?'),
(2389, 2, 8, '¿Quién escribió 20.000 leguas de viaje submarino?'),
(2390, 2, 5, '¿Cuál es la capital de Canadá?'),
(2391, 1, 6, '¿Qué planeta es famoso por sus anillos?'),
(2392, 2, 4, '¿Quién fue el primer emperador romano?'),
(2393, 2, 12, '¿Qué película ganó el Óscar a mejor película en 1998 y trata sobre un barco hundido?'),
(2394, 1, 13, '¿Cuántas notas musicales básicas hay en la escala occidental?'),
(2395, 2, 9, '¿En qué deporte destacó Michael Jordan?'),
(2396, 1, 14, '¿Qué empresa creó Windows?'),
(2397, 2, 10, '¿Qué planeta tarda aproximadamente 365 días en dar una vuelta al Sol?'),
(2398, 1, 11, '¿Qué animal es conocido como el rey de la selva?'),
(2399, 2, 16, '¿Qué ingrediente principal lleva el hummus tradicional?'),
(2400, 2, 4, '¿Qué revolución comenzó en Francia en 1789?'),
(2401, 2, 5, '¿Cuál es la capital de Portugal?'),
(2402, 2, 6, '¿Qué científico formuló las leyes del movimiento y la gravedad?'),
(2403, 2, 8, '¿Quién escribió El principito?'),
(2404, 2, 7, '¿Qué escultor creó el David de Florencia?'),
(2405, 1, 5, '¿En qué continente está Brasil?'),
(2406, 1, 6, '¿Qué gas necesitamos para respirar?'),
(2407, 2, 4, '¿Qué pueblo creó Machu Picchu?'),
(2408, 2, 12, '¿Qué saga tiene como protagonista a Harry Potter?'),
(2409, 2, 13, '¿Qué grupo británico cantaba Bohemian Rhapsody?'),
(2410, 2, 9, '¿Qué país organizó los Juegos Olímpicos de 1992?'),
(2411, 2, 14, '¿Qué lenguaje se utiliza habitualmente para crear páginas web junto con CSS y JavaScript?'),
(2412, 2, 10, '¿Qué nombre recibe una agrupación de estrellas que forma una figura aparente?'),
(2413, 2, 11, '¿Cuál es el animal terrestre más rápido?'),
(2414, 2, 16, '¿De qué país es originaria la pizza tradicional?'),
(2415, 2, 4, '¿Qué civilización inventó la democracia en Atenas?'),
(2416, 1, 5, '¿Cuál es la capital de Alemania?'),
(2417, 2, 6, '¿Cuál es la fórmula química del agua?'),
(2418, 2, 8, '¿Quién escribió 1984?'),
(2419, 2, 7, '¿En qué museo se encuentra la Mona Lisa?'),
(2420, 1, 12, '¿Cómo se llama el muñeco vaquero de Toy Story?'),
(2421, 2, 13, '¿Qué cantante fue conocido como el Rey del Pop?'),
(2422, 1, 9, '¿Cuánto dura un partido de fútbol profesional normalmente?'),
(2423, 1, 14, '¿Qué dispositivo se utiliza para mover el cursor del ordenador?'),
(2424, 2, 10, '¿Qué planeta es el más grande del sistema solar?'),
(2425, 1, 11, '¿Qué animal tiene rayas negras y blancas?'),
(2426, 1, 16, '¿Qué alimento producen las abejas?'),
(2427, 2, 4, '¿Quién fue el líder sudafricano que luchó contra el apartheid?'),
(2428, 2, 5, '¿Cuál es la montaña más alta del mundo?'),
(2429, 1, 6, '¿Qué órgano utilizamos principalmente para ver?'),
(2430, 2, 8, '¿Quién escribió La metamorfosis?'),
(2431, 2, 7, '¿Qué pintor español creó el cuadro Guernica?'),
(2432, 2, 5, '¿Cuál es la capital de Australia?'),
(2433, 2, 6, '¿Qué científico desarrolló la teoría de la relatividad?'),
(2434, 2, 4, '¿Qué explorador llegó a América en 1492?'),
(2435, 1, 12, '¿Cómo se llama el ogro protagonista de una famosa saga de animación?'),
(2436, 2, 13, '¿Qué compositor creó la Novena Sinfonía?'),
(2437, 2, 9, '¿En qué deporte se disputa el Tour de Francia?'),
(2438, 2, 14, '¿Qué empresa desarrolló el buscador Google?'),
(2439, 1, 10, '¿Qué cuerpo celeste orbita alrededor de la Tierra?'),
(2440, 2, 11, '¿Cuál es el animal más grande conocido actualmente?'),
(2441, 2, 16, '¿Qué plato español está hecho principalmente con arroz?'),
(2442, 2, 4, '¿Qué imperio construyó una gran red de carreteras en América del Sur?'),
(2443, 1, 5, '¿Cuál es la capital de Francia?'),
(2444, 2, 6, '¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2445, 2, 8, '¿Quién escribió El señor de los anillos?'),
(2446, 2, 7, '¿Qué movimiento artístico está asociado con Salvador Dalí?'),
(2447, 2, 12, '¿Qué director creó la película E.T.?'),
(2448, 2, 13, '¿Qué instrumento suele tener seis cuerdas?'),
(2449, 2, 9, '¿Qué país inventó el judo?'),
(2450, 1, 14, '¿Qué dispositivo almacena archivos digitales?'),
(2451, 2, 10, '¿Qué planeta está más alejado del Sol?'),
(2452, 2, 11, '¿Qué árbol produce piñas?'),
(2453, 1, 16, '¿Qué fruta amarilla es rica en potasio?'),
(2454, 2, 4, '¿Qué ciudad fue conocida como la capital del Imperio romano?'),
(2455, 2, 5, '¿Cuál es el río más largo del mundo según muchas mediciones modernas?'),
(2456, 2, 6, '¿Qué científico descubrió la penicilina?'),
(2457, 2, 8, '¿Qué personaje vive aventuras junto a Sancho Panza?'),
(2458, 2, 7, '¿Qué edificio famoso diseñó Gaudí en Barcelona?'),
(2459, 1, 12, '¿Qué superhéroe lleva un escudo con una estrella?'),
(2460, 2, 13, '¿Qué instrumento toca normalmente un pianista?'),
(2461, 2, 9, '¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2462, 2, 14, '¿Qué significa la sigla USB?'),
(2463, 2, 10, '¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2464, 2, 11, '¿Qué animal es conocido por cambiar de color para camuflarse?'),
(2465, 2, 16, '¿Cuál es el ingrediente principal del guacamole?'),
(2466, 2, 4, '¿Qué civilización construyó el Coliseo de Roma?'),
(2467, 1, 5, '¿Cuál es la capital de Italia?'),
(2468, 2, 6, '¿Qué elemento químico tiene el símbolo Fe?'),
(2469, 2, 8, '¿Qué escritor creó al personaje Sherlock Holmes?'),
(2470, 2, 7, '¿Qué famoso museo está situado en Madrid y alberga obras de Velázquez y Goya?'),
(2471, 2, 12, '¿Qué película de ciencia ficción presenta al personaje Neo?'),
(2472, 2, 13, '¿Qué banda británica estaba formada por John Lennon, Paul McCartney, George Harrison y Ringo Starr?'),
(2473, 1, 9, '¿Qué deporte practica un nadador?'),
(2474, 2, 14, '¿Qué empresa creó el iPhone?'),
(2475, 2, 10, '¿Cómo se llama nuestra galaxia?'),
(2476, 1, 11, '¿Qué animal doméstico suele llamarse el mejor amigo del hombre?'),
(2477, 2, 16, '¿Qué bebida se obtiene de las hojas del té?'),
(2478, 2, 4, '¿Qué líder impulsó la independencia de la India mediante la resistencia no violenta?'),
(2479, 2, 5, '¿Qué país tiene como capital Buenos Aires?'),
(2480, 1, 6, '¿Qué parte de la planta absorbe agua del suelo?'),
(2481, 2, 4, '¿Quién fue el emperador francés conocido por sus conquistas en Europa?'),
(2482, 2, 5, '¿Cuál es el desierto cálido más grande del mundo?'),
(2483, 2, 6, '¿Qué científico propuso la teoría de la evolución por selección natural?'),
(2484, 2, 8, '¿Quién escribió Romeo y Julieta?'),
(2485, 2, 7, '¿Qué pintor neerlandés creó La noche estrellada?'),
(2486, 2, 12, '¿Cómo se llama el protagonista de la saga Indiana Jones?'),
(2487, 2, 13, '¿Qué compositor fue conocido como el niño prodigio de la música clásica?'),
(2488, 2, 9, '¿En qué deporte se utiliza un bate y una pelota?'),
(2489, 1, 14, '¿Qué componente muestra imágenes en un ordenador?'),
(2490, 2, 10, '¿Qué estrella está en el centro del sistema solar?'),
(2491, 2, 11, '¿Qué mamífero pone huevos?'),
(2492, 2, 16, '¿Qué pasta italiana tiene forma de tubos?'),
(2493, 2, 4, '¿Qué muro cayó en Berlín en 1989?'),
(2494, 1, 5, '¿En qué continente está Japón?'),
(2495, 2, 6, '¿Qué parte del cuerpo humano contiene el cerebro?'),
(2496, 2, 8, '¿Qué personaje literario es un vampiro creado por Bram Stoker?'),
(2497, 2, 7, '¿Qué estilo arquitectónico tiene arcos apuntados y grandes vidrieras?'),
(2498, 2, 12, '¿Qué actor interpretó a Jack Sparrow?'),
(2499, 1, 13, '¿Qué instrumento tiene teclas blancas y negras?'),
(2500, 2, 9, '¿Qué tenista español ganó múltiples Roland Garros?'),
(2501, 2, 14, '¿Qué significa la palabra \'internet\' en relación con redes?'),
(2502, 2, 10, '¿Qué objeto espacial es un fragmento rocoso que orbita alrededor del Sol?'),
(2503, 1, 11, '¿Qué animal tiene una trompa larga?'),
(2504, 2, 16, '¿Qué alimento se obtiene de las uvas fermentadas?'),
(2505, 2, 4, '¿Quién fue conocido por la frase \'Tengo un sueño\'?'),
(2506, 2, 5, '¿Cuál es la capital de Grecia?'),
(2507, 2, 6, '¿Qué instrumento mide la temperatura?'),
(2508, 2, 8, '¿Quién escribió La divina comedia?'),
(2509, 2, 7, '¿Qué arquitecto diseñó la Casa Batlló de Barcelona?'),
(2510, 2, 6, '¿Qué científico formuló la teoría heliocéntrica que situaba al Sol en el centro?'),
(2511, 2, 4, '¿Qué antigua civilización construyó las pirámides de Egipto?'),
(2512, 2, 5, '¿Cuál es la capital de México?'),
(2513, 1, 6, '¿Qué estado del agua tiene forma sólida?'),
(2514, 2, 8, '¿Qué detective fue creado por Agatha Christie?'),
(2515, 2, 7, '¿Qué técnica artística utiliza pequeñas piezas de vidrio o piedra para crear imágenes?'),
(2516, 2, 12, '¿Qué película animada tiene como protagonista a una princesa llamada Elsa?'),
(2517, 2, 13, '¿Qué cantante es conocido como el Rey del Rock?'),
(2518, 1, 9, '¿Cuántos anillos tiene el símbolo olímpico?'),
(2519, 2, 14, '¿Qué sistema operativo utilizan muchos teléfonos móviles?'),
(2520, 2, 10, '¿Cómo se llama el primer hombre que viajó al espacio?'),
(2521, 1, 11, '¿Qué animal produce lana?'),
(2522, 2, 16, '¿Qué ingrediente da picor a muchos platos mexicanos?'),
(2523, 2, 4, '¿Qué documento inglés de 1215 limitó el poder del rey?'),
(2524, 2, 5, '¿Cuál es la isla más grande del mundo?'),
(2525, 2, 6, '¿Qué científico estudió la electricidad y los rayos con una cometa?'),
(2526, 2, 8, '¿Qué novela comienza con un personaje llamado Gregor Samsa?'),
(2527, 2, 7, '¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2528, 2, 12, '¿Qué saga cinematográfica está ambientada en la Tierra Media?'),
(2529, 2, 13, '¿Qué compositor creó Las cuatro estaciones?'),
(2530, 2, 9, '¿En qué deporte se usa una raqueta y un volante?'),
(2531, 2, 14, '¿Qué unidad se utiliza normalmente para medir almacenamiento digital?'),
(2532, 2, 10, '¿Qué planeta es conocido como el planeta rojo?'),
(2533, 2, 11, '¿Qué ave no puede volar y vive en la Antártida?'),
(2534, 2, 16, '¿Qué dulce español se consume tradicionalmente en Navidad?');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `preguntas`
--
ALTER TABLE `pregunta`
ADD PRIMARY KEY (`idPregunta`),
ADD KEY `idCategoria` (`idCategoria`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `preguntas`
--
ALTER TABLE `pregunta`
MODIFY `idPregunta` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2535;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `preguntas`
--
ALTER TABLE `pregunta`
ADD CONSTRAINT `preguntas_ibfk_2` FOREIGN KEY (`idCategoria`) REFERENCES `categoria` (`idCategoria`);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -166,6 +166,9 @@ CREATE TABLE `partida` (
`idPartida` int(11) NOT NULL AUTO_INCREMENT,
`nombrePartida` varchar(100) NOT NULL,
`idUsuario` int(11) NOT NULL,
`fechaCreacion` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`fechaInicio` DATETIME NULL,
`fechaFin` DATETIME NULL,
PRIMARY KEY (`idPartida`),
KEY `FK idUsuario tabla usuario` (`idUsuario`),
CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`)
@@ -178,10 +181,10 @@ CREATE TABLE `partida` (
LOCK TABLES `partida` WRITE;
/*!40000 ALTER TABLE `partida` DISABLE KEYS */;
INSERT INTO `partida` VALUES
(1,'Partida de prueba 1',1),
(2,'Partida de prueba 2',4),
(3,'Partida de prueba 3',9);
INSERT INTO `partida` (idPartida, nombrePartida, idUsuario, fechaInicio, fechaFin) VALUES
(1,'Partida de prueba 1',1, NULL, NULL),
(2,'Partida de prueba 2',4, NULL, NULL),
(3,'Partida de prueba 3',9, NULL, NULL);
/*!40000 ALTER TABLE `partida` ENABLE KEYS */;
UNLOCK TABLES;
@@ -2362,3 +2365,4 @@ UNLOCK TABLES;
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
-- Dump completed on 2026-09-25 10:00:41
-346
View File
@@ -1,346 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 5.2.3
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3307
-- Generation Time: Sep 23, 2026 at 12:02 PM
-- Server version: 8.4.3
-- PHP Version: 8.3.30
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `triviagmatico`
--
-- --------------------------------------------------------
--
-- Table structure for table `categoria`
--
CREATE TABLE `categoria` (
`idCategoria` int NOT NULL,
`nombreCategoria` varchar(50) COLLATE utf8mb4_spanish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `equipo`
--
CREATE TABLE `equipo` (
`idEquipo` int NOT NULL,
`nombreEquipo` varchar(50) COLLATE utf8mb4_spanish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `equipoxpartida`
--
CREATE TABLE `equipoxpartida` (
`idEquipoxPartida` int NOT NULL,
`idPartida` int DEFAULT NULL,
`idEquipo` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `equipoxusuario`
--
CREATE TABLE `equipoxusuario` (
`idEquipoxUsuario` int NOT NULL,
`idUsuario` int NOT NULL,
`idEquipo` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `partida`
--
CREATE TABLE `partida` (
`idPartida` int NOT NULL,
`nombrePartida` varchar(100) COLLATE utf8mb4_spanish_ci NOT NULL,
`idUsuario` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `partidaxpregunta`
--
CREATE TABLE `partidaxpregunta` (
`idPartidaxPregunta` int NOT NULL,
`idPartida` int NOT NULL,
`idPregunta` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `pregunta`
--
CREATE TABLE `pregunta` (
`idPregunta` int NOT NULL,
`idCategoria` int NOT NULL,
`nombrePregunta` varchar(255) COLLATE utf8mb4_spanish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `respuesta`
--
CREATE TABLE `respuesta` (
`idRespuesta` int NOT NULL,
`idPregunta` int NOT NULL,
`nombreRespuesta` varchar(255) COLLATE utf8mb4_spanish_ci NOT NULL,
`correcta` tinyint(1) DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `respuestaalmacenada`
--
CREATE TABLE `respuestaalmacenada` (
`idRespuestaAlmacenada` int NOT NULL,
`idPartidaxPregunta` int NOT NULL,
`idUsuario` int NOT NULL,
`idRespuesta` int NOT NULL,
`primero` tinyint(1) DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
-- --------------------------------------------------------
--
-- Table structure for table `usuario`
--
CREATE TABLE `usuario` (
`idUsuario` int NOT NULL,
`nombreUsuario` varchar(50) COLLATE utf8mb4_spanish_ci NOT NULL,
`contrasena` varchar(100) COLLATE utf8mb4_spanish_ci NOT NULL,
`email` varchar(50) COLLATE utf8mb4_spanish_ci NOT NULL,
`avatar` varchar(200) COLLATE utf8mb4_spanish_ci DEFAULT NULL,
`cookie` varchar(200) COLLATE utf8mb4_spanish_ci DEFAULT NULL,
`aciertos` int NOT NULL,
`victorias` int NOT NULL,
`derrotas` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `categoria`
--
ALTER TABLE `categoria`
ADD PRIMARY KEY (`idCategoria`);
--
-- Indexes for table `equipo`
--
ALTER TABLE `equipo`
ADD PRIMARY KEY (`idEquipo`);
--
-- Indexes for table `equipoxpartida`
--
ALTER TABLE `equipoxpartida`
ADD PRIMARY KEY (`idEquipoxPartida`),
ADD KEY `FK idEquipo tabla equipo` (`idEquipo`),
ADD KEY `FK idPartida tabla partida` (`idPartida`);
--
-- Indexes for table `equipoxusuario`
--
ALTER TABLE `equipoxusuario`
ADD PRIMARY KEY (`idEquipoxUsuario`),
ADD KEY `idUsuario` (`idUsuario`),
ADD KEY `idEquipo` (`idEquipo`);
--
-- Indexes for table `partida`
--
ALTER TABLE `partida`
ADD PRIMARY KEY (`idPartida`),
ADD KEY `FK idUsuario tabla usuario` (`idUsuario`);
--
-- Indexes for table `partidaxpregunta`
--
ALTER TABLE `partidaxpregunta`
ADD PRIMARY KEY (`idPartidaxPregunta`),
ADD KEY `idPartida` (`idPartida`),
ADD KEY `idPregunta` (`idPregunta`);
--
-- Indexes for table `pregunta`
--
ALTER TABLE `pregunta`
ADD PRIMARY KEY (`idPregunta`),
ADD KEY `idCategoria` (`idCategoria`);
--
-- Indexes for table `respuesta`
--
ALTER TABLE `respuesta`
ADD PRIMARY KEY (`idRespuesta`),
ADD KEY `idPregunta` (`idPregunta`);
--
-- Indexes for table `respuestaalmacenada`
--
ALTER TABLE `respuestaalmacenada`
ADD PRIMARY KEY (`idRespuestaAlmacenada`),
ADD KEY `idPartidaxPregunta` (`idPartidaxPregunta`),
ADD KEY `idUsuario` (`idUsuario`),
ADD KEY `idRespuesta` (`idRespuesta`);
--
-- Indexes for table `usuario`
--
ALTER TABLE `usuario`
ADD PRIMARY KEY (`idUsuario`),
ADD UNIQUE KEY `email` (`email`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `categoria`
--
ALTER TABLE `categoria`
MODIFY `idCategoria` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `equipo`
--
ALTER TABLE `equipo`
MODIFY `idEquipo` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `equipoxpartida`
--
ALTER TABLE `equipoxpartida`
MODIFY `idEquipoxPartida` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `equipoxusuario`
--
ALTER TABLE `equipoxusuario`
MODIFY `idEquipoxUsuario` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `partida`
--
ALTER TABLE `partida`
MODIFY `idPartida` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `partidaxpregunta`
--
ALTER TABLE `partidaxpregunta`
MODIFY `idPartidaxPregunta` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `pregunta`
--
ALTER TABLE `pregunta`
MODIFY `idPregunta` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `respuesta`
--
ALTER TABLE `respuesta`
MODIFY `idRespuesta` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `respuestaalmacenada`
--
ALTER TABLE `respuestaalmacenada`
MODIFY `idRespuestaAlmacenada` int NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `usuario`
--
ALTER TABLE `usuario`
MODIFY `idUsuario` int NOT NULL AUTO_INCREMENT;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `equipoxpartida`
--
ALTER TABLE `equipoxpartida`
ADD CONSTRAINT `FK idEquipo tabla equipo` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`) ON DELETE RESTRICT ON UPDATE RESTRICT,
ADD CONSTRAINT `FK idPartida tabla partida` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `equipoxusuario`
--
ALTER TABLE `equipoxusuario`
ADD CONSTRAINT `equipoxusuario_ibfk_1` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`),
ADD CONSTRAINT `equipoxusuario_ibfk_2` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`);
--
-- Constraints for table `partida`
--
ALTER TABLE `partida`
ADD CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) ON DELETE RESTRICT ON UPDATE RESTRICT;
--
-- Constraints for table `partidaxpregunta`
--
ALTER TABLE `partidaxpregunta`
ADD CONSTRAINT `partidaxpregunta_ibfk_1` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`),
ADD CONSTRAINT `partidaxpregunta_ibfk_2` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`);
--
-- Constraints for table `pregunta`
--
ALTER TABLE `pregunta`
ADD CONSTRAINT `pregunta_ibfk_1` FOREIGN KEY (`idCategoria`) REFERENCES `categoria` (`idCategoria`);
--
-- Constraints for table `respuesta`
--
ALTER TABLE `respuesta`
ADD CONSTRAINT `respuesta_ibfk_1` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`);
--
-- Constraints for table `respuestaalmacenada`
--
ALTER TABLE `respuestaalmacenada`
ADD CONSTRAINT `respuestaalmacenada_ibfk_1` FOREIGN KEY (`idPartidaxPregunta`) REFERENCES `partidaxpregunta` (`idPartidaxPregunta`) ON DELETE CASCADE,
ADD CONSTRAINT `respuestaalmacenada_ibfk_2` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) ON DELETE CASCADE,
ADD CONSTRAINT `respuestaalmacenada_ibfk_3` FOREIGN KEY (`idRespuesta`) REFERENCES `respuesta` (`idRespuesta`) ON DELETE CASCADE;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-714
View File
@@ -1,714 +0,0 @@
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19-11.7.2-MariaDB, for Win64 (AMD64)
--
-- Host: localhost Database: triviagmatico
-- ------------------------------------------------------
-- Server version 10.4.32-MariaDB
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;
--
-- Table structure for table `categoria`
--
DROP TABLE IF EXISTS `categoria`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `categoria` (
`idCategoria` int(11) NOT NULL AUTO_INCREMENT,
`nombreCategoria` varchar(50) NOT NULL,
PRIMARY KEY (`idCategoria`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `categoria`
--
LOCK TABLES `categoria` WRITE;
/*!40000 ALTER TABLE `categoria` DISABLE KEYS */;
INSERT INTO `categoria` VALUES
(4,'Historia'),
(5,'Geografía'),
(6,'Ciencia'),
(7,'Arte'),
(8,'Literatura'),
(9,'Deportes'),
(10,'Astronomía'),
(11,'Naturaleza'),
(12,'Cine'),
(13,'Música'),
(14,'Tecnología'),
(15,'Cultura'),
(16,'Gastronomía');
/*!40000 ALTER TABLE `categoria` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipo`
--
DROP TABLE IF EXISTS `equipo`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipo` (
`idEquipo` int(11) NOT NULL AUTO_INCREMENT,
`nombreEquipo` varchar(50) NOT NULL,
PRIMARY KEY (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipo`
--
LOCK TABLES `equipo` WRITE;
/*!40000 ALTER TABLE `equipo` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipo` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipoxpartida`
--
DROP TABLE IF EXISTS `equipoxpartida`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipoxpartida` (
`idEquipoxPartida` int(11) NOT NULL AUTO_INCREMENT,
`idPartida` int(11) DEFAULT NULL,
`idEquipo` int(11) DEFAULT NULL,
PRIMARY KEY (`idEquipoxPartida`),
KEY `FK idEquipo tabla equipo` (`idEquipo`),
KEY `FK idPartida tabla partida` (`idPartida`),
CONSTRAINT `FK idEquipo tabla equipo` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`),
CONSTRAINT `FK idPartida tabla partida` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipoxpartida`
--
LOCK TABLES `equipoxpartida` WRITE;
/*!40000 ALTER TABLE `equipoxpartida` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipoxpartida` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipoxusuario`
--
DROP TABLE IF EXISTS `equipoxusuario`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipoxusuario` (
`idEquipoxUsuario` int(11) NOT NULL AUTO_INCREMENT,
`idUsuario` int(11) NOT NULL,
`idEquipo` int(11) NOT NULL,
PRIMARY KEY (`idEquipoxUsuario`),
KEY `idUsuario` (`idUsuario`),
KEY `idEquipo` (`idEquipo`),
CONSTRAINT `equipoxusuario_ibfk_1` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`),
CONSTRAINT `equipoxusuario_ibfk_2` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipoxusuario`
--
LOCK TABLES `equipoxusuario` WRITE;
/*!40000 ALTER TABLE `equipoxusuario` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipoxusuario` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `partida`
--
DROP TABLE IF EXISTS `partida`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `partida` (
`idPartida` int(11) NOT NULL AUTO_INCREMENT,
`nombrePartida` varchar(100) NOT NULL,
`idUsuario` int(11) NOT NULL,
PRIMARY KEY (`idPartida`),
KEY `FK idUsuario tabla usuario` (`idUsuario`),
CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `partida`
--
LOCK TABLES `partida` WRITE;
/*!40000 ALTER TABLE `partida` DISABLE KEYS */;
/*!40000 ALTER TABLE `partida` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `partidaxpregunta`
--
DROP TABLE IF EXISTS `partidaxpregunta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `partidaxpregunta` (
`idPartidaxPregunta` int(11) NOT NULL AUTO_INCREMENT,
`idPartida` int(11) NOT NULL,
`idPregunta` int(11) NOT NULL,
PRIMARY KEY (`idPartidaxPregunta`),
KEY `idPartida` (`idPartida`),
KEY `idPregunta` (`idPregunta`),
CONSTRAINT `partidaxpregunta_ibfk_1` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`),
CONSTRAINT `partidaxpregunta_ibfk_2` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `partidaxpregunta`
--
LOCK TABLES `partidaxpregunta` WRITE;
/*!40000 ALTER TABLE `partidaxpregunta` DISABLE KEYS */;
/*!40000 ALTER TABLE `partidaxpregunta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `pregunta`
--
DROP TABLE IF EXISTS `pregunta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `pregunta` (
`idPregunta` int(11) NOT NULL AUTO_INCREMENT,
`idCategoria` int(11) NOT NULL,
`nombrePregunta` varchar(255) NOT NULL,
PRIMARY KEY (`idPregunta`),
KEY `idCategoria` (`idCategoria`),
CONSTRAINT `pregunta_ibfk_1` FOREIGN KEY (`idCategoria`) REFERENCES `categoria` (`idCategoria`)
) ENGINE=InnoDB AUTO_INCREMENT=2535 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `pregunta`
--
LOCK TABLES `pregunta` WRITE;
/*!40000 ALTER TABLE `pregunta` DISABLE KEYS */;
INSERT INTO `pregunta` VALUES
(2140,4,'¿En qué año llegó Cristóbal Colón a América?'),
(2141,5,'¿Cuál es la capital de Francia?'),
(2142,6,'¿Qué planeta es conocido como el planeta rojo?'),
(2143,7,'¿Quién pintó la Mona Lisa?'),
(2144,5,'¿Cuál es el océano más grande del planeta?'),
(2145,6,'¿Cuál es el símbolo químico del oro?'),
(2146,8,'¿Quién escribió Don Quijote de la Mancha?'),
(2147,9,'¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2148,10,'¿Cuál es la estrella más cercana a la Tierra?'),
(2149,11,'¿Cuál es el animal terrestre más grande?'),
(2150,4,'¿Quién fue el primer emperador romano?'),
(2151,5,'¿Cuál es la capital de España?'),
(2152,6,'¿Qué gas es imprescindible para la respiración humana?'),
(2153,12,'¿Cómo se llama el protagonista de la saga cinematográfica Indiana Jones?'),
(2154,13,'¿Qué instrumento musical tiene teclas blancas y negras?'),
(2155,5,'¿Cuál es la montaña más alta del mundo?'),
(2156,4,'¿Qué civilización construyó las pirámides de Egipto?'),
(2157,6,'¿Cuál es la fórmula química del agua?'),
(2158,8,'¿Quién escribió Cien años de soledad?'),
(2159,9,'¿Cada cuántos años se celebran los Juegos Olímpicos?'),
(2160,14,'¿Qué significan las siglas CPU?'),
(2161,10,'¿Cuántos planetas tiene actualmente el sistema solar?'),
(2162,11,'¿Cuál es el animal más grande del planeta?'),
(2163,7,'¿Qué movimiento artístico fue desarrollado por Picasso y Braque?'),
(2164,15,'¿Cuántos días tiene un año bisiesto?'),
(2165,5,'¿Cuál es el país más grande del mundo por superficie?'),
(2166,4,'¿Quién fue conocido como el Libertador de gran parte de Sudamérica?'),
(2167,6,'¿Cuál es la unidad básica de la vida?'),
(2168,13,'¿Quién compuso la Novena Sinfonía?'),
(2169,9,'¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2170,4,'¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2171,5,'¿Cuál es la capital de Japón?'),
(2172,6,'¿Qué órgano humano se encarga principalmente de bombear la sangre?'),
(2173,8,'¿Quién escribió Romeo y Julieta?'),
(2174,12,'¿Qué película incluye al personaje Darth Vader?'),
(2175,5,'¿Cuál es la capital de Italia?'),
(2176,6,'¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2177,4,'¿Qué imperio construyó Machu Picchu?'),
(2178,11,'¿Cuál es el felino más grande del mundo?'),
(2179,14,'¿Qué dispositivo se utiliza para mover el cursor en un ordenador?'),
(2180,10,'¿Cuál es el planeta más grande del sistema solar?'),
(2181,13,'¿Qué cantante es conocido como el Rey del Pop?'),
(2182,9,'¿En qué deporte destacó Michael Jordan?'),
(2183,8,'¿Quién escribió La Odisea?'),
(2184,7,'¿Quién pintó La noche estrellada?'),
(2185,5,'¿En qué continente se encuentra Egipto?'),
(2186,6,'¿Qué científico formuló la teoría de la relatividad?'),
(2187,4,'¿Dónde nació la democracia antigua?'),
(2188,16,'¿Cuál es el ingrediente principal del guacamole?'),
(2189,15,'¿Cuántos continentes se reconocen habitualmente?'),
(2190,4,'¿En qué país se encuentra la ciudad antigua de Petra?'),
(2191,5,'¿Cuál es la capital de Portugal?'),
(2192,6,'¿Qué parte de la planta realiza principalmente la fotosíntesis?'),
(2193,12,'¿Quién dirigió la película Titanic?'),
(2194,13,'¿Qué grupo británico lanzó la canción Bohemian Rhapsody?'),
(2195,9,'¿En qué deporte se disputa el torneo de Wimbledon?'),
(2196,14,'¿Qué lenguaje se utiliza principalmente para estructurar páginas web?'),
(2197,10,'¿Cómo se llama nuestra galaxia?'),
(2198,11,'¿Cuál es el animal terrestre más rápido?'),
(2199,16,'¿De qué país es originaria la pizza moderna?'),
(2200,4,'¿Quién fue el primer presidente de Estados Unidos?'),
(2201,5,'¿Cuál es el desierto cálido más grande del mundo?'),
(2202,6,'¿Qué científico propuso las leyes del movimiento y la gravitación universal?'),
(2203,8,'¿Quién escribió El principito?'),
(2204,7,'¿Qué artista pintó los frescos de la Capilla Sixtina?'),
(2205,5,'¿Cuál es la capital de Alemania?'),
(2206,6,'¿Qué vitamina produce principalmente el cuerpo con la exposición al sol?'),
(2207,4,'¿Qué civilización desarrolló un calendario muy avanzado en Mesoamérica?'),
(2208,12,'¿Qué personaje vive en una piña bajo el mar?'),
(2209,13,'¿Qué instrumento toca normalmente un baterista?'),
(2210,9,'¿En qué país nació el fútbol moderno?'),
(2211,14,'¿Qué empresa creó el sistema operativo Windows?'),
(2212,10,'¿Qué planeta es famoso por sus anillos?'),
(2213,11,'¿Qué animal es conocido como el rey de la selva?'),
(2214,16,'¿Cuál es el ingrediente principal del sushi tradicional?'),
(2215,4,'¿Quién fue Napoleón Bonaparte?'),
(2216,5,'¿Cuál es la capital de Argentina?'),
(2217,6,'¿Qué elemento químico tiene el símbolo Fe?'),
(2218,8,'¿Quién escribió La metamorfosis?'),
(2219,7,'¿Qué artista español creó el personaje Don Quijote en ilustraciones famosas?'),
(2220,5,'¿Cuál es la capital de Canadá?'),
(2221,6,'¿Qué órgano del cuerpo humano permite respirar?'),
(2222,4,'¿Qué famoso faraón fue enterrado en una tumba encontrada casi intacta en 1922?'),
(2223,12,'¿Cómo se llama el ogro protagonista de una famosa saga de películas de animación?'),
(2224,13,'¿Qué compositor creó la ópera La flauta mágica?'),
(2225,9,'¿Cuántos puntos vale un triple en baloncesto?'),
(2226,14,'¿Qué significa la sigla WWW?'),
(2227,10,'¿Cuál es el planeta más cercano al Sol?'),
(2228,11,'¿Qué animal produce lana?'),
(2229,16,'¿Cuál es el ingrediente principal del hummus?'),
(2230,4,'¿Qué pueblo antiguo creó la democracia ateniense?'),
(2231,5,'¿Cuál es la capital de México?'),
(2232,6,'¿Qué científico desarrolló la teoría de la evolución por selección natural?'),
(2233,8,'¿Quién escribió Los viajes de Gulliver?'),
(2234,7,'¿Qué pintor español creó el cuadro Guernica?'),
(2235,5,'¿Cuál es la isla más grande del mundo?'),
(2236,6,'¿Cuántos huesos tiene aproximadamente un adulto?'),
(2237,4,'¿Quién fue Julio César?'),
(2238,12,'¿Qué actor interpretó a Jack en Titanic?'),
(2239,13,'¿Qué grupo musical formaron John Lennon y Paul McCartney?'),
(2240,5,'¿Cuál es la capital de Brasil?'),
(2241,6,'¿Qué parte del átomo tiene carga negativa?'),
(2242,4,'¿En qué país surgió la Revolución Industrial?'),
(2243,12,'¿Cómo se llama el ratón protagonista de Disney?'),
(2244,13,'¿Qué cantante española es conocida por la canción Despechá?'),
(2245,9,'¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2246,14,'¿Qué empresa desarrolló el buscador Google?'),
(2247,10,'¿Cómo se llama el satélite natural de la Tierra?'),
(2248,11,'¿Qué animal es conocido por cambiar de color?'),
(2249,16,'¿Qué bebida se obtiene principalmente de la fermentación de la uva?'),
(2250,4,'¿Qué reina egipcia tuvo relación con Julio César y Marco Antonio?'),
(2251,5,'¿Cuál es la capital de Grecia?'),
(2252,6,'¿Qué científico descubrió la radiactividad junto con Pierre Curie?'),
(2253,8,'¿Quién escribió La Divina Comedia?'),
(2254,7,'¿Qué artista español creó el surrealismo con obras como La persistencia de la memoria?'),
(2255,5,'¿Cuál es el río que atraviesa Egipto?'),
(2256,6,'¿Qué planeta habitamos los seres humanos?'),
(2257,4,'¿Qué guerra enfrentó principalmente a Atenas y Esparta?'),
(2258,14,'¿Qué significa la sigla USB?'),
(2259,9,'¿En qué deporte se utiliza una portería y un balón con las manos?'),
(2260,5,'¿Cuál es la capital de Australia?'),
(2261,6,'¿Qué sangre circula por las arterias desde el corazón hacia el cuerpo?'),
(2262,4,'¿Qué pueblo construyó el Coliseo de Roma?'),
(2263,12,'¿Qué película cuenta la historia de un barco que choca contra un iceberg?'),
(2264,13,'¿Qué instrumento tiene seis cuerdas normalmente?'),
(2265,9,'¿En qué deporte se utiliza un bate y una pelota?'),
(2266,14,'¿Qué empresa creó el iPhone?'),
(2267,10,'¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2268,11,'¿Qué animal es conocido por tener una trompa larga?'),
(2269,16,'¿Cuál es el ingrediente principal de las tortillas mexicanas tradicionales?'),
(2270,4,'¿Qué explorador llegó a América en 1492?'),
(2271,5,'¿Cuál es la capital de Francia?'),
(2272,6,'¿Qué científico descubrió la penicilina?'),
(2273,8,'¿Quién escribió El Quijote?'),
(2274,7,'¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2275,5,'¿Cuál es el río más largo del mundo según muchas mediciones?'),
(2276,6,'¿Qué sentido permite percibir los sonidos?'),
(2277,4,'¿Qué civilización construyó las ciudades de Tikal y Palenque?'),
(2278,12,'¿Qué director creó la trilogía de El Señor de los Anillos en cine?'),
(2279,13,'¿Qué instrumento pertenece a la familia de viento?'),
(2280,9,'¿Qué país ganó el Mundial de fútbol de 2022?'),
(2281,14,'¿Qué dispositivo permite realizar llamadas y conectarse a internet?'),
(2282,10,'¿Qué nombre recibe el conjunto formado por una estrella y los cuerpos que orbitan a su alrededor?'),
(2283,11,'¿Cuál es el árbol que produce bellotas?'),
(2284,16,'¿Cuál es el ingrediente principal del gazpacho tradicional?'),
(2285,4,'¿Qué antigua ciudad fue sepultada por el volcán Vesubio?'),
(2286,5,'¿En qué continente está España?'),
(2287,6,'¿Qué parte del cerebro coordina principalmente el equilibrio?'),
(2288,8,'¿Qué personaje literario vive en una casa de Baker Street?'),
(2289,7,'¿Qué arquitecto diseñó la Sagrada Familia de Barcelona?'),
(2290,5,'¿Cuál es el país más poblado del mundo actualmente?'),
(2291,6,'¿Qué gas absorben las plantas durante la fotosíntesis?'),
(2292,4,'¿Quién fue conocido como el Gran Alejandro?'),
(2293,12,'¿Qué superhéroe tiene como identidad a Bruce Wayne?'),
(2294,13,'¿Qué compositor perdió la audición al final de su vida?'),
(2295,9,'¿Cuántos anillos tiene el símbolo olímpico?'),
(2296,14,'¿Qué empresa creó el sistema operativo Android?'),
(2297,10,'¿Qué estrella está en el centro del sistema solar?'),
(2298,11,'¿Qué mamífero es capaz de volar?'),
(2299,16,'¿Qué fruta se utiliza para hacer aceite de oliva?'),
(2300,4,'¿Qué tratado puso fin oficialmente a la Primera Guerra Mundial?'),
(2301,5,'¿Cuál es la capital de Turquía?'),
(2302,6,'¿Qué parte de la célula contiene el material genético?'),
(2303,8,'¿Quién escribió Frankenstein?'),
(2304,12,'¿Qué personaje dice la frase \'Hasta la vista, baby\'?'),
(2305,13,'¿Qué compositor creó Las cuatro estaciones?'),
(2306,9,'¿En qué deporte se utiliza un volante o pluma?'),
(2307,14,'¿Qué significa la sigla IA?'),
(2308,10,'¿Cómo se llama la explosión final de una estrella masiva?'),
(2309,11,'¿Qué animal es famoso por construir presas?'),
(2310,16,'¿Qué país es famoso por el plato llamado paella?'),
(2311,4,'¿Qué civilización utilizaba jeroglíficos?'),
(2312,5,'¿Cuál es la capital de Italia?'),
(2313,6,'¿Qué instrumento se utiliza para medir la temperatura?'),
(2314,8,'¿Quién creó al personaje de Harry Potter?'),
(2315,7,'¿Qué estilo artístico predominó en muchas catedrales medievales?'),
(2316,5,'¿Cuál es la montaña más alta de África?'),
(2317,6,'¿Cuántos sentidos tradicionales tiene el ser humano?'),
(2318,4,'¿Quién fue conocido como el rey del Imperio francés?'),
(2319,12,'¿Qué personaje es un ogro verde?'),
(2320,13,'¿Qué cantante es conocido como el Rey del Rock and Roll?'),
(2321,9,'¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2322,14,'¿Qué aparato se usa para imprimir documentos?'),
(2323,10,'¿Qué es un cometa?'),
(2324,11,'¿Cuál es el animal terrestre más grande?'),
(2325,16,'¿Qué país es famoso por el sushi?'),
(2326,4,'¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2327,5,'¿Cuál es la capital de Japón?'),
(2328,6,'¿Qué científico formuló la teoría de la evolución?'),
(2329,8,'¿Quién escribió Romeo y Julieta?'),
(2330,7,'¿Qué pintor creó la Mona Lisa?'),
(2331,5,'¿Cuál es el océano más grande del planeta?'),
(2332,6,'¿Qué planeta es conocido como el planeta rojo?'),
(2333,4,'¿Qué civilización construyó las pirámides de Guiza?'),
(2334,12,'¿Qué película de animación tiene personajes llamados Woody y Buzz Lightyear?'),
(2335,13,'¿Qué instrumento tiene teclas blancas y negras?'),
(2336,9,'¿En qué deporte destacó Rafael Nadal?'),
(2337,14,'¿Qué red conecta ordenadores a nivel mundial?'),
(2338,10,'¿Qué instrumento permite observar objetos lejanos en el espacio?'),
(2339,11,'¿Qué ave no puede volar y vive en la Antártida?'),
(2340,16,'¿Qué ingrediente se obtiene de la leche y se usa en muchos postres?'),
(2341,4,'¿Quién fue el primer ser humano en pisar la Luna?'),
(2342,5,'¿Cuál es la capital de Rusia?'),
(2343,6,'¿Qué científico es considerado el padre de la física moderna?'),
(2344,8,'¿Qué detective fue creado por Arthur Conan Doyle?'),
(2345,7,'¿Qué movimiento artístico inició Pablo Picasso junto con Braque?'),
(2346,5,'¿Cuál es el país más grande del mundo por superficie?'),
(2347,6,'¿Qué órgano bombea la sangre por el cuerpo?'),
(2348,4,'¿Qué antigua ciudad griega fue famosa por sus guerreros?'),
(2349,12,'¿Qué saga cinematográfica incluye al personaje Darth Vader?'),
(2350,13,'¿Qué cantante interpretó la canción Thriller?'),
(2351,9,'¿Qué país ganó el Mundial de fútbol de 2010?'),
(2352,14,'¿Qué aparato convierte documentos físicos en archivos digitales?'),
(2353,10,'¿Cómo se llama la galaxia vecina más cercana a la Vía Láctea?'),
(2354,11,'¿Qué insecto produce miel?'),
(2355,16,'¿Qué especia es conocida como azafrán?'),
(2356,4,'¿Qué imperio tuvo su capital en Constantinopla?'),
(2357,5,'¿Cuál es la capital de Egipto?'),
(2358,6,'¿Qué unidad se utiliza para medir la fuerza?'),
(2359,8,'¿Qué escritor creó a Don Quijote de la Mancha?'),
(2360,7,'¿Qué color se obtiene al mezclar azul y amarillo?'),
(2361,5,'¿Cuál es la capital de Noruega?'),
(2362,6,'¿Cuál es el símbolo químico del oro?'),
(2363,4,'¿Qué faraón ordenó construir una de las mayores pirámides de Guiza?'),
(2364,12,'¿Qué actor interpretó a Iron Man en el Universo Marvel?'),
(2365,13,'¿Qué banda lanzó el álbum The Dark Side of the Moon?'),
(2366,9,'¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2367,14,'¿Qué significa la sigla CPU?'),
(2368,10,'¿Qué planeta tiene la Gran Mancha Roja?'),
(2369,11,'¿Cuál es el animal terrestre más alto?'),
(2370,16,'¿Qué bebida se prepara con granos tostados y molidos?'),
(2371,4,'¿Quién fue conocido como el Libertador de varios países sudamericanos?'),
(2372,5,'¿Cuál es la capital de Irlanda?'),
(2373,6,'¿Qué planeta está más cerca de la Tierra?'),
(2374,8,'¿Quién escribió La isla del tesoro?'),
(2375,7,'¿Qué artista pintó Las meninas?'),
(2376,5,'¿Qué país tiene forma alargada en la costa oeste de Sudamérica?'),
(2377,6,'¿Qué vitamina se asocia con los cítricos como la naranja?'),
(2378,4,'¿Qué acontecimiento comenzó en 1939?'),
(2379,12,'¿Cómo se llama el león protagonista de El Rey León?'),
(2380,13,'¿Qué instrumento toca un violinista?'),
(2381,9,'¿Qué piloto español ganó varios campeonatos de Fórmula 1?'),
(2382,14,'¿Qué empresa creó la consola PlayStation?'),
(2383,10,'¿Cuántos planetas tiene el sistema solar?'),
(2384,11,'¿Qué animal es conocido por su gran inteligencia marina?'),
(2385,16,'¿De qué país procede tradicionalmente el curry?'),
(2386,4,'¿Qué reina española apoyó el viaje de Colón?'),
(2387,5,'¿Cuál es la capital de España?'),
(2388,6,'¿Qué instrumento permite ver objetos muy pequeños?'),
(2389,8,'¿Quién escribió 20.000 leguas de viaje submarino?'),
(2390,5,'¿Cuál es la capital de Canadá?'),
(2391,6,'¿Qué planeta es famoso por sus anillos?'),
(2392,4,'¿Quién fue el primer emperador romano?'),
(2393,12,'¿Qué película ganó el Óscar a mejor película en 1998 y trata sobre un barco hundido?'),
(2394,13,'¿Cuántas notas musicales básicas hay en la escala occidental?'),
(2395,9,'¿En qué deporte destacó Michael Jordan?'),
(2396,14,'¿Qué empresa creó Windows?'),
(2397,10,'¿Qué planeta tarda aproximadamente 365 días en dar una vuelta al Sol?'),
(2398,11,'¿Qué animal es conocido como el rey de la selva?'),
(2399,16,'¿Qué ingrediente principal lleva el hummus tradicional?'),
(2400,4,'¿Qué revolución comenzó en Francia en 1789?'),
(2401,5,'¿Cuál es la capital de Portugal?'),
(2402,6,'¿Qué científico formuló las leyes del movimiento y la gravedad?'),
(2403,8,'¿Quién escribió El principito?'),
(2404,7,'¿Qué escultor creó el David de Florencia?'),
(2405,5,'¿En qué continente está Brasil?'),
(2406,6,'¿Qué gas necesitamos para respirar?'),
(2407,4,'¿Qué pueblo creó Machu Picchu?'),
(2408,12,'¿Qué saga tiene como protagonista a Harry Potter?'),
(2409,13,'¿Qué grupo británico cantaba Bohemian Rhapsody?'),
(2410,9,'¿Qué país organizó los Juegos Olímpicos de 1992?'),
(2411,14,'¿Qué lenguaje se utiliza habitualmente para crear páginas web junto con CSS y JavaScript?'),
(2412,10,'¿Qué nombre recibe una agrupación de estrellas que forma una figura aparente?'),
(2413,11,'¿Cuál es el animal terrestre más rápido?'),
(2414,16,'¿De qué país es originaria la pizza tradicional?'),
(2415,4,'¿Qué civilización inventó la democracia en Atenas?'),
(2416,5,'¿Cuál es la capital de Alemania?'),
(2417,6,'¿Cuál es la fórmula química del agua?'),
(2418,8,'¿Quién escribió 1984?'),
(2419,7,'¿En qué museo se encuentra la Mona Lisa?'),
(2420,12,'¿Cómo se llama el muñeco vaquero de Toy Story?'),
(2421,13,'¿Qué cantante fue conocido como el Rey del Pop?'),
(2422,9,'¿Cuánto dura un partido de fútbol profesional normalmente?'),
(2423,14,'¿Qué dispositivo se utiliza para mover el cursor del ordenador?'),
(2424,10,'¿Qué planeta es el más grande del sistema solar?'),
(2425,11,'¿Qué animal tiene rayas negras y blancas?'),
(2426,16,'¿Qué alimento producen las abejas?'),
(2427,4,'¿Quién fue el líder sudafricano que luchó contra el apartheid?'),
(2428,5,'¿Cuál es la montaña más alta del mundo?'),
(2429,6,'¿Qué órgano utilizamos principalmente para ver?'),
(2430,8,'¿Quién escribió La metamorfosis?'),
(2431,7,'¿Qué pintor español creó el cuadro Guernica?'),
(2432,5,'¿Cuál es la capital de Australia?'),
(2433,6,'¿Qué científico desarrolló la teoría de la relatividad?'),
(2434,4,'¿Qué explorador llegó a América en 1492?'),
(2435,12,'¿Cómo se llama el ogro protagonista de una famosa saga de animación?'),
(2436,13,'¿Qué compositor creó la Novena Sinfonía?'),
(2437,9,'¿En qué deporte se disputa el Tour de Francia?'),
(2438,14,'¿Qué empresa desarrolló el buscador Google?'),
(2439,10,'¿Qué cuerpo celeste orbita alrededor de la Tierra?'),
(2440,11,'¿Cuál es el animal más grande conocido actualmente?'),
(2441,16,'¿Qué plato español está hecho principalmente con arroz?'),
(2442,4,'¿Qué imperio construyó una gran red de carreteras en América del Sur?'),
(2443,5,'¿Cuál es la capital de Francia?'),
(2444,6,'¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2445,8,'¿Quién escribió El señor de los anillos?'),
(2446,7,'¿Qué movimiento artístico está asociado con Salvador Dalí?'),
(2447,12,'¿Qué director creó la película E.T.?'),
(2448,13,'¿Qué instrumento suele tener seis cuerdas?'),
(2449,9,'¿Qué país inventó el judo?'),
(2450,14,'¿Qué dispositivo almacena archivos digitales?'),
(2451,10,'¿Qué planeta está más alejado del Sol?'),
(2452,11,'¿Qué árbol produce piñas?'),
(2453,16,'¿Qué fruta amarilla es rica en potasio?'),
(2454,4,'¿Qué ciudad fue conocida como la capital del Imperio romano?'),
(2455,5,'¿Cuál es el río más largo del mundo según muchas mediciones modernas?'),
(2456,6,'¿Qué científico descubrió la penicilina?'),
(2457,8,'¿Qué personaje vive aventuras junto a Sancho Panza?'),
(2458,7,'¿Qué edificio famoso diseñó Gaudí en Barcelona?'),
(2459,12,'¿Qué superhéroe lleva un escudo con una estrella?'),
(2460,13,'¿Qué instrumento toca normalmente un pianista?'),
(2461,9,'¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2462,14,'¿Qué significa la sigla USB?'),
(2463,10,'¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2464,11,'¿Qué animal es conocido por cambiar de color para camuflarse?'),
(2465,16,'¿Cuál es el ingrediente principal del guacamole?'),
(2466,4,'¿Qué civilización construyó el Coliseo de Roma?'),
(2467,5,'¿Cuál es la capital de Italia?'),
(2468,6,'¿Qué elemento químico tiene el símbolo Fe?'),
(2469,8,'¿Qué escritor creó al personaje Sherlock Holmes?'),
(2470,7,'¿Qué famoso museo está situado en Madrid y alberga obras de Velázquez y Goya?'),
(2471,12,'¿Qué película de ciencia ficción presenta al personaje Neo?'),
(2472,13,'¿Qué banda británica estaba formada por John Lennon, Paul McCartney, George Harrison y Ringo Starr?'),
(2473,9,'¿Qué deporte practica un nadador?'),
(2474,14,'¿Qué empresa creó el iPhone?'),
(2475,10,'¿Cómo se llama nuestra galaxia?'),
(2476,11,'¿Qué animal doméstico suele llamarse el mejor amigo del hombre?'),
(2477,16,'¿Qué bebida se obtiene de las hojas del té?'),
(2478,4,'¿Qué líder impulsó la independencia de la India mediante la resistencia no violenta?'),
(2479,5,'¿Qué país tiene como capital Buenos Aires?'),
(2480,6,'¿Qué parte de la planta absorbe agua del suelo?'),
(2481,4,'¿Quién fue el emperador francés conocido por sus conquistas en Europa?'),
(2482,5,'¿Cuál es el desierto cálido más grande del mundo?'),
(2483,6,'¿Qué científico propuso la teoría de la evolución por selección natural?'),
(2484,8,'¿Quién escribió Romeo y Julieta?'),
(2485,7,'¿Qué pintor neerlandés creó La noche estrellada?'),
(2486,12,'¿Cómo se llama el protagonista de la saga Indiana Jones?'),
(2487,13,'¿Qué compositor fue conocido como el niño prodigio de la música clásica?'),
(2488,9,'¿En qué deporte se utiliza un bate y una pelota?'),
(2489,14,'¿Qué componente muestra imágenes en un ordenador?'),
(2490,10,'¿Qué estrella está en el centro del sistema solar?'),
(2491,11,'¿Qué mamífero pone huevos?'),
(2492,16,'¿Qué pasta italiana tiene forma de tubos?'),
(2493,4,'¿Qué muro cayó en Berlín en 1989?'),
(2494,5,'¿En qué continente está Japón?'),
(2495,6,'¿Qué parte del cuerpo humano contiene el cerebro?'),
(2496,8,'¿Qué personaje literario es un vampiro creado por Bram Stoker?'),
(2497,7,'¿Qué estilo arquitectónico tiene arcos apuntados y grandes vidrieras?'),
(2498,12,'¿Qué actor interpretó a Jack Sparrow?'),
(2499,13,'¿Qué instrumento tiene teclas blancas y negras?'),
(2500,9,'¿Qué tenista español ganó múltiples Roland Garros?'),
(2501,14,'¿Qué significa la palabra \'internet\' en relación con redes?'),
(2502,10,'¿Qué objeto espacial es un fragmento rocoso que orbita alrededor del Sol?'),
(2503,11,'¿Qué animal tiene una trompa larga?'),
(2504,16,'¿Qué alimento se obtiene de las uvas fermentadas?'),
(2505,4,'¿Quién fue conocido por la frase \'Tengo un sueño\'?'),
(2506,5,'¿Cuál es la capital de Grecia?'),
(2507,6,'¿Qué instrumento mide la temperatura?'),
(2508,8,'¿Quién escribió La divina comedia?'),
(2509,7,'¿Qué arquitecto diseñó la Casa Batlló de Barcelona?'),
(2510,6,'¿Qué científico formuló la teoría heliocéntrica que situaba al Sol en el centro?'),
(2511,4,'¿Qué antigua civilización construyó las pirámides de Egipto?'),
(2512,5,'¿Cuál es la capital de México?'),
(2513,6,'¿Qué estado del agua tiene forma sólida?'),
(2514,8,'¿Qué detective fue creado por Agatha Christie?'),
(2515,7,'¿Qué técnica artística utiliza pequeñas piezas de vidrio o piedra para crear imágenes?'),
(2516,12,'¿Qué película animada tiene como protagonista a una princesa llamada Elsa?'),
(2517,13,'¿Qué cantante es conocido como el Rey del Rock?'),
(2518,9,'¿Cuántos anillos tiene el símbolo olímpico?'),
(2519,14,'¿Qué sistema operativo utilizan muchos teléfonos móviles?'),
(2520,10,'¿Cómo se llama el primer hombre que viajó al espacio?'),
(2521,11,'¿Qué animal produce lana?'),
(2522,16,'¿Qué ingrediente da picor a muchos platos mexicanos?'),
(2523,4,'¿Qué documento inglés de 1215 limitó el poder del rey?'),
(2524,5,'¿Cuál es la isla más grande del mundo?'),
(2525,6,'¿Qué científico estudió la electricidad y los rayos con una cometa?'),
(2526,8,'¿Qué novela comienza con un personaje llamado Gregor Samsa?'),
(2527,7,'¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2528,12,'¿Qué saga cinematográfica está ambientada en la Tierra Media?'),
(2529,13,'¿Qué compositor creó Las cuatro estaciones?'),
(2530,9,'¿En qué deporte se usa una raqueta y un volante?'),
(2531,14,'¿Qué unidad se utiliza normalmente para medir almacenamiento digital?'),
(2532,10,'¿Qué planeta es conocido como el planeta rojo?'),
(2533,11,'¿Qué ave no puede volar y vive en la Antártida?'),
(2534,16,'¿Qué dulce español se consume tradicionalmente en Navidad?');
/*!40000 ALTER TABLE `pregunta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `respuesta`
--
DROP TABLE IF EXISTS `respuesta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `respuesta` (
`idRespuesta` int(11) NOT NULL AUTO_INCREMENT,
`idPregunta` int(11) NOT NULL,
`nombreRespuesta` varchar(255) NOT NULL,
`correcta` tinyint(1) DEFAULT 0,
PRIMARY KEY (`idRespuesta`),
KEY `idPregunta` (`idPregunta`),
CONSTRAINT `respuesta_ibfk_1` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `respuesta`
--
LOCK TABLES `respuesta` WRITE;
/*!40000 ALTER TABLE `respuesta` DISABLE KEYS */;
/*!40000 ALTER TABLE `respuesta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `respuestaalmacenada`
--
DROP TABLE IF EXISTS `respuestaalmacenada`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `respuestaalmacenada` (
`idRespuestaAlmacenada` int(11) NOT NULL AUTO_INCREMENT,
`idPartidaxPregunta` int(11) NOT NULL,
`idUsuario` int(11) NOT NULL,
`idRespuesta` int(11) NOT NULL,
`primero` tinyint(1) DEFAULT 0,
PRIMARY KEY (`idRespuestaAlmacenada`),
KEY `idPartidaxPregunta` (`idPartidaxPregunta`),
KEY `idUsuario` (`idUsuario`),
KEY `idRespuesta` (`idRespuesta`),
CONSTRAINT `respuestaalmacenada_ibfk_1` FOREIGN KEY (`idPartidaxPregunta`) REFERENCES `partidaxpregunta` (`idPartidaxPregunta`) ON DELETE CASCADE,
CONSTRAINT `respuestaalmacenada_ibfk_2` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) ON DELETE CASCADE,
CONSTRAINT `respuestaalmacenada_ibfk_3` FOREIGN KEY (`idRespuesta`) REFERENCES `respuesta` (`idRespuesta`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `respuestaalmacenada`
--
LOCK TABLES `respuestaalmacenada` WRITE;
/*!40000 ALTER TABLE `respuestaalmacenada` DISABLE KEYS */;
/*!40000 ALTER TABLE `respuestaalmacenada` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `usuario`
--
DROP TABLE IF EXISTS `usuario`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `usuario` (
`idUsuario` int(11) NOT NULL AUTO_INCREMENT,
`nombreUsuario` varchar(50) NOT NULL,
`contrasena` varchar(100) NOT NULL,
`email` varchar(50) NOT NULL,
`avatar` varchar(200) DEFAULT NULL,
`cookie` varchar(200) DEFAULT NULL,
`aciertos` int(11) NOT NULL,
`victorias` int(11) NOT NULL,
`derrotas` int(11) NOT NULL,
PRIMARY KEY (`idUsuario`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `usuario`
--
LOCK TABLES `usuario` WRITE;
/*!40000 ALTER TABLE `usuario` DISABLE KEYS */;
/*!40000 ALTER TABLE `usuario` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping routines for database 'triviagmatico'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
-- Dump completed on 2026-09-25 9:33:39
+113 -261
View File
@@ -1,3 +1,17 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Redirección si el usuario no ha iniciado sesión
if (!isset($_SESSION['idUsuario'])) {
header('Location: login.php');
exit();
}
$nombreUsuario = htmlspecialchars($_SESSION['nombreUsuario'] ?? 'Usuario');
$avatarUsuario = htmlspecialchars($_SESSION['avatar'] ?? 'img/avatars/defaultProfile.jpeg');
?>
<!DOCTYPE html>
<html lang="es">
@@ -9,151 +23,99 @@
<title>Perfil</title>
<!-- Bootstrap -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<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 rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Google Font: Fredoka -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap"
rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- Tu CSS -->
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/perfil.css">
<script src="js/jquery-4.0.0.min.js"></script>
</head>
<body>
<?php
include_once 'cabecera.php';
?>
<?php include_once 'cabecera.php'; ?>
<div class="perfil-container">
<div class="perfil-card">
<!-- ========================= -->
<!-- CABECERA -->
<!-- ========================= -->
<div class="perfil-header">
<i class="bi bi-person-circle"></i>
Mi perfil
</div>
<div class="perfil-content">
<div class="row align-items-center g-5">
<!-- ========================= -->
<!-- PERFIL -->
<!-- ========================= -->
<div class="col-md-6 text-center">
<!-- Nombre -->
<h1 id="nombre" class="nombre">
<?php echo $_SESSION['nombreUsuario'] ?>
<?= $nombreUsuario ?>
</h1>
<!-- ========================= -->
<!-- FOTO DE PERFIL -->
<!-- ========================= -->
<div class="foto-container">
<img
id="fotoPerfil"
src="<?= htmlspecialchars($_SESSION['avatar'] ?? '') ?>"
alt="Foto de perfil"
class="avatar rounded-circle">
<img id="fotoPerfil"
src="<?= $avatarUsuario ?>"
alt="Foto de perfil"
class="avatar rounded-circle">
<!-- Botón lápiz -->
<button
type="button"
class="btn-foto"
onclick="seleccionarFoto()"
title="Cambiar foto de perfil"
aria-label="Cambiar foto de perfil">
<button type="button"
class="btn-foto"
onclick="seleccionarFoto()"
title="Cambiar foto de perfil"
aria-label="Cambiar foto de perfil">
<i class="bi bi-pencil-fill"></i>
</button>
<!-- Input oculto -->
<input
type="file"
id="inputFoto"
accept="image/*"
hidden>
<input type="file"
id="inputFoto"
accept="image/*"
hidden>
</div>
<!-- ========================= -->
<!-- CAMBIAR NOMBRE -->
<!-- ========================= -->
<div class="formulario-nombre">
<label
for="nuevoNombre"
class="form-label">
<label for="nuevoNombre" class="form-label">
Cambia tu nombre
</label>
<input
type="text"
id="nuevoNombre"
class="form-control mb-3"
placeholder="Escribe tu nuevo nombre">
<input type="text"
id="nuevoNombre"
class="form-control mb-3"
placeholder="Escribe tu nuevo nombre">
<div class="d-flex justify-content-center gap-2">
<button
type="button"
class="btn-perfil-cambiar"
onclick="cambiarNombre()">
<button type="button"
class="btn-perfil-cambiar"
onclick="cambiarNombre()">
<i class="bi bi-check-lg"></i>
Cambiar nombre
</button>
<button
type="button"
class="btn-perfil-borrar"
onclick="borrarNombre()">
<button type="button"
class="btn-perfil-borrar"
onclick="borrarNombre()">
<i class="bi bi-x-lg"></i>
Borrar
</button>
</div>
@@ -162,11 +124,7 @@
</div>
<!-- ========================= -->
<!-- ESTADÍSTICAS -->
<!-- ========================= -->
<div class="col-md-6">
<div class="estadisticas">
@@ -176,60 +134,33 @@
Estadísticas
</h2>
<div class="estadistica estadistica-victorias">
<i class="bi bi-trophy-fill"></i>
&nbsp; Victorias:
<strong id="victorias">
</strong>
<strong id="victorias">0</strong>
</div>
<div class="estadistica estadistica-derrotas">
<i class="bi bi-x-circle-fill"></i>
&nbsp; Derrotas:
<strong id="derrotas">
</strong>
<strong id="derrotas">0</strong>
</div>
<div class="estadistica estadistica-aciertos">
<i class="bi bi-bullseye"></i>
&nbsp; Aciertos:
<strong id="aciertos">
</strong>
<strong id="aciertos">0</strong>
</div>
<!-- ========================= -->
<!-- CREAR PREGUNTA -->
<!-- ========================= -->
<div class="text-center mt-4">
<button
type="button"
class="btn btn-play-kahoot"
data-bs-toggle="modal"
data-bs-target="#modalCrearPregunta">
<button type="button"
class="btn btn-play-kahoot"
data-bs-toggle="modal"
data-bs-target="#modalCrearPregunta">
<i class="bi bi-plus-circle-fill"></i>
Crear pregunta
</button>
</div>
</div>
@@ -243,203 +174,129 @@
</div>
</div>
<!-- ================================================= -->
<!-- TOAST PREGUNTA CREADA -->
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="ToastCrearPregunta" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class=" toast-header" style="background-color: #46178f;">
<h5 class="text-white me-auto bi bi-joystick me-2"> Pregunta Creada</h5>
</div>
<div class="fs-6 toast-body">
La pregunta ha sido creada correctamente
</div>
</div>
</div>
<!-- MODAL CREAR PREGUNTA -->
<!-- ================================================= -->
<div
class="modal fade"
id="modalCrearPregunta"
tabindex="-1"
aria-labelledby="modalCrearPreguntaLabel"
aria-hidden="true">
<div class="modal fade"
id="modalCrearPregunta"
tabindex="-1"
aria-labelledby="modalCrearPreguntaLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot">
<!-- CABECERA DEL MODAL -->
<div class="modal-header modal-kahoot-header">
<h5
class="modal-title"
id="modalCrearPreguntaLabel">
<h5 class="modal-title" id="modalCrearPreguntaLabel">
<i class="bi bi-question-circle-fill me-2"></i>
Crear pregunta
</h5>
<button
type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
<button type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
</button>
</div>
<!-- CUERPO DEL MODAL -->
<div class="modal-body p-4">
<form id="formCrearPregunta">
<!-- PREGUNTA -->
<div class="mb-4">
<label
for="pregunta"
class="form-label fw-semibold">
<label for="pregunta" class="form-label fw-semibold">
<i class="bi bi-question-lg me-1"></i>
Pregunta
</label>
<textarea
id="pregunta"
name="pregunta"
class="form-control input-kahoot"
rows="3"
placeholder="Escribe aquí la pregunta..."
required></textarea>
<textarea id="pregunta"
name="pregunta"
class="form-control input-kahoot"
rows="3"
placeholder="Escribe aquí la pregunta..."
required></textarea>
</div>
<!-- CATEGORÍA -->
<div class="mb-4">
<label
for="idCategoria"
class="form-label fw-semibold">
<label for="idCategoria" class="form-label fw-semibold">
<i class="bi bi-folder-fill me-1"></i>
Categoría
</label>
<select
id="idCategoria"
name="idCategoria"
class="form-select input-kahoot"
required>
<option value="">
Selecciona una categoría
</option>
<select id="idCategoria"
name="idCategoria"
class="form-select input-kahoot"
required>
<option value="">Selecciona una categoría</option>
</select>
</div>
<!-- RESPUESTA CORRECTA -->
<div class="mb-3">
<label
for="respuestaCorrecta"
class="form-label fw-semibold text-success">
<label for="respuestaCorrecta" class="form-label fw-semibold text-success">
<i class="bi bi-check-circle-fill me-1"></i>
Respuesta correcta
</label>
<input
type="text"
id="respuestaCorrecta"
name="respuestaCorrecta"
class="form-control input-kahoot"
placeholder="Escribe la respuesta correcta..."
required>
<input type="text"
id="respuestaCorrecta"
name="respuestaCorrecta"
class="form-control input-kahoot"
placeholder="Escribe la respuesta correcta..."
required>
</div>
<!-- RESPUESTAS INCORRECTAS -->
<div class="mb-3">
<label
class="form-label fw-semibold text-danger">
<label class="form-label fw-semibold text-danger">
<i class="bi bi-x-circle-fill me-1"></i>
Respuestas incorrectas
</label>
<input type="text"
id="respuestaIncorrecta1"
name="respuestaIncorrecta1"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 1"
required>
<input
type="text"
id="respuestaIncorrecta1"
name="respuestaIncorrecta1"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 1"
required>
<input
type="text"
id="respuestaIncorrecta2"
name="respuestaIncorrecta2"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 2"
required>
<input
type="text"
id="respuestaIncorrecta3"
name="respuestaIncorrecta3"
class="form-control input-kahoot"
placeholder="Respuesta incorrecta 3"
required>
<input type="text"
id="respuestaIncorrecta2"
name="respuestaIncorrecta2"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 2"
required>
<input type="text"
id="respuestaIncorrecta3"
name="respuestaIncorrecta3"
class="form-control input-kahoot"
placeholder="Respuesta incorrecta 3"
required>
</div>
</form>
</div>
<!-- PIE DEL MODAL -->
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-lg me-1"></i>
Cancelar
</button>
<button
type="submit"
form="formCrearPregunta"
class="btn btn-kahoot-login"
id="btnCrearPregunta">
<button type="submit" form="formCrearPregunta" class="btn btn-kahoot-login" id="btnCrearPregunta">
<i class="bi bi-check-lg me-1"></i>
Crear pregunta
</button>
</div>
</div>
@@ -449,14 +306,9 @@
</div>
<!-- Bootstrap JS -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Tu JavaScript -->
<script src="js/perfil.js"></script>
</body>
+155 -290
View File
@@ -1,291 +1,156 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trivial - Resultado final</title>
<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>
<body>
<?php
include_once("cabecera.php");
?>
<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>
<h1 class="fw-bold">
¡Trivial terminado!
</h1>
<p class="text-muted fs-5 mb-0">
Estos son los resultados finales
</p>
</div>
<!-- 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>
<?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>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resultados - Trivial</title>
<link rel="stylesheet" href="css/resultados.css">
<script src="https://jquery.com"></script>
</head>
<body data-id-partida="<?php echo $idPartida; ?>">
<div id="pantalla-espera" class="contenedor">
<h2>⌛ Esperando a que todos los jugadores terminen...</h2>
<p>Calculando estadísticas de velocidad y actualizando perfiles históricos en el servidor.</p>
<div class="loader"></div>
</div>
<div id="pantalla-resultados" class="contenedor" style="display:none;">
<h1>🏆 Resultados de la Partida 🏆</h1>
<h2>Clasificación por Equipos</h2>
<table class="tabla-ranking">
<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>
<script src="js/resultados.js"></script>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
bDatosServer="localhost"
bDatos="triviagmatico"
bDatosUser="root"
bDatosPass=""
urlBase="http://triviagmatico.test"
dirBase="C:/laragon/www/triviagmatico"