Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12

Discussione: [C]Gioco del 15

  1. #1

    [C]Gioco del 15

    Salve a tutti!

    Sto scrivendo il gioco del 15 in C http://it.wikipedia.org/wiki/Gioco_del_quindici :

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    
    void crea_matrice(int [][4]);
    void stampa_matrice(int [][4]);
    void muovi_numero(int [][4]);
    int appartiene_a2D(int n, int [][4]);
    int vittoria(int [][4]);
    
    int matrice_random[4][4];
    int mossa=1;
    
    int main()
    {
        crea_matrice(matrice_random);
        stampa_matrice(matrice_random);
    
        while(mossa<=30)
        {
            muovi_numero(matrice_random);
            system("cls");
            stampa_matrice(matrice_random);
            printf("Mossa numero: %d",mossa);
            mossa++;
        }
    
        return 0;
    }
    
    void crea_matrice(int campo[][4])
    {
        int i,x,y;
        srand(time(NULL));
        for(i=0;i<16;i++)
            {
                x=rand()%4;
                y=rand()%4;
                if(campo[x][y])
                    i--;
                else
                    campo[x][y]=i;
            }
    }
    
    void stampa_matrice(int campo[][4])
    {
        int x,y;
        for(x=0;x<4;x++)
        {
            for(y=0;y<4;y++)
            {
                if(campo[x][y]==0)
                    printf("%7c",255);
                else
                    printf("%7d",campo[x][y]);
            }
            printf("\n\n\n\n");
        }
    }
    
    void muovi_numero(int campo[][4])
    {
        int x,y,n;
        printf("\nDigita il numero da spostare: ");
        scanf("%d",&n);
        if(appartiene_a2D(n,campo) && n!=0)
        {
            for(x=0;x<4;x++)
                for(y=0;y<4;y++)
                {
                    if(campo[x][y]==0)
                    {
                        if(campo[x][y+1]==n)
                        {
                            campo[x][y+1]=0;
                            campo[x][y]=n;
                            break;
                        }
                        else if(campo[x][y-1]==n)
                        {
                            campo[x][y-1]=0;
                            campo[x][y]=n;
                            break;
                        }
                        else if(campo[x+1][y]==n)
                        {
                            campo[x+1][y]=0;
                            campo[x][y]=n;
                            break;
                        }
                        else if(campo[x-1][y]==n)
                        {
                            campo[x-1][y]=0;
                            campo[x][y]=n;
                            break;
                        }
                        else
                        {
                            printf("\nERRORE!! Il numero %d non puo' essere spostato\n",n);
                            muovi_numero(campo);
                        }
                    }
                }
        }
        else
        {
            printf("\nERRORE!! Devi digitare un numero da 1 a 15.\n");
            muovi_numero(campo);
        }
    }
    
    int appartiene_a2D(int n, int campo[][4])
    {
        int r,c;
        for(r=0;r<4;r++)
            for(c=0;c<4;c++)
                if(n==campo[r][c])
                    return 1;
        return 0;
    }
    E sto avendo dei problemi nella funzione muovi_numero(), in pratica riesco a spostare un numero a sinistra, destra e giù ma non su.

    codice:
    else if(campo[x+1][y]==n)
                        {
                            campo[x+1][y]=0;
                            campo[x][y]=n;
                            break;
                        }
    Secondo voi dove sbaglio? Grazie a chi mi aiuta

  2. #2
    I vari break che hai piazzato fanno uscire solo dal for più interno; il ciclo sulle x continua ad andare, individua nuovamente il numero inserito e scambia di nuovo, effettivamente annullando il primo spostamento. Puoi risolvere con un flag controllato nella condizione del for esterno, o più banalmente con un return.

    Per inciso, ci sono un po' di altri errori su quelle condizioni, in particolare non consideri che sui bordi vai a sforare l'array del campo (ad esempio, se il ciclo è arrivato ad (x,y)=(3,3), i vari if vanno a controllare gli elementi (3,4) e (4,3), sforando dai bordi dell'array).
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Grazie mille, in effetti non avevo pensato agli effetti di quei break. Mi è bastato mettere un "x++" alla fine per aggirare il controllo
    Esiste un metodo "più elegante" o va bene quello da me proposto?

  4. #4
    Originariamente inviato da Ashley_Riot
    Mi è bastato mettere un "x++" alla fine per aggirare il controllo
    Non ho ben capito... posta la funzione modificata.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Certo :

    codice:
    else if(campo[x+1][y]==n)
                        {
                            campo[x][y]=n;
                            campo[x+1][y]=0;
                            x++;
                            break;

  6. #6
    Sì dovrebbe funzionare, ma esegui comunque un tot di cicli a vuoto... Ribadisco, con una return al posto del break risolvi a colpo.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Quindi devo piazzare un return alla fine di ogni if?

    codice:
    else if(campo[x+1][y]==n)
                        {
                            campo[x][y]=n;
                            campo[x+1][y]=0;
                            return;
                        }

  8. #8
    Sì, al posto del break; in quel modo appena hai fatto lo scambio esci dalla funzione - il che ha senso, visto che, fatto uno scambio, non resta più nulla da fare.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Perfetto! Ti ringrazio per l'aiuto, questo dovrebbe essere il codice finale :

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    
    void crea_matrice_ordinata(int [][4]);
    void crea_matrice_random(int [][4]);
    void stampa_matrice(int [][4]);
    void muovi_numero(int [][4]);
    int appartiene_a2D(int n, int [][4]);
    int vittoria(int [][4], int [][4]);
    
    int matrice[4][4];
    int matrice_random[4][4];
    int mossa=1;
    
    int main()
    {
        crea_matrice_random(matrice_random);
        crea_matrice_ordinata(matrice);
        stampa_matrice(matrice_random);
    
        while(mossa<=30 || vittoria(matrice_random,matrice))
        {
            muovi_numero(matrice_random);
            system("cls");
            stampa_matrice(matrice_random);
            mossa++;
        }
    
        if(mossa>=30)
            printf("\n\nGAME OVER!! Hai raggiunto le 30 mosse possibili.\n");
        else if(vittoria(matrice_random,matrice))
            printf("\n\nCOMPLIMENTI!! Hai ordinato tutti i numeri alla %d-esima mossa\n", mossa);
    
        return 0;
    }
    
    void crea_matrice_ordinata(int campo[][4])
    {
        int x,y;
        int i=1;
        for(x=0;x<4;x++)
            for(y=0;y<4;y++)
            {
                campo[x][y]=i;
                if(campo[x][y]==16)
                    campo[x][y]=0;
                i++;
            }
    }
    void crea_matrice_random(int campo[][4])
    {
        int i,x,y;
        srand(time(NULL));
        for(i=0;i<16;i++)
            {
                x=rand()%4;
                y=rand()%4;
                if(campo[x][y])
                    i--;
                else
                    campo[x][y]=i;
            }
    }
    
    void stampa_matrice(int campo[][4])
    {
        int x,y;
        for(x=0;x<4;x++)
        {
            for(y=0;y<4;y++)
            {
                if(campo[x][y]==0)
                    printf("%7c",255);
                else
                    printf("%7d",campo[x][y]);
            }
            printf("\n\n\n\n");
        }
    }
    
    void muovi_numero(int campo[][4])
    {
        int x,y,n;
        printf("\n\n\n\nMossa numero: %d\n",mossa);
        printf("Digita il numero da spostare: ");
        scanf("%d",&n);
        if(appartiene_a2D(n,campo) && n!=0)
        {
            for(x=0;x<4;x++)
            {
                for(y=0;y<4;y++)
                {
                    if(campo[x][y]==0)
                    {
                        if(campo[x][y+1]==n  && y+1<=3)
                        {
                            campo[x][y]=n;
                            campo[x][y+1]=0;
                            return;
                        }
                        else if(campo[x][y-1]==n && y>=0)
                        {
                            campo[x][y]=n;
                            campo[x][y-1]=0;
                            return;
                        }
                        else if(campo[x+1][y]==n  && x+1<=3)
                        {
                            campo[x][y]=n;
                            campo[x+1][y]=0;
                            return;
                        }
                        else if(campo[x-1][y]==n && x>=0)
                        {
                            campo[x][y]=n;
                            campo[x-1][y]=0;
                            return;
                        }
                        else
                        {
                            printf("\n\nERRORE!! Il numero %d non puo' essere spostato\n\n",n);
                            muovi_numero(campo);
    
                        }
                    }
                }
            }
        }
        else
        {
            printf("\nERRORE!! Devi digitare un numero da 1 a 15.\n");
            muovi_numero(campo);
        }
    }
    
    int appartiene_a2D(int n, int campo[][4])
    {
        int r,c;
        for(r=0;r<4;r++)
            for(c=0;c<4;c++)
                if(n==campo[r][c])
                    return 1;
        return 0;
    }
    
    int vittoria(int campo[][4], int campo_ordinato[0][4])
    {
        int x,y;
        for(x=0;x<4;x++)
            for(y=0;y<4;y++)
                if(campo[x][y]!=campo_ordinato[x][y])
                    return 0;
        return 1;
    }
    Ho aggiunto anche lo condizioni nei vari if che mi permettono di non sforare le caselle della matrice, come da te suggerito

  10. #10
    Occhio, l'ordine delle condizioni deve essere invertito (prima controlli se le coordinate sono sensate, poi accedi all'elemento), altrimenti prima sfori e poi controlli.

    Quindi non così
    codice:
    campo[x][y+1]==n && y+1<=3
    ma così:
    codice:
    y+1<=3 && campo[x][y+1]==n
    (nota che puoi fare questo perché l'operatore && garantisce che se l'espressione a sinistra è false quella a destra non viene valutata, altrimenti dovresti fare due if nidificati)
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.