Inicio Apuntes FPApuntes DAW Sopa de letras, crea la tuya propia con JavaScript

Sopa de letras, crea la tuya propia con JavaScript

Crea tu juego de sopa de letras para el navegador web

Publicado por entreunosyceros
Publicado el: Última actualización:

AVISO: Esta entrada tiene más de dos años desde su publicación. Es posible que el contenido esté desactualizado.

Una vez más aquí. Hoy vengo a dejar un pequeño artículo por el que un usuario me ha preguntado esta misma semana. El caso, es que este necesita crear una sopa de letras (a saber por qué). Supongo que alguna disfruta a día de hoy buscando palabras en uno de esos libros de pasatiempos, en los que las sopa de letras eran las reinas. Por si alguien todavía no lo sabe, la idea de las sopas de letras, es encontrar una lista de palabras entre un batiburrillo de letras. 

En este ejemplo, veremos como crear crear un juego de sopa de letras con Javascript, utilizando wordfind.js, que nos dará todos los posibles casos de uso. Bueno, pues buscando un poco por internet, se puede encontrar en páginas como esta, cómo crear esta sopa de letras con algunas líneas de código.

En esta página que nombré en las anteriores líneas, se muestra que para crear la sopa de letras, podemos trabajar con wordfind.js. Esta es una biblioteca javascript simple para generar rompecabezas de búsqueda de palabras. Se puede obtener una copia del script en su repositorio oficial de Github , sin embargo, el repositorio no proporciona una versión minimizada. Aun que en la página de dónde saqué la mayoría del código que vamos a ver, si que ofrecen una versión minimizada, a la que hay poco que modificar.

El código para crear tu propia sopa de letras

Sopa de letras creada con JavaScript

Para este ejemplo solo necesitaremos crear los siguientes archivos, los cuales guardaremos todos en la misma carpeta.

Archivo index.html

Dentro del archivo index.html crearemos la estructura de la sopa de letras. Además añadiremos jquery y los otros dos archivos js que vamos a crear (wordfind y wordfindgame). En este archivo añadiremos un array con las palabras que los usuarios tendremos que buscar (no les han puesto acentos, para hacerlo más complicado en la sopa de letras). También vamos a crear dos funciones, con las cuales podremos resolver la sopa de letras o reiniciarla. A estas funciones accederemos gracias a los dos botones que se han colocado en la parte inferior de la página.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Sopa de letras - JavaScript</title>
    <link rel="stylesheet" href="style.css" type="text/css" media="all" />
        <!-- Dependencias -->
    <script src="https://code.jquery.com/jquery-2.2.4.min.js" crossorigin="anonymous"></script>
    <script src="wordfind.js"></script>
    <script src="wordfindgame.js"></script>
</head>

<body>
    <!-- Estructura de la sopa de letras-->
    <div class="titulo">Sopa de Letras</div>
    <input type="button" id="BTNresolver" value="Resolver sopa de letras" />
    <input type="button" value="Reiniciar la sopa de letras" id="BTNrefresh">
    <div id="contenedor"></div>
    <div id="palabras-sopadeletras"></div>

    <!-- Construcción de la sopa de letras -->
    <script>
        // Array con las palabras que el usuario debe buscar
        var palabras = ['pie', 'localizar', 'coche',
            'culo', 'pelo', 'formula',
            'resfriado', 'perro', 'pescador',
            'repartidor', 'programador', 'velocimetro',
            'contador', 'salinidad', 'tabaco',
            'oso', 'ceniza', 'electricidad',
            'buho', 'frecuencia', 'entreunosyceros',
            'onanismo', 'osmosis', 'zapato'
        ];

        // Comienza un juego de palabras
        var sopaLetras = wordfindgame.create(palabras, '#contenedor', '#palabras-sopadeletras');

        // Función para resolver la sopa de petras             
        $("#BTNresolver").click(function () {
            var resultado = wordfindgame.solve(sopaLetras, palabras);
            console.log(resultado);
        });

        // Función para reiniciar la sopa de letras
        $("#BTNrefresh").click(function () {
            window.location.href = window.location.href;
        });
    </script>
</body>

</html>

Archivo style.css

Dentro del archivo style.css vamos a añadir algunas reglas CSS para darle un poco de estilo a la sopa de letras. Cada cual que lo mejore o lo cambie a su gusto. Bien es cierto que no se han añadido reglas para dispositivos móviles, por lo que se deduce que este ejemplo está pensado para funcionar en navegadores web desde una pantalla decente.

Aquí no se hace nada más que eso, por lo que dentro del archivo solo hay que pegar el siguiente código:

body {
    background-color: #000000;
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    max-height: 100vh;
}

/* Contenedor de la sopa de letras */

#contenedor {
    border: 1px solid rgb(0, 17, 255);
    padding: 20px;
    float: left;
    margin: 150px 20px;
}

#contenedor div {
    width: 100%;
    margin: 0 auto;
}

/* Estilo para cada cuadrado de la sopa de letras */

#contenedor .letra {
    height: 30px;
    width: 30px;
    text-transform: uppercase;
    background-color: white;
    border: 0;
    font: 1em sans-serif;
}

/* Colores cuando se selecciona un cuadrado */

#contenedor .selected {
    background-color: rgb(8, 179, 2);
}

#contenedor:hover .selected:hover {
    background-color: rgb(145, 255, 0);
    font-weight: bold;
}

#contenedor>div>button:hover {
    background-color: rgb(145, 255, 0);
    font-weight: bold;
}

/* Indica que la letra es parte de una palabra que se ha encontrado */

#contenedor .found {
    background-color: #c0c0c0;
    color: white;
    border: 1px solid black;
    font-weight: bold;
    text-shadow: 0px 2px 3px #000;
}

#contenedor .found:hover {
    background-color: rgb(145, 255, 0);
    font-weight: bold;
}

/* Colores de palabras no encontradas cuando se pulsa el botón Resolver sopa de letras*/

#contenedor .solved {
    background-color: purple;
    color: white;
}

/* Cambio de color de fondo cuando se encuentras todas las palabras*/

#contenedor .complete {
    background-color: green;
}

/**
* Estilos para la lista de palabras
*/

#palabras-sopadeletras {
    padding-top: 20px;
    -moz-column-count: 2;
    -moz-column-gap: 20px;
    -webkit-column-count: 2;
    -webkit-column-gap: 20px;
    column-count: 2;
    column-gap: 20px;
    width: 300px;
}

#palabras-sopadeletras ul {
    list-style-type: none;
}

#palabras-sopadeletras li {
    padding: 3px 0;
    font: 1em sans-serif;
}

/*Indica que la palabra ha sido encontrada en la lista */

#palabras-sopadeletras .palabraEncontrada {
    text-decoration: line-through;
    color: rgb(255, 0, 0);
}

/**
*  Estilos para el botón
*/

#BTNrefresh {
    position: absolute;
    bottom: 0em;
}

#BTNresolver {
    bottom: 3em;
    position: absolute;
}

/* Título */

.titulo {
    display: inline-block;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding: 10px;
    border: none;
    font: normal 48px/normal "Warnes", Helvetica, sans-serif;
    color: rgba(255, 255, 255, 1);
    text-decoration: normal;
    text-align: center;
    -o-text-overflow: clip;
    text-overflow: clip;
    white-space: pre;
    text-shadow: 0 0 10px rgba(255, 255, 255, 1), 0 0 20px rgba(255, 255, 255, 1), 0 0 30px rgba(255, 255, 255, 1), 0 0 40px #ff00de, 0 0 70px #ff00de, 0 0 80px #ff00de, 0 0 100px #ff00de;
    -webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
    -moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
    -o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
    transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
    position: absolute;
    top: 1em;
}

.titulo:hover {
    text-shadow: 0 0 10px rgba(255, 255, 255, 1), 0 0 20px rgba(255, 255, 255, 1), 0 0 30px rgba(255, 255, 255, 1), 0 0 40px #00ffff, 0 0 70px #00ffff, 0 0 80px #00ffff, 0 0 100px #00ffff;
}

Archivo wordfindgame.js

Como indicaba al principio del artículo, los dos archivos js que vamos a añadir se pueden sacar del respositorio en GitHub de esta biblioteca, pero allí no estará minificado. Se puede utilizar el código que ofrecen en este repositorio, o el siguiente para pegar en el archivo wordfindgame.js:

/**
* wordfindgame.js
* Script to create the GUI
* Wordfindgame.js
* (c) 2012 Bill, BunKat LLC.
* Wordfind is freely distributable under the MIT license.
* For all details and documentation: http://github.com/bunkat/wordfind
*/
!function(e,t,n){"use strict";var r=function(){var r,o,a,l=function(e,n){for(var r="",o=0,a=n.length;a>o;o++){var l=n[o];r+="<div>";for(var u=0,s=l.length;s>u;u++)r+='<button class="letra" x="'+u+'" y="'+o+'">',r+=l[u]||"&nbsp;",r+="</button>";r+="</div>"}t(e).html(r)},u=function(e,n){for(var r="<ul>",o=0,a=n.length;a>o;o++){var l=n[o];r+='<li class="word '+l+'">'+l}r+="</ul>",t(e).html(r)},s=[],i="",d=function(){t(this).addClass("selected"),o=this,s.push(this),i=t(this).text()},c=function(e){if(o){var n=s[s.length-1];if(n!=e){for(var r,l=0,u=s.length;u>l;l++)if(s[l]==e){r=l+1;break}for(;r<s.length;)t(s[s.length-1]).removeClass("selected"),s.splice(r,1),i=i.substr(0,i.length-1);var d=p(t(o).attr("x")-0,t(o).attr("y")-0,t(e).attr("x")-0,t(e).attr("y")-0);d&&(s=[o],i=t(o).text(),n!==o&&(t(n).removeClass("selected"),n=o),a=d);var c=p(t(n).attr("x")-0,t(n).attr("y")-0,t(e).attr("x")-0,t(e).attr("y")-0);c&&(a&&a!==c||(a=c,h(e)))}}},f=function(t){var n=t.originalEvent.touches[0].pageX,r=t.originalEvent.touches[0].pageY,o=e.elementFromPoint(n,r);c(o)},v=function(){c(this)},h=function(e){for(var n=0,o=r.length;o>n;n++)if(0===r[n].indexOf(i+t(e).text())){t(e).addClass("selected"),s.push(e),i+=t(e).text();break}},z=function(){for(var e=0,n=r.length;n>e;e++)r[e]===i&&(t(".selected").addClass("found"),r.splice(e,1),t("."+i).addClass("palabraEncontrada")),0===r.length&&t(".letra").addClass("complete");t(".selected").removeClass("selected"),o=null,s=[],i="",a=null},p=function(e,t,r,o){for(var a in n.orientations){var l=n.orientations[a],u=l(e,t,1);if(u.x===r&&u.y===o)return a}return null};return{create:function(e,o,a,s){r=e.slice(0).sort();var i=n.newPuzzle(e,s);return l(o,i),u(a,r),window.navigator.msPointerEnabled?(t(".letra").on("MSPointerDown",d),t(".letra").on("MSPointerOver",c),t(".letra").on("MSPointerUp",z)):(t(".letra").mousedown(d),t(".letra").mouseenter(v),t(".letra").mouseup(z),t(".letra").on("touchstart",d),t(".letra").on("touchmove",f),t(".letra").on("touchend",z)),i},solve:function(e,r){for(var o=n.solve(e,r).found,a=0,l=o.length;l>a;a++){var u=o[a].word,s=o[a].orientation,i=o[a].x,d=o[a].y,c=n.orientations[s];if(!t("."+u).hasClass("palabraEncontrada")){for(var f=0,v=u.length;v>f;f++){var h=c(i,d,f);t('[x="'+h.x+'"][y="'+h.y+'"]').addClass("solved")}t("."+u).addClass("palabraEncontrada")}}}}};window.wordfindgame=r()}(document,jQuery,wordfind);

Archivo wordfind.js

El otro archivo JavaScript que vamos a crear se llama wordfind.js. Este, como en el caso anterior, se puede descargar desde el repositorio en GitHub de esta librería, pero también puedes pegar dentro del archivo el siguiente código:

// wordfind.js
/**
* Wordfind.js
* (c) 2012 Bill, BunKat LLC.
* Wordfind is freely distributable under the MIT license.
* @documentation http://github.com/bunkat/wordfind
*/
(function(){"use strict";var n=function(){var n="abcdefghijklmnoprstuvwyz",r=["horizontal","horizontalBack","vertical","verticalUp","diagonal","diagonalUp","diagonalBack","diagonalUpBack"],t={horizontal:function(n,r,t){return{x:n+t,y:r}},horizontalBack:function(n,r,t){return{x:n-t,y:r}},vertical:function(n,r,t){return{x:n,y:r+t}},verticalUp:function(n,r,t){return{x:n,y:r-t}},diagonal:function(n,r,t){return{x:n+t,y:r+t}},diagonalBack:function(n,r,t){return{x:n-t,y:r+t}},diagonalUp:function(n,r,t){return{x:n+t,y:r-t}},diagonalUpBack:function(n,r,t){return{x:n-t,y:r-t}}},o={horizontal:function(n,r,t,o,e){return o>=n+e},horizontalBack:function(n,r,t,o,e){return n+1>=e},vertical:function(n,r,t,o,e){return t>=r+e},verticalUp:function(n,r,t,o,e){return r+1>=e},diagonal:function(n,r,t,o,e){return o>=n+e&&t>=r+e},diagonalBack:function(n,r,t,o,e){return n+1>=e&&t>=r+e},diagonalUp:function(n,r,t,o,e){return o>=n+e&&r+1>=e},diagonalUpBack:function(n,r,t,o,e){return n+1>=e&&r+1>=e}},e={horizontal:function(n,r,t){return{x:0,y:r+1}},horizontalBack:function(n,r,t){return{x:t-1,y:r}},vertical:function(n,r,t){return{x:0,y:r+100}},verticalUp:function(n,r,t){return{x:0,y:t-1}},diagonal:function(n,r,t){return{x:0,y:r+1}},diagonalBack:function(n,r,t){return{x:t-1,y:n>=t-1?r+1:r}},diagonalUp:function(n,r,t){return{x:0,y:t-1>r?t-1:r+1}},diagonalUpBack:function(n,r,t){return{x:t-1,y:n>=t-1?r+1:r}}},i=function(n,r){var t,o,e,i=[];for(t=0;t<r.height;t++)for(i.push([]),o=0;o<r.width;o++)i[t].push("");for(t=0,e=n.length;e>t;t++)if(!a(i,r,n[t]))return null;return i},a=function(n,r,o){var e=l(n,r,o);if(0===e.length)return!1;var i=e[Math.floor(Math.random()*e.length)];return c(n,o,i.x,i.y,t[i.orientation]),!0},l=function(n,r,i){for(var a=[],l=r.height,c=r.width,h=i.length,g=0,v=0,p=r.orientations.length;p>v;v++)for(var d=r.orientations[v],s=o[d],x=t[d],y=e[d],k=0,B=0;l>B;)if(s(k,B,l,c,h)){var w=u(i,n,k,B,x);(w>=g||!r.preferOverlap&&w>-1)&&(g=w,a.push({x:k,y:B,orientation:d,overlap:w})),k++,k>=c&&(k=0,B++)}else{var U=y(k,B,h);k=U.x,B=U.y}return r.preferOverlap?f(a,g):a},u=function(n,r,t,o,e){for(var i=0,a=0,l=n.length;l>a;a++){var u=e(t,o,a),f=r[u.y][u.x];if(f===n[a])i++;else if(""!==f)return-1}return i},f=function(n,r){for(var t=[],o=0,e=n.length;e>o;o++)n[o].overlap>=r&&t.push(n[o]);return t},c=function(n,r,t,o,e){for(var i=0,a=r.length;a>i;i++){var l=e(t,o,i);n[l.y][l.x]=r[i]}};return{validOrientations:r,orientations:t,newPuzzle:function(n,t){var o,e,a=0,l=t||{};o=n.slice(0).sort(function(n,r){return n.length<r.length?1:0});for(var u={height:l.height||o[0].length,width:l.width||o[0].length,orientations:l.orientations||r,fillBlanks:void 0!==l.fillBlanks?l.fillBlanks:!0,maxAttempts:l.maxAttempts||3,preferOverlap:void 0!==l.preferOverlap?l.preferOverlap:!0};!e;){for(;!e&&a++<u.maxAttempts;)e=i(o,u);e||(u.height++,u.width++,a=0)}return u.fillBlanks&&this.fillBlanks(e,u),e},fillBlanks:function(r){for(var t=0,o=r.length;o>t;t++)for(var e=r[t],i=0,a=e.length;a>i;i++)if(!r[t][i]){var l=Math.floor(Math.random()*n.length);r[t][i]=n[l]}},solve:function(n,t){for(var o={height:n.length,width:n[0].length,orientations:r,preferOverlap:!0},e=[],i=[],a=0,u=t.length;u>a;a++){var f=t[a],c=l(n,o,f);c.length>0&&c[0].overlap===f.length?(c[0].word=f,e.push(c[0])):i.push(f)}return{found:e,notFound:i}},print:function(n){for(var r="",t=0,o=n.length;o>t;t++){for(var e=n[t],i=0,a=e.length;a>i;i++)r+=(""===e[i]?" ":e[i])+" ";r+="\n"}return console.log(r),r}}},r="undefined"!=typeof exports&&null!==exports?exports:window;r.wordfind=n()}).call(this);

Y con esto ya tendrás disponible la sopa de letras para jugar las veces que quieras. Cada vez que la reinicies, las palabras se colocorán aleatoriamente, por lo que cada vez tendrás que buscar las palabras en diferentes lugares. Además, dentro del archivo index.html, podrás cambiar, añadir o retirar palabras a tu gusto. Si añades más palabras, estas se añadirán de forma automática a la sopa de letras.

Esto espero que sirva al usuario que quiere crear sus propias sopas de letras. Si quieres ver funcionando este ejemplo de sopa de letras, puedes consultar el siguiente enlace de nuestra selección de ejemplos.

También te puede interesar ...

Deja un comentario

* Al utilizar este formulario, aceptas que este sitio web almacene y maneje tus datos.

Resumen de privacidad
cookies entreunosyceros

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible.

La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudarnos a comprender qué secciones de la web encuentras más interesantes y útiles.

Nunca almacenamos información personal de ningún tipo.

Tienes toda la información sobre privacidad, derechos legales y cookies en nuestra página sobre la política de privacidad o en la página sobre nuestra política de cookies.

Cookies necesarias

Las cookies estrictamente necesarias tiene que activarse siempre para que podamos guardar tus preferencias de ajustes de cookies.

Si desactivas esta cookie no podremos guardar tus preferencias. Esto significa que cada vez que visites esta web tendrás que activar o desactivar las cookies de nuevo.

Cookies de terceros

Esta web utiliza las siguientes cookies adicionales:

- Mailchimp: Recordar si ya estás suscrito al boletín de noticias y sino ofrecértelo al salir.

- Accesibilidad: Para saber tus ajustes de accesibilidad en cada visita.

- Comentarios: Saber si has leído y aceptado nuestra política de privacidad a la hora de dejar un comentario en la web.

- Google Analytics: Localización para recopilar información anónima tal como el número de visitantes del sitio, o las páginas más populares.

- Goggle Adsense: Anuncios personalizados según tu geolocalización y preferencias.

Dejar estas cookies activadas nos permite mejorar nuestra web.

Adblock Detectado!!

Ayúdanos deshabilitando la extensión AdBlocker de tu navegador para visitar esta web.
Si no sabes hacerlo en Chrome, consulta el siguiente enlace. Si utilizas Firefox, puedes consultar este otro enlace.
Esto mejorará tu experiencia en este sitio web.