Neste tutorial, vamos te ensinar do mais absoluto zero, como programar o jogo da velha em C++, um game super bacana que você pode usar para jogar com algum amigo.
Lógica do Jogo da Velha em C++
Vamos usar uma matriz, 3x3, de inteiros, para representar as jogadas.
Se a casa tiver o número 0, ela está vazia. Se tiver o número 1 é porque o jogador 1 jogou lá, e se tiver -1, é porque o jogador 2 jogou naquela posição.
Vamos explicar, por partes, as funções.
A função
init(), inicializa o tabuleiro, colocando 0 em todas as casas.
A função
show() vai exibir o tabuleiro, imprimir o tabuleiro bonitinho, com barras, underlines, espaçamentos corretos e, se tem X ou 0 em cada casa. Essa última parte quem faz é a função
printBlock().
A função
printBlock() vai em cada casa do tabuleiro, se tiver 0 lá, ela retorna um espaço vazio ' '.
Se tiver o número 1 lá, ela imprime X. Se tiver -1 lá, é porque o jogador 2 jogou nessa casa, e lá vai ter um O.
A função
playMove() realiza uma jogada, ou seja, pede a linha e a coluna que o jogador vai jogar.
Lembrando que ele vai digitar valores de 1 até 3, e o array vai de 0 até 2, por isso temos que subtrair uma unidade dos dados digitados pelo usuário (row-- e col--). Também devemos checar se ela está ocupada (board[row][col]), e se o usuário digitou valores corretos (entre 1 e 3). Se tudo estiver ok, ela preenche com 1 ou -1 a casa que o jogador escolheu.
A função
checkContinue() vai verificar se ainda tem espaço em branco, ou seja, se ainda é possível realizar alguma jogada. Se tiver espaço em branco, retorna 1, se não tiver, retorna 0.
A função
checkWin() vai checar se alguém ganhou. Para isso, basta somar cada linha, cada coluna e cada diagonal, se alguma dessas fileiras tiver soma 3, o jogador 1 ganhou e retornamos 1. Se a soma for -3, o jogador 2 ganhou, e retornamos -1. Se ninguém tiver ganhado, até aquele momento, retornamos 0.
Agora vamos pra função
main(). Ela cria o tabuleiro 3x3, a variável
cont (que vai perguntar se o jogador vai querer jogar de novo ou não, as variáveis player1 e player2 , que vão armazenar o placar do jogo), e a variável
result, que armazena a informação de quem ganhou o jogo.
O jogo vai ocorrer dentro de um DO WHILE.
Primeiro, inicializamos o tabuleiro com valores 0.
Agora vamos fazer uma partida, para isso, chamamos a função
game().
A função
game() é onde ocorre a magia, o desenrolar do jogo.
Primeiro, declaramos a variável
turn, que vai dizer se é o jogador 1 ou 2 que vai jogar. A cada jogada, devemos incrementar ela em uma unidade (turn++), para mudar a vez para o próximo jogador.
Após dizer de quem é a vez, vamos fazer a jogada, através da função playMove(). Note que passamos a informação de quem é o jogador, através da expressão turn%2. Se ela der 0, é a vez do jogador 1 (e coloca o número 1, representado pelo X no tabuleiro), se der 1, é a vez do jogador (e preenchemos a matriz com o número -1, que vai ser representado pelo caractere O no tabuleiro).
Em seguida, devemos checar se o tabuleiro ainda tem posições vazias, pra jogar. Se tiver, armazenamos o número 1 na variável
cont, senão, armazenamos o valor 0.
Também devemos checar se após essa jogada, alguém ganhou. Se o jogador 1 tiver ganhado, armazenamos 1 na variável
win. Se o jogador 2 tiver ganhado, armazenamos o valor -1. Se ninguém tiver ganhado, armazenamos o valor 0.
Pronto. Uma jogada terminou. Vai ter uma próxima jogada? Isso depende.
Se ainda tiver espaço vazio (cont=1) e ninguém tiver ganhado (win=0, o mesmo que !win), vai ter outra jogada.
Se não tiver mais espaço vazio (cont=0) ou alguém tiver ganhado (win=1 ou win=-1), não vai ter próxima jogada, e sai do laço DO WHILE.
Após o laço, vamos verificar o que ocorreu. Se win=1, o jogador 1 ganhou e a função game retorna 1.
Se win=-1, o jogador 2 ganhou e retornamos 2. Se nenhum tiver ganhado, é porque o tabuleiro tá cheio (cont=0) e deu empate, então retornamos 0.
Esse retorno, vai lá pra função main(), na variável
result. Ele pega o resultado, e manda pra função
scoreboard(), junto com os valores de player1 e player2, ela é responsável por controlar o placar.
Após a exibição do placar, perguntamos se vai querer jogar novamente o jogo ou sair.
Se digitar 1 (continuar), a variável cont fica com valor 1, o laço WHILE dá verdadeiro, e outra partida será iniciada. Senão, se for 0, o laço termina junto com o jogo.
Bacana, não é?
Pessoal, o código abaixo tem quase 200 linhas. Podem existir erros, sem dúvidas.
Se encontrarem algum, ou alguma melhoria, por favor escreva nos comentários, ok?
Código do jogo da Velha em C++
#include <iostream>
using namespace std;
void init(int board[][3]); // Initializes the board with 0's
char printBlock(int block); // Prints each square of the board
void show(int board[][3]); // Show the board
void playMove(int board[][3], int); // Play one move
int checkContinue(int *board[3]); // Check if there is still white space
int checkWin(int *board[3]); // Check if anyone won
int game(int board[][3]); // PLay an entire game
void scoreboard(int, int &, int &); // Show the scoreboard
int main()
{
int board[3][3];
int cont=0, player1=0, player2=0, result;
do{
init(board);
result = game(board);
show(board);
scoreboard(result, player1, player2);
cout<<"\n Outra partida?"<<endl;
cout<<"0. Sair"<<endl;
cout<<"1. Jogar de novo"<<endl;
cin >> cont;
}while(cont);
return 0;
}
void init(int board[][3])
{
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
board[i][j]=0;
}
char printBlock(int block)
{
if(block==0)
return ' ';
else if(block==1)
return 'X';
else
return 'O';
}
void show(int board[][3])
{
cout<<endl;
for(int row=0 ; row<3 ; row++){
cout<<" "<< printBlock(board[row][0]) <<" |";
cout<<" "<< printBlock(board[row][1]) <<" |";
cout<<" "<< printBlock(board[row][2]) <<endl;
if(row!=2){
cout<<"___ ___ ___\n"<<endl;
}
}
}
void playMove(int board[][3], int player)
{
int row, col, check;
do{
cout<<"Linha: ";
cin >>row;
cout<<"Coluna: ";
cin >> col;
row--; col--;
check = board[row][col] || row<0 || row>2 || col<0 || col>2;
if(check)
cout<<"Essa casa não está vazia ou fora do intervalo 3x3"<<endl;
}while(check);
if(player==0)
board[row][col]=1;
else
board[row][col]=-1;
}
int checkContinue(int board[][3])
{
for(int i=0 ; i<3 ; i++)
for(int j=0 ; j<3 ; j++)
if(board[i][j]==0)
return 1;
return 0;
}
int checkWin(int board[][3])
{
int row, col, sum;
// Adding the lines
for(row=0 ; row<3 ; row++){
sum=0;
for(col=0 ; col<3 ; col++)
sum += board[row][col];
if(sum==3)
return 1;
if(sum==-3)
return -1;
}
// Adding the columns
for(col=0 ; col<3 ; col++){
sum=0;
for(row=0 ; row<3 ; row++)
sum += board[row][col];
if(sum==3)
return 1;
if(sum==-3)
return -1;
}
// Adding the diagonals
sum=0;
for(row=0 ; row<3 ; row++)
sum += board[row][row];
if(sum==3)
return 1;
if(sum==-3)
return -1;
sum=board[0][2]+board[1][1]+board[2][0];
if(sum==3)
return 1;
if(sum==-3)
return -1;
return 0;
}
int game(int board[][3])
{
int turn=0, cont, win;
do{
show(board);
cout<<"Jogador "<<1+turn%2<<endl;
playMove(board, turn%2);
turn++;
cont=checkContinue(board);
win = checkWin(board);
}while(cont && !win);
if(win==1){
cout<<"Jogador 1 ganhou!\n"<<endl;
return 1;
}else
if(win==-1){
cout<<"Jogador 2 ganhou!\n"<<endl;
return 2;
}else
cout<<"Empate\n"<<endl;
return 0;
}
void scoreboard(int result, int &player1, int &player2)
{
if(result==1)
player1++;
if(result==2)
player2++;
cout<<"Placar: "<<endl;
cout<<player1<<" x "<<player2<<endl;
}
Desafio em C++
Crie uma versão modificada deste jogo, que pergunta ao usuário se ele deseja jogar com um amigo ou contra o computador. Se ele escolher jogar contra a máquina, faça com que seu código escolha alguma casa aleatória, quando for a vez da máquina.
Será que alguém seria capaz de fazer e postar nos comentários, o resultado?