Some product links are affiliate links which means
if you something we'll receive a small commission.
Youtube Link
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<title>Othello</title>
</head>
<body>
<div class="board"></div>
<script src="./index.js"></script>
</body>
</html>
css
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-image: linear-gradient(135deg, #c6d8d7, #eeefde 60%, #c6d8d7);
}
.board {
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(8, 1fr);
width: 400px;
height: 400px;
border: 10px solid #333;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.cell {
border: 1px solid #333;
background-color: #149f54;
display: flex;
align-items: center;
justify-content: center;
}
.black::before {
background-color: #000;
}
.black::before,
.white::before {
content: "";
border-radius: 50%;
display: block;
width: 80%;
height: 80%;
transition: 0.3s ease-in-out;
margin: auto;
}
.white::before {
background-color: #fff;
}
js
let board = [
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "B", "W", "", "", ""],
["", "", "", "W", "B", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
];
let currentPlayer = "B";
const boardElement = document.querySelector(".board");
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
const cellElement = document.createElement("div");
cellElement.classList.add("cell");
if (board[i][j] === "B") {
cellElement.classList.add("black");
} else if (board[i][j] === "W") {
cellElement.classList.add("white");
}
cellElement.addEventListener("click", function () {
if (isValidMove(i, j, "B")) {
board[i][j] = "B";
flipTiles(i, j, "B");
updateBoard();
setTimeout(() => {
aiMove();
}, (Math.floor(Math.random() * 8) + 2) * 100);
const randomRow = Math.floor(Math.random() * 8);
const randomCol = Math.floor(Math.random() * 8);
if (isValidMove(randomRow, randomCol, "W")) {
board[randomRow][randomCol] = "W";
flipTiles(randomRow, randomCol, "W");
updateBoard();
}
}
});
boardElement.appendChild(cellElement);
}
}
function updateBoard() {
const cells = document.querySelectorAll(".cell");
for (let i = 0; i < cells.length; i++) {
const row = Math.floor(i / 8);
const col = i % 8;
cells[i].className = "cell";
if (board[row][col] === "B") {
cells[i].classList.add("black");
} else if (board[row][col] === "W") {
cells[i].classList.add("white");
}
}
}
function isValidMove(row, col, player) {
if (board[row][col] !== "") {
return false;
}
const opponent = player === "B" ? "W" : "B";
for (let dr = -1; dr <= 1; dr++) {
for (let dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) {
continue;
}
let r = row + dr;
let c = col + dc;
let foundOpponent = false;
while (r >= 0 && r < 8 && c >= 0 && c < 8) {
if (board[r][c] === opponent) {
foundOpponent = true;
} else if (board[r][c] === player && foundOpponent) {
return true;
} else {
break;
}
r += dr;
c += dc;
}
}
}
return false;
}
function aiMove() {
let validMoves = [];
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (isValidMove(i, j, "W")) {
validMoves.push({ row: i, col: j });
}
}
}
if (validMoves.length > 0) {
const randomIndex = Math.floor(Math.random() * validMoves.length);
const { row, col } = validMoves[randomIndex];
board[row][col] = "W";
flipTiles(row, col, "W");
updateBoard();
}
}
function flipTiles(row, col, player) {
const opponent = player === "B" ? "W" : "B";
for (let dr = -1; dr <= 1; dr++) {
for (let dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) {
continue;
}
let r = row + dr;
let c = col + dc;
let foundOpponent = false;
let tilesToFlip = [];
while (r >= 0 && r < 8 && c >= 0 && c < 8) {
if (board[r][c] === opponent) {
foundOpponent = true;
tilesToFlip.push({ row: r, col: c });
} else if (board[r][c] === player && foundOpponent) {
for (const tile of tilesToFlip) {
board[tile.row][tile.col] = player;
}
break;
} else {
break;
}
r += dr;
c += dc;
}
}
}
}
function isGameOver() {
let isBoardFull = true;
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] === "") {
isBoardFull = false;
break;
}
}
if (!isBoardFull) {
break;
}
}
let hasValidMove = false;
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (isValidMove(i, j, currentPlayer)) {
hasValidMove = true;
break;
}
}
if (hasValidMove) {
break;
}
}
return isBoardFull || !hasValidMove;
}