othello
by turbographics2000
HTML
<div id="msg">このページのタブを右クリックして"タブを複製"で複製すると開始します。(複製は1回のみすること)</div>
<div id="board"></div>
CSS
#board {
width: calc(30px * 8);
height: calc(30px * 8);
border: 1px solid;
}
#board > div {
width: 30px;
height: 30px;
border: 1px solid;
box-sizing: border-box;
float: left;
}
#board > div::after {
content: " ";
display: block;
border-radius: 100%;
height: 100%;
}
#board > div.kuro::after {
border: 1px solid;
background: black;
}
#board > div.shiro::after {
border: 1px solid;
background: white;
}
JavaScript
var kuro = 1, shiro = 2, enemy = { 1: shiro, 2: kuro }, elms = {},myTurn = 0, turn = kuro;
var offsets = [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]];
var bc = new BroadcastChannel('othello');
bc.onmessage = (evt) => {
if (evt.data === 'join') {
bc.postMessage('join_ack');
} else if(evt.data === 'join_ack') {
myTurn = kuro;
msg.textContent = 'あなたの番です';
bc.postMessage('shiro');
} else if (evt.data === 'shiro') {
myTurn = shiro;
} else {
elms[evt.data].click();
if(myTurn === turn) msg.textContent = 'あなたの番です';
}
}
bc.postMessage('join');
var arr = Array(8 * 8).fill(0).map((v, i) => {
v = (i === 27 || i === 36) ? kuro : (i === 28 || i === 35) ? shiro : v;
elms[i] = board.appendChild(document.createElement('div'));
elms[i].dataset.i = i;
var flip = (k, t) => {
elms[k].dataset.v = t;
elms[k].className = ['', 'kuro', 'shiro'][t];
};
flip(i, v);
elms[i].onclick = function () {
if (+this.dataset.v || !myTurn) return;
var pos = [+this.dataset.i % 8, +this.dataset.i / 8 | 0];
offsets.forEach(offset => {
var loopCnt = Math.min(...[0, 1].map(o => offset[o] < 0 ? pos[o] : offset[o] > 0 ? 7 - pos[o] : 8));
var f = [], ap, x = pos[0], y = pos[1];
for (var l = 0; l < loopCnt; l++) {
x += offset[0], y += offset[1];
if (!arr[ap = x + y * 8]) return;
if (arr[ap] === enemy[turn]) f.push(ap);
else if (arr[ap] === turn) {
if (f.length) {
f.push(+this.dataset.i); // こうしちゃうと置いたところを最高8回設定してしまうが気にしない。
f.forEach(j => flip(j, arr[j] = turn));
}
break;
}
}
});
if (+this.dataset.v) {
turn = enemy[turn];
msg.innerHTML = ' ';
...