Sei sulla pagina 1di 12

view plaincopy to clipboardprint?

1. #include <stdio.h>
2.
3. int main()
4. {
5. char velha[3][3];
6. int linha, coluna;
7. for(linha = 0; linha < 3; linha++)
8. {
9. for(coluna = 0; coluna < 3; coluna++)
10. {
11. velha[linha][coluna] = ' ';
12. }
13. }
14. int jogada = 0;
15. while(1)
16. {
17. printf("Digite as coordenadas:\n");
18. int i, j;
19. scanf("%d %d", &i, &j);
20. if(velha[i][j] != ' ')
21. {
22. printf("Posicao ocupada!! Tente de novo.\n");
23. continue;
24. }
25.
26. if(jogada%2 == 0)
27. {
28. velha[i][j] = 'x';
29. }
30. else {
31. velha[i][j] = 'o';
32. }
33. for(linha = 0; linha < 3; linha++)
34. {
35. printf("|");
36. for(coluna = 0; coluna < 3; coluna++)
37. {
38. printf("%c|", velha[linha][coluna]);
39. }
40. printf("\n");
41. // Linhas
42. if(velha[0][0] == velha[0][1] && velha[0][1] ==
velha[0][2] && velha[0][0] != ' ')
43. {
44. printf("O jogador %c ganhou.\n", velha[0][0]);
45. break;
46. }
47. else if(velha[1][0] == velha[1][1] && velha[1][1] ==
velha[1][2] && velha[1][0] != ' ')
48. {
49. printf("O jogador %c ganhou.\n", velha[1][0]);
50. break;
51. }
52. else if(velha[2][0] == velha[2][1] && velha[2][1] ==
velha[2][2] && velha[2][0] != ' ')
53. {
54. printf("O jogador %c ganhou.\n", velha[2][0]);
55. break;
56. }
57.
58. // Colunas
59. else if(velha[0][0] == velha[1][0] && velha[1][0]
== velha[2][0] && velha[0][0] != ' ')
60. {
61. printf("O jogador %c ganhou.\n", velha[0][0]);
62. break;
63. }
64. else if(velha[0][1] == velha[1][1] && velha[1][1] ==
velha[2][1] && velha[0][1] != ' ')
65. {
66. printf("O jogador %c ganhou.\n", velha[0][1]);
67. break;
68. }
69. else if(velha[0][2] == velha[1][2] && velha[1][2] ==
velha[2][2] && velha[0][2] != ' ')
70. {
71. printf("O jogador %c ganhou.\n", velha[0][2]);
72. break;
73. }
74.
75. // Diagonais
76. else if(velha[0][0] == velha[1][1] && velha[1][1] ==
velha[2][2] && velha[0][0] != ' ')
77. {
78. printf("O jogador %c ganhou.\n", velha[0][0]);
79. break;
80. }
81. else if(velha[2][0] == velha[1][1] && velha[1][1] ==
velha[0][2] && velha[2][0] != ' ')
82. {
83. printf("O jogador %c ganhou.\n", velha[2][0]);
84. break;
85. }
86. jogada++;
87. }
88.
89. return 0;
90. }


Programao Estruturada
Professores autores
Anne Carolyne Cunha Martins
Eduardo Aranha
Julliane Cavalcanti
Keivilany Janielle de Lima Coelho
Aula 14 Desenvolvendo um jogo da velha

Apresentao
Na aula anterior, encerramos todo o contedo terico de nossa disciplina, estudando as
funes grficas. Vimos, ao longo de todo a disciplina de Programao Estruturada, como
utilizar os principais recursos disponveis na linguagem de programao C. Durante o nosso
estudo, voc teve a oportunidade de exercitar todos os contedos abordados de forma
prtica, visualizando o funcionamento de programas simples ou trechos de programas.
Nesta aula, vamos aplicar o conhecimento que adquirimos no estudo de nossa disciplina de
uma forma interessante e divertida. Vamos desenvolver um Jogo da Velha.
Desenvolveremos, na aula de hoje, o jogo bsico, com instanciao de jogadores e das
posies de marcao no tabuleiro. Ao longo da implementao, voc ver os trechos de
cdigo para cada funcionalidade e poder implementar voc mesmo o que aprender aqui.


Objetivos

Ao final desta aula, voc ser capaz de:
Desenvolver as funcionalidades mais bsicas de um jogo da velha.
Identificar, no cdigo do jogo, funcionalidades aplicveis a outros
jogos de tabuleiro, como o jogo de damas


Jogo da velha
Voc j deve conhecer o jogo da velha. Trata-se de um jogo em turnos alternados entre dois
jogadores, que se passa em um tabuleiro de nove posies (3 x 3). No jogo, cada jogador,
em sua vez, faz uma marcao em uma das posies do tabuleiro, sendo essa marcao o
smbolo X ou o smbolo O. Veja o tabuleiro do jogo da velha na Figura 1.

Figura 1 - Tabuleiro do jogo da velha

A marcao, no jogo da velha, feita de forma alternada, at que todo o tabuleiro seja
preenchido (nesse caso, ocorre empate) ou at que, antes disso, um dos jogadores complete
uma sequncia de trs smbolos em uma linha, coluna ou diagonal. O jogador que completar
primeiro a sequncia, vence. Na Figura 2, voc pode ver algumas situaes de vitria do
jogo da velha.

Figura 2 - Situaes de vitria no jogo da velha

Voc j deve ter jogado muitas vezes esse jogo. Tradicionalmente, para jogar, precisamos
apenas de papel, lpis e dois jogadores dispostos a competir.
Mas, e para implementar esse joguinho no computador em uma linguagem de programao?
Como fazer?
Antes de comear a sair por a escrevendo um monte de cdigo, precisamos, primeiro,,
estruturar o que realmente queremos fazer. Quais so os elementos do jogo da velha? Dois
jogadores e um tabuleiro de nove posies (3 x 3). Os requisitos para o jogo, dessa forma,
so as variveis para os jogadores, o desenho do tabuleiro e a lgica das jogadas.
Para isso, precisamos declarar variveis globais, para armazenar os valores que sero
utilizados em todo o jogo, criar uma matriz de 3 x 3, para desenhar o tabuleiro e diversas
funes com utilidades especficas, que sero chamadas por uma funo principal, que
executar o jogo. Vamos implementar? Mos obra!

Declarao das variveis globais
Pois bem, depois da incluso das bibliotecas que iremos utilizar no jogo, precisamos declarar
as variveis que armazenaro os valores referentes aos jogadores e ao tabuleiro. Veja:

char jog;
int linha = 0, coluna = 0, win, casa[3][3];

A varivel do tipo char jog declarada como varivel global para armazenar o jogador da
vez. A matriz casa, de inteiros de 3 x 3 posies, declarada para desenhar o tabuleiro
para que possa ser visualizado pelos jogadores. Alm disso, a matriz sempre percorrida, a
fim de verificar se h sequncia de smbolos iguais nas suas linhas, colunas ou diagonais
(sabemos que, quando isso ocorre, o jogo deve terminar e o vencedor anunciado).
As variveis do tipo int linha e coluna so declaradas para que seja feita a verificao dos
valores escolhidos pelo usurio, na hora de definir em que campo do tabuleiro ir fazer sua
marcao. Se o jogador escolher um campo invlido, uma mensagem de aviso exibida
(veremos isso daqui a pouco).
A varivel win, tambm do tipo int, declarada para armazenar o vencedor do jogo.
Atravs do valor armazenado nessa varivel, poderemos fazer a verificao de quem foi o
vencedor.

Desenhando o tabuleiro
Aps a declarao das variveis globais, para armazenar dados referentes aos jogadores e
ao tabuleiro, precisamos desenhar o tabuleiro. A funo desenha, representada abaixo, faz
isso. Veja:

void desenha(int x, int y)
{
if (casa[x][y] == ' ') printf(" "); //campo no marcado
aparece em branco ( )
if (casa[x][y] == 1) printf("X"); //campo marcado pelo
jogador 1 aparece com X
if (casa[x][y] == 2) printf("O"); //campo marcado pelo
jogador 1 aparece com O
}

Voc viu que declaramos uma matriz de inteiros para desenhar o tabuleiro. Mas, no jogo da
velha, no utilizamos nmeros nas marcaes. Utilizamos os smbolos X e O. Na funo
desenha dizemos, basicamente, que no campo de valor 1 da matriz que declaramos
(escolhido pelo jogador 1) ser marcado o smbolo X e no campo de valor 2 (escolhido pelo
jogador 2) ser marcado o smbolo O.
importante determinar, no cdigo, que os campos que no estiverem marcados ainda,
devem ser exibidos com o caractere espao em branco (por isso, as trs estruturas IF, e no
somente duas).
A funo desenha do tipo void, pois no retornar valor aps a sua execuo (voc viu
isso na Aula 12 Funes matemticas e do sistema) e recebe como argumentos dois
valores inteiros, que so referentes aos jogadores 1 e 2.
Voc viu, tambm, na aula sobre funes, que uma funo pode ser chamada pelo programa
ou por outra funo. o que ocorre na funo jogo, representada abaixo, que chama a
funo desenha para que o tabuleiro do jogo seja efetivamente exibido na tela. Veja:

01
02
03
04
05
06
07
08
09
10
11
12
void jogo() {
printf(" 1 2 3\n"); //aqui,so mostrados os nmeros das colunas do
tabuleiro
printf("1 "); //aqui mostrado o nmero da primeira linha
desenha(0, 0); //aqui exibido o campo que cruza a linha 1 com a coluna 1
printf(" | "); //caractere de diviso entre dois campos
desenha(0, 1); //aqui exibido o campo que cruza a linha 1 com a coluna 2
printf(" | "); //caractere de diviso entre dois campos
desenha(0, 2); //aqui exibido o campo que cruza a linha 1 com a coluna 3
printf("\n -----------\n2 "); //desenha linha horizontal e mostra nmero da
linha 2
desenha(1, 0); //aqui exibido o campo que cruza a linha 2 com a coluna 1
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
printf(" | "); //caractere de diviso entre dois campos
desenha(1, 1); //aqui exibido o campo que cruza a linha 2 com a coluna 2
printf(" | "); //caractere de diviso entre dois campos
desenha(1, 2); //aqui exibido o campo que cruza a linha 2 com a coluna 3
printf("\n -----------\n3 "); //desenha linha horizontal e mostra nmero da
linha 3
desenha(2, 0); //aqui exibido o campo que cruza a linha 3 com a coluna 1
printf(" | "); //caractere de diviso entre dois campos
desenha(2, 1); //aqui exibido o campo que cruza a linha 3 com a coluna 2
printf(" | "); //caractere de diviso entre dois campos
desenha(2, 2); //aqui exibido o campo que cruza a linha 3 com a coluna 3
}


Veja que na linha que nomeamos 1, so desenhados os campos (0,0), (0,1) e (0,2),
separados pelo caractere |. Na linha 2 so desenhados os campos (1,0), (1,1) e (1,2),
tambm separados por |. Na linha 3, por fim, temos os campos (2,0), (2,1) e (2,2). Veja
os comentrios no trecho de cdigo exibido. Dessa forma, quando o jogo carregado, o
tabuleiro exibido conforme a Figura 3.

Figura 3 - Tabuleiro 'desenhado' pela funo 'desenha'

Veja que, na Figura 3, o tabuleiro mostrado com os nmeros das colunas acima e os
nmeros das linhas ao lado. As linhas desenhadas para separar os campos na vertical so os
caracteres | e as linhas horizontais foram desenhadas no momento da insero dos
nmeros das linhas. Por exemplo, aps completar o desenho da linha 1, temos printf("\n
-----------\n2 "); que d uma quebra de linha, desenha a linha horizontal e d outra
quebra de linha para, ento, exibir o nmero da linha seguinte.


Atividade 1

Alm do jogo da velha, existem inmeros outros jogos de tabuleiro que
poderiam ser representados em C atravs do uso de matrizes.

Que tal desenharmos o tabuleiro de um desses jogos com o que vimos at
aqui?

Sabendo que o tabuleiro de um jogo de damas tem 64 posies (8 x 8),
desenhe o tabuleiro para esse jogo, utilizando a mesma metodologia que
acabamos de utilizar para o jogo da velha.


Fazendo e validando as marcaes
J desenhamos o tabuleiro. Como fazer, ento, para definir de que forma sero feitas as
marcaes de cada jogador?
Vimos, h pouco, que precisamos definir uma varivel (jog) para armazenar o jogador da
vez.
Com base nessa varivel, que o computador vai definir de quem a vez e o smbolo que
ser marcado. A funo jogar, cujo cdigo completo voc ver mais adiante, recebe como
argumento uma varivel do tipo int, a que chamamos jogador.
O programa l o argumento e define, a partir dele, quem o jogador da vez para, em
seguida, informar isso aos usurios. Veja o trecho de cdigo a seguir:

void jogar (int jogador) {
int i = 0;
if (jogador == 1) jog = 1;
if (jogador == 2) jog = 2;

O programa recebe o argumento na funo jogar e, caso o valor da varivel jogador seja
1, esse valor armazenado na varivel jog. O mesmo ocorre se o valor da varivel for 2.
Esse valor determinado na funo principal (funo main, que veremos mais adiante) do
programa, quando a funo jogar chamada.
A varivel jog ser utilizada na mensagem que informa ao usurio de quem a vez:

Printf ("\n\n Vez do Jogador %d. ", jog);

Bom, j sabemos como mostrar de quem a vez de jogar. Mas, ainda temos que determinar
como sero feitas as marcaes no tabuleiro. Precisamos, para isso, oferecer as opes para
que o jogador escolha em que campo do tabuleiro (em que linha e coluna da matriz) ir
fazer a sua marcao.
As variveis (linha e coluna) do tipo int que declaramos junto com a varivel jog l no
incio sero utilizadas nesse momento, para armazenar os valores das linhas e colunas
digitados pelo jogador. Podemos fazer isso, acrescentando mensagem que mostramos h
pouco, a solicitao para que o jogador da vez escolha a linha e a coluna em que far sua
marcao. Veja:

printf ("\n\n Vez do Jogador %d. Escolha a Linha (1,2,3): ", jog);
scanf ("%d", &linha); //lendo a linha escolhida
printf ("\n\n Vez do Jogador %d. Escolha a Coluna (1,2,3): ", jog);
scanf ("%d", &coluna); //lendo a coluna escolhida
Mas, no s isso. Precisamos validar a escolha do jogador. Se a linha ou coluna escolhida
for maior que 3 ou menor que 1, a marcao no pode ser feita, pois o nosso tabuleiro s
tem linhas e colunas de 1 a 3.
importante avisar ao jogador, caso isso ocorra. Veja o cdigo abaixo, com a funo jogar
ainda incompleta, mas um pouco mais elaborada, com a validao da escolha do usurio:


01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void jogar (int jogador)
{
int i = 0; //inicializando contador da estrutura while
if (jogador == 1) jog = 1;
if (jogador == 2) jog = 2;

//Definindo o jogador
da vez
while (i == 0) {
linha = 0; //inicializando valor da linha
coluna = 0; //inicializando valor da coluna
while (linha < 1 || linha > 3)
{
printf("\n\n Vez do Jogador %d. Escolha a Linha (1,2,3): ", jog);
scanf("%d", &linha); //lendo linha escolhida
if (linha < 1 || linha > 3) printf("\nAviso: Linha invalida! Voce
so pode escolher as linhas de 1 a 3.\n"); //Aviso de linha invlida, caso o
jogador tenha escolhido linha menor que 1 ou maior que 3
}
while (coluna < 1 || coluna > 3)
{
printf("\n\n Vez do Jogador %d. Escolha a Coluna (1,2,3): ", jog);
scanf("%d", &coluna); //lendo coluna escolhida
if (coluna < 1 || coluna > 3) printf("\nAviso: Coluna invalida!
Voce so pode escolher as colunas de 1 a 3.\n"); //Aviso de coluna invlida,
caso o jogador tenha escolhido coluna menor que 1 ou maior que 3
}
linha--;
coluna--;
(...)


Veja os comentrios em verde.
Veja que, aps a leitura da escolha do usurio (para a linha e para a coluna), temos um IF
que valida a escolha, avisando que no permitido escolher linha ou coluna menor que 1 ou
maior que 3.
Veja, tambm, que a seleo da linha e a seleo da coluna esto inseridas, cada uma, em
uma estrutura while. Isso feito para que, enquanto o valor da linha e/ou da coluna digitado
pelo jogador for invlido, a mensagem que solicita a escolha de uma linha e/ou coluna vlida
seja exibida.
Dessa forma, o programa s passa para a parte seguinte do cdigo, aps a seleo validada
desse ponto de vista (linha e coluna com valor entre 1 e 3).
Feito isso, ainda falta uma validao importante: se o jogador tentar marcar um campo que
no esteja vazio, ele deve ser avisado de que no pode fazer isso. Veja o trecho de cdigo
abaixo:


01
02
03
04
05
06
07
08
09
if (casa[linha][coluna] != 1 && casa[linha][coluna] != 2) { //se no estiver
marcado
casa[linha][coluna] = jog; //marcar com o smbolo do jogador da vez
i = 1;
} else { //se o campo escolhido j estivar marcado
Printf ("Ja houve jogada nesta casa! Escolha outra casa.\n");//aviso
}


O trecho de cdigo analisa se o campo selecionado pelo jogador da vez no est marcado.
Se no estiver, feita a marcao com o smbolo do jogador da vez (jog) e o contador do
lao whilerecebe o valor 1.
Essa alterao no valor do contador ocorre para que, ao ser feita a marcao, a execuo
saia do lao (lembre-se de que a condio para o lao era o contador i = 0). J que a
marcao foi realizada, no h mais porque permanecer no lao.
Caso o campo escolhido pelo jogador j esteja marcado, o IF no executado, mas sim o
ELSE, em que uma mensagem avisa ao jogador para escolher outro campo. A jogada s
concluda quando a condio do IF atendida. S assim, a marcao realizada e o
contador alterado, para a execuo sair do lao. Veja o cdigo da funo jogar completo a
seguir:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void jogar (int jogador) {
int i = 0;
if (jogador == 1) jog = 1;
if (jogador == 2) jog = 2;
while (i == 0) {
linha = 0;
coluna = 0;
while (linha < 1 || linha > 3) {
printf ("\n\n Vez do Jogador %d. Escolha a Linha (1,2,3): ", jog);
scanf ("%d", &linha);
if (linha < 1 || linha > 3) printf ("\nAviso: Linha invalida! Voce
so pode escolher as linhas de 1 a 3.\n");
}
while (coluna < 1 || coluna > 3) {
printf ("\n\n Vez do Jogador %d. Escolha a Coluna (1,2,3): ", jog);
scanf ("%d", &coluna);
if (coluna < 1 || coluna > 3) printf ("\nAviso: Coluna invalida!
Voce so pode escolher as colunas de 1 a 3.\n");
}
linha--;
coluna--;
if (casa[linha][coluna] != 1 && casa[linha][coluna] != 2) {
casa[linha][coluna] = jog;
i = 1;
} else {
printf ("Ja houve jogada nesta casa! Escolha outra casa.\n");
}
}
}



Atividade 2

Observando as regras do jogo de damas, preencha o tabuleiro que voc
criou naAtividade 1, crie uma funo que determine as jogadas e as
valide. Dica: importante lembrar que a lgica do jogo de damas
diferente da lgica do jogo da velha.
Lembre: o cdigo para o jogo de damas um pouco mais complexo. Voc
ter que determinar a mudana de posio das peas, sem sobrepor (duas
peas no podem ocupar uma mesma posio na matriz); ter que
decrementar a quantidade de peas do jogador, quando uma pea sua for
comida por uma pea do adversrio; ter que impedir o jogador de mover
a pea para trs etc. Est lanado o desafio!


Verificando se houve vencedor
O jogo da velha termina no momento em que todas as casas so preenchidas ou quando um
dos jogadores completa uma sequncia de smbolos em uma linha, em uma coluna ou em
uma diagonal. Para o jogo finalizar, importante que, durante toda a partida, seja feita a
verificao do status do jogo. Ou seja, o programa deve verificar se, antes de todas as casas
serem preenchidas, j existe um vencedor. Esse controle realizado pela seguinte funo:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void check() {
int i = 0;
//verificando se houve vencedor na Horizontal:
for (i = 0; i < 3; i++) {
if (casa[i][0] == casa[i][1] && casa[i][0] == casa[i][2]) {
if (casa[i][0] == 1) win = 1;
if (casa[i][0] == 2) win = 2;
}
}
//verificando se houve vencedor na Vertical:
for (i = 0; i < 3; i++) {
if (casa[0][i] == casa[1][i] && casa[0][i] == casa[2][i]) {
if (casa[0][i] == 1) win = 1;
if (casa[0][i] == 2) win = 2;
}
}
//verificando se houve vencedor na Diagonal de cima para baixo:
if (casa[0][0] == casa[1][1] && casa[0][0] == casa[2][2]) {
if (casa[0][0] == 1) win = 1;
if (casa[0][0] == 2) win = 2;
}
//verificando se houve vencedor na Diagonal de baixo para cima:
if (casa[0][2] == casa[1][1] && casa[0][2] == casa[2][0]) {
if (casa[0][2] == 1) win = 1;
if (casa[0][2] == 2) win = 2;
}
}


Lembre-se de que a varivel win foi criada no incio do nosso cdigo para armazenar o
vencedor (que pode ser o valor inteiro 1 ou 2). Cada estrutura for, na funo check, verifica
se houve vencedor em uma situao especfica. Todas as situaes de vitrias possveis so
checadas (na vertical, na horizontal e na diagonal).

Colocando o jogo para funcionar
Depois de escrevermos todas essas funes, voc deve estar ansioso para ver o jogo
funcionando, no mesmo?
Para isso, falta apenas a definio da funo principal: a funo main. Nela, so chamadas as
outras funes do jogo para que ele funcione. Veja o cdigo da funo main:

01
02
03
int main() {
int i = 0;
//percorre todo o tabuleiro, nas nove posies:
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
for (i = 0; i < 9; i++) {
limpa(); //chama a funo limpa(), para limpar a tela
jogo(); //chama a funo jogo(), que desenha o tabuleiro
if (!divi(i, 2)) jogar(2);
else jogar(1);
check(); //chama a funo check (), para ver se algum ganhou
if (win == 1 || win == 2) i = 10; //sai do lao antes de completar o
tabuleiro, se algum tiver vencido
}
limpa();//chama a funo limpa(), para limpar a tela
jogo();//chama a funo jogo(), para desenhar novamente o tabuleiro
if (win == 1 || win == 2) { //verifica se houve vencedor
printf ("\nJogador %d o ganhador!\n", win);//informa o vencedor
sleep(2); //Para por 2 segundos o display, para que o jogador possar
visualizar a mensagem
} else { //se no houve vencedor
printf ("\nNo houve vencedor! O jogo foi empate!!\n");//informa o
empate
sleep(2); //Para por 2 segundos o display, para que o jogador possar
visualizar a mensagem
}
return 0;
}


Observe os comentrios em verde, no cdigo. A funo limpa, que chamada algumas
vezes na funo principal, usada para limpar a tela e sua implementao a seguinte:

void limpa() {
system("cls");
}

Vamos implementar? Junte todas as funes em um cdigo s e execute. Veja como fica a
tela inicial do jogo na Figura 4.

Figura 4 - Tela inicial do jogo da velha

Veja que aparece o tabuleiro, a informao de quem a vez e a solicitao para a escolha da
linha.
Aps a escolha da linha, o jogador escolhe a coluna e a marcao feita. Veja, na Figura 5,
a marcao feita para a linha 2 e coluna 2.


Figura 5 - Marcao do primeiro jogador na linha 2 e coluna 2

Nesse momento, a marcao feita na linha e coluna escolhidas e a vez de jogar passa para
o jogador 2. As jogadas so realizadas, alternadamente, at que haja um vencedor ou o
empate.

Agora que voc implementou o jogo e ele funcionou, teste e divirta-se vontade.
Na prxima aula, incluiremos alguns adicionais ao jogo, como cadastro de
jogadores, ranking e contagem de tempo . At l!

Potrebbero piacerti anche