H5游戏开拓:一笔画

H5游戏开拓:息灭星星

2018/01/25 · HTML5 ·
游戏

原稿出处: 坑坑洼洼实验室   

「消释星星」是风流倜傥款很优质的「解除类游戏」,它的玩的方法相当粗略:消亡相连通的同色砖块。

图片 1

H5游戏开荒:单笔画

2017/11/07 · HTML5 ·
游戏

原稿出处: 坑坑洼洼实验室   

图片 2

SQL 练习题答案

1. 游戏法则

「消释星星」存在多少个版本,但是它们的平整除了「关卡分值」有些出入外,其余的法规都是平等的。作者介绍的版本的游戏准绳收拾如下:

1. 色砖布满

  • 10 x 10 的表格
  • 5种颜色 —— 红、绿、蓝,黄,紫
  • 每类色砖个数在钦命区间内随便
  • 5类色砖在 10 x 10 表格中随性所欲分布

2. 免除法则

四个或多个以上同色砖块相连通正是可被破除的砖块。

3. 分值准则

  • 撤除总分值 = n * n * 5
  • 奖励总分值 = 二零零一 – n * n * 20

「n」表示砖块数量。上边是「总」分值的法则,还会有「单」个砖块的分值法则:

  • 消除砖块得分值 = 10 * i + 5
  • 剩余砖块扣分值 = 40 * i + 20

「i」表示砖块的索引值(从 0
初阶卡塔 尔(阿拉伯语:قطر‎。轻巧地说,单个砖块「得分值」和「扣分值」是三个等差数列。

4. 关卡分值

关卡分值 = 1000 + (level – 1) * 二〇〇〇;「level」几日前前关卡数。

5. 及格条件

  • 可免除色块空头支票
  • 合计分值 >= 当前关卡分值

上面五个规范化还要创立游戏才得以过得去。

H5游戏开荒:一笔画

by leeenx on 2017-11-02

一笔画是图论[科普](https://zh.wikipedia.org/wiki/%E5%9B%BE%E8%AE%BA)中一个家喻户晓的主题材料,它源点于柯克赖斯特彻奇堡七桥主题素材[科普](https://zh.wikipedia.org/wiki/%E6%9F%AF%E5%B0%BC%E6%96%AF%E5%A0%A1%E4%B8%83%E6%A1%A5%E9%97%AE%E9%A2%98)。科学家欧拉在她1736年刊出的舆论《柯热那亚堡的七桥》中不但化解了七桥难题,也建议了一笔画定理,顺带消灭了一笔画难点。用图论的术语来讲,对于三个加以的连通图[科普](https://zh.wikipedia.org/wiki/%E8%BF%9E%E9%80%9A%E5%9B%BE)留存一条无独有偶含有所有线段而且未有再一次的渠道,那条路子正是「一笔画」。

搜索连通图那条路径的长河就是「一笔画」的游乐经过,如下:

图片 3

 

2. MVC 设计情势

作者此番又是运用了 MVC
格局来写「杀绝星星」。星星「砖块」的数据构造与各类气象由 Model
实现,游戏的宗意在 Model 中达成;View 映射 Model
的变迁并做出相应的行事,它的任务重视是彰显动漫;客户与游乐的相互作用由
Control 完毕。

从逻辑规划上看,Model 十分重而View 与 Control
比较轻,然而,从代码量上看,View 十分重而 Model 与 Control 相对超轻。

娱乐的贯彻

「一笔画」的贯彻不复杂,作者把贯彻进程分成两步:

  1. 底图绘制
  2. 交互作用绘制

「底图绘制」把连通图以「点线」的样式显得在画布上,是游玩最轻松达成的片段;「人机联作绘制」是顾客绘制解题路线的历程,那些历程会重点是管理点与点动态成线的逻辑。

一、补充作业一、

 

设有三个关系:

               S(SNO, SNAME, AGE, SEX,Sdept)

               SC(SNO, CNO, GRADE)

               C(CNO, CNAME, TEACHER)

试用关系代数表达式表示下列查询:

 

1、查询学号为S3学生所学课程的课程名与任课教师名。

  

2、查询至少选修LIU老师所教课程中一门课的女生姓名。

3、查询WANG同学不学的课程的课程号。

4、查询至少选修两门课程的学生学号。

5、查询选修课程中包含LIU老师所教全部课程的学生学号。

补充作业二、

 

三个关系同上,试用SQL语言表示下列查询:

 

1、  查询门门课程都及格的学生的学号

方法1:

提示:根据学号分组,就得到每个学生所有的课程成绩,在某个学生这一组成绩里,如果他所有的课程成绩都大于60分则输出该组学生的学号

Select sno frome sc group by sno having(min(grade)>=60)

 

2、查询既有课程大于90分又有课程不及格的学生的学号

自身连接:

Select sno from sc where grade >90 and sno in (select sno from sc where grade<60)

 

3、查询平均分不及格的课程号和平均成绩

Select cno , avg(GRADE) from sc group by cno having avg(grade)<60

查询平均分及格的课程号和课程名

Select C.cno , Cname from SC,C where C.cno=SC.cno group by C.cno having avg(grade)>=60

 

4、找出至少选修了2号学生选修过的全部课程的学生号

提示:不存在这样的课程y,学生2选修了y,而学生x没有选。

SELECT DISTINCT Sno

   FROM SC as SCX

   WHERE NOT EXISTS

      (SELECT *

       FROM SC as SCY

       WHERE SCY.Sno =‘2’AND NOT EXISTS

                               (SELECT *

                                  FROM SC SCZ

                          WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno))



5、求各门课程去掉一个最高分和最低分后的平均分

第一步,求所有成绩的平均分(去掉一个最高分和最低分)

select   avg(GRADE)   from   SC       where   GRADE   not   in (select   top   1   GRADE   from   SC order   by   GRADE)     and     GRADE   not   in (select   top   1   GRADE   from   SC order   by   GRADE   desc)  

第二步,将所有成绩按各门课程的课程号CNO分组

SELECT CNO avg(GRADE)   from   SC       where   GRADE   not   in (select   top  1  GRADE   from   SC order   by   GRADE)     and     GRADE   not   in (select   top  1  GRADE   from   SC order   by   GRADE   desc) group by CNO

3. Model

10 x 10 的报表用长度为 100 的数组可全面映射游戏的有数「砖块」。

[ R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G,
G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y,
Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R,
R, G, G, B, B, Y, Y, P, P, R, R, G, G, B, B, Y, Y, P, P, R, R, G, G, B,
B, Y, Y, P, P ]

1
2
3
4
5
6
7
8
9
10
11
12
[
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P,
R, R, G, G, B, B, Y, Y, P, P
]

卡宴 – 鲜绿,G – 松石绿,B – 青灰,Y – 中绿,P – 宝石红。Model
的基本职务是以下五个:

  • 浮动砖墙
  • 消亡砖块 (生成砖块分值卡塔 尔(阿拉伯语:قطر‎
  • 做实砖墙
  • 免除残砖 (生成表彰分值卡塔尔国

底图绘制

「一笔画」是多关卡的游乐形式,笔者决定把关卡(连通图卡塔尔的定制以多个布置接口的花样对外暴光。对外揭示关卡接口需求有风流倜傥套描述连通图形状的正统,而在作者前面有五个筛选:

  • 点记法
  • 线记法

举个连通图 —— 五角星为例来讲一下那七个选项。

图片 4

点记法如下:

JavaScript

levels: [ // 当前关卡 { name: “五角星”, coords: [ {x: Ax, y: Ay}, {x:
Bx, y: By}, {x: Cx, y: Cy}, {x: Dx, y: Dy}, {x: Ex, y: Ey}, {x: Ax, y:
Ay} ] } … ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
levels: [
// 当前关卡
{
name: "五角星",
coords: [
{x: Ax, y: Ay},
{x: Bx, y: By},
{x: Cx, y: Cy},
{x: Dx, y: Dy},
{x: Ex, y: Ey},
{x: Ax, y: Ay}
]
}
]

线记法如下:

JavaScript

levels: [ // 当前关卡 { name: “五角星”, lines: [ {x1: Ax, y1: Ay, x2:
Bx, y2: By}, {x1: Bx, y1: By, x2: Cx, y2: Cy}, {x1: Cx, y1: Cy, x2: Dx,
y2: Dy}, {x1: Dx, y1: Dy, x2: Ex, y2: Ey}, {x1: Ex, y1: Ey, x2: Ax, y2:
Ay} ] } ]

1
2
3
4
5
6
7
8
9
10
11
12
13
levels: [
// 当前关卡
{
name: "五角星",
lines: [
{x1: Ax, y1: Ay, x2: Bx, y2: By},
{x1: Bx, y1: By, x2: Cx, y2: Cy},
{x1: Cx, y1: Cy, x2: Dx, y2: Dy},
{x1: Dx, y1: Dy, x2: Ex, y2: Ey},
{x1: Ex, y1: Ey, x2: Ax, y2: Ay}
]
}
]

「点记法」记录关卡通过海关的多少个答案,即端点要按自然的相继寄存到数组
coords中,它是有序性的笔录。「线记法」通过两点描述连通图的线条,它是冬季的记录。「点记法」最大的优势是表现更轻巧,但它必得记录三个及格答案,笔者只是关卡的搬运工不是关卡创立者,所以小编最后选取了「线记法」。:卡塔尔国

 

3.1 生成砖墙

砖墙分两步生成:

  • 色砖数量分配
  • 打垮色砖

理论上,能够将 100 个格子能够均分到 5
类颜色,可是作者玩过的「清除星星」都不应用均分政策。通过解析七款「消释星星」,其实能够窥见四个准则—— 「色砖之间的多少差在多个恒定的区间内」。

设若把守旧意义上的均分称作「完全均分」,那么「灭亡星星」的分配是黄金时代种在均分线上下波动的「不完全均分」。

图片 5

作者把地方的「不完全均分」称作「波动均分」,算法的切实贯彻能够仰慕「国步辛劳均分算法」。

「打垮色砖」其实正是将数组乱序的进程,作者推荐应用「
费雪耶兹乱序算法」。

以下是伪代码的得以实现:

JavaScript

// 波动均分色砖 waveaverage(5, 4, 4).forEach( // tiles 即色墙数组
(count, clr) => tiles.concat(generateTiles(count, clr)); ); //
克制色砖 shuffle(tiles);

1
2
3
4
5
6
7
// 波动均分色砖
waveaverage(5, 4, 4).forEach(
// tiles 即色墙数组
(count, clr) => tiles.concat(generateTiles(count, clr));
);
// 打散色砖
shuffle(tiles);

相互之间绘制

在画布上制图路线,从视觉上实属「采用或三番四次连通图端点」的历程,这几个进度需求缓和2个难点:

  • 手指下是或不是有端点
  • 当选点到待选中点时期是不是成线

募集连通图端点的坐标,再监听手指滑过的坐标能够知晓「手指下是不是有一些」。以下伪代码是搜罗端点坐标:

JavaScript

// 端点坐标音讯 let coords = []; lines.forEach(({x1, y1, x2, y2})
=> { // (x1, y1) 在 coords 数组荒诞不经 if(!isExist(x1, y1))
coords.push([x1, y1]); // (x2, y2) 在 coords 数组不设有
if(!isExist(x2, y2)) coords.push([x2, y2]); });

1
2
3
4
5
6
7
8
// 端点坐标信息
let coords = [];
lines.forEach(({x1, y1, x2, y2}) => {
// (x1, y1) 在 coords 数组不存在
if(!isExist(x1, y1)) coords.push([x1, y1]);
// (x2, y2) 在 coords 数组不存在
if(!isExist(x2, y2)) coords.push([x2, y2]);
});

以下伪代码是监听手指滑动:

JavaScript

easel.addEventListener(“touchmove”, e => { let x0 =
e.targetTouches[0].pageX, y0 = e.targetTouches[0].pageY; // 端点半径
—— 取连通图端点半径的2倍,提高活动端体验 let r = radius * 2;
for(let [x, y] of coords){ if(Math.sqrt(Math.pow(x – x0, 2) +
Math.pow(y – y0), 2) <= r){ // 手指下有端点,决断能还是无法连线
if(canConnect(x, y)) { // todo } break; } } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
easel.addEventListener("touchmove", e => {
let x0 = e.targetTouches[0].pageX, y0 = e.targetTouches[0].pageY;
// 端点半径 —— 取连通图端点半径的2倍,提升移动端体验
let r = radius * 2;
for(let [x, y] of coords){
if(Math.sqrt(Math.pow(x – x0, 2) + Math.pow(y – y0), 2) <= r){
// 手指下有端点,判断能否连线
if(canConnect(x, y)) {
// todo
}
break;
}
}
})

在未绘制任何线段或端点从前,手指滑过的任性端点都会被视作「一笔画」的起先点;在绘制了线段(或有选中式点心卡塔 尔(阿拉伯语:قطر‎后,手指滑过的端点能无法与选中式茶食串连成线段必要依据现成标准进行剖断。

图片 6

上海教室,点A与点B可连接成线段,而点A与点C不能够三翻五次。小编把「能够与钦定端点连接成线段的端点称作卓有成效连接点」。连通图端点的有效性连接点从连通图的线条中领取:

JavaScript

coords.forEach(coord => { // 有效连接点(坐标卡塔 尔(阿拉伯语:قطر‎挂载在端点坐标下
coord.validCoords = []; lines.forEach(({x1, y1, x2, y2}) => { //
坐标是日前线段的源点 if(coord.x === x1 && coord.y === y1) {
coord.validCoords.push([x2, y2]); } // 坐标是如今线段的终端 else
if(coord.x === x2 && coord.y === y2) { coord.validCoords.push([x1,
y1]); } }) })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
coords.forEach(coord => {
// 有效连接点(坐标)挂载在端点坐标下
coord.validCoords = [];
lines.forEach(({x1, y1, x2, y2}) => {
// 坐标是当前线段的起点
if(coord.x === x1 && coord.y === y1) {
coord.validCoords.push([x2, y2]);
}
// 坐标是当前线段的终点
else if(coord.x === x2 && coord.y === y2) {
coord.validCoords.push([x1, y1]);
}
})
})

But…有效连接点只好剖断七个点是不是为底图的线条,这只是三个静态的参照,在实际上的「交互作用绘制」中,会碰着以下意况:

图片 7
如上海体育场所,AB已串连成线段,当前选中式点心B的有效连接点是 A 与 C。AB
已经三番四次成线,若是 BA 也串连成线段,那么线段就又一次了,所以当时 BA
不可能成线,独有 AC 本事成线。

对选中点来说,它的实惠连接点有二种:

  • 与选中式茶食「成线的可行连接点」
  • 与选中式茶食「未成线的管用连接点」

内部「未成线的有效连接点」才具参加「交互作用绘制」,况且它是动态的。

图片 8

回头本节内容开头提的多少个难点「手指下是或不是有端点」 与
「选中式茶食到待选中式茶食时期是不是成线」,其实可统生龙活虎为二个主题材料:手指下是还是不是留存「未成线的有用连接点」。只须把监听手指滑动遍历的数组由连通图全部的端点坐标
coords 替换为当前选中式茶食的「未成线的有效性连接点」就能够。

迄今截至「单笔画」的要害意义已经落到实处。能够超越体验一下:

图片 9

 1、查询7号课程未有考试战绩的学子学号。

3.2 消弭砖块

「解除砖块」的国有国法非常粗略 —— 隔壁相连通相似色即能够撤废

图片 10
前三个结合切合「相邻相连通相仿色就可以以祛除」,所以它们能够被驱除;第多少个组成即便「相邻相仿色」可是不「相连结」所以它无法被免去。

「息灭砖块」的还要有一个人命关天的职务:生成砖块对应的分值。在「游戏准则」中,小编曾经提供了相应的数学公式:「消灭砖块得分值
= 10 * i + 5」。

「撤消砖块」算法完成如下:

JavaScript

function clean(tile) { let count = 1; let sameTiles =
searchSameTiles(tile); if(sameTiles.length > 0) { deleteTile(tile);
while(true) { let nextSameTiles = []; sameTiles.forEach(tile => {
nextSameTiles.push(…searchSameTiles(tile)); makeScore(++count * 10 +
5); // 标志当前分值 deleteTile(tile); // 删除砖块 }); //
解除完结,跳出循环 if(next萨姆eTiles.length === 0) break; else {
sameTiles = next萨姆eTiles; } } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function clean(tile) {
let count = 1;
let sameTiles = searchSameTiles(tile);
if(sameTiles.length > 0) {
deleteTile(tile);
while(true) {
let nextSameTiles = [];
sameTiles.forEach(tile => {
nextSameTiles.push(…searchSameTiles(tile));
makeScore(++count * 10 + 5); // 标记当前分值
deleteTile(tile); // 删除砖块
});
// 清除完成,跳出循环
if(nextSameTiles.length === 0) break;
else {
sameTiles = nextSameTiles;
}
}
}
}

免除的算法使用「递归」逻辑上会清晰一些,可是「递归」在浏览器上轻便「栈溢出」,所以笔者未有利用「递归」达成。

机动识图

作者在录加入关贸总协定协会卡配置时,发掘多个7条边以上的连接图超轻巧录错或录重线段。小编在思维是还是不是开拓叁个自动识别图形的插件,毕竟「一笔画」的图片是有法规的几何图形。

图片 11

地点的关卡「底图」,一眼就能够识出七个颜色:

  • 白底
  • 端点颜色
  • 线条颜色

再正是这两种颜色在「底图」的面积大小顺序是:白底 > 线段颜色 >
端点颜色。底图的「搜罗色值表算法」很简单,如下伪代码:

JavaScript

let imageData = ctx.getImageData(); let data = imageData.data; // 色值表
let clrs = new Map(); for(let i = 0, len = data.length; i < len; i +=
4) { let [r, g, b, a] = [data[i], data[i + 1], data[i + 2],
data[i + 3]]; let key = `rgba(${r}, ${g}, ${b}, ${a})`; let value =
clrs.get(key) || {r, g, b, a, count: 0}; clrs.has(key) ? ++value.count :
clrs.set(rgba, {r, g, b, a, count}); }

1
2
3
4
5
6
7
8
9
10
let imageData = ctx.getImageData();
let data = imageData.data;
// 色值表
let clrs = new Map();
for(let i = 0, len = data.length; i < len; i += 4) {
let [r, g, b, a] = [data[i], data[i + 1], data[i + 2], data[i + 3]];
let key = `rgba(${r}, ${g}, ${b}, ${a})`;
let value = clrs.get(key) || {r, g, b, a, count: 0};
clrs.has(key) ? ++value.count : clrs.set(rgba, {r, g, b, a, count});
}

对于连通图来说,只要把端点识别出来,连通图的大致也就出来了。

    Select sno fromsc where cno=’7′ and
grade is null

3.3 狠抓砖墙

砖墙在衰亡了一些砖石后,会情不自禁空洞,那时亟需对墙体实行加强:

向下夯实 向左夯实 向左下夯实(先下后左)

黄金时代种高效的贯彻方案是,每回「毁灭砖块」后直接遍历砖墙数组(10×10数组卡塔 尔(英语:State of Qatar)再把空洞抓牢,伪代码表示如下:

JavaScript

for(let row = 0; row < 10; ++row) { for(let col = 0; col < 10;
++col) { if(isEmpty(row, col)) { // 水平方向(向左卡塔尔国做实if(isEmptyCol(col)) { tampRow(col); } // 垂直方向(向下卡塔 尔(英语:State of Qatar)狠抓 else {
tampCol(col); } break; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(let row = 0; row < 10; ++row) {
for(let col = 0; col < 10; ++col) {
if(isEmpty(row, col)) {
// 水平方向(向左)夯实
if(isEmptyCol(col)) {
tampRow(col);
}
// 垂直方向(向下)夯实
else {
tampCol(col);
}
break;
}
}
}

But…
为了压实一个硕华而不实对一张大数组举办全量遍历并非风姿洒脱种高效的算法。在笔者看来影响「墙体加强」功能的成分有:

  1. 定位空洞
  2. 砖块移动(抓好卡塔 尔(英语:State of Qatar)

环顾墙体数组的严重性指标是「定位空洞」,但能或必须要扫描墙体数组直接「定位空洞」?

墙体的「空洞」是由于「清除砖块」产生的,换种说法 ——
被免去的砖头留下来的坑位正是墙体的架空。在「杀绝砖块」的同不常候标志空洞的岗位,这样就毫无全量扫描墙体数组,伪代码如下:

JavaScript

function deleteTile(tile) { // 标识空洞 markHollow(tile.index); //
删除砖块逻辑 … }

1
2
3
4
5
6
function deleteTile(tile) {
// 标记空洞
markHollow(tile.index);
// 删除砖块逻辑
}

在上头的抓好动图,其实能够见见它的抓牢进程如下:

  1. 泛泛上方的砖头向下移动
  2. 空驶列车左侧的砖头向左移动

墙体在「坚实」进程中,它的界线是实时在更动,假诺「做实」不按实际边界进行围观,会产生多余的空域扫描:

图片 12

哪些记录墙体的分界?
把墙体拆分成一个个单身的列,那么列最最上端的空白格片段正是墙体的「空白」,而其余非顶端的空白格片段即墙体的「空洞」。

图片 13

作者利用生龙活虎组「列集结」来描述墙体的境界并记下墙体的虚幻,它的模型如下:

JavaScript

/* @ count – 列砖块数 @ start – 最上端行索引 @ end – 底部行索引 @
pitCount – 坑数 @ topPit – 最顶端的坑 @ bottomPit – 最尾部的坑 */ let
wall = [ {count, start, end, pitCount, topPit, bottomPit}, {count,
start, end, pitCount, topPit, bottomPit}, … ];

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
@ count – 列砖块数
@ start – 顶部行索引
@ end – 底部行索引
@ pitCount – 坑数
@ topPit – 最顶部的坑
@ bottomPit – 最底部的坑
*/
let wall = [
{count, start, end, pitCount, topPit, bottomPit},
{count, start, end, pitCount, topPit, bottomPit},
];

这几个模型能够描述墙体的多少个细节:

  • 空列
  • 列的连接空洞
  • 列的非一而再再而三空洞
JavaScript

// 空列 if(count === 0) { ... } // 连续空洞 else if(bottomPit -
topPit + 1 === pitCount) { ... } // 非连续空洞 else { ... }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f3d2c2df29914802382-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f3d2c2df29914802382-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f3d2c2df29914802382-1" class="crayon-line">
// 空列
</div>
<div id="crayon-5b8f3d2c2df29914802382-2" class="crayon-line crayon-striped-line">
if(count === 0) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-3" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-4" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-5" class="crayon-line">
// 连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-6" class="crayon-line crayon-striped-line">
else if(bottomPit - topPit + 1 === pitCount) { 
</div>
<div id="crayon-5b8f3d2c2df29914802382-7" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-8" class="crayon-line crayon-striped-line">
}
</div>
<div id="crayon-5b8f3d2c2df29914802382-9" class="crayon-line">
// 非连续空洞
</div>
<div id="crayon-5b8f3d2c2df29914802382-10" class="crayon-line crayon-striped-line">
else {
</div>
<div id="crayon-5b8f3d2c2df29914802382-11" class="crayon-line">
 ...
</div>
<div id="crayon-5b8f3d2c2df29914802382-12" class="crayon-line crayon-striped-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>

砖块在撤消后,映射到单个列上的空洞会有三种分布形态 —— 接二连三与非延续。

图片 14

「延续空洞」与「非三回九转空洞」的压实进度如下:

图片 15

实际上「空驶列车」放大于墙体上,也许有「空洞」相近的布满形态 ——
三番五次与非接二连三。
图片 16

它的坚实进程与虚空相通,这里就不赘述了。

端点识别

批驳上,通过募集的「色值表」能够直接把端点的坐标记别出来。小编设计的「端点识别算法」分以下2步:

  1. 按像素扫描底图直到遭逢「端点颜色」的像素,步向第二步
  2. 从底图上海消防弭端点并记下它的坐标,重回继续第一步

伪代码如下:

JavaScript

for(let i = 0, len = data.length; i < len; i += 4) { let [r, g, b,
a] = [data[i], data[i + 1], data[i + 2], data[i + 3]]; //
当前像素颜色归属端点 if(isBelongVertex(r, g, b, a)) { // 在 data
中清空端点 vertex = clearVertex(i); // 记录端点音讯vertexes.push(vertext); } }

1
2
3
4
5
6
7
8
9
10
for(let i = 0, len = data.length; i < len; i += 4) {
let [r, g, b, a] = [data[i], data[i + 1], data[i + 2], data[i + 3]];
// 当前像素颜色属于端点
if(isBelongVertex(r, g, b, a)) {
// 在 data 中清空端点
vertex = clearVertex(i);
// 记录端点信息
vertexes.push(vertext);
}
}

But…
上面包车型地铁算法只可以跑无损图。小编在选择了一张手提式有线电话机截屏做测量试验的时候开采,收罗到的「色值表」长度为
5000+ !那直接招致端点和线条的色值无法直接拿到。

通过深入分析,能够窥见「色值表」里超越贰分之一色值都以看似的,也正是在原先的「采撷色值表算法」的根基上增多叁个左近颜色过滤即能够找寻端点和线条的主色。伪代码完成如下:

JavaScript

let lineColor = vertexColor = {count: 0}; for(let clr of clrs) { //
与底色左近,跳过 if(isBelongBackground(clr)) continue; //
线段是多少第二多的水彩,端点是第三多的颜料 if(clr.count >
lineColor.count) { [vertexColor, lineColor] = [lineColor, clr] } }

1
2
3
4
5
6
7
8
9
let lineColor = vertexColor = {count: 0};
for(let clr of clrs) {
// 与底色相近,跳过
if(isBelongBackground(clr)) continue;
// 线段是数量第二多的颜色,端点是第三多的颜色
if(clr.count > lineColor.count) {
[vertexColor, lineColor] = [lineColor, clr]
}
}

取到端点的主色后,再跑贰次「端点识别算法」后居识别出 203
个端点!那是怎么吗?

图片 17

上海体育场面是扩充5倍后的底图局地,紫灰端点的四周和中间充斥着大量噪点(杂色块卡塔尔。事实上在「端点识别」进程中,由于噪点的留存,把本来的端点被分解成十七个或数十二个小端点了,以下是跑过「端点识别算法」后的底图:

图片 18

透过上海体育地方,能够直观地搜查缴获一个定论:识别出来的小端点只在对象(大卡塔尔端点上集聚分布,并且大端点范围内的小端点叠合交错。

假如把叠合交错的小端点归拢成三个多边点,那么这几个大端点将非常左近指标端点。小端点的晤面伪代码如下:

JavaScript

for(let i = 0, len = vertexes.length; i < len – 1; ++i) { let vertexA
= vertexes[i]; if(vertextA === undefined) continue; // 注意这里 j = 0
并不是 j = i +1 for(let j = 0; j < len; ++j) { let vertexB =
vertexes[j]; if(vertextB === undefined) continue; //
点A与点B有增大,点B归总到点A并剔除点B if(isCross(vertexA, vertexB)) {
vertexA = merge(vertexA, vertexB); delete vertexA; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for(let i = 0, len = vertexes.length; i < len – 1; ++i) {
let vertexA = vertexes[i];
if(vertextA === undefined) continue;
// 注意这里 j = 0 而不是 j = i +1
for(let j = 0; j < len; ++j) {
let vertexB = vertexes[j];
if(vertextB === undefined) continue;
// 点A与点B有叠加,点B合并到点A并删除点B
if(isCross(vertexA, vertexB)) {
vertexA = merge(vertexA, vertexB);
delete vertexA;
}
}
}

加了小端点归拢算法后,「端点识别」的正确度就上来了。经小编本地测验已经可以百分百 识别有损的连通图了。

 

3.4 杀绝残砖

上一小节提到了「描述墙体的界限并记下墙体的肤浅」的「列集结」,笔者是直接动用这些「列集合」来解除残砖的,伪代码如下:

JavaScript

function clearAll() { let count = 0; for(let col = 0, len =
this.wall.length; col < len; ++col) { let colInfo = this.wall[col];
for(let row = colInfo.start; row <= colInfo.end; ++row) { let tile =
this.grid[row * this.col + col]; tile.score = -20 – 40 * count++; //
标识奖赏分数 tile.removed = true; } } }

1
2
3
4
5
6
7
8
9
10
11
function clearAll() {
let count = 0;
for(let col = 0, len = this.wall.length;  col < len; ++col) {
let colInfo = this.wall[col];
for(let row = colInfo.start; row <= colInfo.end; ++row) {
let tile = this.grid[row * this.col + col];
tile.score = -20 – 40 * count++; // 标记奖励分数
tile.removed = true;
}
}
}

线条识别

作者分五个步骤实现「线段识别」:

  1. 加以的多少个端点连接成线,并搜聚连线上N个「样板点」;
  2. 遍历样本点像素,假使像素色值不对等线段色值则意味着这多个端点之间不设有线段

如何搜聚「样式点」是个问题,太密集会影响属性;太疏松精准度无法作保。

在小编前面有四个接收:N 是常量;N 是变量。
假设 N === 5。局地提取「样式点」如下:

图片 19

上海体育场合,会识别出三条线条:AB, BC 和 AC。而实在,AC不可能成线,它只是因为
AB 和 BC 视觉上共一线的结果。当然把 N 值向上提升能够缓慢解决那么些难点,可是 N
作为常量的话,这一个常量的取量须要靠涉世来判定,果然遗弃。

为了制止 AB 与 BC 同处平素线时 AC 被辨认成线段,其实很简单 ——
多少个「样品点」的间距小于或等于端点直径
假设 N = S / (2 * R),S 表示两点的离开,科雷傲代表端点半径。局地提取「样式点」如下:

图片 20

如上海体育地方,成功地绕过了 AC。「线段识别算法」的伪代码完结如下:

JavaScript

for(let i = 0, len = vertexes.length; i < len – 1; ++i) { let {x: x1,
y: y1} = vertexes[i]; for(let j = i + 1; j < len; ++j) { let {x:
x2, y: y2} = vertexes[j]; let S = Math.sqrt(Math.pow(x1 – x2, 2) +
Math.pow(y1 – y2, 2)); let N = S / (R * 2); let stepX = (x1 – x2) / N,
stepY = (y1 – y2) / n; while(–N) { // 样品点不是线段色
if(!isBelongLine(x1 + N * stepX, y1 + N * stepY)) break; } //
样板点都合格 —- 表示两点成线,保存 if(0 === N) lines.push({x1, y1, x2,
y2}) } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(let i = 0, len = vertexes.length; i < len – 1; ++i) {
let {x: x1, y: y1} = vertexes[i];
for(let j = i + 1; j < len; ++j) {
let {x: x2, y: y2} = vertexes[j];
let S = Math.sqrt(Math.pow(x1 – x2, 2) + Math.pow(y1 – y2, 2));
let N = S / (R * 2);
let stepX = (x1 – x2) / N, stepY = (y1 – y2) / n;
while(–N) {
// 样本点不是线段色
if(!isBelongLine(x1 + N * stepX, y1 + N * stepY)) break;
}
// 样本点都合格 —- 表示两点成线,保存
if(0 === N) lines.push({x1, y1, x2, y2})
}
}

 2、查询7号课程成绩在90分以上或60分以下的学子学号。

4. View

View 主要的职能有五个:

  • UI 管理
  • 映射 Model 的变化(动画)

UI
处理注重是指「分界面绘制」与「财富加载处理」,这两项成效比较宽泛本文就直接略过了。View
的核心是「映射 Model
的转换」并达成对应的卡通。动漫是错落有致的,而映射的准则是大约的,如下伪代码:

JavaScript

update({originIndex, index, clr, removed, score}) { // 还尚未originIndex 或未有色值,直接不管理 if(originIndex === undefined || clr
=== undefined) return ; let tile = this.tiles[originIndex]; // tile
存在,推断颜色是还是不是相像 if(tile.clr !== clr) { this.updateTileClr(tile,
clr); } // 当前目录变化 —– 表示地点也可能有变化 if(tile.index !== index)
{ this.updateTileIndex(tile, index); } // 设置分数 if(tile.score !==
score) { tile.score = score; } if(tile.removed !== removed) { //
移除或足够当前节点 true === removed ? this.bomb(tile) :
this.area.addChild(tile.sprite); tile.removed = removed; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
update({originIndex, index, clr, removed, score}) {
// 还没有 originIndex 或没有色值,直接不处理
if(originIndex === undefined || clr === undefined) return ;
let tile = this.tiles[originIndex];
// tile 存在,判断颜色是否一样
if(tile.clr !== clr) {
this.updateTileClr(tile, clr);
}
// 当前索引变化 —– 表示位置也有变化
if(tile.index !== index) {
this.updateTileIndex(tile, index);
}
// 设置分数
if(tile.score !== score) {
tile.score = score;
}
if(tile.removed !== removed) {
// 移除或添加当前节点
true === removed ? this.bomb(tile) : this.area.addChild(tile.sprite);
tile.removed = removed;
}
}

Model 的砖头每一回数据的改良都会布告到 View 的砖头,View
会根据对应的变化做相应的动作(动漫卡塔 尔(阿拉伯语:قطر‎。

个性优化

是因为「自动识图」须求对图像的的像素点举办围观,那么品质确实是个须要关爱的难点。作者设计的「自动识图算法」,在辨别图像的进程中供给对图像的像素做两遍扫描:「收罗色值表」
与 「搜集端点」。在扫描次数上实际很难下落了,但是对于一张 750 * 1334
的底图来讲,「自动识图算法」要求遍历两次长度为
750 * 1334 * 4 = 4,002,000
的数组,压力还是会有的。作者是从压缩被围观数组的尺码来进步质量的。

被围观数组的尺寸怎么裁减?
小编直接通过降低画布的尺码来达成减少被扫描数组尺寸的。伪代码如下:

JavaScript

// 要削减的翻番 let resolution = 4; let [width, height] = [img.width
/ resolution >> 0, img.height / resolution >> 0];
ctx.drawImage(img, 0, 0, width, height); let imageData =
ctx.getImageData(), data = imageData;

1
2
3
4
5
// 要压缩的倍数
let resolution = 4;
let [width, height] = [img.width / resolution >> 0, img.height / resolution >> 0];
ctx.drawImage(img, 0, 0, width, height);
let imageData = ctx.getImageData(), data = imageData;

把源图片缩短4倍后,获得的图片像素数组唯有原来的
4^2 = 16倍。那在质量上是比很大的升迁。

Select sno from sc where cno=’7′ and grade
not between 60and 90

5. Control

Control 要拍卖的业务超级多,如下:

  • 绑定 Model & View
  • 改换通过海关分值
  • 剖断通过海关条件
  • 对外交事务件
  • 顾客人机联作

初叶化时,Control 把 Model 的砖头单向绑定到 View 的砖块了。如下:

Object.defineProperties(model.tile, { originIndex: { get() {…}, set(){
… view.update({originIndex}) } }, index: { get() {…}, set() { …
view.update({index}) } }, clr: { get() {…}, set() { …
view.update({clr}) } }, removed: { get() {…}, set() { …
view.update({removed}) } }, score: { get() {…}, set() { …
view.update({score}) } } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Object.defineProperties(model.tile, {
    originIndex: {
        get() {…},
        set(){
            …
            view.update({originIndex})
        }
    },  
    index: {
        get() {…},
        set() {
            …
            view.update({index})
        }
    },
    clr: {
        get() {…},
        set() {
            …
            view.update({clr})
        }
    },
    removed: {
        get() {…},
        set() {
            …
            view.update({removed})
        }
    },  
    score: {
        get() {…},
        set() {
            …
            view.update({score})
        }
    }
})
 

「通过海关分值」与「判别通过海关条件」这对逻辑在本文的「游戏法规」中有连锁介绍,这里不再赘言。

对外交事务件规划如下:

name detail
pass 通关
pause 暂停
resume 恢复
gameover 游戏结束

客商交互作用 APIs 规划如下:

name type deltail
init method 初始化游戏
next method 进入下一关
enter method 进入指定关卡
pause method 暂停
resume method 恢复
destroy method 销毁游戏

选择「自动识图」的建议

固然小编在地面测验的时候能够把装有的「底图」识别出来,不过并无法保险其余开辟者上传的图片是还是不是被很好的甄别出来。小编建议,能够把「自动识图」做为多少个独自的工具使用。

笔者写了二个「自动识图」的独立工具页面:
能够在此个页不熟稔成对应的关卡配置。

 

6. 问题

在乐乎有四个关于「消亡星星」的话题:popstar关卡是怎么希图的?

以此话题在最后提议了三个主题材料 ——
「不恐怕清除和最大得分不满意过关条件的矩阵」

图片 21

「不或许排除的矩阵」其实就是最大得分为0的矩阵,本质上是「最大得分不满意过关条件的矩阵」。

最大得分不满意过关条件的矩阵
求「矩阵」的最大得分是三个「马鞍包难点」,求解的算法简单:对当下矩阵用「递归」的款式把持有的肃清分支都执行二回,并取最高分值。不过javascript 的「递归」极易「栈溢出」招致算法无法实践。

实质上在腾讯网的话题中涉嫌叁个缓和方案:

互连网查到有程序提议做个工具随便生成关卡,自动测算,把相符得分条件的卡子筛选出来

这几个建设方案代价是昂贵的!小编提供有源码并未消除那么些标题,而是用贰个比较取巧的法子:进去游玩前检查是事为「无法消除矩阵」,假使是重复生成关卡矩阵

小心:小编使用的取巧方案并未缓慢解决难点。

结语

上面是本文介绍的「一笔画」的线上
DEMO 的二维码:

图片 9

13日游的源码托管在:
个中玩耍完成的着入眼代码在:
自行识图的代码在:

感激恒心阅读完本小说的读者。本文仅代表小编的个人观点,如有不妥之处请多多支持。

感激您的读书,本文由 坑坑洼洼实验室
版权全体。假如转发,请注解出处:凹凸实验室()

1 赞 1 收藏
评论

图片 23

 3、查询课程名以“数据”四个字开端的持有课程的课程号和课程名。

7. 结语

下边是本文介绍的「撤销星星」的线上 DEMO 的二维码:

图片 24

游戏的源码托管在:

谢谢耐烦阅读完本小说的读者。本文仅表示小编的个人观点,如有不妥之处请多多支持。
要是对「H5游戏开荒」感兴趣,款待关心大家的专栏。

Select cno,cname from c where cname like
‘数据%’

仿效资料

  • Knapsack problem
  • NP-completeness
  • popstar关卡是哪些安插的?
  • 费雪耶兹乱序算法
  • 兵荒马乱均分算法

    1 赞 收藏
    评论

图片 23

 

 4、查询各类学员具备科指标平分战表,输出学子学号和平均成绩。

    Select sno,avg(grade)from sc group by
sno

 5、查询每门学科的选修人数,输出课程号和选修人数。

    Selectcno,count(*) from sc group by
cno

 6、查询选修7号课程的学员的学号、姓名、性别。

    Selects.sno,sname,ssex from s,sc where
s.sno=sc.sno and cno=’7′

    或: Select sno,sname,ssex from s
where sno in

              ( Select sno from sc where
cno=’7′ )

 7、查询选修7号课程的学童的平均年龄。

    Selectavg(sage) from s,sc where
s.sno=sc.sno and cno=’7′

    或: Select avg(sage) from s where sno
in

              (Select sno from sc where
cno=’7′ )

 8、查询有30名以上学子选修的课程号。

    Select cno fromsc group by cno having
count(*)>30

 9、查询于今从没考试不如格的学子学号。

    Select distinctsno from sc where sno
not in

         ( Select sno from sc where
grade<60 )

    或: Select sno from sc group by sno
havingmin(grade)>=60

10、查询全部考试成绩的平均分相似的上学的小孩子学号分组

二、

 1、寻找选修课程号为C2的学习者学号与成就。

Select sno,grade from sc where
cno=’C2′

 

 2、寻找选修课程号为C4的学生学号与姓名。

    Selects.sno,sname from s,sc where
s.sno=sc.sno and cno=’C4′

    注意本题也得以用嵌套做

思忖本题改为“找寻选修课程号为C4的学习者学号、姓名与成就”后还是能用嵌套做呢?

 

 3、寻找选修课程名称为 Maths
的上学的小孩子学号与姓名。

    Selects.sno,sname from s,sc,c

    where  s.sno=sc.sno and c.cno=sc.cno
andcname=’Maths’

静心本题也能够用嵌套做

 

 4、搜索选修课程号为C2或C4的学习者学号。

    Select distinctsno from sc where cno
in (‘C2′,’C4’)

或: Select distinct sno from sc where
cno=’C2′ or cno=’C4′

 

 5、搜索选修课程号为C2和C4的学员学号。

    Select sno fromsc where cno=’C2′ and
sno in

         ( Select sno from sc where
cno=’C4′ )

    注意本题也能够用三番三次做

思考:Select distinct sno from sc where
cno=’C2′ andcno=’C4’正确吗?

 

 6、搜索不学C2课程的上学的小孩子姓名和年龄。

    Selectsname,sage from s where sno not
in

         ( Selectsno from sc where
cno=’C2′ )

    或: Select sname,sage from s where
not exists

              (Select * from sc where
sno=s.sno and cno=’C2′ )

 

 7、寻找选修了数据库课程的装有学子姓名。(同3)

    Select snamefrom s,sc,c

where  s.sno=sc.snoand c.cno=sc.cno and
cname=’数据库’

 

 8、搜索数据库课程不如格的女人姓名。

    连接:Select sname from s,sc,c

         where  s.sno=sc.sno
andc.cno=sc.cno and cname=’数据库’

                and grade<60 and
ssex=’女’

    嵌套:Select sname from s where
ssex=’女’ and  sno in

               (Select sno from sc where
grade<60 and cno in

                     ( Select cno from c
where cname=’数据库’ )

               )

 

 9、寻觅各门课程的平分战绩,输出课程名和平均战表。

    Selectcname,avg(grade) from
sc,c

    wherec.cno=sc.cno  group by
c.cno,cname

研究本题也得以用嵌套做吧?

 

10、寻觅各种学子的平均战表,输出学子姓名和平均成绩。

    Selectsname,avg(grade) from
s,sc

    wheres.sno=sc.sno group by
s.sno,sname

思忖本题也得以用嵌套做呢?

 

11、找寻足足有二十六个学子选修的课程名。

    Select cnamefrom c where cno in

         ( Selectcno from sc group by cno
having count(*)>=30 )

专心本题也得以用延续做

 

12、寻找选修了不菲于3门科指标学子姓名。

    Select snamefrom s where sno in

         ( Selectsno from sc group by sno
having count(*)>=3 )

注意本题也足以用三番五次做

 

13、找寻各门课程的大成均不低于90分的上学的小孩子姓名。

   Select snamefrom s,sc where
s.sno=sc.sno

         group bys.sno,sname having
min(grade)>=90

方法二:

Select sname from s where sno not
in

         ( Selectsno from sc where
grade<90 )

假诺有一门不低于90分就能够输出该学员学号

 

14、寻找数据库课程战绩不低于该门课程平均分的学习者姓名。

    Select snamefrom s,sc,c

    where  s.sno=sc.sno and sc.cno=c.cno
and cname=’数据库’ and grade>

         ( Selectavg(grade) from
sc,c

           where sc.cno=c.cnoand
cname=’数据库’

         )

15、搜索各类系科男女学子的平均年龄和人数。

    Selectsdept,ssex,avg(sage),count(*)
from s group by sdept,ssex

16、找寻计算机系(JSJ)课程平均分最高的学习者学号和人名。

    Selects.sno,sname from s,sc where
s.sno=sc.sno and sdept=’JSJ’

    group bys.sno,sname

    havingavg(grade) >=ALL

         ( Selectavg(grade) from
s,sc

           wheres.sno=sc.sno and
sdept=’JSJ’

           group bys.sno

         )

17、(补充)查询每门课程的及格率。

    本题能够分三步做:

   

    第1步:获得每门课的选修人数

     createview  v_all(cno,cnt)

         as selectcno, count(*) from sc
group by cno

    第2步:获得每门课及格人数

     createview 
v_pass(cno,cnt_pass)

         as selectcno, count(*) from sc
where grade>=60 group by cno

   
第3步:每门课的合格人数/每门课选修人数

     selectv_all.cno, cnt_pass*100/cnt 
from  v_all, v_pass

     where v_all.cno = v_pass.cno

 

18、查询平均分比不上格的学习者的学号,姓名,平均分。

    Selectsc.sno,sname,avg(grade) from
student,sc

    wherestudent.sno=sc.sno

    group bysc.sno,sname

    havingavg(grade)<60

构思本题也能够用嵌套做呢?

 

19、查询平均分不比格的学员人数。

    Select count(*)from student

    where sno in

         ( selectsno from sc group by sno
having avg(grade)<60 )

    下边是一个优越的谬误

Select count(*) from sc group by sno
havingavg(grade)<60

那是各样学子有几门不比格的数码

 

三、

 1、查询薪金在1000到3000元之间的男人业务员的全名和办公室编号。

    SelectYname,Ono from YWY

    where Salarybetween 1000 and 3000 and
Ysex=’男’

 2、查询各样办公室的业务员人数,输出办公室编号和呼应的食指。

    SelectOno,count(*) from YWY group by
Ono

 3、查询各个顾客在二〇〇四年三月进货的总金额,输出客商号和相应的总金额。

    SelectKno,sum(Fmoney) from FP

    where Fdatebetween ‘2002.5.1’ and
‘2002.5.31’

    group by Kno

 4、查询二零零二年7月进货次数超越5次的富有顾客号,且按客商号升序排序。 

    Select Kno fromFP

    where Fdatebetween ‘2002.5.1’ and
‘2002.5.31’

    group by Kno

    havingcount(*)>5

    order by KnoASC

 5、查询各办公室男人和女人业务员的平均工资。

    SelectOno,Ysex,avg(Salary) from YWY
group by Ono,Ysex

 6、查询二零零零年3月早已在王海亮业务员手中购得过商品的顾客号、

            客商姓名和联系电话。

    SelectKno,Kname,Phone from KH where
Kno in

         ( SelectKno from FP

           whereFdate between ‘2002.5.1’
and ‘2002.5.31’ and Yno in

                      ( Select Yno from
YWY where Yname=’王海亮’ )

         )

    注意本题也能够用一而再三番五次做

 7、查询全部报酬比1538号业务员高的业务员的号子、姓名和报酬。

    SelectYno,Yname,Salary from YWY where
Salary >

         ( SelectSalary from YWY where
Yno=’1538′ )

 8、查询全数与1538号业务员在同多个办公的此外业务员的号子和人名。

    SelectYno,Yname from YWY where
Yno!=’1538′ and Ono in

         ( SelectOno from YWY where
Yno=’1538′ )

 9、查询出卖总金额最高的业务员的编号。

    Select Yno fromFP group by Yno having
sum(Fmoney) >=ALL

         ( Selectsum(Fmoney) from FP group
by Yno )

10、查询全体业务员的号码、姓名、薪俸甚至薪水比她高的其余业务员的平均薪酬。

    动用自连接

   
SelectY1.Yno,Y1.Yname,Y1.Salary,avg(Y2.Salary)

    from   YWY Y1, YWY Y2

    where  Y1.Salary < Y2.Salary

    group by  Y1.Yno  

 

四、

 1、寻找各类班级的班级代码、学子人数、平均战表。

    SelectBJDM,count(*),avg(CJ) from SC
group by BJDM

 2、搜索各种学员的班级代码、学子姓名、考试科目数、总成绩。

    SelectBJDM,XSXM,count(*),sum(CJ) from
SC

    group byBJDM,BNXH,XSXM

 3、输出一张表格,每位学子对应一条记下,包罗字段:

         
班级代码、学生姓名、语文成绩、数学成绩、外语战表。

   
SelectSC1.BJDM,SC1.XSXM,SC1.CJ,SC2.CJ,SC3.CJ

    from  SC SC1, SC SC2, SC SC3

    whereSC1.BJDM=SC2.BJDM and
SC1.BNXH=SC2.BNXH and

         SC2.BJDM=SC3.BJDM and
SC2.BNXH=SC3.BNXH and

          SC1.KM=’语文’ and SC2.KM=’数学’
and SC3.KM=’外语’

 4、输出一张表格,有实际业绩低于60分的每位学子对应一条记下,包罗字段:

         
班级代码、学子姓名、最低战表。

    SelectBJDM,XSXM,min(CJ) from SC

    where  CJ<60 group by
BJDM,BNXH,XSXM

    或:  SelectBJDM,XSXM,min(CJ) from
SC

          group byBJDM,BNXH,XSXM

          havingmin(CJ)<60

 5、输出一张表格,有成就低于60分的各位学子对应一条记下,满含字段:

         
班级代码、学子姓名、最高战表、平均战绩。

    SelectBJDM,XSXM,max(CJ) from SC

    group byBJDM,BNXH,XSXM

    havingmin(CJ)<60

    请酌量下列做法是不是科学:

          SelectBJDM,XSXM,max(CJ),avg(CJ)
from SC

         where  CJ<60 group
byBJDM,BNXH,XSXM

 6、输出一张表格,全部成绩都非常的大于60分的每位学生对应一条记下,包罗字段:

         
班级代码、学生姓名、平均战绩。

    SelectBJDM,XSXM,avg(CJ) from SC

    group by BJDM,BNXH,XSXM

    havingmin(CJ)>=60

 7、输出一张表格,每一位学子对应一条记下,满含字段:

         
班级代码、学子姓名、去掉四个低于分后的平分成绩。

   
SelectBJDM,XSXM,(sum(CJ)-min(CJ))/(count(*)-1) from SC

    group byBJDM,BNXH,XSXM

 8、输出一张表格,每门科目对应一条记下,包罗字段:

         
科目、去掉二个低于分后的平分成绩。

    Select
KM,(sum(CJ)-min(CJ))/(count(*)-1)from SC

    group by KM

 

 

 

        实验辅导中“八 SQL查询语句”
的答案

 

 1、查询年龄在19至23岁期间的女人的学号,姓名,年龄,按年龄从大到小排列。

    Selectsno,sname,sage from
student

    where sagebetween 19 and 21 and
ssex=’女’

    order by sagedesc

 2、查询姓名中有“明”字的学员人数。

    Select count(*)from student

    where snamelike “%明%”

 3、查询1001科目未有成绩的学习者的学号。

    Select sno fromsc where cno=’1001′ and
grade is null

 4、查询JSJ、SX、WL系的学子学号,姓名,结果按系及学号排列。

    Selectsno,sname,sdept from
student

    where sdept in( ‘JSJ’, ‘SX’, ‘WL’
)

    order bysdept,sno

 5、总括每一门课的总分、平均分,最高分、最低分。

   
Selectcno,sum(grade),avg(grade),max(grade),min(grade)

    from sc

    group by cno

 6、查询平均分当先90分的男学生学号及平均分。

    连接:

    selectsc.sno,avg(grade) from
student,sc

    wherestudent.sno=sc.sno and
ssex=’男’

    group by sc.sno

    havingavg(grade)>90

    嵌套:

    selectsno,avg(grade) from sc

    where sno in (select sno from student
where ssex=’男’)

    group by sno

    havingavg(grade)>90

 7、查询选修课程超越2门的学童姓名。

    select snamefrom student,sc

    where student.sno=sc.sno

    group bysc.sno,sname

    havingcount(*)>2

    本题也足以用嵌套做

 8、查询 JSJ 系的上学的儿童选修的课程号。

    Select distinctcno from
student,sc

    where  student.sno=sc.sno and
sdept=’JSJ’

    本题也得以用嵌套做

 9、查询选修1002学科的学习者的学习者姓名(用一而再和嵌套2种办法)

    连接:Select sname from student,sc

          wherestudent.sno=sc.sno and
cno=’1002′

    嵌套:Select sname from student where
sno in

              (select sno from sc where
cno=’1002′ )

10、查询学子姓名以至他选修课程的课程号及成绩。

    Selectsname,cno,grade from
student,sc

    wherestudent.sno=sc.sno

    考虑本题也能够用嵌套做啊?

11、查询选修“数据库原理”课且成绩 80
以上的上学的小孩子姓名(用一而再接二连三和嵌套2种形式)

    连接:Select sname from
student,sc,course

          wherestudent.sno=sc.sno and
sc.cno=course.cno and

               cname=’数据库原理’ and
grade>80

    嵌套:Select sname from student where
sno in 

               (select sno from sc where
grade>80 and cno in 

                    ( select cno from
course where cname=’数据库原理’ )

               )

 

14、查询未有选修1002课程的上学的儿童的上学的儿童姓名。

    Select snamefrom student

    where sno notin ( select sno from sc
where cno=’1002′)