Se há algo que sempre gostei de fazer ao aprender uma linguagem de programação nova é escrever algum joguinho para testar os meus conhecimentos. Cada vez temos mais provas de que a gamificação é uma ótima ferramenta de aprendizagem!
O Jogo da Velha é um clássico que desafia os seus conhecimentos de uma linguagem sem fazer você quebrar demais a cabeça. Por isso, hoje vou te ensinar como fazer um jogo da velha em Javascript, usando também HTML e CSS.
Como fazer um jogo da velha em javascript
A ferramenta que usei para fazer este programa foi o Gedit, um editor de texto para Linux, mas para criar seu jogo da velha em javascript você pode usar qualquer outro editor de texto, como o Sublime, Notepad++ ou até o bom e velho Bloco de Notas.
Criando pastas e estruturando diretórios
Para começar, crie uma pasta chamada “Jogo da Velha”. Dentro desta pasta, crie outras duas, uma chamada “css” e a outra chamada “scripts”.
A sua estrutura de diretórios deve ficar assim:
.
└── Jogo da Velha
├── css
└── scripts
Código HTML e CSS para o Jogo da Velha
Para conseguir focar no Javascript, vou deixar os códigos de HTML e CSS disponíveis sem entrar a fundo neles.
Caso você queria aprender mais sobre isso, confira o nosso Curso de HTML e CSS.
Abra o bloco de notas, ou o editor de sua preferência e salve o arquivo a seguir como “index.html” na raiz da pasta Jogo da Velha.
<htmllang="pt-br"><head><title>Jogo da Velhatitle><metacharset="UTF-8"><linkrel="stylesheet"href="css/main.css">head><body><h1>Jogador <spanid="jogador">span>h1><main><div><inputtype="button"value="_"><inputtype="button"value="_"><inputtype="button"value="_">div><div><inputtype="button"value="_"><inputtype="button"value="_"><inputtype="button"value="_">div><div><inputtype="button"value="_"><inputtype="button"value="_"><inputtype="button"value="_">div>main><inputtype="button"value="Reiniciar"id="reiniciar"><scriptsrc="scripts/velha.js"><s```cript>
body>html>
Em seguida, faça um novo arquivo com o código CSS a seguir chamado “main.css” e salve-o dentro da pasta “css”
body {
background-color: #AAA;
text-align: center;
font-family: Verdana, Helvetica, sans-serif;
font-size: 1.3em;
}
input {
background-color: white;
font-size: 6vw;
width: 12vw;
height:12vw;
margin: 0;
color: white;
}
#jogador {
display: inline;
}
#reiniciar {
margin-top: 2%;
width: 10vw;
height:6vw;
font-size: 1em;
color: black;
}
Por último, crie um arquivo de texto vazio e salve-o como “velha.js” dentro da pasta scripts. Depois de fazer isso, a sua árvore de diretórios deve estar mais ou menos assim:
.
└── JogodaVelha
├── css
│ └── main.css
├── index.html
└── scripts
└── velha.js
Se você abrir o arquivo index.html no seu navegador, poderá ver como está a nossa interface de usuário.
- A Label do Jogador, o quadrado pontilhado no topo, é uma tag span com id “jogador” e será responsável por mostrar se é a vez do jogador “X” ou “O”.
- Cada um dos quadradinhos brancos do nosso tabuleiro, a nossa “casa”, é formado por tags input de tipo botão. Ao clicar nela, será marcado X ou O, de acordo com a vez do jogador atual, indicada pelo Label do Jogador.
- O botão reiniciar, formado pelo tag input de tipo botão, serve para limpar todas as casas e reiniciar a partida.
Lógica Javascript para o Jogo da Velha
Agora podemos começar a escrever a nossa lógica no arquivo “velha.js” dentro da pasta scripts. No nosso código Javascript, precisaremos referenciar esses objetos para poder interagir com eles e fazer com que reajam aos cliques ou mudanças de estado no código, vamos começar pegando estes elementos do HTML:
//Obtendo os elementos do DOM com que vamos interagir
const casas = document.getElementsByTagName('input'); //pega a lista de casas do tabuleiro do jogo
const b_reiniciar = document.getElementById('reiniciar'); //pega o botão de reiniciar
const label_jogador = document.getElementById('jogador'); //pegar o label do jogador que usaremos para mostrar qual jogador tem a vez
Tudo bastante simples até agora, não?
Usamos os métodos document.getElementById para pegar o botão de reiniciar e o label do jogador, e o método getElementsByTagName para obter todos os input presentes no HTML.
Interessante notar que, entre as posições 0 e 8, temos as casas do tabuleiro e, na posição 9, teríamos o botão de reiniciar porque também se trata de um input. Usei uma variável separada para o botão de reiniciar para deixar o código um pouco mais fácil de entender, mas é bom lembrar, na hora de usar a constante casas, de usar apenas os valores entre 0 e 8 nos loops, para não pôr a lógica errada dentro do botão de reiniciar.
Agora que temos os elementos HTML, seria útil criar variáveis que indicam o estado do jogo. Por exemplo: de quem é a vez, se alguém venceu a partida, e, caso sim, quem é este vencedor.
//Definindo variáveis de estado do jogovar jogador = '_'; //Define o jogador atual (_ = jogador indefinido; X = jogador X, O = jogador O)var vencedor = '_'; //Define se há um vencedor ou não (_ = indefinido; X = jogador X, O = jogador O)
sortearJogador(); //Escolhe aleatoriamento o jogador inicial
O símbolo ‘_’ vai ser usado no programa tanto para definir 3 coisas: que nenhum jogador tem a vez, que ninguém venceu a partida ainda ou que uma casa está vazia. Este símbolo é arbitrário e poderia ter sido qualquer outro. Ele, na verdade, é mostrado dentro das casas do tabuleiro pelo app, mas fiz uma lógica para que toda a vez que este caractere aparecesse, que a fonte ficasse da mesma cor do fundo de forma a ficar invisível.
Poderíamos ter também criado um vetor que guardasse o estado das jogadas, mas optei por ler os valores armazenados na variável casas diretamente.
E, quanto ao método sortearJogador(), vamos definir ele depois. Mas ele sorteia qual jogador vai começar a partida.
Adicionando interatividade ao Jogo da Velha Javascript
Agora que temos os elementos do DOM e as variáveis de estado, podemos adicionar interatividade ao nosso jogo. Um bom começo seria usando o método addEventListener() para agregar um método que executa quando os botões, formados pelas casas e botão de reiniciar, forem pressionados.
//Define a resposta ao evento de clique nas casas do "tabuleiro"for(var i=0;i<9;i++) {
casas[i].addEventListener('click', (event) => {
//se a casa estiver vazia e ninguém tiver vencido a partidaif( (event.target.value=='_') && (vencedor=='_')) {
event.target.value=jogador; //preenche a casa com X ou Oevent.target.style.color='black'; //torna o valor da casa visível
trocarJogador(); //função que troca a vez do jogador, a ser definida depois
vencedor = vitoria(); //Executa a função vitoria() que defineremos depois, ela retorna o vencedor da partida, caso exista.//se o vencedor existe, imprimeif(vencedor!='_') {
label_jogador.innerText=`${vencedor} venceu!`;
}
}
});
}
O código pode parecer um pouco grande, mas é bem simples: ele adiciona uma lógica em cada botão da casa. Se a casa estiver vazio e ainda não houver um vencedor ele:
- Preenche a posição com o jogador atual.
- Troca a vez para a do próximo jogador.
- Atualiza a variável vencedor caso uma condição de vitória seja alcançada.
- Se um jogador tiver vencido, imprime uma mensagem dizendo quem ganhou.
Interessante notar que o botão da casa não reage se já estiver preenchida ou se já houver um vencedor, ou seja, o jogo já estiver ganho por alguém.
//Define a resposta ao evento de clique no botão Reiniciar
b_reiniciar.addEventListener('click', (event) => {
for(var i=0;i<9;i++) {
casas[i].value='_'; //Limpa todas as casas
casas[i].style.color='white'; //Torna o valor _ invisível
casas[i].style.backgroundColor='white'; //Torna o fundo branco
}
vencedor = '_'; //Reseta o vencedor
sortearJogador(); //Escolhe aleatoriamente qual jogador irá começar
});
O botão de reiniciar apenas reseta os valores de todas as variáveis e elementos HTML para os seus valores iniciais e permite que seja jogada uma nova partida.
Definindo funções sortearJogador(), trocarJogador() e vitoria()
Agora tudo o que falta é definir as funções sortearJogador(), trocarJogador() e vitoria(). Vamos inserir no nosso código estes métodos:
//Usa uma função que decide aleatoriamente o jogador a fazer a primeira jogadavar sortearJogador = function() {
if(Math.floor(Math.random() * 2)==0) {
jogador = "O"; //define o jogador O como atual
label_jogador.innerText="O"; //exibe na página qual é o jogador atual
label_jogador.style.color='#F00'; //deixa o texto na cor vermelha
}else{
jogador = "X";//define o jogador X como atual
label_jogador.innerText="X"; //exibe na página qual é o jogador atual
label_jogador.style.color='#00F'; //deixa o texto na cor azul
}
}
sortearJogador();
Talvez você não saiba o que a função (Math.floor(Math.random() * 2) faça. O conceito aqui é, basicamente, aquele de cara ou coroa, retornando hora o número 0, hora o número 1. Dependendo de qual lado da moeda cair, ele atualiza as variáveis para colocar X ou O como jogador inicial.
//Alterna a vez entre os jogadores X e Y
var trocarJogador = function() {
if(jogador=='X') {
jogador='O';
label_jogador.innerText='O';
label_jogador.style.color='#F00';
}else{
jogador='X';
label_jogador.innerText='X';
label_jogador.style.color='#00F';
}
}
A função trocarJogador() faz quase a mesma coisa que a sortearJogador(). A diferença é que a primeira define o jogador atual baseado na sorte, sendo que a segunda define a vez do jogador baseado em quem fez a última jogada.
Agora só falta a função vitoria():
//Verifica se uma condição de vitória foi atingida e colore a linha da vitória
var vitoria = function() {
if((casas[0].value==casas[1].value) && (casas[1].value==casas[2].value) && casas[0].value!='_' ) {
casas[0].style.backgroundColor='#0F0';
casas[1].style.backgroundColor='#0F0';
casas[2].style.backgroundColor='#0F0';
return casas[0].value;
}elseif((casas[3].value==casas[4].value) && (casas[4].value==casas[5].value) && casas[3].value!='_' ) {
casas[3].style.backgroundColor='#0F0';
casas[4].style.backgroundColor='#0F0';
casas[5].style.backgroundColor='#0F0';
return casas[3].value;
}elseif((casas[6].value==casas[7].value) && (casas[7].value==casas[8].value) && casas[6].value!='_' ) {
casas[6].style.backgroundColor='#0F0';
casas[7].style.backgroundColor='#0F0';
casas[8].style.backgroundColor='#0F0';
return casas[6].value;
}elseif((casas[0].value==casas[3].value) && (casas[3].value==casas[6].value) && casas[0].value!='_' ) {
casas[0].style.backgroundColor='#0F0';
casas[3].style.backgroundColor='#0F0';
casas[6].style.backgroundColor='#0F0';
return casas[0].value;
}elseif((casas[1].value==casas[4].value) && (casas[4].value==casas[7].value) && casas[1].value!='_' ) {
casas[1].style.backgroundColor='#0F0';
casas[4].style.backgroundColor='#0F0';
casas[7].style.backgroundColor='#0F0';
return casas[1].value;
}elseif((casas[2].value==casas[5].value) && (casas[5].value==casas[8].value) && casas[2].value!='_' ) {
casas[2].style.backgroundColor='#0F0';
casas[5].style.backgroundColor='#0F0';
casas[8].style.backgroundColor='#0F0';
return casas[2].value;
}elseif((casas[0].value==casas[4].value) && (casas[4].value==casas[8].value) && casas[0].value!='_' ) {
casas[0].style.backgroundColor='#0F0';
casas[4].style.backgroundColor='#0F0';
casas[8].style.backgroundColor='#0F0';
return casas[0].value;
}elseif((casas[2].value==casas[4].value) && (casas[4].value==casas[6].value) && casas[2].value!='_' ) {
casas[2].style.backgroundColor='#0F0';
casas[4].style.backgroundColor='#0F0';
casas[6].style.backgroundColor='#0F0';
return casas[2].value;
}
return'_';
}
É uma função bem grande, mas se você notar, ela faz a mesma coisa várias vezes: ela vai checando as diferentes linhas: as horizontais, as verticais e as diagonais uma por uma.
Quando é encontrada uma combinação em que todos os elementos sejam igual e não estejam vazios, o fundo das casas que formam a linha são coloridas de verde-claro e é retornado o jogador que preencheu aquela linha, ou seja, o nosso vencedor. Se nenhuma linha satisfizer essas condições, é retornado ‘_’, o nosso jogador indefinido.
O jogo está pronto, e agora?
Ok, se tudo estiver certo, você deve ter um bom e velho jogo da velha rodando no seu navegador. O próximo passo, como diz o lema da Platzi, é Nunca Parar de Aprender!
Confira os cursos da programação que temos na plataforma. Eu acho que você pode se interessar especialmente por esses aqui:
Pode ver o código completo do Jogo da Velha em Javascript na minha página do Github.