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 = '&nbsp;';
           ...