O Jogo da Velha é um dos jogos mais simples e conhecidos do mundo. Neste tutorial, vamos criar uma versão moderna utilizando HTML, CSS e JavaScript, com um modo multiplayer e uma IA poderosa que nunca perde no nível difícil!
Recursos do Jogo
✅ Interface moderna e responsiva
✅ Modo 2 jogadores ou contra o bot
✅ Três níveis de dificuldade (Fácil, Médio e Difícil)
✅ IA com algoritmo Minimax que garante que o bot nunca perca no nível difícil
Veja o projeto ao vivo no link abaixo:
Veja o vídeo no YouTube:
1. Estruturando o Projeto
Crie um arquivo index.html e adicione o seguinte código:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jogo da Velha</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="game-container">
<div id="controls">
<select id="gameMode">
<option value="player">2 Jogadores</option>
<option value="bot" selected>Jogar com Robô</option>
</select>
<select id="difficulty" disabled>
<option value="1">Fácil</option>
<option value="2" selected>Médio</option>
<option value="3">Difícil</option>
</select>
</div>
<div id="board"></div>
<div id="status">Vez do jogador X</div>
<button id="restart" style="display: none;">Reiniciar</button>
</div>
<script src="script.js"></script>
</body>
</html>
2. Estilizando com CSS
Agora, crie um arquivo style.css e adicione o código para deixar o jogo visualmente mais agradável:
body {
font-family: 'Arial', sans-serif;
text-align: center;
background-color: #121212;
color: #ffffff;
margin: 0;
padding: 20px;
}
.container {
max-width: 400px;
margin: 0 auto;
background: #1e1e1e;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
h1 {
font-size: 24px;
color: #ffffff;
margin-bottom: 15px;
}
.select-container {
margin-bottom: 15px;
}
label {
font-size: 16px;
font-weight: bold;
margin-right: 5px;
}
select {
padding: 8px;
font-size: 14px;
border-radius: 6px;
border: 1px solid #444;
background-color: #222;
color: #fff;
cursor: pointer;
transition: all 0.3s ease;
}
select:hover {
border-color: #00bcd4;
}
#board {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 8px;
justify-content: center;
margin: 20px auto;
background: #121212;
padding: 10px;
border-radius: 10px;
}
.cell {
width: 100px;
height: 100px;
background: #2e7d32;
border: 2px solid #1b5e20;
font-size: 36px;
font-weight: bold;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background 0.3s ease, transform 0.2s;
}
.cell:hover {
background: #388e3c;
}
.animated {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: scale(0.8); }
to { opacity: 1; transform: scale(1); }
}
#status {
font-size: 18px;
font-weight: bold;
margin-top: 10px;
color: #ffffff;
}
#restart {
margin-top: 15px;
padding: 12px 20px;
font-size: 16px;
background: #00bcd4;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
display: none;
}
#restart:hover {
background: #0097a7;
}
@media (max-width: 500px) {
#board {
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 80px);
}
.cell {
width: 80px;
height: 80px;
font-size: 28px;
}
}
3. Criando a Lógica do Jogo com JavaScript
Agora, crie um arquivo script.js e adicione o código que implementa toda a lógica do jogo, incluindo o modo bot com IA avançada.
let currentPlayer = "X";
let cells = ["", "", "", "", "", "", "", "", ""];
let gameActive = false;
let mode = "player";
let difficulty = 1;
const board = document.getElementById("board");
const statusText = document.getElementById("status");
const restartButton = document.getElementById("restart");
const difficultySelect = document.getElementById("difficulty");
const gameModeSelect = document.getElementById("gameMode");
window.onload = function() {
mode = gameModeSelect.value;
updateDifficultyState();
createBoard();
};
function updateDifficultyState() {
difficultySelect.disabled = mode !== "bot";
}
function createBoard() {
board.innerHTML = "";
cells.fill("");
currentPlayer = "X";
gameActive = true;
statusText.textContent = `Vez do jogador ${currentPlayer}`;
restartButton.style.display = "none";
cells.forEach((_, index) => {
const cellElement = document.createElement("div");
cellElement.classList.add("cell");
cellElement.dataset.index = index;
cellElement.addEventListener("click", handleCellClick);
board.appendChild(cellElement);
});
if (mode === "bot" && currentPlayer === "O") {
setTimeout(botMove, 500);
}
}
function handleCellClick(event) {
const index = event.target.dataset.index;
if (cells[index] !== "" || !gameActive || (mode === "bot" && currentPlayer === "O")) return;
playMove(index, currentPlayer);
if (mode === "bot" && gameActive) {
setTimeout(botMove, 500);
}
}
function playMove(index, player) {
cells[index] = player;
const cell = document.querySelector(`.cell[data-index="${index}"]`);
cell.textContent = player;
cell.classList.add("animated");
const winner = checkWinner();
if (winner) {
statusText.textContent = winner === "empate" ? "Empate!" : `Jogador ${winner} venceu!`;
gameActive = false;
restartButton.style.display = "inline-block";
} else {
currentPlayer = player === "X" ? "O" : "X";
statusText.textContent = `Vez do jogador ${currentPlayer}`;
}
}
function checkWinner() {
const winningCombinations = [
[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6]
];
for (let combination of winningCombinations) {
const [a, b, c] = combination;
if (cells[a] && cells[a] === cells[b] && cells[a] === cells[c]) {
return cells[a]; // Retorna "X" ou "O"
}
}
return cells.includes("") ? null : "empate";
}
function botMove() {
if (!gameActive) return;
let availableMoves = cells.map((cell, index) => (cell === "" ? index : null)).filter(index => index !== null);
let botChoice;
if (difficulty === 1) {
botChoice = availableMoves[Math.floor(Math.random() * availableMoves.length)];
} else if (difficulty === 2) {
botChoice = mediumBot(availableMoves);
} else {
botChoice = hardBot() || mediumBot(availableMoves);
}
playMove(botChoice, "O");
}
function mediumBot(availableMoves) {
return availableMoves.find(index => checkMove(index, "O")) || availableMoves[0];
}
function hardBot() {
let bestScore = -Infinity;
let bestMove = null;
for (let index = 0; index < cells.length; index++) {
if (cells[index] === "") {
cells[index] = "O";
let score = minimax(cells, 0, false);
cells[index] = "";
if (score > bestScore) {
bestScore = score;
bestMove = index;
}
}
}
return bestMove;
}
function minimax(board, depth, isMaximizing) {
let result = checkWinner();
if (result === "O") return 10 - depth;
if (result === "X") return depth - 10;
if (result === "empate") return 0;
if (isMaximizing) {
let bestScore = -Infinity;
for (let i = 0; i < board.length; i++) {
if (board[i] === "") {
board[i] = "O";
let score = minimax(board, depth + 1, false);
board[i] = "";
bestScore = Math.max(bestScore, score);
}
}
return bestScore;
} else {
let bestScore = Infinity;
for (let i = 0; i < board.length; i++) {
if (board[i] === "") {
board[i] = "X";
let score = minimax(board, depth + 1, true);
board[i] = "";
bestScore = Math.min(bestScore, score);
}
}
return bestScore;
}
}
function checkMove(index, player) {
cells[index] = player;
let result = checkWinner();
cells[index] = "";
return result;
}
function restartGame() {
createBoard();
}
restartButton.addEventListener("click", restartGame);
gameModeSelect.addEventListener("change", () => {
mode = gameModeSelect.value;
updateDifficultyState();
createBoard();
});
difficultySelect.addEventListener("change", () => {
difficulty = parseInt(difficultySelect.value);
});
O código completo do jogo da Velha está disponível abaixo:
Ver Código Completo no GitHub.
Como funciona a IA do Bot?
No nível difícil, utilizamos o algoritmo Minimax, uma técnica muito comum em jogos de tabuleiro, como Xadrez. Esse algoritmo analisa todas as possíveis jogadas futuras e escolhe a melhor opção, garantindo que o bot sempre vença ou empate.
-
O bot avalia todas as jogadas possíveis.
-
Simula os movimentos do oponente.
-
Escolhe a jogada que maximiza suas chances de vitória.
-
Evita movimentos que poderiam levar à derrota.
Graças a esse sistema, o bot se torna imbatível no nível difícil!
4. Como Jogar?
-
Modo 2 jogadores: Basta selecionar "2 Jogadores" e alternar as jogadas clicando no tabuleiro.
-
Modo contra o bot: Escolha "Jogar com Robô" e selecione a dificuldade.
-
Dificuldades:
-
Fácil: O bot joga aleatoriamente.
-
Médio: O bot tenta bloquear algumas jogadas.
-
Difícil: O bot nunca perde (utiliza Minimax).
-
Para reiniciar a partida, clique no botão "Reiniciar".
5. Melhorando o Projeto
Se você quiser personalizar ou expandir o jogo, aqui estão algumas ideias:
✅ Adicionar efeitos visuais ao clicar nas células.
✅ Criar um placar para contar vitórias e derrotas.
✅ Fazer um modo online para jogar com amigos à distância.
✅ Adicionar sons quando um jogador marca um ponto.
6. Conclusão
Neste tutorial, criamos um Jogo da Velha completo, com um bot que desafia qualquer jogador. O código é simples, mas poderoso, utilizando HTML, CSS e JavaScript para garantir uma ótima experiência.
Se gostou do projeto, compartilhe com seus amigos e deixe seu comentário abaixo!
Comentários
Postar um comentário
Obrigado pelo seu feedback!