以下がオセロの実装例です。evalや他のサイトへの遷移、リダイレクトは使用していません。また、セキュリティ脆弱性がないように、プレイヤーが入力した値が正しいかどうかをチェックしています。 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>オセロ</title> <style> table { border-collapse: collapse; } td { width: 40px; height: 40px; border: 1px solid black; text-align: center; font-size: 30px; } td.empty { background-color: green; cursor: pointer; } td.black { background-color: black; color: white; } td.white { background-color: white; border: 1px solid black; } </style> </head> <body> <table id="board"> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty black"></td> <td class="empty white"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty white"></td> <td class="empty black"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty black"></td> <td class="empty white"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty white"></td> <td class="empty black"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> <tr> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> <td class="empty"></td> </tr> </table> <script> let currentPlayer = "black"; const board = document.getElementById("board"); const cells = board.getElementsByTagName("td"); for (let i = 0; i < cells.length; i++) { cells[i].addEventListener("click", function() { const row = Math.floor(i / 8); const col = i % 8; if (canPlaceStone(row, col)) { placeStone(row, col); currentPlayer = currentPlayer === "black" ? "white" : "black"; updateMessage(`次は${currentPlayer}の番です`); } else { alert("そこには打てません"); } }); } function canPlaceStone(row, col) { if (cells[row * 8 + col].classList.contains("black") || cells[row * 8 + col].classList.contains("white")) { return false; } let canPlace = false; const currentStone = currentPlayer === "black" ? "white" : "black"; const directions = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]; for (let i = 0; i < directions.length; i++) { const dir = directions[i]; let r = row + dir[0]; let c = col + dir[1]; while (r >= 0 && r < 8 && c >= 0 && c < 8) { if (cells[r * 8 + c].classList.contains(currentStone)) { r += dir[0]; c += dir[1]; } else if (cells[r * 8 + c].classList.contains(currentPlayer)) { canPlace = true; break; } else { break; } } } return canPlace; } function placeStone(row, col) { const currentStone = currentPlayer === "black" ? "white" : "black"; cells[row * 8 + col].classList.add(currentPlayer); const directions = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]]; for (let i = 0; i < directions.length; i++) { const dir = directions[i]; const captures = []; let r = row + dir[0]; let c = col + dir[1]; while (r >= 0 && r < 8 && c >= 0 && c < 8) { if (cells[r * 8 + c].classList.contains(currentStone)) { captures.push(r * 8 + c); r += dir[0]; c += dir[1]; } else if (cells[r * 8 + c].classList.contains(currentPlayer)) { for (let j = 0; j < captures.length; j++) { cells[captures[j]].classList.replace(currentStone, currentPlayer); } break; } else { break; } } } } function updateMessage(message) { const messageElem = document.getElementById("message"); messageElem.innerHTML = message; } updateMessage(`先手は黒です`); </script> </body> </html> ``` ジョークを入れるとすると、例えば最初にアプリを開いた時に「オセロに興味がない人にはオススメしません。亀の甲より年の功というけど、このアプリは亀の甲にも及びませんからね。」というメッセージを表示したり、「オセロは立派な脳トレです。筋肉は鍛えなくても、人間の本質を磨くのには十分です。」というメッセージを表示したりするのも面白いかもしれません。