Els objectius d'aquest document són proporcionar una comprensió clara del codi HTML i JavaScript utilitzat per crear un joc bàsic de Go. Aprendràs com inicialitzar i configurar un document HTML, aplicar estils CSS per millorar l'aparença, i implementar la lògica de joc amb JavaScript. Els conceptes clau inclouen la creació i manipulació del DOM, gestió d'esdeveniments, i actualització dinàmica del contingut de la pàgina, tots essencials per desenvolupar aplicacions web interactives.
<!DOCTYPE html>
<html lang="en">
Aquesta part inicialitza el document com un document HTML5 i estableix l'idioma a anglès.
<head>
La secció de capçalera inclou metadades sobre el document HTML.
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Go Game</title>
Aquests elements estableixen la codificació de caràcters, la configuració de la finestra gràfica per al disseny responsiu, i el títol del document com "Go Game".
<style>
#go-board {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-gap: 1px;
background-color: #000;
}
.stone {
background-color: #f0f0f0;
border: 1px solid #ccc;
padding: 0;
margin: 0;
text-align: center;
font-size: 24px;
cursor: pointer;
box-sizing: border-box;
}
.black {
background-color: #000;
color: #fff;
}
.white {
background-color: #fff;
color: #000;
}
.captured {
background-color: #d3d3d3;
color: #000;
}
#captured-counts {
margin-top: 20px;
}
#captured-counts span {
display: inline-block;
margin-right: 20px;
font-size: 18px;
}
</style>
Aquesta secció inclou estils CSS per al tauler del joc de Go, les pedres, i el recompte de pedres capturades, definint el seu aspecte i disposició.
</head>
<body>
La secció de cos conté el contingut visible del document HTML.
<div id="go-board"></div>
Aquest element div és el contenidor per al tauler del joc de Go.
<div id="captured-counts">
<span id="black-captured">Pedres negres capturades: 0</span>
<span id="white-captured">Pedres blanques capturades: 0</span>
</div>
Aquest element div i els seus elements fill span mostren el recompte de pedres negres i blanques capturades.
<script>
const boardContainer = document.getElementById('go-board');
const boardSize = 9;
const stoneSize = 50;
let currentPlayer = 'black';
let gameBoard = [];
let capturedStones = { black: 0, white: 0 };
</script>
Aquest script inicialitza variables per al joc de Go, incloent el contenidor del tauler, la mida, la mida de les pedres, el jugador actual, la matriu del tauler de joc i el recompte de pedres capturades.
<script>
for (let i = 0; i < boardSize; i++) {
gameBoard.push([]);
for (let j = 0; j < boardSize; j++) {
const stone = document.createElement('div');
stone.className = 'stone';
stone.style.width = `${stoneSize}px`;
stone.style.height = `${stoneSize}px`;
stone.dataset.row = i;
stone.dataset.col = j;
boardContainer.appendChild(stone);
gameBoard[i].push(stone);
}
}
boardContainer.addEventListener('click', handleStoneClick);
</script>
Aquest script crea les pedres (elements div) per al tauler de joc i afegeix un gestor d'esdeveniments de clic per gestionar la col·locació de les pedres.
function handleStoneClick(event) {
const stone = event.target;
if (stone.classList.contains('stone') && !stone.classList.contains('black') && !stone.classList.contains('white')) {
placeStone(stone);
}
}
Aquesta funció gestiona el clic en les pedres. Si l'element clicat és una pedra que no té cap color assignat (negra o blanca), s'anomena la funció `placeStone` per col·locar-hi la pedra del jugador actual.
function placeStone(stone) {
stone.classList.add(currentPlayer);
const row = parseInt(stone.dataset.row);
const col = parseInt(stone.dataset.col);
const captured = captureStones(row, col);
if (captured) {
updateBoard();
}
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updateCapturedCounts();
}
Aquesta funció col·loca una pedra al tauler. Afegeix la classe del jugador actual a la pedra, comprova si es capturen pedres adversàries i actualitza el tauler i el recompte de pedres capturades després de cada jugada.
function captureStones(row, col) {
const color = currentPlayer;
const opponentColor = color === 'black' ? 'white' : 'black';
let captured = false;
function getNeighbors(r, c) {
return [
[r - 1, c],
[r + 1, c],
[r, c - 1],
[r, c + 1]
].filter(([nr, nc]) => nr >= 0 && nr < boardSize && nc >= 0 && nc < boardSize);
}
function hasLiberties(r, c, colorToCheck) {
const visited = new Set();
const stack = r, c;
let hasLiberty = false;
while (stack.length > 0) {
const [cr, cc] = stack.pop();
getNeighbors(cr, cc).forEach(([nr, nc]) => {
const neighborStone = gameBoard[nr][nc];
if (!visited.has(neighborStone)) {
visited.add(neighborStone);
if (!neighborStone.classList.contains('black') && !neighborStone.classList.contains('white')) {
hasLiberty = true;
} else if (neighborStone.classList.contains(colorToCheck)) {
stack.push([nr, nc]);
}
}
});
}
return hasLiberty;
}
function removeCapturedStones(r, c, colorToRemove) {
const visited = new Set();
const stack = r, c;
while (stack.length > 0) {
const [cr, cc] = stack.pop();
const stone = gameBoard[cr][cc];
if (stone.classList.contains(colorToRemove)) {
stone.classList.remove('black', 'white');
stone.classList.add('captured');
capturedStones[colorToRemove]++;
visited.add(stone);
getNeighbors(cr, cc).forEach(([nr, nc]) => {
const neighborStone = gameBoard[nr][nc];
if (!visited.has(neighborStone)) {
stack.push([nr, nc]);
}
});
}
}
}
getNeighbors(row, col).forEach(([nr, nc]) => {
const neighborStone = gameBoard[nr][nc];
if (neighborStone.classList.contains(opponentColor) && !hasLiberties(nr, nc, opponentColor)) {
captured = true;
removeCapturedStones(nr, nc, opponentColor);
}
});
return captured;
}
Aquesta funció comprova les pedres que es poden capturar al voltant de la pedra col·locada. Utilitza les funcions `getNeighbors`, `hasLiberties`, i `removeCapturedStones` per identificar i eliminar pedres capturades, actualitzant el recompte de pedres capturades.
function updateBoard() {
gameBoard.forEach(row => {
row.forEach(stone => {
if (stone.classList.contains('captured')) {
stone.classList.remove('captured');
stone.className = 'stone';
}
});
});
}
Aquesta funció actualitza el tauler eliminant l'estil de capturat de les pedres. Reestableix les pedres capturades a l'estat original per a les properes jugades.
function updateCapturedCounts() {
document.getElementById('black-captured').textContent = `Pedres negres capturades: ${capturedStones.black}`;
document.getElementById('white-captured').textContent = `Pedres blanques capturades: ${capturedStones.white}`;
}
Aquesta funció actualitza el recompte de pedres capturades mostrades a la interfície d'usuari, canviant els textos dels elements corresponents.
function initGame() {
gameBoard.forEach(row => {
row.forEach(stone => {
stone.className = 'stone';
});
});
currentPlayer = 'black';
capturedStones = { black: 0, white: 0 };
updateCapturedCounts();
}
Aquesta funció inicialitza el joc, configurant el tauler de pedres, establint el jugador actual com a "black" i posant a zero el recompte de pedres capturades.