Olá pessoal…
Recentemente decidi criar um jogo da velha em Linguagem C, demonstrando o funcionamento do código e a lógica por trás.
O jogo é simples, e segue as regras do jogo real, com uma dificuldade moderada (sim é possível fechar a máquina com uma jogada em L por exemplo).
Ao executar, é mostrado a tela inicial, onde é preciso pressionar o -Enter- para prosseguir.
Após essa primeira tela, é solicitado se deseja o O ou o X.
Depois de selecionar, é mostrado a tela do jogo, onde os botões de 1 a 9, definem as posições em que você quer jogar, o -Espaço- inicia um novo jogo, e o -Enter- finaliza.
E ao finalizar é mostrado os créditos do jogo.
O jogo foi pensado para ser rodado tanto no Windows como em distros Linux, para distros Linux é necessário ter a biblioteca gconio.h (saiba mais em Programação: GCC + GConio.h).
Abaixo um print rodando em Windows.
Abaixo o código fonte desenvolvido.
/*================================================*
* Jogo - Jogo da veia |
* Versao - 1.2 |
* Autor - Daniel Atilio |
*================================================*/
//Biblioteca
#include <stdio.h>
#include <time.h>
//Se o sistema for Windows, utiliza a conio e a limpeza é via cls
#ifdef WIN32
#include <conio.h>
#include <windows.h>
#define LIMPA_TELA system("cls");
int ENTER = 13;
int SETA_CIMA = 72;
int SETA_BAIXO = 80;
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//Se for Linux, utiliza a gconio e a limpeza fica o usr/bin/clear
#else
#include <gconio.h>
#define LIMPA_TELA system("/usr/bin/clear");
int ENTER = 10;
int SETA_CIMA = 65;
int SETA_BAIXO = 66;
#endif
//Espera 2 segundos
#define ESPERA sleep(2);
//Funções utilizadas
void pintaQuadro(); //função que desenha o quadro utilizado no programa
void titulo(); //função que desenha a tela de título
void limpar(); //função para limpar a tela
void pintaPlacar(); //função para desenhar o placar acima
void pintaPrincipal(); //função que desenha o 'sustenido' principal
void pintaOpcao(char cPos);
int retDispon(char cJogada);
//Variáveis utilizadas no fonte inteiro
int nLinFin = 25;
int nColFin = 50;
char cEscolha = 'X';
char cMaquina = 'O';
char cUsados[9] = " ";
int nColunas[9] = {16,23,30,16,23,30,16,23,30};
int nLinhas[9] = {7,7,7,11,11,11,15,15,15};
int nPlacarMaq = 0;
int nPlacarJog = 0;
//programa principal
main(){
char cOpc = ' ';
char cCarac = '#';
//montagem da tela de título
limpar();
titulo();
pintaQuadro();
gotoxy((nColFin/2)-16,nLinFin-1);
printf("Pressione [ENTER] para iniciar...");
//Aguardando o usuário apertar o [Enter]
cOpc = getch();
while (cOpc != ENTER) {
cOpc = getch();
}
//Criação do quadro e posicionamento para começar o jogo
limpar();
cOpc = ' ';
pintaQuadro();
gotoxy((nColFin/2)-10, 3);
printf("Selecione uma opcao:");
gotoxy((nColFin/2)-6, 5);
printf("[ ] - Opcao X");
gotoxy((nColFin/2)-6, 7);
printf("[ ] - Opcao O");
gotoxy((nColFin/2)-16,nLinFin-1);
printf("Pressione [ENTER] para confirmar");
gotoxy((nColFin/2)-5,5);
cEscolha = 'X';
cMaquina = 'O';
//Aguardando o usuário apertar o [Enter], para escolher entre X ou O
while (cOpc != ENTER) {
cOpc = getch();
//seta para cima, opção X
if (cOpc == SETA_CIMA){
gotoxy((nColFin/2)-5,5);
cEscolha = 'X';
cMaquina = 'O';
}
//seta para baixo, opção O
if (cOpc == SETA_BAIXO){
gotoxy((nColFin/2)-5,7);
cEscolha = 'O';
cMaquina = 'X';
}
}
//Criação do quadro e posicionamento para começar o jogo
limpar();
cOpc = ' ';
pintaQuadro();
pintaPlacar();
pintaPrincipal();
gotoxy(25, 3);
//Enquanto não for pressionado [Enter]
while (cOpc != ENTER) {
//Pega a tecla digitada
cOpc = getch();
//49 = 1 até 57 = 9
if (cOpc >= 49 && cOpc <= 57){
pintaOpcao(cOpc);
}
//32 = espaco
if (cOpc == 32) {
pintaPrincipal();
}
//Posicionando no fim da tela, e imprimindo a tecla apertada
//gotoxy(nColFin-6,nLinFin-1);
//printf("[%4d]",cOpc);
gotoxy(25, 3);
}
//Limpando a tela, desenhando o quadro e imprimindo dados do projeto e espera o tempo pré estipulado
limpar();
pintaQuadro();
gotoxy((nColFin/2)-9,4);
printf("------------------");
gotoxy((nColFin/2)-19,6);
printf("Desenvolvedor ......... Daniel Atilio");
gotoxy((nColFin/2)-9,nLinFin-5);
printf("Jogo da Veia v1.2");
gotoxy((nColFin/2)-5,nLinFin-4);
printf("18/07/2016");
gotoxy((nColFin/2)-7,nLinFin-1);
printf("Volte Sempre...\n");
ESPERA;
printf("\n");
}
void pintaQuadro(){
int nAtu;
//percorrendo as colunas e imprimindo na tela
for (nAtu = 2; nAtu <= nColFin; nAtu++){
gotoxy(nAtu, 1);
printf("=");
gotoxy(nAtu, nLinFin);
printf("=");
}
//percorrendo as linhas e imprimindo na tela
for (nAtu = 2; nAtu <= nLinFin; nAtu++){
gotoxy(1, nAtu);
printf("|");
gotoxy(nColFin, nAtu);
printf("|");
}
//imprimindo os asteriscos
gotoxy(1,1);
printf("*");
gotoxy(nColFin, 1);
printf("*");
gotoxy(1, nLinFin);
printf("*");
gotoxy(nColFin, nLinFin);
printf("*");
}
void titulo(){
//posicionando no começo do quadro e imprimindo
gotoxy(0,2);
printf(" *-------* *----* *-----* *----* \n");
printf(" |__. .__| | | | .__.| | |\n");
printf(" | | | *--* | | | | *--* |\n");
printf(" | | | | | | | | *-* | | | |\n");
printf(" *--* | | *--* | | | | | | *--* |\n");
printf(" | | | | | *--* | | |\n");
printf(" *----* *----* *----* *----*\n");
printf(" -> DA <-\n");
printf(" *-*\n");
printf(" / /\n");
printf(" *-*\n");
printf(" *--* *--* *------* *---* * \n");
printf(" | | | | | ____| | | / \\ \n");
printf(" * * * * | |__. | | / \\ \n");
printf(" \\ * / | __| | | / * \\ \n");
printf(" \\ / | |____. | | * * * *\n");
printf(" \\ / | | | | | | | |\n");
printf(" * *------* *---* *--* *--*\n");
gotoxy((nColFin/2)-9,nLinFin-4);
printf("Jogo da Veia v1.2");
}
void limpar(){
int nLinha = 0, nColuna = 0;
//limpando a tela pelo comando do sistema
LIMPA_TELA;
//por precaução, percorre as linhas e colunas e imprime um espaço em branco, para não ficar nenhuma sujeira na tela
for (nLinha = 1; nLinha <= nLinFin; nLinha++){
for (nColuna = 1; nColuna <= nColFin; nColuna++){
gotoxy(nColuna,nLinha);
printf(" ");
}
}
}
void pintaPlacar(){
int nAtu;
//percorrendo as colunas e imprimindo na tela
for (nAtu = 2; nAtu <= nColFin-1; nAtu++){
gotoxy(nAtu, 5);
printf("-");
}
//quadro você
gotoxy(3, 2);
printf("*----* Voce");
gotoxy(3, 3);
printf("| ;P |");
gotoxy(3, 4);
printf("*----* x %4d", nPlacarJog);
//quadro máquina
gotoxy(nColFin-1-21, 2);
printf(" Maquina *----*");
gotoxy(nColFin-1-21, 3);
printf(" | XD |");
gotoxy(nColFin-1-21, 4);
printf(" x %4d *----*", nPlacarMaq);
//separação
gotoxy(25,2);
printf("|");
gotoxy(25,3);
printf("x");
gotoxy(25,4);
printf("|");
}
void pintaPrincipal(){
int nAtual;
gotoxy((nColFin/2)-11,6);
printf(" * * ");
gotoxy((nColFin/2)-11,7);
printf(" | | ");
gotoxy((nColFin/2)-11,8);
printf(" | | ");
gotoxy((nColFin/2)-11,9);
printf(" | | ");
gotoxy((nColFin/2)-11,10);
printf("*------*------*------*");
gotoxy((nColFin/2)-11,11);
printf(" | | ");
gotoxy((nColFin/2)-11,12);
printf(" | | ");
gotoxy((nColFin/2)-11,13);
printf(" | | ");
gotoxy((nColFin/2)-11,14);
printf("*------*------*------*");
gotoxy((nColFin/2)-11,15);
printf(" | | ");
gotoxy((nColFin/2)-11,16);
printf(" | | ");
gotoxy((nColFin/2)-11,17);
printf(" | | ");
gotoxy((nColFin/2)-11,18);
printf(" * * ");
gotoxy(2,nLinFin-5);
printf("[1][2][3] => Posicao");
gotoxy(2,nLinFin-4);
printf("[4][5][6] => Posicao");
gotoxy(2,nLinFin-3);
printf("[7][8][9] => Posicao");
gotoxy(2,nLinFin-2);
printf("[Espaco] => Iniciar novo jogo");
gotoxy(2,nLinFin-1);
printf("[Enter] => Finalizar");
gotoxy((nColFin/2)-16,nLinFin-6);
printf(" ");
for (nAtual = 0; nAtual <= 8; nAtual++)
cUsados[nAtual] = ' ';
}
void pintaOpcao(char cPos){
int nPosAtu = ("%d", cPos) - 48;
int nColOpc = nColunas[nPosAtu-1];
int nLinOpc = nLinhas[nPosAtu-1];
int nColMaq = 0;
int nLinMaq = 0;
int nGanhou = 0; //0=empate;1=ganhou;2=perdeu;4=deu veia
int nDispon = -1;
int nAtual = 0;
int nPosMaq = 0;
int nOk = 0; //Quantas casas disponíveis
int nTrava = 0;
int nRand = -1;
time_t tTempo;
//caso já esteja preenchido
if (cUsados[nPosAtu-1] != ' '){
gotoxy((nColFin/2)-15,nLinFin-6);
printf("Escolha uma posicao em branco!");
}
//caso tenha posição para preencher
else {
gotoxy((nColFin/2)-15,nLinFin-6);
printf(" ");
cUsados[nPosAtu-1] = cEscolha;
//pintando
gotoxy(nColOpc,nLinOpc);
//pinta X
if(cEscolha == 'X'){
printf("+ +");
gotoxy(nColOpc,nLinOpc+1);
printf(" ++ ");
gotoxy(nColOpc,nLinOpc+2);
printf("+ +");
}
//senão, pinta O
else {
printf(" -- ");
gotoxy(nColOpc,nLinOpc+1);
printf("- -");
gotoxy(nColOpc,nLinOpc+2);
printf(" -- ");
}
//primeira linha
if (cUsados[0] == cEscolha && cUsados[1] == cEscolha && cUsados[2] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//segunda linha
if (cUsados[3] == cEscolha && cUsados[4] == cEscolha && cUsados[5] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//terceira linha
if (cUsados[6] == cEscolha && cUsados[7] == cEscolha && cUsados[8] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//primeira coluna
if (cUsados[0] == cEscolha && cUsados[3] == cEscolha && cUsados[6] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//segunda coluna
if (cUsados[1] == cEscolha && cUsados[4] == cEscolha && cUsados[7] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//terceira coluna
if (cUsados[2] == cEscolha && cUsados[5] == cEscolha && cUsados[8] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//diagonal
if (cUsados[0] == cEscolha && cUsados[4] == cEscolha && cUsados[8] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//diagonal /
if (cUsados[2] == cEscolha && cUsados[4] == cEscolha && cUsados[6] == cEscolha){
gotoxy((nColFin/2)-6,nLinFin-6);
printf("Voce Ganhou!");
nGanhou = 1;
}
//Percorrendo as posições, para ver se deu veia
nOk = 0;
for (nAtual = 0; nAtual <= 8; nAtual++){
if (cUsados[nAtual] == ' ')
nOk++;
}
//se não tiver nenhuma opção disponível, deu veia
if (nOk == 0){
nGanhou = 4;
gotoxy((nColFin/2)-5,nLinFin-6);
printf("Deu Veia!");
}
//Se o usuário não ganhou ainda
if (nGanhou != 1 && nGanhou != 4){
//verifica se tem duas posições preenchidas da máquina
nDispon = retDispon(cMaquina);
if (nDispon != -1){
nColMaq = nColunas[nDispon];
nLinMaq = nLinhas[nDispon];
cUsados[nDispon] = cMaquina;
//pintando
gotoxy(nColMaq,nLinMaq);
//pinta X
if(cMaquina == 'X'){
printf("+ +");
gotoxy(nColMaq,nLinMaq+1);
printf(" ++ ");
gotoxy(nColMaq,nLinMaq+2);
printf("+ +");
}
//senão, pinta O
else {
printf(" -- ");
gotoxy(nColMaq,nLinMaq+1);
printf("- -");
gotoxy(nColMaq,nLinMaq+2);
printf(" -- ");
}
}
else {
//verifica se tem duas posições preenchidas do oponente
nDispon = retDispon(cEscolha);
if (nDispon != -1){
nColMaq = nColunas[nDispon];
nLinMaq = nLinhas[nDispon];
cUsados[nDispon] = cMaquina;
//pintando
gotoxy(nColMaq,nLinMaq);
//pinta X
if(cMaquina == 'X'){
printf("+ +");
gotoxy(nColMaq,nLinMaq+1);
printf(" ++ ");
gotoxy(nColMaq,nLinMaq+2);
printf("+ +");
}
//senão, pinta O
else {
printf(" -- ");
gotoxy(nColMaq,nLinMaq+1);
printf("- -");
gotoxy(nColMaq,nLinMaq+2);
printf(" -- ");
}
}
else{
//senão encontrar nenhuma, verifica se o meio está disponível
if (cUsados[4] == ' '){
nPosMaq = 4;
}
//Se o meio não estiver, utiliza um random, até conseguir algum canto
else {
//inicializa o random
srand((unsigned) time(&tTempo));
while (nTrava == 0){
//Gera um valor randomico entre 0 e 8
nRand = rand() % 9;
//Se o número tiver disponível, altera a trava
if (cUsados[nRand] == ' '){
nPosMaq = nRand;
nTrava = 1;
}
}
}
nColMaq = nColunas[nPosMaq];
nLinMaq = nLinhas[nPosMaq];
cUsados[nPosMaq] = cMaquina;
//pintando
gotoxy(nColMaq,nLinMaq);
//pinta X
if(cMaquina == 'X'){
printf("+ +");
gotoxy(nColMaq,nLinMaq+1);
printf(" ++ ");
gotoxy(nColMaq,nLinMaq+2);
printf("+ +");
}
//senão, pinta O
else {
printf(" -- ");
gotoxy(nColMaq,nLinMaq+1);
printf("- -");
gotoxy(nColMaq,nLinMaq+2);
printf(" -- ");
}
}
}
} //Se o usuário não ganhou ainda
//primeira linha
if (cUsados[0] == cMaquina && cUsados[1] == cMaquina && cUsados[2] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//segunda linha
if (cUsados[3] == cMaquina && cUsados[4] == cMaquina && cUsados[5] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//terceira linha
if (cUsados[6] == cMaquina && cUsados[7] == cMaquina && cUsados[8] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//primeira coluna
if (cUsados[0] == cMaquina && cUsados[3] == cMaquina && cUsados[6] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//segunda coluna
if (cUsados[1] == cMaquina && cUsados[4] == cMaquina && cUsados[7] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//terceira coluna
if (cUsados[2] == cMaquina && cUsados[5] == cMaquina && cUsados[8] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//diagonal
if (cUsados[0] == cMaquina && cUsados[4] == cMaquina && cUsados[8] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
//diagonal /
if (cUsados[2] == cMaquina && cUsados[4] == cMaquina && cUsados[6] == cMaquina){
gotoxy((nColFin/2)-9,nLinFin-6);
printf("Maquina Ganhou!");
nGanhou = 2;
}
}
//Se jogador ganhou, aumenta o placar
if (nGanhou == 1){
nPlacarJog++;
}
//Se máquina ganhou, aumenta o placar
else if (nGanhou == 2){
nPlacarMaq++;
}
pintaPlacar();
//Se alguém ganhou, pinta as posições vazias
if (nGanhou != 0){
for (nAtual = 0; nAtual <= 8; nAtual++)
if (cUsados[nAtual] == ' ')
cUsados[nAtual] = 'Z';
}
//Verificando posições
/*for (nAtual = 0; nAtual <= 8; nAtual++){
gotoxy(nColFin-1-nAtual,nLinFin-5);
printf("%c",cUsados[nAtual]);
}*/
}
int retDispon(char cJogada){
int nPosicao = -1;
//Linha 1: [Z][Z][ ]
if ((cUsados[0] == cJogada) && (cUsados[1] == cJogada) && (cUsados[2] == ' '))
return 2;
//Linha 1: [Z][ ][Z]
if ((cUsados[0] == cJogada) && (cUsados[1] == ' ') && (cUsados[2] == cJogada))
return 1;
//Linha 1: [ ][Z][Z]
if ((cUsados[0] == ' ') && (cUsados[1] == cJogada) && (cUsados[2] == cJogada))
return 0;
//*****************************************//
//Linha 2: [Z][Z][ ]
if ((cUsados[3] == cJogada) && (cUsados[4] == cJogada) && (cUsados[5] == ' '))
return 5;
//Linha 2: [Z][ ][Z]
if ((cUsados[3] == cJogada) && (cUsados[4] == ' ') && (cUsados[5] == cJogada))
return 4;
//Linha 2: [ ][Z][Z]
if ((cUsados[3] == ' ') && (cUsados[4] == cJogada) && (cUsados[5] == cJogada))
return 3;
//*****************************************//
//Linha 3: [Z][Z][ ]
if ((cUsados[6] == cJogada) && (cUsados[7] == cJogada) && (cUsados[8] == ' '))
return 8;
//Linha 3: [Z][ ][Z]
if ((cUsados[6] == cJogada) && (cUsados[7] == ' ') && (cUsados[8] == cJogada))
return 7;
//Linha 3: [ ][Z][Z]
if ((cUsados[6] == ' ') && (cUsados[7] == cJogada) && (cUsados[8] == cJogada))
return 6;
//*****************************************//
/*Coluna 1:
[Z]
[Z]
[ ]
*/
if ((cUsados[0] == cJogada) && (cUsados[3] == cJogada) && (cUsados[6] == ' '))
return 6;
/*Coluna 1:
[Z]
[ ]
[Z]
*/
if ((cUsados[0] == cJogada) && (cUsados[3] == ' ') && (cUsados[6] == cJogada))
return 3;
/*Coluna 1:
[ ]
[Z]
[Z]
*/
if ((cUsados[0] == ' ') && (cUsados[3] == cJogada) && (cUsados[6] == cJogada))
return 0;
//*****************************************//
/*Coluna 2:
[Z]
[Z]
[ ]
*/
if ((cUsados[1] == cJogada) && (cUsados[4] == cJogada) && (cUsados[7] == ' '))
return 7;
/*Coluna 2:
[Z]
[ ]
[Z]
*/
if ((cUsados[1] == cJogada) && (cUsados[4] == ' ') && (cUsados[7] == cJogada))
return 4;
/*Coluna 2:
[ ]
[Z]
[Z]
*/
if ((cUsados[1] == ' ') && (cUsados[4] == cJogada) && (cUsados[7] == cJogada))
return 1;
//*****************************************//
/*Coluna 3:
[Z]
[Z]
[ ]
*/
if ((cUsados[2] == cJogada) && (cUsados[5] == cJogada) && (cUsados[8] == ' '))
return 8;
/*Coluna 3:
[Z]
[ ]
[Z]
*/
if ((cUsados[2] == cJogada) && (cUsados[5] == ' ') && (cUsados[8] == cJogada))
return 5;
/*Coluna 3:
[ ]
[Z]
[Z]
*/
if ((cUsados[2] == ' ') && (cUsados[5] == cJogada) && (cUsados[8] == cJogada))
return 2;
//*****************************************//
/*Diagonal Esquerda
[Z]
[Z]
[ ]
*/
if ((cUsados[0] == cJogada) && (cUsados[4] == cJogada) && (cUsados[8] == ' '))
return 8;
/*Diagonal Esquerda
[Z]
[ ]
[Z]
*/
if ((cUsados[0] == cJogada) && (cUsados[4] == ' ') && (cUsados[8] == cJogada))
return 4;
/*Diagonal Esquerda
[ ]
[Z]
[Z]
*/
if ((cUsados[0] == ' ') && (cUsados[4] == cJogada) && (cUsados[8] == cJogada))
return 0;
//*****************************************//
/*Diagonal Direita
[Z]
[Z]
[ ]
*/
if ((cUsados[2] == cJogada) && (cUsados[4] == cJogada) && (cUsados[6] == ' '))
return 6;
/*Diagonal Direita
[Z]
[ ]
[Z]
*/
if ((cUsados[2] == cJogada) && (cUsados[4] == ' ') && (cUsados[6] == cJogada))
return 4;
/*Diagonal Direita
[ ]
[Z]
[Z]
*/
if ((cUsados[2] == ' ') && (cUsados[4] == cJogada) && (cUsados[6] == cJogada))
return 2;
return nPosicao;
}
Bom pessoal, por hoje é só.
Abraços e até a próxima.





eu gosto