已经一年没写前端代码了,手生得很,为了上班划水,三天写了个空当接龙游戏
兼容现代浏览器
free-cell
css
free-cell.css
img
存放图片素材(图片素材已上传至下载资源)
js
free-cell.js
free-cell.html
num-color-type.png
num–数字(1 - 13)
color–颜色(1-红色 2-黑色)
type–类型(1–红心 2-黑桃 3-梅花 4-方块)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>空当接龙</title>
<link rel="stylesheet" type="text/css" href="css/free-cell.css">
</head>
<body>
<div class="container">
<div class="menu"><span id="re-init" class="re-init">重新开始</span></div>
<div class="top-panel">
<div id="top-left-panel" class="top-left-panel">
<div class="top-left-cell"><div class="top-cell" data-index="0"></div></div>
<div class="top-left-cell"><div class="top-cell" data-index="1"></div></div>
<div class="top-left-cell"><div class="top-cell" data-index="2"></div></div>
<div class="top-left-cell"><div class="top-cell" data-index="3"></div></div>
</div>
<div id="top-right-panel" class="top-right-panel">
<div class="top-right-cell"><div class="top-cell"></div></div>
<div class="top-right-cell"><div class="top-cell"></div></div>
<div class="top-right-cell"><div class="top-cell"></div></div>
<div class="top-right-cell"><div class="top-cell"></div></div>
</div>
<div class="king-panel">
<div class="king pri-king"></div>
<div class="king sec-king"></div>
<div class="king sec-king"></div>
<div class="king pri-king"></div>
</div>
</div>
<div class="splitter"></div>
<div id="bottom-panel" class="bottom-panel">
<div class="bottom-cell bottom-cell-1" data-index="0"></div>
<div class="bottom-cell bottom-cell-2" data-index="1"></div>
<div class="bottom-cell bottom-cell-3" data-index="2"></div>
<div class="bottom-cell bottom-cell-4" data-index="3"></div>
<div class="bottom-cell bottom-cell-5" data-index="4"></div>
<div class="bottom-cell bottom-cell-6" data-index="5"></div>
<div class="bottom-cell bottom-cell-7" data-index="6"></div>
<div class="bottom-cell bottom-cell-8" data-index="7"></div>
</div>
</div>
</body>
<script type="text/javascript" src="js/free-cell.js"></script>
</html>
.container {margin: auto;width: 1020px;height: 600px;background: #00AA00;overflow-x: hidden;overflow-y: scroll}
.menu {height: 30px;background: #D0CECC;position: relative;z-index: 4;padding-left: 8px;}
.re-init {line-height: 30px;font-size: 16px;cursor: pointer;
-webkit-user-select: none;-ms-user-select: none;user-select: none;}
.top-panel {position: relative;height: 160px;}
.top-left-panel {position: absolute;top: 0;left: 10px;width: 450px;height: 160px;}
.top-left-cell {
float: left;margin: 10px 0 0 10px;height: 140px;width: 100px;
background: url("../img/back-face-top.png") no-repeat;background-size: 100% 100%;}
.top-right-panel {position: absolute;top: 0;right: 10px;width: 450px;height: 160px;}
.top-right-cell {float: right;margin: 10px 10px 0 0;height: 140px;width: 100px;
background: url("../img/back-face-top.png") no-repeat;background-size: 100% 100%;}
.top-cell {position: relative;top: -26px;left: 0;height: 140px;width: 100px;}
.king-panel {position: absolute;width: 50px;height: 50px;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}
.king {float: left;width: 50%;height: 50%;border: 1px outset #009900;opacity: 0.9;
-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
.pri-king {background: url("../img/pri-king.png") no-repeat center;background-size: cover;}
.sec-king {background: url("../img/sec-king.png") no-repeat center;background-size: cover;}
.splitter {margin: auto;width: 960px;height: 1px;background: #80d079;}
.bottom-panel {
position: relative;margin: 10px auto 0 auto;width: 960px;height: 600px;}
.bottom-cell {
position: absolute;top: 0;height: 140px;width: 100px;
background: url("../img/back-face-bottom.png") no-repeat;background-size: 100% 100%;}
.bottom-cell > .cell-container {margin-top: -26px;}
.bottom-cell-1 {left: 10px;}
.bottom-cell-2 {left: 130px;}
.bottom-cell-3 {left: 250px;}
.bottom-cell-4 {left: 370px;}
.bottom-cell-8 {right: 10px;}
.bottom-cell-7 {right: 130px;}
.bottom-cell-6 {right: 250px;}
.bottom-cell-5 {right: 370px;}
.cell-container {position: absolute;top: 26px;left: 0;height: 140px;width: 100px;z-index: 0;}
.cell-body {
position: absolute;top: 0;left: 0;height: 140px;width: 100px;
-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;
border: 1px solid #D0CECC;border-radius: 4px;background-size: 100% 100%;
background-repeat: no-repeat;z-index: 0;}
#cell-1 > .cell-body {background-image: url("../img/1-1-1.png");}
#cell-2 > .cell-body {background-image: url("../img/2-2-2.png");}
#cell-3 > .cell-body {background-image: url("../img/5-1-4.png");}
#cell-4 > .cell-body {background-image: url("../img/6-1-1.png");}
#cell-5 > .cell-body {background-image: url("../img/7-2-3.png");}
#cell-6 > .cell-body {background-image: url("../img/10-2-2.png");}
#cell-7 > .cell-body {background-image: url("../img/12-1-4.png");}
#cell-8 > .cell-body {background-image: url("../img/13-1-1.png");}
.layer {
position: absolute;top: 26px;left: 0;height: 140px;width: 100px;z-index: 2;display: none;
-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;
border: 2px solid #77cfd0;box-shadow:rgb(11, 234, 235) 0 0 12px inset;}
(function () {
function Cell(num, color, type) {
this.num = num;
this.color = color;
this.type = type;
this.dom = (function (window) {
var cellContainer = window.document.createElement('div');
cellContainer.className = 'cell-container';
var cellBody = window.document.createElement('div');
cellBody.className = 'cell-body';
cellBody.setAttribute('data-num', num);
cellBody.setAttribute('data-color', color);
cellBody.setAttribute('data-type', type);
cellBody.style.cssText = 'background-image: url("img/' + num + '-' + color + '-' + type + '.png");';
cellContainer.appendChild(cellBody);
return cellContainer;
})(window);
}
var ver = 26;
var param = {
topLeftCells: [null, null, null, null],
topRightCells: [[], [], [], []],
bottomCells: [[], [], [], [], [], [], [], []]
};
var topLeftCellDoms = window.document.querySelectorAll('#top-left-panel .top-cell');
var topRightCellDoms = window.document.querySelectorAll('#top-right-panel .top-cell');
var bottomCellDoms = window.document.querySelectorAll('#bottom-panel .bottom-cell');
var bottomPanel = window.document.querySelector('#bottom-panel');
var topLeftPanel = window.document.querySelector('#top-left-panel');
var reInitButton = window.document.querySelector('#re-init');
var layer = (function (window) {
var layer = window.document.createElement('div');
layer.className = 'layer';
return layer;
})(window);
reInitButton.addEventListener('click', (function () {
var startTime = +new Date();
return function (e) {
var now = + new Date();
if (now - startTime > 1500) {
startTime = now;
reInit();
}
}
})());
init();
bottomPanel.addEventListener('dblclick', function (e) {
e.preventDefault();
var target = e.target;
var parent = null;
if (target.classList.contains('cell-body')) {
parent = target.parentNode;
} else if (target.classList.contains('cell-container')) {
parent = target;
target = parent.childNodes[0];
}
if (parent == null) {
return;
}
var bottomIndex = getIndexInBottomCellsFirst(parent);
if (bottomIndex < 0) {
return;
}
var cell = param.bottomCells[bottomIndex][0];
var topRightIndex = getIndexInTopRightCells(cell);
if (topRightIndex >= 0) {
param.bottomCells[bottomIndex].shift();
param.topRightCells[topRightIndex].unshift(cell);
topRightCellDoms[topRightIndex].appendChild(cell.dom);
if (gameOverOrRun()) {
autoMoveToTopRight();
}
} else {
var topLeftIndex = getIndexInNullTopLeftCells();
if (topLeftIndex < 0) {
return;
}
param.bottomCells[bottomIndex].shift();
param.topLeftCells[topLeftIndex] = cell;
topLeftCellDoms[topLeftIndex].appendChild(cell.dom);
if (gameOverOrRun()) {
autoMoveToTopRight();
}
}
});
topLeftPanel.addEventListener('dblclick', function (e) {
e.preventDefault();
var target = e.target;
var parent = null;
if (target.classList.contains('cell-body')) {
parent = target.parentNode;
} else if (target.classList.contains('cell-container')) {
parent = target;
target = parent.childNodes[0];
}
if (parent == null) {
return;
}
var topLeftIndex = getIndexInTopLeftCells(parent);
if (topLeftIndex < 0) {
return;
}
var cell = param.topLeftCells[topLeftIndex];
var topRightIndex = getIndexInTopRightCells(cell);
if (topRightIndex >= 0) {
param.topLeftCells[topLeftIndex] = null;
param.topRightCells[topRightIndex].unshift(cell);
topRightCellDoms[topRightIndex].appendChild(cell.dom);
autoMoveToTopRight();
}
});
window.document.oncontextmenu = function (e) {
return false;
};
dragEvent(topLeftPanel, (function () {
var closest = null, selfTopLeftCell = null, selfTopLeftCellIndex = -1;
var topLeftCells = param.topLeftCells;
var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms;
var bottomCellDomsXY = null, topLeftCellDomsXY = null, topRightCellDomsXY = null;
return function (parent, target, btnNum, phase, clientX, clientY, eX, eY, dx, dy) {
if (btnNum === 0) {
if (phase === 'down') {
closest = getClosest(parent, 'top-cell');
selfTopLeftCellIndex = closest.getAttribute('data-index') - 0;
selfTopLeftCell = topLeftCells[selfTopLeftCellIndex];
bottomCellDomsXY = getBottomCellDomsXY();
topLeftCellDomsXY = getTopLeftOrRightCellDomsXY(topLeftCellDomList);
topRightCellDomsXY = getTopLeftOrRightCellDomsXY(topRightCellDomList);
} else if (phase === 'move') {
closest.style.zIndex = 3;
parent.style.left = dx + 'px';
parent.style.top = ver + dy + 'px';
var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
if (indexInTopLeftCells > -1) {
if (topLeftCells[indexInTopLeftCells] === null) {
showLayer(topLeftCellDoms[indexInTopLeftCells]);
} else {
hideLayer();
}
} else {
var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
if (indexInTopRightCells > -1) {
if (canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell)) {
showLayer(topRightCellDoms[indexInTopRightCells]);
} else {
hideLayer();
}
} else {
var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
if (indexInBottomCells > -1 && canDropToBottom(indexInBottomCells, selfTopLeftCell, 0)) {
showLayer(bottomCellDoms[indexInBottomCells], bottomCellDomsXY[indexInBottomCells].height);
} else {
hideLayer();
}
}
}
} else {
hideLayer();
closest.style.zIndex = 0;
parent.style.left = 0 + 'px';
parent.style.top = ver + 'px';
target.style.zIndex = 0;
var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
if (indexInTopLeftCells > -1) {
if (topLeftCells[indexInTopLeftCells] === null) {
topLeft2TopLeft(selfTopLeftCellIndex, indexInTopLeftCells);
}
} else {
var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
if (indexInTopRightCells > -1) {
if (canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell)) {
topLeft2TopRight(selfTopLeftCellIndex, indexInTopRightCells);
}
} else {
var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
if (indexInBottomCells > -1 && canDropToBottom(indexInBottomCells, selfTopLeftCell, 0)) {
topLeft2Bottom(selfTopLeftCellIndex, indexInBottomCells);
}
}
}
}
}
}
})());
dragEvent(bottomPanel, (function () {
var closest = null, selfBottomCell = null, selfBottomCellIndex = -1, inBottomCellIndex = -1;
var bottomCells = param.bottomCells, topLeftCells = param.topLeftCells;
var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms;
var bottomCellDomsXY = null, topLeftCellDomsXY = null, topRightCellDomsXY = null;
var canMove = false;
return function (parent, target, btnNum, phase, clientX, clientY, eX, eY, dx, dy) {
if (btnNum === 2) {
if (phase === 'down') {
target.style.zIndex = 3;
} else {
target.style.zIndex = 0;
}
} else if (btnNum === 0) {
if (phase === 'down') {
closest = getClosest(parent, 'bottom-cell');
selfBottomCellIndex = closest.getAttribute('data-index') - 0;
selfBottomCell = bottomCells[selfBottomCellIndex];
inBottomCellIndex = getInCellIndex(target, selfBottomCell);
canMove = canMoveBottomCell(selfBottomCellIndex, inBottomCellIndex);
if (!canMove) {
target.style.zIndex = 3;
return;
}
bottomCellDomsXY = getBottomCellDomsXY();
if (inBottomCellIndex === 0) {
topLeftCellDomsXY = getTopLeftOrRightCellDomsXY(topLeftCellDomList);
topRightCellDomsXY = getTopLeftOrRightCellDomsXY(topRightCellDomList);
}
} else if (phase === 'move') {
if (!canMove) {
return;
}
closest.style.zIndex = 3;
parent.style.left = dx + 'px';
parent.style.top = ver + dy + 'px';
var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
if (indexInBottomCells > -1) {
if (indexInBottomCells !== selfBottomCellIndex
&& canDropToBottom(indexInBottomCells, selfBottomCell[inBottomCellIndex], inBottomCellIndex)) {
showLayer(bottomCellDoms[indexInBottomCells], bottomCellDomsXY[indexInBottomCells].height);
} else {
hideLayer();
}
} else if (inBottomCellIndex === 0) {
var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
if (indexInTopLeftCells > -1) {
if (topLeftCells[indexInTopLeftCells] === null) {
showLayer(topLeftCellDoms[indexInTopLeftCells]);
} else {
hideLayer();
}
} else {
var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
if (indexInTopRightCells > -1 && canDropBottomToTopRight(indexInTopRightCells, selfBottomCell)) {
showLayer(topRightCellDoms[indexInTopRightCells]);
} else {
hideLayer();
}
}
}
} else {
if (!canMove) {
target.style.zIndex = 0;
return;
}
hideLayer();
closest.style.zIndex = 0;
parent.style.left = 0 + 'px';
parent.style.top = ver + 'px';
target.style.zIndex = 0;
var indexInBottomCells = getIndexInBottomCells(eX, eY, bottomCellDomsXY);
if (indexInBottomCells > -1) {
if (indexInBottomCells !== selfBottomCellIndex
&& canDropToBottom(indexInBottomCells, selfBottomCell[inBottomCellIndex], inBottomCellIndex)) {
bottom2Bottom(selfBottomCell, inBottomCellIndex, indexInBottomCells);
if (gameOverOrRun()) {
autoMoveToTopRight();
}
}
} else if (inBottomCellIndex === 0) {
var indexInTopLeftCells = getIndexInTopCells(eX, eY, topLeftCellDomsXY);
if (indexInTopLeftCells > -1) {
if (topLeftCells[indexInTopLeftCells] === null) {
bottom2TopLeft(selfBottomCell, indexInTopLeftCells);
if (gameOverOrRun()) {
autoMoveToTopRight();
}
}
} else {
var indexInTopRightCells = getIndexInTopCells(eX, eY, topRightCellDomsXY);
if (indexInTopRightCells > -1 && canDropBottomToTopRight(indexInTopRightCells, selfBottomCell)) {
bottom2TopRight(selfBottomCell, indexInTopRightCells);
if (gameOverOrRun()) {
autoMoveToTopRight();
}
}
}
}
}
}
}
})());
function showLayer(parent, height) {
parent.appendChild(layer);
if (height) {
layer.style.top = '0px';
layer.style.height = height + 'px';
} else {
layer.style.top = ver + 'px';
layer.style.height = '140px';
}
layer.style.display = 'block';
}
function hideLayer() {
layer.style.display = 'none';
}
function gameOverOrRun() {
if (isSuccess()) {
window.setTimeout(function () {
alert("恭喜,游戏成功了");
});
} else if (isFail()) {
window.setTimeout(function () {
alert("已无牌可移动了");
});
}
return true;
}
function isSuccess() {
var topRightCells = param.topRightCells;
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i].length < 13) {
return false;
}
}
return true;
}
function isFail() {
var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
var topLeft = [], topRight = [], bottom = [];
for (var i = 0; i < topLeftCells.length; i++) {
if (topLeftCells[i] === null || topLeftCells[i].num === 1) {
return false;
}
topLeft.push(topLeftCells[i]);
}
for (var i = 0; i < bottomCells.length; i++) {
if (bottomCells[i].length === 0 || bottomCells[i][0].num === 1) {
return false;
}
bottom.push(bottomCells[i][0]);
}
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i].length > 0) {
topRight.push(topRightCells[i][0]);
}
}
for (var i = 0; i < topLeft.length; i++) {
for (var j = 0; j < topRight.length; j++) {
if (topLeft[i].num === topRight[j].num + 1 && topLeft[i].type === topRight[j].type) {
return false;
}
}
for (var j = 0; j < bottom.length; j++) {
if (topLeft[i].num === bottom[j].num - 1 && topLeft[i].color !== bottom[j].color) {
return false;
}
}
}
for (var i = 0; i < bottom.length; i++) {
for (var j = 0; j < topRight.length; j++) {
if (bottom[i].num === topRight[j].num + 1 && bottom[i].type === topRight[j].type) {
return false;
}
}
for (var j = 0; j < bottom.length; j++) {
if (bottom[i].num === bottom[j].num - 1 && bottom[i].color !== bottom[j].color) {
return false;
}
}
}
return true;
}
function autoMoveToTopRight() {
var autoMove = false;
(function timeoutMoveToTopRight() {
window.setTimeout(function () {
autoMove = moveOneToTopRight();
if (autoMove) {
timeoutMoveToTopRight();
}
}, 200);
})();
}
function moveOneToTopRight() {
var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
var one = getOneCanMoveTopRight();
if (one === null) {
return false;
}
var indexInTopRightCells = -1;
if (one.position === 'topLeft') {
var cell = topLeftCells[one.index];
if (cell.num === 1) {
for (var i = topRightCells.length - 1; i >= 0; i--) {
if (topRightCells[i].length === 0) {
indexInTopRightCells = i;
break;
}
}
} else {
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i][0].num + 1 === cell.num && topRightCells[i][0].type === cell.type) {
indexInTopRightCells = i;
break;
}
}
}
topLeft2TopRight(one.index, indexInTopRightCells);
} else {
var cells = bottomCells[one.index];
if (cells[0].num === 1) {
for (var i = topRightCells.length - 1; i >= 0; i--) {
if (topRightCells[i].length === 0) {
indexInTopRightCells = i;
break;
}
}
} else {
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i][0].num + 1 === cells[0].num && topRightCells[i][0].type === cells[0].type) {
indexInTopRightCells = i;
break;
}
}
}
bottom2TopRight(cells, indexInTopRightCells);
}
return true;
}
function getOneCanMoveTopRight() {
var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
var num = 13;
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i].length === 0) {
num = 1;
break;
}
var tmpNum = topRightCells[i][0].num;
if (tmpNum < num) {
num = tmpNum + 1;
}
}
for (var i = 0; i < topLeftCells.length; i++) {
if (topLeftCells[i] !== null && topLeftCells[i].num === num) {
return {
position: 'topLeft',
index: i
};
}
}
for (var i = 0; i < bottomCells.length; i++) {
if (bottomCells[i].length > 0 && bottomCells[i][0].num === num) {
return {
position: 'bottom',
index: i
}
}
}
return null;
}
function canMoveBottomCount() {
var topLeftCells = param.topLeftCells, bottomCells = param.bottomCells;
var count = 1;
for (var i = 0; i < topLeftCells.length; i++) {
if (topLeftCells[i] === null) {
count++;
}
}
for (var i = 0; i < bottomCells.length; i++) {
if (bottomCells[i].length === 0) {
count++;
}
}
return count;
}
function canMoveBottomCell(selfBottomCellIndex, inBottomCellIndex) {
var bottomCellArr = param.bottomCells[selfBottomCellIndex];
var cell = bottomCellArr[inBottomCellIndex];
for (var i = inBottomCellIndex - 1; i >= 0; i--) {
if (bottomCellArr[i].num + 1 !== cell.num || bottomCellArr[i].color === cell.color) {
return false;
}
cell = bottomCellArr[i];
}
return true;
}
function canDropTopLeftToTopRight(indexInTopRightCells, selfTopLeftCell) {
var topRightCell = param.topRightCells[indexInTopRightCells];
return topRightCell.length === 0 ? selfTopLeftCell.num === 1
: selfTopLeftCell.num === topRightCell[0].num + 1 && selfTopLeftCell.type === topRightCell[0].type;
}
function canDropBottomToTopRight(indexInTopRightCells, selfBottomCell) {
var topRightCell = param.topRightCells[indexInTopRightCells];
return topRightCell.length === 0 ? selfBottomCell[0].num === 1
: selfBottomCell[0].num === topRightCell[0].num + 1 && selfBottomCell[0].type === topRightCell[0].type;
}
function canDropToBottom(indexInBottomCells, selfCell, inBottomCellIndex) {
var bottomCell = param.bottomCells[indexInBottomCells];
if (inBottomCellIndex > 0) {
var count = canMoveBottomCount();
if (bottomCell.length === 0 ? inBottomCellIndex + 1 >= count : inBottomCellIndex >= count) {
return false;
}
}
return bottomCell.length === 0
|| selfCell.num - 0 + 1 === bottomCell[0].num && selfCell.color - 0 !== bottomCell[0].color;
}
function topLeft2TopLeft(selfTopLeftCellIndex, indexInTopLeftCells) {
var topLeftCells = param.topLeftCells;
var topLeftCellDomList = topLeftCellDoms;
var cell = topLeftCells[selfTopLeftCellIndex];
topLeftCells[selfTopLeftCellIndex] = null;
topLeftCellDomList[indexInTopLeftCells].appendChild(cell.dom);
topLeftCells[indexInTopLeftCells] = cell;
}
function topLeft2TopRight(selfTopLeftCellIndex, indexInTopRightCells) {
var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells;
var topRightCellDomList = topRightCellDoms;
var cell = topLeftCells[selfTopLeftCellIndex];
topLeftCells[selfTopLeftCellIndex] = null;
if (topRightCells[indexInTopRightCells].length > 0) {
topRightCells[indexInTopRightCells][0].dom.appendChild(cell.dom);
cell.dom.style.top = 0;
} else {
topRightCellDomList[indexInTopRightCells].appendChild(cell.dom);
}
topRightCells[indexInTopRightCells].unshift(cell);
}
function topLeft2Bottom(selfTopLeftCellIndex, indexInBottomCells) {
var topLeftCells = param.topLeftCells, bottomCells = param.bottomCells;
var bottomCellDomList = bottomCellDoms;
var cell = topLeftCells[selfTopLeftCellIndex];
topLeftCells[selfTopLeftCellIndex] = null;
if (bottomCells[indexInBottomCells].length > 0) {
bottomCells[indexInBottomCells][0].dom.appendChild(cell.dom);
} else {
bottomCellDomList[indexInBottomCells].appendChild(cell.dom);
}
bottomCells[indexInBottomCells].unshift(cell);
}
function bottom2TopLeft(selfBottomCell, indexInTopLeftCells) {
var topLeftCells = param.topLeftCells;
var topLeftCellDomList = topLeftCellDoms;
var cell = selfBottomCell.shift();
topLeftCellDomList[indexInTopLeftCells].appendChild(cell.dom);
topLeftCells[indexInTopLeftCells] = cell;
gameOverOrRun();
}
function bottom2TopRight(selfBottomCell, indexInTopRightCells) {
var topRightCells = param.topRightCells;
var topRightCellDomList = topRightCellDoms;
var cell = selfBottomCell.shift();
var topRightCell = topRightCells[indexInTopRightCells];
if (topRightCell.length > 0) {
topRightCell[0].dom.appendChild(cell.dom);
cell.dom.style.top = 0;
} else {
topRightCellDomList[indexInTopRightCells].appendChild(cell.dom);
}
topRightCell.unshift(cell);
gameOverOrRun();
}
function bottom2Bottom(selfBottomCell, inBottomCellIndex, indexInBottomCells) {
var bottomCells = param.bottomCells;
var bottomCellDomList = bottomCellDoms;
var cells = selfBottomCell.splice(0, inBottomCellIndex + 1);
if (bottomCells[indexInBottomCells].length > 0) {
bottomCells[indexInBottomCells][0].dom.appendChild(cells[cells.length - 1].dom);
} else {
bottomCellDomList[indexInBottomCells].appendChild(cells[cells.length - 1].dom);
}
var targetCell = bottomCells[indexInBottomCells];
for (var i = cells.length - 1; i >= 0; i--) {
targetCell.unshift(cells[i]);
}
gameOverOrRun();
}
function getBottomCellDomsXY() {
var width = 100, minHeight = 140;
var bottomCellDomList = bottomCellDoms, bottomCells = param.bottomCells;
var bottomCellDomsXY = [];
var point = null;
for (var i = 0; i < bottomCellDomList.length; i++) {
point = getAbsPoint(bottomCellDomList[i]);
point.width = width;
point.height = (function (i) {
var length = bottomCells[i].length;
if (length < 2) {
return minHeight;
} else {
return minHeight + (length - 1) * ver;
}
})(i);
bottomCellDomsXY.push(point);
}
return bottomCellDomsXY;
}
function getTopLeftOrRightCellDomsXY(topLeftOrRightCellDoms) {
var width = 100, height = 140;
var topCellDomsXY = [];
var point = null;
for (var i = 0; i < topLeftOrRightCellDoms.length; i++) {
point = getAbsPoint(topLeftOrRightCellDoms[i]);
point.width = width;
point.height = height;
topCellDomsXY.push(point);
}
return topCellDomsXY;
}
function getInCellIndex(target, selfCell) {
var num = target.getAttribute("data-num") - 0;
var type = target.getAttribute('data-type') - 0;
for (var i = 0; i < selfCell.length; i++) {
if (selfCell[i].num === num && selfCell[i].type === type) {
return i
}
}
return -1;
}
function getIndexInTopCells(eX, eY, cellDomsXY) {
for (var i = 0; i < cellDomsXY.length; i++) {
if (eX >= cellDomsXY[i].x
&& eX <= cellDomsXY[i].x + cellDomsXY[i].width
&& eY >= cellDomsXY[i].y + ver
&& eY <= cellDomsXY[i].y + cellDomsXY[i].height + ver
) {
return i;
}
}
return -1;
}
function getIndexInBottomCells(eX, eY, cellDomsXY) {
for (var i = 0; i < cellDomsXY.length; i++) {
if (eX >= cellDomsXY[i].x
&& eX <= cellDomsXY[i].x + cellDomsXY[i].width
&& eY >= cellDomsXY[i].y
&& eY <= cellDomsXY[i].y + cellDomsXY[i].height
) {
return i;
}
}
return -1;
}
function getClosest(target, clazz) {
var parent = target;
for(;;) {
parent = parent.parentNode;
if (parent === null) {
return null;
} else if (parent.classList.contains(clazz)) {
return parent;
}
}
}
function getIndexInNullTopLeftCells() {
var topLeftCells = param.topLeftCells;
for (var i = 0; i < topLeftCells.length; i++) {
if (topLeftCells[i] === null) {
return i;
}
}
return -1;
}
function getIndexInTopLeftCells(dom) {
var topLeftCells = param.topLeftCells;
for (var i = 0; i < topLeftCells.length; i++) {
if (topLeftCells[i] !== null && dom === topLeftCells[i].dom) {
return i;
}
}
return -1;
}
function getIndexInTopRightCells(cell) {
var topRightCells = param.topRightCells;
if (cell.num === 1) {
for (var i = topRightCells.length - 1; i >= 0; i--) {
if (topRightCells[i].length === 0) {
return i;
}
}
return -1;
} else {
for (var i = 0; i < topRightCells.length; i++) {
if (topRightCells[i].length > 0) {
var topRightCell = topRightCells[i][0];
if (topRightCell.num + 1 === cell.num && topRightCell.type === cell.type) {
return i;
}
}
}
return -1;
}
}
function getIndexInBottomCellsFirst(dom) {
var bottomCells = param.bottomCells;
for (var i = 0; i < bottomCells.length; i++) {
if (bottomCells[i].length > 0 && dom === bottomCells[i][0].dom) {
return i;
}
}
return -1;
}
function reInit() {
var topLeftCells = param.topLeftCells, topRightCells = param.topRightCells, bottomCells = param.bottomCells;
var topLeftCellDomList = topLeftCellDoms, topRightCellDomList = topRightCellDoms, bottomCellDomList = bottomCellDoms;
for (var i = 0; i < topLeftCells.length; i++) {
topLeftCells[i] = null;
topLeftCellDomList[i].innerHTML = '';
}
for (var i = 0; i < topRightCells.length; i++) {
topRightCells[i].length = 0;
topRightCellDomList[i].innerHTML = '';
}
for (var i = 0; i < bottomCells.length; i++) {
bottomCells[i].length = 0;
bottomCellDomList[i].innerHTML = '';
}
init();
}
function init() {
var initArr = [];
var num, type, color;
var random;
for (var i = 0; i < 52; i++) {
num = ~~(i / 4) + 1;
type = i % 4 + 1;
color = (type === 1 || type === 4) ? 1 : 2;
random = ~~(Math.random() * initArr.length);
initArr.splice(random, 0, new Cell(num, color, type));
}
var bottomCells = param.bottomCells;
appendTimeout(bottomCells, initArr, 0);
}
function appendTimeout(bottomCells, initArr, i) {
window.setTimeout(function () {
if (i > initArr.length - 1) {
return;
}
appendBottom(bottomCells[i % 8], bottomCellDoms[i % 8], initArr[i]);
appendTimeout(bottomCells, initArr, i + 1);
}, 25);
}
function appendBottom(bottomCell, bottomCellDom, cell) {
if (bottomCell.length === 0) {
bottomCellDom.appendChild(cell.dom);
} else {
bottomCell[0].dom.appendChild(cell.dom);
}
bottomCell.unshift(cell);
}
function dragEvent(dom, func) {
var disX = 0,disY = 0, clientX = 0, clientY = 0, dx = 0, dy = 0;
var el = dom.setCapture ? dom : document;
var docElem, win,
elem = dom,
doc = elem && elem.ownerDocument;
if ( !doc ) {
return;
}
docElem = doc.documentElement;
win = getWindow( doc );
dom.onmousedown = function (ev) {
dom.focus();
var oEvent = ev || window.event, target = oEvent.target, btnNum = oEvent.button;
var parent = null;
if (target.classList.contains('cell-body')) {
parent = target.parentNode;
} else if (target.classList.contains('cell-container')) {
parent = target;
target = parent.childNodes[0];
}
if (parent == null) {
return false;
}
var xOffset = ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 );
var yOffset = ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 );
disX = dx = oEvent.offsetX || oEvent.layerX || 0; disY = dy = oEvent.offsetY || oEvent.layerY || 0;
clientX = oEvent.clientX; clientY = oEvent.clientY;
var timeoutFunc = function (phase, oEvent) {
func(parent, target, btnNum, phase, clientX + xOffset, clientY + yOffset,
oEvent.clientX + xOffset, oEvent.clientY + yOffset, oEvent.clientX - clientX, oEvent.clientY - clientY);
};
timeoutFunc('down', oEvent);
if (btnNum !== 2) {
el.onmousemove = function (ev) {
var oEvent = ev || window.event;
if(oEvent.stopPropagation) {
oEvent.stopPropagation();
} else {
oEvent.cancelBubble = true;
}
dx = disX + oEvent.clientX - clientX; dy = disY + oEvent.clientY - clientY;
if (dx < 0) {dx = 0} else if (dx > dom.offsetWidth - 1) {dx = dom.offsetWidth - 1}
if (dy < 0) {dy = 0} else if (dy > dom.offsetHeight - 1) {dy = dom.offsetHeight - 1}
timeoutFunc('move', oEvent);
return false;
};
}
el.onmouseup = function (ev) {
var oEvent = ev || window.event;
if(oEvent.stopPropagation) {
oEvent.stopPropagation();
} else {
oEvent.cancelBubble = true;
}
timeoutFunc('up', oEvent);
el.onmousemove = null; el.onmouseup = null; if(dom.releaseCapture) {dom.releaseCapture();}
};
if(dom.setCapture) {dom.setCapture();}
return false;
};
}
function isWindow ( obj ) {
return obj != null && obj == obj.window;
}
function getWindow( elem ) {
return isWindow( elem ) ?
elem :
elem.nodeType === 9 ?
elem.defaultView || elem.parentWindow :
false;
}
function getAbsPoint (el){
var docElem, win,
box = { top: 0, left: 0 },
elem = el,
doc = elem && elem.ownerDocument;
if ( !doc ) {
return;
}
docElem = doc.documentElement;
if ( typeof elem.getBoundingClientRect !== typeof undefined ) {
box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
x: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ),
y: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 )
};
}
})();