#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
/* Constantes */
#define Q_LINHAS 3
#define Q_COLUNAS 3
/* Valores dos objetos no jogo */
enum t_objetos {
VAZIO,
CRUZ,
BOLA,
VELHA
};
void
limpaTabuleiro(enum t_objetos t[][Q_COLUNAS]);
int
validaJogada(enum t_objetos t[][Q_COLUNAS], int linha, int coluna);
enum t_objetos
verificaVitoria(enum t_objetos t[][Q_COLUNAS]);
int main(void)
{
enum
t_objetos tabuleiro[Q_LINHAS][Q_COLUNAS],
vez = CRUZ;
int
locais[Q_LINHAS*Q_COLUNAS],
contador,
linhas,
colunas;
char opcao;
/* Inicia o gerador de numeros aleatorios */
srand(time(NULL));
do {
/* Limpa o tabuleiro */
limpaTabuleiro(tabuleiro);
/*
* Inicia o local das jogadas
* Coloca todos os locais das jogadas em sequencia
*/
for (contador = 0; contador < Q_LINHAS*Q_COLUNAS; contador++) {
locais[contador] = contador;
}
/*
* Embaralha o local das jogadas
* Com o algoritmo Fisher Yates
*/
for (contador = 0; contador < Q_LINHAS*Q_COLUNAS; contador++) {
int indice = rand()%(Q_LINHAS*Q_COLUNAS);
int temporario = locais[contador];
locais[contador] = locais[indice];
locais[indice] = temporario;
}
/* Faz as jogadas */
do {
contador = 0;
while (contador < (Q_LINHAS*Q_COLUNAS)) {
if (validaJogada(tabuleiro, locais[contador]/Q_LINHAS, locais[contador]%Q_COLUNAS)) {
/* Coloca a jogada no tabuleiro */
tabuleiro[locais[contador]/Q_LINHAS][locais[contador]%Q_COLUNAS] = vez;
if (vez == CRUZ) {
vez = BOLA;
} else {
vez = CRUZ;
}
break;
}
contador++;
}
} while (verificaVitoria(tabuleiro) == VAZIO);
/* Mostra o tabuleiro */
for (linhas = 0; linhas < Q_LINHAS; linhas++) {
for (colunas = 0; colunas < Q_COLUNAS; colunas++) {
switch (tabuleiro[linhas][colunas]) {
case VAZIO:
if (linhas < Q_LINHAS-1) {
printf("_");
} else {
printf(" ");
}
break;
case CRUZ:
printf("X");
break;
case BOLA:
printf("O");
break;
}
if (colunas < Q_COLUNAS-1) {
printf("|");
}
}
printf("\n");
}
switch (verificaVitoria(tabuleiro)) {
case CRUZ:
printf("Vitoria da cruz!\n");
break;
case BOLA:
printf("Vitoria da bola!\n");
break;
case VELHA:
printf("Ninguem ganhou!\n");
}
printf("\n");
printf("Rodar a simulacao novamente\nS|N:");
scanf("%c%*c", &opcao);
} while (toupper(opcao) == 'S');
return(0);
}
void
limpaTabuleiro(enum t_objetos t[][Q_COLUNAS])
{
int linhas, colunas;
for (linhas = 0; linhas < Q_LINHAS; linhas++) {
for (colunas = 0; colunas < Q_COLUNAS; colunas++) {
t[linhas][colunas] = VAZIO;
}
}
}
int
validaJogada(enum t_objetos t[][Q_COLUNAS], int linha, int coluna)
{
if (t[linha][coluna] == VAZIO) {
return(1);
}
return(0);
}
enum t_objetos
verificaVitoria(enum t_objetos t[][Q_COLUNAS])
{
int
linhas,
colunas,
contador;
enum t_objetos objeto;
/* Verifica as linhas */
for (linhas = 0; linhas < Q_LINHAS; linhas++) {
objeto = t[linhas][0];
contador = 1;
for (colunas = 1; colunas < Q_COLUNAS; colunas++) {
if (objeto == t[linhas][colunas]) {
contador++;
}
}
if (contador >= Q_LINHAS) {
if (objeto != VAZIO) {
return(objeto);
}
}
}
/* Verifica as colunas */
for (colunas = 0; colunas < Q_COLUNAS; colunas++) {
objeto = t[0][colunas];
contador = 1;
for (linhas = 1; linhas < Q_LINHAS; linhas++) {
if (objeto == t[linhas][colunas]) {
contador++;
}
}
if (contador >= Q_LINHAS) {
if (objeto != VAZIO) {
return(objeto);
}
}
}
/* Verifica diagona esquerda */
objeto = t[0][0];
contador = 1;
for (linhas = 1, colunas = 1; linhas < Q_LINHAS||colunas < Q_COLUNAS; linhas++, colunas++) {
if (objeto == t[linhas][colunas]) {
contador++;
}
}
if (contador >= Q_LINHAS) {
if (objeto != VAZIO) {
return(objeto);
}
}
/* Verifica diagona direita */
objeto = t[Q_LINHAS-1][0];
contador = 1;
for (linhas = Q_LINHAS-2, colunas = 1; linhas > 0||colunas < Q_COLUNAS; linhas--, colunas++) {
if (objeto == t[linhas][colunas]) {
contador++;
}
}
if (contador >= Q_LINHAS) {
if (objeto != VAZIO) {
return(objeto);
}
}
/* Verifica velha */
contador = 0;
for (linhas = 0; linhas < Q_LINHAS; linhas++) {
for (colunas = 0; colunas < Q_COLUNAS; colunas++) {
if (t[linhas][colunas] != VAZIO) {
contador++;
}
}
}
if (contador == (Q_LINHAS*Q_COLUNAS)) {
return(VELHA);
}
return(VAZIO);
}