游戏效果如下图所示:


规则:

 
在4X5的格子中,有随机的互不相等的10个数,每个数据有两份(也就是20个数,有两两相等的十对),随机分布在20个格子中。游戏开始,弹出二十个数的序列。每次点击格子会显示当前格子中的数据并暂时保留显示,直到下一次点击,如果下一次点击显示的数据与保留的数据不同,则之前点击保留的数据会消失(仍然存在于该格子但不显示)。如果连续点击显示的两个数据一样,则两个数据都会显示并且不会再消失。

  直到所有数据都通过连续点击相同数据的方式显示出来,就算游戏结束,报出游戏用时。此时可以点击开始游戏或刷新来继续。

分析:

  1:二十个格子对应二十个数据,产生两组相等的十个随机数并放入数组,数组下标决定显示位置。
  2:每个格子的状态的三种:数据隐藏,暂时保留数据和永久显示。数据隐藏的格子通过点击的下一次状态是暂时保留。暂时保留数据的格子通过点击下一次状态是永久显示或数据隐藏,这里要根据连续两次获取的数据是否相等来判断。永久显示之后状态已经不可变,只能永久显示出来,此时对点击是无效的。

  3 :计时从点击开始按钮之后,点击第一个格子时开始。直到游戏完成或点击刷新重开,期间计时器不能停止。
  4 :得出,这里需要一个布尔值,记录游戏是否已经开始,已经开始的游戏对开始按钮应该拒绝,计时器运行直到游戏完成。游戏完成时,改变布尔值,计时器停止工作,显示游戏用时,开始按钮可用。

实现:

表格通过script创建,其中的元素先默认显示为“”空字符串。通过对应的点击来显示。CSS样式可自行设定。

  <table border:1>
<script>
var rowlength = 4;
var collength = 5;
var str = '';
for (var i = 0; i < rowlength; i++) {
str += '<tr>'
for (var j = 0; j < collength; j++) {
//这里将每个td的id拼接为imgxx xx为元素索引
var index = i * collength + j;
var id = "img" + index;
//注意这里字符串 每个''是一个字符串进行输出
str += '<td id="' + id + '" onclick="showImg(' + index + ')">';
str += '</td>';
}
str += '</tr>'
}
document.write(str);
</script>
</table>

 NEW_START记录是否可以开始游戏的变量
 times记录已用时间
 trans记录每个格子的翻转状态 ,数组每个格子有三种状态 0:隐藏-1:显示(仍可翻转)-2:显示(不可翻转)。也就是数组的每个元素只有三个可能的值0,1,2)
numArr三十个数的随机序列数组

 var NEW_START = true;

     var times = 0;

     var trans = [];

     var numArr = [];
 

通过ID获取到元素的方法:

 function $(id) {
return document.getElementById(id);
}

下面通过函数获取到二十个随机数,两两相等的十组(可参见:生成指定范围随机数

 function getNum() {
var index = 0;
var arrLength = rowlength * collength / 2;
var arr = new Array();
while (index < arrLength) {
var flag = true;
var num = parseInt(Math.random() * 100);
for (var i in arr) {
if (arr[i] == num || arr[i] < 1) {
flag = false;
}
}
if (flag == true) {
arr[index] = num;
index++;
}
}
//alert(arr.length);
//arr是十个互不相等的随机数
// newArr数组就是每个随机数都有两个的数组
var newArr = new Array();
for (var i = 0; i < arrLength; i++) {
newArr[i] = arr[i];
newArr[arrLength + i] = arr[i];
}
return newArr;
}

创建表格,生成随机数数组这些都是准备工作。

下面是具体的逻辑:


开始游戏的点击函数

<input type="button"
id="startButton"
value="开始游戏"
onclick="init()">

点击开始游戏,需要初始化游戏相关的参数,注意如果已经开始,就需要拒绝处理。将数组元素用排序函数打乱做到随机性。

 function init() {
//如果已经开始 拒绝点击
if (NEW_START == false) {
return;
}
//结束时用于显示时间的h4标签
$('end').innerHTML = ''; var count = rowlength * collength;
//将每个格子的数据隐藏 初始化每个格子的翻转状态
for (var i = 0; i < count; i++) {
$('img' + i).innerHTML = '';
trans[i] = 0;
}
//将游戏用时置为0
times = 0;
$('gametime').innerHTML = times + '秒';
//获取随机的三十个数的随机序列数组 注意排序函数的使用
numArr = getNum().sort(function () {
return Math.random() - 0.5;
}); alert("已生成随机数,按表格顺序排列:" + numArr);
}

计时函数

在点击第一个格子时,就需要开始计时。NEW_START=false表示已经开始,需要确保只在游戏进行中时才计时。每秒调用自身一次,并通过innerHTML把所用时间实时显示出来。

用时:<span id="gametime">0秒</span>
1
function countTime() {
if (NEW_START == false) {
setTimeout('countTime()', 1000);
$('gametime').innerHTML = times + "秒";
times++;
}
}

每个格子的点击函数(超重点)

在未开始时拒绝点击格子的(没有效果)。进入游戏点击第一个格子,游戏开始,状态改变,NEW_START=false表示已经开始不可创建新游戏。计时开始。
后面的点击事件就需要判断点击的格子来处理不同的逻辑:

  • 点击已永久显示的元素,不处理return。
  • 点击刚显示但不是永久显示的元素,也不处理return。
      (注意这里判断是不是同一元素是直接通过状态值在trans中将索引index查找出来后对比)
  • 点击未显示元素,获取值,与前一个显示的元素对比:
    • 相等,都将trans中对应索引的状态值改为2,表示永久显示
    • 不等,新点击元素在trans中对应索引状态值改为1(暂时保留),前一个点击的元素索引值为0(需要隐藏)。

设置完状态值,就立马需要更新显示(refreshUI函数)。更新显示时根据记录状态值的数组trans来操作的。

 function showImg(index) {
//未点击开始,还未初始化,退出
if (numArr[0] == undefined) {
return;
} //初次点击进入,开启计时
if (NEW_START) {
NEW_START = false;
countTime();
}
//1-点击已经彻底显示的元素 退出
if (trans[index] == 2) {
return;
}
//将点击的格子的元素显示出来,并改变翻转状态
//alert(index);
//alert(numArr) var clickEle = $('img' + index);
clickEle.innerHTML = numArr[index]; //已点击元素的index
var transIndex;
for (var i in trans) {
if (trans[i] == 1) {
transIndex = i;
}
}
//2-如果点击的是刚刚已显示元素
if (transIndex == index) {
trans[index] = 1;
return;
}
//3-点击新元素 与先前显示元素对比 两种情况-相等 不等
else {
if (numArr[transIndex] == numArr[index]) {
trans[transIndex] = 2;
trans[index] = 2;
} else {
trans[transIndex] = 0;
trans[index] = 1;
}
}
refreshUI();
}
 

根据状态值设置显示的函数refreshUI

根据trans中每个元素的值,改变对应索引的格子的值。注意,如果格子的数据永久显示,需要记录已经永久显示的格子的数量,当等于所有格子数量时,表示已经全部显示。需要判定游戏结束,显示出游戏用时。

 function refreshUI() {
//此处用fore循环会最后存在一个undefined
//count记录已经被彻底显示的个数
var count = 0;
for (var i = 0; i < trans.length; i++) {
if (trans[i] == 0) {
$('img' + i).innerHTML = '';
}
if (trans[i] == 1) {
$('img' + i).innerHTML = numArr[i];
}
if (trans[i] == 2) {
$('img' + i).innerHTML = numArr[i]
count++;
}
}
if (count == collength * rowlength) {
NEW_START = true;
var endTime = times;
$('end').innerHTML = '用时' + endTime + '秒!!游戏结束,点击开始游戏继续';
$('gametime').innerHTML = endTime + "秒";
}
}

通过数组和表格的配合,实现配对游戏,加深对表格创建和数组的运用。处理逻辑和数据显示分离,根据状态值做到不同显示的状态。

web前端/H5/javascript学习群:250777811
欢迎大家关注我的微信号公众号,公众号名称:web前端EDU。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)

JavaScript实现数字配对游戏的更多相关文章

  1. SDOI 2016 数字配对

    题目大意:给定n个数字以及每个数字的个数和权值,将满足条件的数字配对,使得总代价不小于0,且配对最多 最大费用最大流拆点,对于每个点,连一条由S到该点的边,容量为b,花费为0,再连一条到T的边 对于每 ...

  2. 【BZOJ-4514】数字配对 最大费用最大流 + 质因数分解 + 二分图 + 贪心 + 线性筛

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 726  Solved: 309[Submit][Status ...

  3. 用原生javascript模拟经典FC游戏公路争霸

    #用原生javascript模拟经典FC游戏公路争霸 前几天看了园子里面的随笔 [原生javascript开发仿微信打飞机小游戏](http://www.cnblogs.com/Mr-Nobody/p ...

  4. Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例

    1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...

  5. 洛谷P1118 数字三角形游戏

    洛谷1118 数字三角形游戏 题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直 ...

  6. 图论(费用流):BZOJ 4514 [Sdoi2016]数字配对

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 820  Solved: 345[Submit][Status ...

  7. java猜数字小游戏

    /* * * 猜数字小游戏 * * 先由系统生成一个2-100之间的随机数字, * * 然后捕获用户从控制台中输入的数字是否与系统生成的随机数字相同, * * 如果相同则统计用户所猜的次数,并给出相应 ...

  8. BZOJ 4514: [Sdoi2016]数字配对 [费用流 数论]

    4514: [Sdoi2016]数字配对 题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数 ...

  9. 简单的C语言猜数字小游戏

    猜数字小游戏可谓是C语言最为基础的一个知识点了,我们可以在此基础上进行延伸,实现随机数的猜测,然后是加入再来一局的模式,等等.这里是抛砖引玉,希望你能做出你的经典之作. #include <st ...

随机推荐

  1. sprintf()函数使用异常

    调试STM32F103,比如如下代码:使用springf函数,这个函数是把最后两个参数先格式化成字符串 ,输出到ERROR_STRING,如果他们合并的长度大于30会出现深情况? ] sprintf( ...

  2. android版本vqmon移植IOS版

    IOS交叉编译 1.android版本 vqmon已经正常运行,现需要开放IOS版本,作移植工作. 2. 注意事项: 1)ROOT权限,IOS必须越狱.  2)依赖库:pcap, ffmpeg,lib ...

  3. 《Cracking the Coding Interview》——第2章:链表——题目4

    2014-03-18 02:27 题目:将一个单链表按照一个值X分为两部分,小于X的部分放在大于等于X的部分之前. 解法:按照值和X的大小,分链表为两条链表,然后连起来成一条. 代码: // 2.4 ...

  4. Vue组件编写

    Vue无疑是近来最火的一个前端框架,它吸取了angular1.x和react的精华,性能优良,而且易于上手,本文主要是关于如何去写一个组件. 首先是项目目录 编写组件 在这里我写了一个日期控件(移动端 ...

  5. JavaWeb项目中使用ajax上传文件

    1.jsp $("#cxsc").click(function(){ var bankId = $("#bankId").val(); var formdata ...

  6. Ubuntu 安装jdk与tomcat

    1.官网下载jdk,地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ,选择 ...

  7. HTML5应用:setCustomValidity(message)接口

    本文转自http://tid.tenpay.com/?p=3592 HTML5表单验证给前端人员带来了便利,但是在用户体验上存在一些缺陷,默认的提示对用户很不友好,无法准确的获取想要的信息.好在大牛们 ...

  8. 【Android】实验7 BindService模拟通信 截止提交日期2016.5.3

    实验7 BindService模拟通信 [目的] 实现启动端和BindService之间的双向通信 [要求] 1)   实现从启动端传递一个数据至BindService端: 2)   实现使用Bind ...

  9. js文字跳动效果

    /*! * chaffle v1.0.0 * * Licensed under MIT * Copyright 2013-2014 blivesta * http://blivesta.com */ ...

  10. 【bzoj5047】空间传送装置 堆优化Dijkstra

    题目描述 n个点e条边的有向图,每条边是m种类型之一.第i种类型在第x时刻通过所花费的时间为$(a_i*x+b_i)\mod c_i+d_i$.可以在某个点停留.问:在s时刻从1号点出发,到达每个点所 ...