# 一、实验目的
本次实验目为练习 JavaScript 的程序编写,以实现 Web 页面的交互功能
# 二、实验内容
制作一个拼图游戏(3*3)
# 三、实验步骤
1.确定需求
- 一个拼图游戏要实现一个 3*3 的网格布局,其中一块为空白,剩余 8 块可以自由移动,当 8 块位置正确后,再添加剩余的一块,就可以完成拼图
- 要有完整图片的提示信息
- 记录游戏时间、步数
- 可以随机打乱拼图
2.设计页面原型
根据需求,设计界面原型。
- 上方居中显示标题和
- 主题部分分为两大块:游戏区和提示区。游戏区为一个 3*3 网格,每个格中填充一张图片块,其中一个块为空白。点击上、下、左、右四个方向有空白块的图片可以向空白块移动该图片。提示区上方为完整图片,下面是计时和步数。在最下面有重新开始的按钮和添加最后一块(检查胜利)的按钮,如果在所有图片位置正确时点击,则会自动填充最后一块,结束计时,显示成功的对勾提示。否则会显示错误提示。
- 底端显示作者信息
- 设计响应式页面以适应所有宽度的设备
3.实现布局
编写 index.html、index.css
关键技术:
- 游戏区

游戏区 game_block 中存在网格块 grid,其中包含九个子块 p0-p8,每个子块中有一张图片。
样式使用 flex 布局,设置固定宽度使得每行显示三个块,且中间不保留空隙

- 菜单区

样式不做过多赘述
- 伪类动作

对图片、按钮,使用:hover {cursor: pointer}使的当鼠标悬停时,变为指针
对拼图图片,使用:hover{transform.scale(1.1)}设置鼠标悬停在图片上方时,图片略微放大以指示该图片
- 响应式设计


使用了媒体查询,确保在页面宽度改变时拼图显示正常
同时在<head>中设置 viewport 视窗,限制移动端的视窗长度
```c++
<meta name="viewport" cotent="width=device-width">
```
4.实现交互
编写 index.js,使用 jQuery 编写
核心交互功能
- 初始化页面:声明变量,启动定时器,初始化拼图

Steps 记录步数,minute、second 为 HTML 页面上显示的时间,timer 是计时器,每 1 秒执行 updateTime 函数,更新页面上的时间:(判断秒数进位分钟,个位数的分、秒显示为两位)

Random 为游戏中缺少的图片块(0-8)编号,empty 为游戏中网格当前为空白的块(0-8)编号,pictures 是一个数组,下标为图片块编号,值为图片块当前的位置编号,如果图片块缺少,值为-1
resetPicture 函数对拼图重新进行排序

首先先将 pictures 数组初始化为正确顺序,然后再调用 shuffle 函数按照随机交换方法打乱。之后,生成一个 0-8 的随机数,作为缺少的图片块的编号,并且更新 empty、pictures 的值
之后,要检查当前生成的随机打乱是否有解,调用 checkPossible 函数

原理为,首先建立棋盘数组,存储网格中每个块放置的图片块编号。初始数组为正确顺序(缺少的块编号为-1),打乱数组为刚才打乱后的顺序。如果一个随机打乱有解,那么对于初始数组和打乱数组的逆序数,其奇偶性应该相同。如果不同,则将打乱数组倒数第 2、3 个元素对调,即可变为可行解。
最后,根据打乱顺序设置图片
- 操作拼图
首先判断点击块是否可以移动
如果可以,获取目标位置,交换之,并记录步数

- 获胜
判断除去缺少块以外的其它块是否在正确位置上,如果在,添加缺少图片,显示对勾,停止计时器,补全 pictures 数组。否则,显示 x

- 重置页面
刷新布局,重设定时器和计步器

# 四、实验结果
界面效果

获胜

不满足胜利条件

平板电脑效果:

手机效果

# 五、实验结论
熟练掌握了 jQuery 对 DOM 文档的操作
# 六、源代码
1. index.html
```
<!DOCTYPE html>
<html>
<head>
<title>Homework2, Xingyu Liu</title>
<meta charset=" tf-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" type="text/css" href="./index.css">
<script type="text/javascript" src="./jquery-3.4.0.min.js"></script>
</head>
<body>
<div class="title_block">
<h1>Picture Puzzle</h1>
</div>
<div class="outside_block">
<div class="game_block">
<div class="grid">
<div id="p0"><img></div>
<div id="p1"><img></div>
<div id="p2"><img></div>
<div id="p3"><img></div>
<div id="p4"><img></div>
<div id="p5"><img></div>
<div id="p6"><img></div>
<div id="p7"><img></div>
<div id="p8"><img></div>
</div>
</div>
<div class="menu_block">
<div class="menu_content">
<div class="origin_img_block">
<img id="origin_img" src="./image/all.jpg">
</div>
<div class="score_block">
<span id="time_tip" class="tip">时间:</span>
<span id="minute" class="score time">00</span>
<span>:</span>
<span id="second" class="score time">00</span>
<span id="step_tip" class="tip">步数:</span>
<span