Programando tu propio TRIVIAL paso a paso (I)

Creando juego trivial con PHP

 

Hoy os voy a ayudar a programar  tu propio TRIVIAL paso a paso .

 

Este proyecto, el TRIVIAL, el famoso juego de preguntas y respuestas, fuė uno de los que realizé durante mis estudios de Fullstack Developer y por eso, quiero agradecer a mi profesor JUAN PABLO, la paciencia que tuvo y lo mucho que me ayudó.

El funcionamiento es bastante simple, pero es necesario seguir los pasos ya que este programa de preguntas y respuestas debe hacer muchas cosas para que funcione correctamente.

Usaremos PHP y algo (muy poco) de AJAX.

Supongo que estarás un poco familiarizado con el concepto básico del AJAX.

AJAX no es un lenguaje de programación, sino un conjunto de tecnologías (HTML-JavaScript-CSS-DHTML-PHP/ASP.NET/JSP-XML) que nos permiten hacer páginas de internet más interactivas.

La característica fundamental de AJAX es permitir actualizar parte de una página con información que se encuentra en el servidor sin tener que refrescar completamente la página.

De modo similar podemos enviar información al servidor.

Veréis que se entiende muy bien.

Al final, ya sabemos que sólo son preguntas con respuestas, pero tiene su intringulis. Pero no temas, al final todo quedará muy claro. Si yo he sido capaz de completarlo….

No hace falta que copies todo el código, podrás descargar el sistema completo y verlo funcionar al final de la segunda parte de este post.

Vamos a empezar esta primera parte de la entrada con lo mas importante, LA BASE DE DATOS.

Es muy importante hacer correctamente esa base de datos ya que tiene que guardarnos muchos datos y lo tiene que hacer correctamente.

Tendrá 3 tablas:

  • Preguntas, con sus respuestas (incluida la correcta por cada pregunta)
  • Resultados . Debe guardar las preguntas respondidas por cada usuario (nos servirá para hacer un ránking en el futuro)
  • Usuarios. Nombres y contraseñas.

Es importante hacer la tabla ‘resultados‘ entre ‘preguntas‘ y ‘usuarios‘ para evitar que a un mismo usuario se le muestre alguna pregunta que ya ha respondida.

Una vez entendido esto, pasamos a crear la base de datos. Has de llamarla ‘trivial’.

1. CREAMOS LA BASE DE DATOS

Ahora, a través de una consulta SQL, inserta el código siguiente:

-- MySQL dump 10.13  Distrib 5.7.17, for Win64 (x86_64)
--
-- Host: 127.0.0.1    Database: trivial
-- ------------------------------------------------------
-- Server version	5.5.5-10.1.33-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 utf8 */;
/*!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' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `preguntas`
--

DROP TABLE IF EXISTS `preguntas`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `preguntas` (
  `idpreguntas` int(11) NOT NULL AUTO_INCREMENT,
  `pregunta` varchar(100) DEFAULT NULL,
  `respuesta1` varchar(45) DEFAULT NULL,
  `respuesta2` varchar(45) DEFAULT NULL,
  `respuesta3` varchar(45) DEFAULT NULL,
  `respuesta4` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`idpreguntas`)
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `resultados`
--

DROP TABLE IF EXISTS `resultados`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `resultados` (
  `idresultados` int(11) NOT NULL AUTO_INCREMENT,
  `idusuarios` int(11) DEFAULT NULL,
  `idpreguntas` int(11) DEFAULT NULL,
  `puntos` int(11) DEFAULT NULL,
  PRIMARY KEY (`idresultados`)
) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `usuarios`
--

DROP TABLE IF EXISTS `usuarios`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `usuarios` (
  `idusuarios` int(11) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(45) DEFAULT NULL,
  `password` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`idusuarios`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!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 */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2019-01-05 21:32:41

Bueno, ya tienes creada la base de datos pero …. ESTÁ VACIA !!!

Si, no he puesto ni preguntas ni respuestas. Eso te lo dejo a tí como ejercicio.

Puedes hacerlo de 2 maneras diferentes:

  • 1. Accediendo a la base de datos y rellenando los campos directamente
  • 2. Creando un CRUD para gestionar la base de datos y poder añadir, borrar o modificar las preguntas que quieras incluir en el juego.

Si  lo necesitas, puedes consultar esta entrada donde te explico cómo hacer un CRUD de cualquier base de datos.

LA RESPUESTA CORRECTA SIEMPRE HA DE SER LA OPCIÓN 1 DE LAS 4 OPCIONES.

Una vez preparada la base de datos con tus nuevas preguntas y respuestas, ahora vamos con la estructura del programa:

2. Estructura de archivos del programa.

  • login.php Preguntamos al usuario su nombre y contraseña y se valida o se registra en el caso de que sea un nuevo usuario jugador.
  • index.php  La página principal. Nuestro «tablero de juego».
  • trivial.js  La página de javascript que se encarga de hacer las peticiones de ajax.
  • libreria.php  Página con todas las funciones que requieran de conexión a la base de datos.
  • pregunta.php  La página de backend de Ajax que nos devuelve una fila de la base de datos
  • resultado.php  La página de backend de Ajax que nos guarda los resultados que le pasemos.

login.php

Podrás ver que se compone de un simple formulario que te pide un ‘nombre’ y un ‘password’. Recuperamos esos dos campos y, mediante la función comprobarUsuario() comprobamos si dicho usuario existe y si  la contraseña es correcta.

Si todo es correcto nos redirigen a index.php. En caso de error de contraseña salta un error y , si el usuario no existe, se crea como nuevo jugador.

Aqui pongo el código de este primer archivo.

<?php
require_once 'libreria.php';
$error="";
session_start();
//Recuperamos el valor de nombre y password
$nombre= filter_input(INPUT_POST, 'nombre');
$password= filter_input(INPUT_POST, 'password');
 
//Si no están vacíos es porque hay un registro o login, lo comprobamos en la BD
if (!empty($nombre) && !empty($password)){
    //La función comprobar Usuario nos devuelve el id del usuario si existe
    $idUsuario=comprobarUsuario($nombre,$password);
    //Si existe el usuario guardamos la información en la BD y redirigimos al index
    if ($idUsuario){
        $_SESSION['idUsuario']=$idUsuario;
        $_SESSION['nombre']=$nombre;
        header("location:index.php");
    } else{
        $error="Usuario o contraseña incorrecta";
    }
}
?>
<html>
    <head>
        <title>Preguntas y Respuestas</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> 
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> 
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> 
    </head>
    <body>
        <div class="container" >
            <div class="jumbotron">
            <h1>Introduce tu usuario y contraseña</h1>
            <h2 class="text-danger"><?=$error?></h2>
            </div>
            <form method="post">
                <div class="form-group">
                    <label for="nombre">Usuario:</label>
                    <input type="text" class="form-control" name="nombre">
                </div>
                <div class="form-group">
                    <label for="pwd">Password:</label>
                    <input type="password" class="form-control" name="password">
                </div>
                <button type="submit" class="btn btn-primary">Enviar</button>
            </form>
        </div>
    </body>
</html>

index.php

Al llegar a este archivo, comprobamos si estamos logeados para poder seguir jugando. En caso contrario, nos devuelve a login.php

Si todo es correcto, recuperamos la puntuación con la funcion getPuntuacion()

<?php
session_start();
//Si no está definida la variable de sesión es que no se ha logueado, lo mandamos al login
if (empty($_SESSION['idUsuario'])) {
    header("location:login.php");
}
require_once("libreria.php");
//Recuperamos la puntuación para mostrarla
$puntuacion = getPuntuacion($_SESSION['idUsuario']);
?>

El resto del archivo index.php es el ‘tablero de juego’.

Aquí, puedes explayarte utilizando todo el CSS o Bootstrap que desees para convertir esta parte en un estupendo tablero de juego de preguntas. Eso lo dejo a tu criterio.

<html>
    <head>
        <title>Preguntas y Respuestas</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
        <link href="style.css" rel="stylesheet" type="text/css"/>
        
    </head>
    <body>
        <div class="container" >
            <div class="jumbotron">
                <h1>Jugador: <?= $_SESSION['nombre'] ?></h1>
                <p>Puntuación: <span id="puntuacion"><?= $puntuacion ?></span></p>
            </div>
            <div class="row">
                <div class="col-12" id="mensaje" style="min-height: 70px;"></div>
            </div>
            <div class="row tablero">
                <div class="col-12">
                    <h1 id="pregunta" class="text-center">Bienvenido al trivial. Muy pronto preguntas</h1>
                </div>
            </div>
            <div class="row tablero">
                <div class="col-lg-6 col-sm-12 text-center">
                    <button id="res1" class="btn btn-lg btn-success">.</button>
                </div>
                <div class="col-lg-6 col-sm-12 text-center">
                    <button id="res2" class="btn btn-lg btn-success">.</button>
                </div>
            </div>

            <div class="row tablero">
                <div class="col-lg-6 col-sm-12 text-center">
                    <button id="res3" class="btn btn-lg btn-success">.</button>
                </div>
                <div class="col-lg-6 col-sm-12 text-center">
                    <button id="res4" class="btn btn-lg btn-success">.</button>
                </div>
            </div>
        </div>
        <script src="trivial.js" type="text/javascript"></script>

    </body>
</html>

Verás que al final de este archivo ya hemos cargado el archivo trivial.js

Eso es porque, para cargar preguntas, necesitamos 3 cosas:

Buscamos una pregunta por AJAX …

var preguntas;
//Busca una pregunta por Ajax
function cargarPregunta() {
    $.get("pregunta.php", function (datos, status) {
 
        if (status == "success") {
            preguntas = JSON.parse(datos);
            pintarPregunta();
        }
    });
}

…. y se la enviamos al archivo pregunta.php

<?php
 
require_once 'libreria.php';
session_start();
//Obtenemos una pregunta de la base de datos
$fila = getPregunta($_SESSION['idUsuario']);
 
//La fila que recuperamos la organizamos de una manera más amigable para el JS
$res['pregunta'] = $fila['pregunta'];
$res['id'] = $fila['idpreguntas'];
$res['correcta'] = $fila['respuesta1'];
$res['respuestas'] = [$fila['respuesta1'], $fila['respuesta2'], $fila['respuesta3'], $fila['respuesta4']];
shuffle($res['respuestas']);
 
//Lo codificamos en JSON
echo json_encode($res);

Como podrás observar, he configurado el juego para que la respuesta correcta sea siempre la respuesta1. Puedes modificarlo, si lo necesitas. Recuerda que también lo tenemos preparado para que el tablero nos muestre las 4 opciones posibles desordenadas.

Ahora recibimos la pregunta y la mostramos en el tablero:

//Pinta la pregunta en nuestro HTML
function pintarPregunta() {
    $('#pregunta').text(preguntas.pregunta);
    $('#res1').text(preguntas.respuestas[0]);
    $('#res2').text(preguntas.respuestas[1]);
    $('#res3').text(preguntas.respuestas[2]);
    $('#res4').text(preguntas.respuestas[3]);
    $(".tablero").show();
    $('#mensaje div').fadeOut();
}

Podrás observar que, para recibir la pregunta, usamos la funcion getPregunta() que nos devuelve una pregunta de la base de datos que no se haya hecho antes a este mismo usuario. Esta es la consulta SQL:

$sql = "SELECT * FROM preguntas where idpreguntas not in (select idpreguntas from resultados where idusuarios=$idUsuario) order by rand() limit 1";

( luego veremos más detalladamente el archivo libreria.php )

Y ahora, una vez tenemos la pregunta nueva y mostrada en nuestro tablero, sólo nos queda esperar a que el usuario responda con un click de su raton en una de las 4 opciones mostradas. En ese momento comprobaremos si la respuesta seleccionada es o no la respuesta correcta.

Y esto lo hacemos con la tercera parte del archivo trivial.js

$(function () {
    cargarPregunta();
    //Enlazar con los botones el evento click y comprobar si la respuesta es correcta
    $('button').click(function () {
        var puntos = 0;
        //Comprobamos que el botón pulsado es la respuesta correcta
        if ($(this).text() === preguntas.correcta) {
            $('#mensaje').html('<div class="alert alert-success alert-dismissible">  <button type="button" class="close" data-dismiss="alert">&times;</button>  <strong>¡Bien! </strong> Respuesta correcta.</div>')
            puntos = 1;
        } else {
            $('#mensaje').html('<div class="alert alert-danger alert-dismissible">  <button type="button" class="close" data-dismiss="alert">&times;</button>  <strong>¡Error! </strong> Respuesta incorrecta.</div>')
 
        }
        //Escondemos el tablero para queno pueda pulsar más botones
        $(".tablero").hide();
        //LLamamos por ajax con post para guardar los resultados, la función nos devuelve la puntuación
        $.post("resultado.php", {idPregunta: preguntas.id, puntos: puntos}, function (datos, status) {
            $('#puntuacion').text(datos);
            cargarPregunta();
        });
 
    });
});

Y una vez se ha comprobado que el usuario ha respondido, se manda el resultado a resultado.php.

Pero eso lo veremos en la segunda parte de esta entrada, junto con el archivo libreria.php

Compartir esta entrada.

12 thoughts on “Programando tu propio TRIVIAL paso a paso (I)

    1. Eso es sencillo. En esa otra página creas una función PHP que consulte a la base de datos los nombres de los participantes y la puntuación. Puedes ver las preguntas respondidas correctamente y las erroneas y hacer un porcentaje de acierto para crear un ránking.

    1. Buenas Daniel, yo lo que haría es que si en unos segundos no se responde a la pregunta, salte a la siguiente y la marque como errónea. Se puede hacer facilmente con javascript.
      Quizas recoja todos los comentarios y los añada a una nueva versión.
      En cualquier caso, gracias por tu interés.

  1. Hola:
    ¿Que habría que hacer para poner una pagina cor preguntas respondidas, preguntas acertadas y preguntas falladas?
    Gracias por adelantado

  2. Hola,
    como agrego una pagina final donde despues de responder todas las preguntas, registre el resultado final y el listado en orden de mayor puntaje a menor de los que ya respondieron?
    Gracias.

    1. Deberás hacer una consulta en la base de datos para que te muestre los resultados de cada jugador:
      SELECT idusuarios, sum(puntos)total FROM trivial.resultados group by idusuarios order by total desc
      Generar la tabla lo dejo en tus manos.
      Suerte!!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

CAPTCHA ImageChange Image