来一盘紧张而又刺激的五子棋:自带注释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
img {
border: 0;
}
ol,
ul,
li {
list-style: none;
}
#frame {
width: 1000px;
height: 1000px;
margin: 100px auto;
border: 5px solid #333;
background: #fdda9c;
position: relative;
overflow: hidden;
}
#Board {
width: 1050px;
height: 1050px;
position: absolute;
top: -25px;
left: -25px;
}
.cBefore {
width: 100%;
height: 100%;
position: absolute;
background: rgba(0, 0, 0, 0.2);
z-index: 10;
}
.cButt {
width: 100px;
height: 200px;
position: absolute;
left: 50%;
top: 50%;
margin: -120px 0 0 -90px;
background: #fff;
padding: 20px 40px;
}
.cButt input {
width: 100px;
height: 50px;
margin: 5px 0;
border-radius: 5px;
}
#Board li {
width: 50px;
height: 50px;
position: relative;
float: left;
}
#Board li::before {
content: "";
width: 100%;
position: absolute;
border-bottom: 1px solid #333;
top: 50%;
left: 0;
}
#Board li::after {
content: "";
height: 100%;
position: absolute;
border-right: 1px solid #333;
top: 0;
left: 50%;
}
#Board li span {
display: block;
width: 46px;
height: 46px;
position: absolute;
background: #000000;
top: 2px;
left: 2px;
border-radius: 50%;
z-index: 9;
}
/* #aaaa {
width: 500px;
height: 50px;
} */
</style>
</head>
<script>
window.onload = function fnGobang() {
var oWasp = document.getElementById("frame");
var oBoard = document.createElement("ul");
oBoard.id = "Board";
oWasp.appendChild(oBoard);
/*每个棋格的尺寸*/
var gridSize = 50;
/*计算棋格数量,具体公式为 容器边长/棋格尺寸*/
var W = oBoard.offsetWidth / gridSize; //行
var H = oBoard.offsetWidth / gridSize; //列
/*定义黑白子数组*/
var arrBlack = [];
var arrWhite = [];
/*定义黑白子判定,Pass作为交换空间,排序用*/
var Pass = 0;
var noPass = false;
var S = R = L = 1;
/*一行一行画棋盘线*/
for (var i = 0; i < W * H; i++) {
var cGrid = document.createElement("li");
oBoard.appendChild(cGrid);
}
/*获取下一级的li对象,形成一个数组,方便取值*/
var oGoard = oBoard.getElementsByTagName("li");
for (var i = 0; i < oGoard.length; i++) {
oGoard[i].index = i;
oGoard[i].onclick = function () {
/*棋子添加逻辑:如果没有子元素。则添加棋子span;以防止同一坐标添加多个对象*/
if (!this.childNodes[0]) {
/*定义span,表示棋子,默认样式是黑色*/
var cPieces = document.createElement("span");
/*判断棋子类型,并添加如棋子数组中,并将数组排序,以便后续判定*/
/*如果是白子,则将颜色转换呈白色白色*/
if (noPass) {
arrWhite.push(this.index)
cPieces.style.background = "#fff"
sort(arrWhite, Pass)
fnWin(arrWhite, "白棋胜!");
} else {
arrBlack.push(this.index)
sort(arrBlack, Pass)
fnWin(arrBlack, "黑棋胜!")
}
this.appendChild(cPieces);
/*排序方法,成立的前提是原本的数组是有序的,且从小到大*/
function sort(arr, pa) {
for (var j = arr.length; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
pa = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = pa;
}
}
}
/*胜利判定函数*/
function fnWin(arr, str) {
if (arr.length >= 5) {
for (var j = 0; j < arr.length; j++) { //alert(j)
/*横:共5种情况0xxxx x0xxx xx0xx xxx0x xxxx0
由于数组是排序过的,因此,只需做两步,连续4个和判定边界
所谓边界判定,即上下两行由于下表是连续的,因此需要排除此类5子分别位于上下两行的情况情况
边界判定原理为:后四个子出现在新一行第一个不能判定胜利
*/
console.log(arr)
if ((arr[j + 4] - arr[j] == 4) && ( arr[j+1]%W!=0) && ( arr[j+2]%W!=0) && ( arr[j+3]%W!=0)&& ( arr[j+4]%W!=0)){
alertWin(str)
}
for (var k = j + 1; k < arr.length; k++) {
/*纵 情况类似,也只需"连续"+边界
此时的连续是隔行连续
边界判定原理:数组中存在想减为S*W的元素,其中S为连子数量
*/
if (arr[k] - arr[j] === S * W) {
if (S == 4) {
alertWin(str+"纵")
S = 1;
break;
} else {
S++
}
}
/*左斜 情况类似,也只需"连续"+边界
此时的连续是隔行连续
边界判定原理:数组中存在想减为S*(W-1)的元素
其中S为连子数量,每隔一行,下标与正下方的点多差上1
*/
if (arr[j] % W >= 4) {
if (arr[k] - arr[j] === L * (W - 1)) { //左斜
if (L == 4) {
alertWin(str+"左斜")
L = 1;
break;
} else {
L++
}
}
}
/*右斜 情况类似,也只需"连续"+边界
此时的连续是隔行连续
边界判定原理:数组中存在想减为S*(W+1)的元素,
其中S为连子数量,每隔一行,下标与正下方的点多多上1
*/
if (W-(arr[j] % W) >5-S) {
if (arr[k] - arr[j] === R * (W + 1)) {
if (R == 4) {
alertWin(str+"右斜")
R = 1;
break;
} else {
R++
}
}
}
}
/*判定条件恢复初始化*/
S = L = R = 1;
}
}
}
/*黑白棋子攻守转换*/
noPass = !noPass;
}
}
}
function alertWin(a) { //结束
var cBefore = document.createElement("div");
cBefore.className = "cBefore";
var cButt = document.createElement("div");
cButt.className = "cButt";
for (var i = 0; i < 3; i++) { //按钮
var cButton = document.createElement("input");
cButton.type = "button"
cButt.appendChild(cButton)
}
var oButt = cButt.getElementsByTagName("input");
oButt[0].value = a;
oButt[0].style.cssText = "background:none;border:none;"
oButt[1].value = "重新开始";
oButt[2].value = "返回游戏";
for (var i = 1; i < 3; i++) {
oButt[i].index = i;
oButt[i].onclick = function () {
if (this.index == 2) {
cBefore.removeChild(cButt);
cBefore.style.background = "rgba(0,0,0,0)"
} else {
frame.removeChild(oBoard);
fnGobang()
}
}
}
cBefore.appendChild(cButt);
oBoard.appendChild(cBefore);
}
}
</script>
<body>
<div id="frame">
<ul id="Board">
</ul>
</div>
<!-- <div id="aaaa">
</div> -->
</body>
</html>