Jump to content

Jogo da Velha


JOAOBERNARD070
Go to solution Solved by antseq,

Recommended Posts

Boas tou com dificuldade em q seja possível ganhar nas colunas, n consigo encontrar o erro nas funções verificaColuna e verificaTodasColunas.

Se me puderem ajudar agradecia

#include <stdio.h>
#include <stdlib.h>
#include "JogoDaVelha.h"

int main() {
    char pedra[] = {'X', 'O'};
    int l = 3;
    int c = 3;
    char **jogo = geraTabuleiro(l,c);
    int indexPedra = 0; // joga a primeira pedra

    char voltaJogar;
    do{  //:::::::::::::::::::::::::::::::::::::::::::::
        acercaDe();
        limpaTabuleiro(jogo,l,c);
        imprimeTabuleiro(jogo,l,c);
        //Joga o jogo
        while( ! jogoAcabou(jogo, pedra[indexPedra], l, c)){ //verificar se ganhou ou acabou

            //trocar a pedra
            if( indexPedra==0)
                indexPedra=1;
            else
                indexPedra=0;
            //joga a pedra na posição que será escolhida
            jogaPedra(jogo, pedra[indexPedra],l,c);
        }

        printf("Jogo terminado");
        if( ganhou(jogo, pedra[indexPedra],l, c))
            printf("\nParabens !!! A pedra %c GANHOU ",pedra[indexPedra]);
        else
            printf("\nEmpataram");
        //::::::::::::::::::::::::::::::::::::::::::::::
        printf("\nDeseja volta a jogar ? (n/N para terminar) ");
        scanf(" %c",&voltaJogar);
    }while(voltaJogar != 'n' && voltaJogar != 'N'  );
    return 0;
}
//
// Created by joaob on 12/04/2020.
//
#ifndef JOGODAVELHA_JOGODAVELHA_H
#define JOGODAVELHA_JOGODAVELHA_H

char VAZIO;
void acercaDe();
//cria o tabuleiro do jogo
char **geraTabuleiro(int linhas, int colunas);
//liberta a memória alocada
void liberta(char **velha, int linhas);
//imprime na consola o tabuleiro
void imprimeTabuleiro(char **velha, int linhas, int colunas);
//limpa as posições do tabuleiro, retornando em cada uma  a char VAZIO
void limpaTabuleiro(char **velha, int linhas, int colunas);
//joga uma pedra no tabuleiro
void jogaPedra(char **velha , char pedra, int linhas, int colunas);
//verifica se todas as posicoes estão ocupadas
int estaCompleto(char **velha, int linhas, int colunas);
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verifica uma linha
int verificaLinha(char *velha, char pedra, int linhas);
//verifica todas as linhas
int verificaTodasLinhas(char **velha, char pedra, int linhas);
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verifica uma coluna
int verificaColuna(char *velha, char pedra, int colunas);
//verifica todas as colunas
int verificaTodasColunas(char **velha, char pedra, int colunas);
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verificar a diagonal principal
int ganhouDiagonalPrincipal(char **velha, char pedra, int linhas);
//verificar a diagonal inversa
int ganhouDiagonalInversa(char **velha, char pedra, int linhas);
//verifica se o jogador ganhou na diagonal
int ganhouDiagonal(char **velha, char pedra, int linhas);
//verificar se a pedra ganhou no jogo velha
int ganhou(char **velha, char pedra, int linhas, int colunas);
//verificar se o jogo está acabado
int jogoAcabou(char **velha ,char pedra, int linhas, int colunas);

#endif //JOGODAVELHA_JOGODAVELHA_H

 

//
// Created by joaob on 12/04/2020.
//
#include <stdio.h>
#include <stdlib.h>

char VAZIO = '.';
void acercaDe(){
    printf("J O G O   D A   V E L H A \n");
    printf("(c) Jo@o Vieira 2020\n");
    printf("Aluno nº 21594 de Programacao II\n");
}

char **geraTabuleiro(int linhas, int colunas) {         // matriz[linhas][coluna]
    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //alocar uma matriz quadrada
    //:::::::::::::::::::::::::::::::::::::::::::::::::::::::
    // gerar o vetor de ponteiro de vetores inteiros
    int **m = (int **) malloc(linhas * sizeof(int *));
    //gerar as linhas
    for (int i = 0; i < linhas; i++) {
        m[i] = (int *) malloc(colunas * sizeof(int));
    }
    for(int y=0; y < linhas; y++){
        for(int x=0; x < colunas; x++){
            m[y][x] = 'X';
        }
    }
    //retornar a matriz
    return m;
}

void liberta(char **m, int linhas){
    //libertar as linhas
    for(int y = 0; y < linhas; y++){
        free(m[y]);
    }
    //libertar a matriz
    free(m);
}

void imprimeTabuleiro(char **velha, int linhas, int colunas){
    for(int y = 0; y < linhas; y++){
        for(int x = 0; x < colunas; x++){
            printf( " %c ", velha[y][x]);
        }
        printf("\n"); //muda para a proxima linha
    }
}

void limpaTabuleiro(char **velha, int linhas, int colunas){
    for(int y= 0; y < linhas; y++){
        for(int x= 0; x < colunas; x++){
            velha[y][x] = VAZIO;
        }
    }
}

void jogaPedra(char **velha , char pedra, int linhas, int colunas){
    int linha, coluna;
    while(1){//repete até introduzir uma posição válida
        //:::::::::::::::::::::::::::::::::::::::::::::
        printf("\nJogador %c", pedra);
        //introduzir uma linha válida
        while(1){
            printf("\nIntroduza a linha : ");
            scanf("%d", &linha);
            if( linha >= 0 && linha < linhas){
                break;
            } else{
                printf("Linha invalida");
            }
        }
        //:::::::::::::::::::::::::::::::::::::::::::::
        while(1){
            printf("\nIntroduza a Coluna : ");
            scanf("%d", &coluna);
            if( coluna >= 0 && coluna < colunas){
                break;
            } else{
                printf("Coluna invalida");
            }
        }

        //verificar se introduziu uma posicao valida
        if(velha[linha][coluna] == VAZIO){
            break;
        } else{
            //mensagem
            printf("\n ERRO posicao ocupada");
        }

    }
    // jogar a pedra na posição válida
    velha[linha][coluna] = pedra;
    //atualizar o tabuleiro
    imprimeTabuleiro(velha, linhas, colunas);
}

//verifica se todas as posicoes estão ocupadas
int estaCompleto(char **velha, int linhas, int colunas){
    for(int y= 0; y < linhas; y++) {//percorre todas as linhas
        for (int x = 0; x < colunas; x++) {//percorre todas as colunas
            //verificar se a posicao y,x é igual a vazio
            if( velha[y][x] == VAZIO)
                return 0; // nao esta completo
        }
    }
    //estao todas ocupadas
    return 1;
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verificar as linhas
int verificaLinha(char *velha, char pedra, int linhas){
    for(int i=0; i < linhas ; i++){
        if(velha[i]!= pedra)
            return 0; //existe uma posicao que não é ocupada pela pedra
    }
    return 1; //todas as posições são do tipo pedra
}

int verificaTodasLinhas(char **velha, char pedra, int linhas){
    for(int y=0; y < linhas; y++){//percorre as linhas
        if( verificaLinha(velha[y], pedra, linhas)) //verificar se ganhou na linha y
            return 1;
    }
    //não ganhou nas linhas
    return 0;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verificar as colunas
int verificaColuna(char *velha, char pedra, int colunas){
    for(int i=0; i < colunas ; i++){
        if(velha[i]!= pedra)
            return 0; //existe uma posicao que não é ocupada pela pedra
    }
    return 1; //todas as posições são do tipo pedra
}

int verificaTodasColunas(char **velha, char pedra, int colunas){
    for(int x = 0; x < colunas; x++){//percorre as colunas
        if( verificaColuna(velha[x], pedra, colunas)) //verificar se ganhou na coluna x
            return 1;
    }
    //não ganhou nas colunas
    return 0;
}

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//verificar as diagonais
int ganhouDiagonalPrincipal(char **velha, char pedra, int linhas){
    for(int y=0; y < linhas ; y++){
        if( velha[y][y] != pedra)
            return 0; // na diagonal principal existe uma marca diferente
    }
    return 1;//ganhou na diagonal
}

//verificar as diagonais
int ganhouDiagonalInversa(char **velha, char pedra, int linhas){
    for(int y=0; y < linhas ; y++){
        if( velha[linhas - y - 1][y] != pedra)
            return 0; // na diagonal principal existe uma marca diferente
    }
    //ganhou na diagonal inversa
    return 1;
}

int ganhouDiagonal(char **velha, char pedra, int linhas){
    return ganhouDiagonalInversa(velha,pedra,linhas) ||
           ganhouDiagonalPrincipal(velha,pedra,linhas);
}

//verificar se a pedra ganhou no jogo velha
int ganhou(char **velha, char pedra, int linhas, int colunas){
    //verifico se ganhou nas linhas
    if( verificaTodasLinhas(velha, pedra,linhas))
        return 1;
    //verifico se ganhou nas diagonais
    if( ganhouDiagonal(velha,pedra,linhas))
        return 1;
    //ganhou nas colunas
    if( verificaTodasColunas(velha, pedra, colunas))
        return 1;
    return 0; // não ganhou
}


//verificar se o jogo está acabado
int jogoAcabou(char **velha ,char pedra, int linhas, int colunas){
    if( estaCompleto(velha, linhas, colunas)) //tabuleiro completa
        return 1;
    //verificar se ganhou
    if( ganhou(velha,pedra, linhas, colunas))
        return 1;

    return 0; // o jogo não acabou nem ganhou
}
Link to comment
Share on other sites

14 horas atrás, JOAOBERNARD070 disse:

Boas tou com dificuldade em q seja possível ganhar nas colunas, n consigo encontrar o erro nas funções verificaColuna e verificaTodasColunas.

Se me puderem ajudar agradecia

Viva,

Vc tem uma matriz digamos velha[lin][col],

Na função "verificaTodasLinhas" está a chamar "if(verificaLinha(velha[y] ,,,", ou seja passa apenas uma linha específica (a linha y)

Na função "verificaTodasColunas" está a chamar "if(verificaColuna(velha[x] ,,,", ou seja passa apenas uma LINHA [está a fazer o mesmo que nas linhas] específica (a linha x)

Outro problema... (não o detectou porque o nº de linhas e colunas são idênticos e iguais a 3):

* Quando verifica uma linha específica, dentro da linha X tem de fazer um for de 0 até X colunas

no seu código verificaLinha tem "for(int i=0; i < linhas ; i++)" => Numa linha deve percorrer as colunas

* Quando verifica uma coluna específica, dentro da coluna X tem de fazer um for de 0 até X linhas

no seu código verificaColuna tem "for(int i=0; i < colunas ; i++)" => Numa coluna deve percorrer as linhas

Para não complicar o seu código, mais valia passar as funções verificaLinha e verificaColuna, o arrray completo, a linha/coluna a verificar, numero de colunas/linhas da matriz.

verificaLinha(char **velha, char pedra, int linhaparaverificar, int colunas)

verificaColuna(char **velha, char pedra, int colunaparaverificar, int linhas)

cps

Link to comment
Share on other sites

  • Solution
47 minutos atrás, JOAOBERNARD070 disse:

N percebi a sua explicação podia me exemplificar em código sff??

Mais código do que eu já inclui nos meus comentários... é um pouco difícil.

Não consegues "ver" que o teu "verificaTodasColunas" está a fazer o mesmo que o "verificaTodasLinhas"?

Explicando de outra forma, tem em consideração a seguinte matriz 3 x 3:

L1C1 L1C2 L1C3

L2C1 L2C2 L2C3

L3C1 L3C2 L3C3

Quando queres verificar a linha 2, Deves verificar na L2 as Colunas C1, C2, C3 (L2C1, L2C2, L2C3)

Quando queres verificar a coluna 3, Dever verificar na C3 as Linhas L1, L2, L3 (L1C3, L2C3, L3C3)

cps,

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.