本文概述
你是否曾经在火车站或公共汽车上买过的那些廉价书籍中找到寻字游戏?字母汤的想法是在表格中找到单词列表(所谓的汤)。这次, 你将学习如何轻松地使用Javascript和wordfind.js(以所有可能的用例作为解决方案, 多个方向, 单词重叠等)来创建文字游戏的汤。
要求
为了创建字母汤, 我们将使用wordfind.js, wordfind是一个简单的JavaScript库, 用于生成单词查找(也称为单词搜索)难题。你可以在此处的Github官方存储库中获取脚本的副本, 但是该存储库未提供该脚本的缩小版本, 因此你可以在项目中使用以下缩小版本:
// 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="abcdefghijklmnoprstuvwy", 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);
使用脚本标记将引用添加到html文档中, 你就可以开始了:
<script src="wordfind.js"></script>
用GUI实施
如果你想要完整的实现(并且已经构建了UI, 并且将事件处理程序用作用户选择等), 则需要将jQuery作为项目中的依赖项。你可以从CDN向项目添加jQuery引用:
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
此外, 你需要添加另一个脚本, 该脚本将负责为用户创建GUI(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="puzzleSquare" x="'+u+'" y="'+o+'">', r+=l[u]||" ", 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("wordFound")), 0===r.length&&t(".puzzleSquare").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(".puzzleSquare").on("MSPointerDown", d), t(".puzzleSquare").on("MSPointerOver", c), t(".puzzleSquare").on("MSPointerUp", z)):(t(".puzzleSquare").mousedown(d), t(".puzzleSquare").mouseenter(v), t(".puzzleSquare").mouseup(z), t(".puzzleSquare").on("touchstart", d), t(".puzzleSquare").on("touchmove", f), t(".puzzleSquare").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("wordFound")){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("wordFound")}}}}};window.wordfindgame=r()}(document, jQuery, wordfind);
并在你的文档中添加参考:
<script src="wordfindgame.js"></script>
以下示例显示了使用两个脚本(wordfind.js和wordfindgame.js)的完整实现(但在初始化时没有自定义选项)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Wordfind game Javascript</title>
</head>
<body>
<!-- Add required markup -->
<div id="puzzle-container"></div>
<div id="puzzle-words"></div>
<input type="button" id="solveBTN" value="Solve puzzle"/>
<!-- Add dependencies -->
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="wordfind.js"></script>
<script src="wordfindgame.js"></script>
<!-- Add our logic -->
<script>
// An array with the words to show
var words = ['cows', 'tracks', 'arrived', 'located', 'sir', 'seat', 'division', 'effect', 'underline', 'view', 'annual', 'anniversary', 'centennial', 'millennium', 'perennial', 'artisan', 'apprentice', 'meteorologist', 'blizzard', 'tornado', 'intensify', 'speed', 'count', 'consonant', 'someone', 'sail', 'rolled', 'bear', 'wonder', 'smiled', 'angle', 'absent', 'decadent', 'excellent', 'frequent', 'impatient', 'cell', 'cytoplasm', 'organelle', 'diffusion', 'osmosis', 'respiration'
];
// Start a basic word game without customization !
var gamePuzzle = wordfindgame.create(words, '#puzzle-container', '#puzzle-words');
$("#solveBTN").click(function(){
// Solve the puzzle !
var result = wordfindgame.solve(gamePuzzle, words);
console.log(result);
});
</script>
</body>
</html>
结果应该是类似于以下内容的字母汤:
注意:你可以将样式应用于拼图的容器div。如果你今天不觉得受启发, 则可以使用存储库中提供的样式(前缀不正确, 以防止与当前的库和样式不兼容), 或者可以使用以下仅适用于拼图容器的规则。
在这种情况下, 样式规则基于代码中提到的选择器(#puzzle-container和#puzzle-words):
#puzzle-container {
border: 1px solid black;
padding: 20px;
float: left;
margin: 30px 20px;
}
#puzzle-container div {
width: 100%;
margin: 0 auto;
}
/* style for each square in the puzzle */
#puzzle-container .puzzleSquare {
height: 30px;
width: 30px;
text-transform: uppercase;
background-color: white;
border: 0;
font: 1em sans-serif;
}
#puzzle-container button::-moz-focus-inner {
border: 0;
}
/* indicates when a square has been selected */
#puzzle-container .selected {
background-color: orange;
}
/* indicates that the square is part of a word that has been found */
#puzzle-container .found {
background-color: blue;
color: white;
}
#puzzle-container .solved {
background-color: purple;
color: white;
}
/* indicates that all words have been found */
#puzzle-container .complete {
background-color: green;
}
/**
* Styles for the word list
*/
#puzzle-words {
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;
}
#puzzle-words ul {
list-style-type: none;
}
#puzzle-words li {
padding: 3px 0;
font: 1em sans-serif;
}
/* indicates that the word has been found */
#puzzle-words .wordFound {
text-decoration: line-through;
color: gray;
}
/**
* Styles for the button
*/
#solve {
margin: 0 30px;
}
你已经准备好出发了!
没有GUI的实现
如果你只是在寻找生成寻字游戏的逻辑, 那么今天就是你的幸运日! Wordfind提供了一个简单的API, 可以检索数组中的游戏结构。
var words = ['cow'];
var puzzle = wordfind.newPuzzle(words, {
// Set dimensions of the puzzle
height: 3, width: 3, // or enable all with => orientations: wordfind.validOrientations, orientations: ['horizontal', 'vertical'], // Set a random character the empty spaces
fillBlanks: true, preferOverlap: false
});
console.log(puzzle);
// Output array:
//[[A, X, C], // [P, E, O], // [J, I, W]]
Puzzle变量将是一个数组, 其上的每个项目都等同于表上的一行:
一个 | X | C |
P | Ë | Ø |
Ĵ | 一世 | w ^ |
如果你想自己实现用户界面, 并且只需要生成字母汤的逻辑, 则此功能非常有用。库中有很多有用的选项, 你应该阅读。
如果需要, 你可以在此处查看正式的有效实施。玩得开心 !
评论前必须登录!
注册