ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

di il
6 risposte

ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

Buona sera a tutti, ammetto che questo è il mio primi post, quindi se avete consigli su come poterlo scrivere meglio, sono ben accetti.
Avverto che non programmo da molto, anzi si può dire che sono praticamente un neofita, mi sono però messo in testa da qualche giorno di scrivere un programma in c che emuli il gioco: Forza 4; il programma funzione sola in parte; mi spiego meglio: riconosce solo la combinazione di 4 "gettoni" orrizzontale, quella verticale ed obliqua non so perchè non le riconosce; chiedo quindi aiuto a voi per consigli.
qua sotto lascio il codice:

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

int **CREA_MATRICE(int,int);
void RIEMPI_MATRICE(int**,int,int);
void VIS_MATRICE(int**,int,int);
int CADUTA(int**,int,int,int);
int VITTORIA(int**, int, int, int);
int ESPLORA(int**,int,int,int);


//alternanaza giocatori
int ALT_GIOCATORI(int);
int ALT_GIOCATORI_INV(int);

int main(){
    int **matrice;
    int riga=8;
    int colonna=10;
    int giocatore=1;
    int scelta=0;
    int i=0;
    int alt=0;
    int cond=-1;
    int fine=0;


    //inizzializzo e riempio la matrice con 0.
    matrice=CREA_MATRICE(riga,colonna);
    RIEMPI_MATRICE(matrice,riga,colonna);

    //visualizzo il campo di gioco.
    VIS_MATRICE(matrice,riga,colonna);
    //gestione caduta del gettone
    do {
        alt=CADUTA(matrice, riga, colonna, giocatore);
        VIS_MATRICE(matrice, riga, colonna);

        if(ESPLORA(matrice,riga,colonna,giocatore)==1) {
            printf("\n\nil giocatore %d ha vinto...CONGRATULAZIONE!!\n", giocatore);
            fine=1;
        }
        if(alt==1)
            giocatore=ALT_GIOCATORI_INV(giocatore);
        else
        giocatore=ALT_GIOCATORI(giocatore);
    }while(!fine);

    return 0;
}
int **CREA_MATRICE(int riga,int colonna){
    int **matrice;
    int i=0;

    matrice=(int**)malloc(riga*sizeof(int*));
    for(i=0;i<riga;i++){
        matrice[i]=(int*)malloc(colonna*sizeof(int));
    }
    return matrice;
}
void RIEMPI_MATRICE(int **matrice,int riga,int colonna){
    int i=0,j=0;

    for(i=0;i<riga;i++){
        for(j=0;j<colonna;j++){
            matrice[i][j]=0;
        }
    }
}
void VIS_MATRICE(int **matrice,int riga,int colonna) {
    int i = 0, j = 0;

    printf("          0  1  2  3  4  5  6  7  8  9");
    for (i = 0; i < riga; i++) {
        printf("\n");
        printf("riga %d |", i + 1);
        for (j = 0; j < colonna; j++) {
            printf("  %d", matrice[i][j]);
        }
        printf("  |");
    }
}
int CADUTA(int **matrice,int riga,int colonna,int giocatore){
    int i=0,j=0;
    int scelta=-1;
    int driga=riga;
    int ex=0;

    printf("\n\n");
    printf("giocatore %d, ",giocatore);
    printf("scegli la colonna in cui far cadere il gettone.\n");
    do{
        scanf("%d",&scelta);
        if(scelta<0||scelta>colonna-1)
            printf("scelta sbagliata,ritenta per favore.\n");

    }while(scelta<0||scelta>colonna-1);

    //ciclo di controllo riga
    for(i=riga-1;i>=0;i--){
        if(matrice[i][scelta]!=0)
            driga=driga-1;
        if(driga==0) {
            printf("colonna piena; ritenta.\n");
            ex=1;
        }
    }

    //assegnazione valore per colonna
    for (i = driga-1; i >= 0; i--) {
        matrice[i][scelta] = giocatore;
        break;
    }
return ex;
}
int ESPLORA(int **matrice,int riga,int colonna,int giocatore){
    int i,j;

    for(i=riga-1;i>=0;i--){
        for(j=0;j<colonna;j++){
            if(VITTORIA(matrice,i,j,giocatore)!=0)
                return 1;
        }
    }
    return 0;
}
int VITTORIA(int **matrice, int riga, int colonna, int giocatore){
    int i=0,j=0;
    int cont=0;
    int step=0;
    int drighe,dcolonne,delta;

            for(step=1;step<=4;step++){
                switch(step){
                    case 1:                            //movimento orrizzontale a destra;
                        drighe=0;
                        dcolonne=1;
                        break;
                    case 2:                           //movimento diagonale a destra verso l'alto;
                        drighe=1;
                        dcolonne=1;
                        break;
                    case 3:                           //movimento verticale in alto;
                        drighe=1;
                        dcolonne=0;
                        break;
                    case 4:                           //movimento diagonale a sinistra in alto.
                        drighe=1;
                        dcolonne=-1;
                        break;
                }
                for(delta=0;delta<4;delta++){
                    if(riga<0||riga>=8)
                        break;
                    if(colonna<0||colonna>=10)
                        break;

                    if(matrice[riga][colonna]==giocatore)
                        cont++;
                    riga=riga+drighe;
                    colonna=colonna+dcolonne;
                }

                if(cont==4)
                    return 1;
            }
        return 0;
}

int ALT_GIOCATORI(int giocatore){
    if(giocatore==1)
        giocatore=2;
    else
        giocatore=1;
    return giocatore;
}
int ALT_GIOCATORI_INV(int giocatore){
    if(giocatore==1)
        giocatore=1;
    else
        giocatore=2;
    return giocatore;
}
grazie a tutti in anticipo

6 Risposte

  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    Inserisci il codice tra tag code o non si capisce nulla. Leggi il regolamento.
  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    Ciao, io più semplicemente farei qualcosa del genere:
    #include <stdio.h>
    #include <windows.h>
    
    #define R 6
    #define C 7
    
    #define EMPTY 7
    #define G_1 12
    #define G_2 14
    
    void cambia_colore(int colore)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colore);
    }
    
    void inizializza(int m[R][C], int v[C])
    {
        for(unsigned int j = 0; j < C; ++j)
        {
            v[j] = R;
            for(unsigned int i = 0; i < R; ++i)
            {
                m[i][j] = EMPTY;
            }
        }
    }
    
    int inserimento(int m[R][C], int v[C], int j, int g)
    {
        if(v[j])
        {
            m[--v[j]][j] = g;
            return 1;
        }
        return 0;
    }
    
    int vittoria(int m[R][C], int j, int g)
    {
        return 0;
    }
    
    int griglia_piena(int v[C])
    {
        for(unsigned int j = 0; j < C; ++j)
        {
            if(v[j])
            {
                return 0;
            }
        }
        return 1;
    }
    
    void stampa_griglia(int m[R][C])
    {
        system("CLS");
        for(unsigned int j = 0; j < C; ++j)
        {
            printf("%d ", j);
        }
        printf("\n\n");
        for(unsigned int i = 0; i < R; ++i)
        {
            for(unsigned int j = 0; j < C; ++j)
            {
                cambia_colore(m[i][j]);
                printf("O ");
            }
            printf("\n");
        }
        printf("\n");
        cambia_colore(EMPTY);
    }
    
    int main()
    {
        int m[R][C];
        int v[C];
        int g = G_1;
        int j;
        inizializza(m, v);
        stampa_griglia(m);
        while(1)
        {
            do
            {
                printf("COLONNA --> ");
                scanf("%d", &j);
            }
            while(j < 0 || j >= C || !inserimento(m, v, j, g));
            stampa_griglia(m);
            if(vittoria(m, j, g) || griglia_piena(v))
            {
                break;
            }
            g = G_1 * (g != G_1) + G_2 * (g != G_2);
        }
        return 0;
    }
    Per quanto riguarda la funzione vittoria() ci penso un po' e poi ti faccio sapere come imposterei il problema.
  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    Ok, grazie mille, nel mentre mi vedo il codice che hai postato.
  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    Allora, ho dato un'occhiata al tuo codice e più o meno ho intuito quello che stai cercando di fare, ma io userei un approccio diverso.
    Per esempio tu ad ogni inserimento cerchi una sequenza di 4 gettoni nell'intera griglia, quando invece basterebbe controllare che l'ultimo inserimento effettuato sia parte di una sequenza di almeno 4 gettoni del giocatore di turno. A partire dall'ultimo inserimento la ricerca va fatta in 4 direzioni:
    - verticale --> a partire dal gettone in esame in questo caso la ricerca va fatta in una solo verso, ossia verso il basso, in quanto ovviamente verso l'alto non ci saranno altri gettoni. Basta quindi un semplice for su un indice i che parte dalla riga successiva a quella del gettone considerato e viene incrementato finché non viene raggiunta la fine della griglia o viene intercettata una casella non appartenente al giocatore di turno. Ovviamente ad ogni iterazione va incrementato anche un apposito contatore;
    - orizzontale --> in questo caso invece la ricerca va effettuata in due versi, ossia a sinistra e a destra del gettone in esame. Saranno quindi necessari due for simili a quello che ho illustrato nel caso precedente. La variabile contatore sarà in comune ai due for e la condizione di vittoria, che nel caso verticale può essere scritta come cont==4, sarà cont>=4 in quanto potrebbero verificarsi anche sequenza vincenti più lunghe;
    - diagonale principale --> la logica è quella del caso orizzontale;
    - diagonale secondaria --> come sopra.

    Ovviamente l'algoritmo illustrato può essere ottimizzato attraverso alcuni controlli (if), ma possono cmq essere trascurati in quanto non produrrebbero miglioramenti percepibili dall'utente.
  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    In questo modo evito quindi di cercare ogni volta per tutta la griglia e dovrei guadagnare in tempo di esecuzione giusto?
  • Re: ESERCIZIO DI PROGRAMMAZIONE IN C: GIOCO FORZA 4

    Il guadagno in tempo in un caso del genere quasi sicuramente non sarebbe neanche percettibile, il punto è adottare un'impostazione logica più efficiente. Per esempio vedi la differenza tra la tua funzione CADUTA() e la mia inserimento().
Devi accedere o registrarti per scrivere nel forum
6 risposte