<div id="wrapper">
<h1>MineSwipper</h1>
<input id="hor" type="number" placeholder="가로" value="10">
<input id="ver" type="number" placeholder="세로" value="10">
<input id="mine" type="number" placeholder="지뢰" value="20">
<button id="exec">Start</button>
<table id="table">
<--지뢰부분-->
<thead></thead>
<tbody></tbody>
</table>
</div>
#wrapper {
width: 100%;
text-align: center;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
h1 {
font: normal 1.75em "Larsseit";
color: #252525;
text-align: center;
padding: 50px 0 30px;
}
#table {
border-collapse: collapse;
display: block;
text-align: center;
margin: 30px 0;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
td {
width: 20px;
height: 20px;
line-height: 20px;
border: solid 1px #252525;
text-align: center;
background: #c9c9c9;
font: normal "Larsseit";
}
td.opened {
background: #fff;
}
td.flag {
background: #252525;
color: #fff;
}
td.question {
background: #999;
}
td.bomb {
color: transparent;
}
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 80px;
background-color: #252525;
border: none;
color: #fff;
padding: 5px 0 5px 8px;
box-sizing: border-box;
margin-right: 5px;
}
/*input 초기화*/
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
#exec {
width: 80px;
background-color: #252525;
border: none;
color: #fff;
padding: 5px;
box-sizing: border-box;
}
.result {
margin-top: 20px;
font: normal 1.25em "Larsseit";
}
let table = document.querySelector('#table');
let tbody = document.querySelector('#table tbody');
let result = document.createElement('div');
result.classList.add('result');
table.appendChild(result);
let dataset = [];
let stop = false;
let openedBlock = 0;
let codeTable = {
openBk: -1,
question: -2,
flag: -3,
flagBomb: -4,
quesBomb: -5,
bomb: 1,
default: 0,
}
document.querySelector('#exec').addEventListener('click', function() {
// 초기화
tbody.innerHTML = '';
result.textContent = '';
dataset = [];
stop = false;
openedBlock = 0;
let hor = parseInt(document.querySelector('#hor').value);
let ver = parseInt(document.querySelector('#ver').value);
let mine = parseInt(document.querySelector('#mine').value);
// bomb 테이블 만들기
for (let i = 0; i < ver; i += 1) {
let arr = [];
let tr = document.createElement('tr'); //line
dataset.push(arr);
for (let j = 0; j < hor; j += 1) {
arr.push(codeTable.default);
let td = document.createElement('td'); //block
td.addEventListener('contextmenu', function(e) {
e.preventDefault();
if (stop) {
return;
}
let parentTr = e.currentTarget.parentNode;
let parentBody = e.currentTarget.parentNode.parentNode;
let block = Array.prototype.indexOf.call(parentTr.children, e.currentTarget);
let line = Array.prototype.indexOf.call(parentBody.children, parentTr);
if (e.currentTarget.textContent === '' || e.currentTarget.textContent === '×') {
e.currentTarget.textContent = '⚑';
e.currentTarget.classList.remove('bomb');
e.currentTarget.classList.add('flag');
if (dataset[line][block] === codeTable.bomb) {
dataset[line][block] = codeTable.flagBomb;
} else {
dataset[line][block] = codeTable.flag;
}
} else if (e.currentTarget.textContent === '⚑') {
e.currentTarget.textContent = '?';
e.currentTarget.classList.remove('flag');
e.currentTarget.classList.add('question');
if (dataset[line][block] === codeTable.flagBomb) {
dataset[line][block] = codeTable.questionBomb;
} else {
dataset[line][block] = codeTable.question;
}
} else if (e.currentTarget.textContent === '?') {
e.currentTarget.classList.remove('question');
if (dataset[line][block] === codeTable.bomb || dataset[line][block] === codeTable.flagBomb || dataset[line][block] === codeTable.questionBomb) {
e.currentTarget.textContent = '×';
e.currentTarget.classList.add('bomb');
dataset[line][block] = codeTable.bomb;
} else {
e.currentTarget.textContent = '';
dataset[line][block] = codeTable.default;
}
}
});
td.addEventListener('click', function(e) {
if (stop) {
return;
}
let parentTr = e.currentTarget.parentNode;
let parentBody = e.currentTarget.parentNode.parentNode;
let block = Array.prototype.indexOf.call(parentTr.children, e.currentTarget);
let line = Array.prototype.indexOf.call(parentBody.children, parentTr);
if ([codeTable.openBk, codeTable.flag, codeTable.flagBomb, codeTable.questionBomb, codeTable.question].includes(dataset[line][block])) {
return;
}
// 클릭했을때
e.currentTarget.classList.add('opened');
openedBlock += 1;
if (dataset[line][block] === codeTable.bomb) { //bomb클릭
e.currentTarget.textContent = '💣';
result.textContent = 'Failed';
stop = true;
} else { // bomb가 아닌 경우 주변 bomb 개수
let nearBy = [
dataset[line][block - 1], dataset[line][block + 1],
];
if (dataset[line - 1]) {
nearBy = nearBy.concat(dataset[line - 1][block - 1], dataset[line - 1][block], dataset[line - 1][block + 1]);
}
if (dataset[line + 1]) {
nearBy = nearBy.concat(dataset[line + 1][block - 1], dataset[line + 1][block], dataset[line + 1][block + 1]);
}
let numOfNearby = nearBy.filter(function(v) {
return [codeTable.bomb, codeTable.flagBomb, codeTable.quesBomb].includes(v);
}).length;
//거짓인값 : false, '', 0 , null, undefined, NaN
e.currentTarget.textContent = numOfNearby || '';
dataset[line][block] = codeTable.openBk;
if (numOfNearby === 0) {
//주변 8칸 동시 오픈 (재귀함수)
let nearbyBlock = [];
if (tbody.children[line - 1]) {
nearbyBlock = nearbyBlock.concat([
tbody.children[line - 1].children[block - 1],
tbody.children[line - 1].children[block],
tbody.children[line - 1].children[block + 1],
]);
}
nearbyBlock = nearbyBlock.concat([
tbody.children[line].children[block - 1],
tbody.children[line].children[block + 1],
]);
if (tbody.children[line + 1]) {
nearbyBlock = nearbyBlock.concat([
tbody.children[line + 1].children[block - 1],
tbody.children[line + 1].children[block],
tbody.children[line + 1].children[block + 1],
]);
}
nearbyBlock.filter(function(v) {
return !!v;
}).forEach(function(nextBlock) {
let parentTr = nextBlock.parentNode;
let parentBody = nextBlock.parentNode.parentNode;
let nextBB = Array.prototype.indexOf.call(parentTr.children, nextBlock);
let nextBL = Array.prototype.indexOf.call(parentBody.children, parentTr);
if (dataset[nextBL][nextBB] !== codeTable.openBk) {
nextBlock.click();
}
});
}
if (openedBlock === hor * ver - mine) {
result.textContent = 'Success!';
stop = true;
}
}
});
tr.appendChild(td); //line > block
}
tbody.appendChild(tr);
}
// bomb 제작
let numbers = Array(hor * ver).fill().map(function(elem, index) {
return index; //1~100
});
let shuffle = [];
while (numbers.length > hor * ver - mine) {
let shiftValue = numbers.splice(Math.floor(Math.random() * numbers.length), 1)[0];
shuffle.push(shiftValue);
}
// bomb심기
for (let k = 0; k < shuffle.length; k++) {
let col = Math.floor(shuffle[k] / ver);
let row = shuffle[k] % ver;
// tbody.children[col].children[row].textContent = '×';
dataset[col][row] = codeTable.bomb;
}
});