Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [c] Reimpostazione delle variabili tramite ricorsione

    Salve a tutti,

    Sto sviluppando un piccolo programmino che mi simula il gioco dell'impiccato, e fin ora non ho avuto particolari problemi.
    Ho utilizzato delle funzioni costruite da me per emulare la funzione gotoxy() (non ANSI-Compatibile) della libreria tcconio.h.
    In questa applicazione faccio uso massicio di puntatori a stringhe (so che si dovrebbero utilizzare solo quando necessario, ma è per imparare )
    Spiego un pochettino cosa fa il gioco.
    1) Dichiaro le variabili che mi servono, una dinamica in vista di leggere le parole da indovinare
    da un file.
    2) Controllo che le variabili impiccato e parola contengano le lettere inserite dall'utente.
    3) Se le contengono le stampo a schermo nella posizione giusta
    Se non le contengono decremento il contatore di possibilità (quante volte posso provare)
    4) Alla fine si chiede all'utente se vuole ancora giocare.

    E qui sorge il problema, poiché non funziona piu niente, nel senso che il confronto tra la variabile impiccato e parola non va più.
    Ho provato a fare diverse prove con il debug, e le variabili assumono tutte i valori che dovrebbero, a parte la variabile impiccato che non cambia come dovrebbe.

    Qualcuno mi sa dire dove sto sbagliando?

    Vi posto qui sotto il sorgente, così potete compilarvelo se volete darci un occhiata
    L'ho compilato con gcc sotto linux e con mingw sotto windows. Con questi due compilatori funziona.

    Vi saremi veramente MOLTO grato se qualcuno potesse aiutarmi (mi rendo conto che ci vuole un po' di tempo per risolvere )

    Ciao.

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
       #define W_HEIGHT 15
       #define W_WIDTH 80
       #define CLEAR system("cls") /* Per DOS/Windows */
    // #define CLEAR system("clear") /* Per Unix/Linux */
    
    void search_pattern(char *c, char *s, char pattern);
    int count_pattern(char *c, char pattern);
    void titolo(void);
    void fill_m_array(char (*ptr)[W_WIDTH], int n);
    int draw_xy(int h, int w, char (*ptr)[W_WIDTH], char *string);
    void print_m_array(char (*ptr)[W_WIDTH], int n);
    
    char multi[W_HEIGHT][W_WIDTH];
    
    int main(void)
    {
      int i;
      char scelta;
      char c, parola[] = "materasso";
      char count[2] = {57,0};
      char *impiccato = NULL;
      impiccato = (char *)malloc(sizeof(parola)+1);
      /* per inizializzare la stringa */
      strcpy(impiccato,parola);
        for(i=0;impiccato[i];i++)
        {
          impiccato[i]='-';
        }
      /*      -----------------       */
      titolo();
      draw_xy(7,15,multi,impiccato);
      draw_xy(4,50,multi,"Tentativi rimasti:");
      draw_xy(4,70,multi,count);
      print_m_array(multi,W_HEIGHT);
        while(strcmp(impiccato,parola) && count[0]>48)
        {
           printf("Inserisci un carattere [a-zA-Z0-9]: ");
           c = getchar();
              if(count_pattern(parola,c))
              {
                 search_pattern(parola,impiccato,c);
                 draw_xy(7,15,multi,impiccato);
              }
              else
              {
                  count[0]--;
                  draw_xy(4,70,multi,count);
              }
           c = getchar(); //to avoid entering the '\n' char
           print_m_array(multi,W_HEIGHT);
        }
        
        //Chek if the user's won the game
        if(count[0]==48) //means 0 in ASCII table
        {
           draw_xy(4,50,multi,"Spiacente, hai perso!");
        }
        if(!strcmp(impiccato,parola) && count[0]>48)
        {
           draw_xy(4,50,multi,"Complimenti, hai vinto!");
        }
    
        do
        {
           print_m_array(multi,W_HEIGHT);
           printf("Vuoi ancora giocare? [y/n]: ");
           scanf("%c",&scelta);
           printf("\n");
        } while(scelta!='y' && scelta!='n');
      
        if(scelta==121)
           main();
        else
           return 0;
    }
    
    /******************************************/
    /*                                        */
    /*   FUNZIONI PER LA GESTIONE DEL GIOCO   */
    /*                                        */
    /******************************************/
    
    void search_pattern(char *c, char *s, char pattern)
    {
     int i;
     for(i=0;*c;i++)
     {
        if(*c++==pattern)
           *(s+i) = pattern;
     }
    }
    
    int count_pattern(char *c, char pattern)
    {
     int i, pattern_count=0;
    
     for(i=0;*c;i++)
     {
        if(*c++==pattern)
      	   pattern_count++;
     }
     return pattern_count;
    }
    
    /*******************************************/
    /*                                         */
    /*  FUNZIONI PER LA GESTIONE DELLO SCHERMO */
    /*                                         */
    /*******************************************/
    
    void titolo(void)
    {
      fill_m_array(multi,W_HEIGHT);
      draw_xy(0,0,multi,"Gioco dell'impiccato");
      draw_xy(1,0,multi,"====================");
      draw_xy(0,W_WIDTH-22,multi,"Created by Noise 2006");
    }
    
    void fill_m_array(char (*ptr)[W_WIDTH], int n)
    {
      int i,j;
      char *p;
      p = (char *)ptr;
      for(i=0;i<n;i++)
      {
         for(j=W_WIDTH*i;j<(W_WIDTH*i)+(W_WIDTH-1);j++)
         {
            *p++ = ' ';
         }
         *p++='\n';
      }
    }
    
    int draw_xy(int h, int w, char (*ptr)[W_WIDTH], char *string)
    {
       int i;
       char *p;
       p = (char *)ptr;
       p += (h * W_WIDTH + w); //posiziona il puntatore dove si vuole scrivere
       while(*string)
       {
             *p++ = *string++;
       }
       return 1;
    }
    
    void print_m_array(char (*ptr)[W_WIDTH], int n)
    {
      int i;
      char *p;
      p = (char *)ptr;
      CLEAR;
      for(i=0;i<(W_WIDTH*n);i++)
      {
         printf("%c", *p++);
      }
    }
    If today was perfect, there would be no need for tomorrow...
    Live as you want, the wildest way you can, till you're alive!!

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Il problema era determinato dal fatto che l'input della domanda finale manteneva nel buffer il carattere di line feed e questo faceva perdere il sincronismo per le risposte seguenti.

    Ma era piu' "grave" il fatto che venisse richiamata la main() alla fine per ripetere il programma. Dato che non esegui un goto, viene conservato nello stack il punto di rientro della chiamata alla funzione e questo, oltre che essere teoricamente sbagliato, puo' anche causare problemi. E un altro errore grave era la allocazione della memoria (con la malloc) senza la relativa liberazione (con la free).

    In piu', ho tolto qualche confronto con valori ASCII e li ho sostituiti con i caratteri corrispondenti e ho tolto qualche parentesi { } inutili, per maggiore leggibilita'.
    Le funzioni sono ottimizzabili ma questi sono dettagli.

    In grassetto le correzioni ...

    codice:
    int main(void)
    {
      int i;
      char scelta;
      char c, parola[] = "materasso";
    
      do
      {
         char count[2] = {'9', 0};
    
        char *impiccato = (char *)malloc(sizeof(parola)+1);
        strcpy(impiccato,parola);
        for(i=0;impiccato[i];i++)
          impiccato[i]='-';
    
        titolo();
        draw_xy(7,15,multi,impiccato);
        draw_xy(4,50,multi,"Tentativi rimasti:");
        draw_xy(4,70,multi,count);
        print_m_array(multi,W_HEIGHT);
    
        while(strcmp(impiccato,parola) && count[0]>'0') 		{
          printf("Inserisci un carattere [a-zA-Z0-9]: ");
          c = getchar();
          if(count_pattern(parola,c))
          {
            search_pattern(parola,impiccato,c);
            draw_xy(7,15,multi,impiccato);
          }
          else
          {
            count[0]--;
            draw_xy(4,70,multi,count);
          }
          
          c = getchar(); //to avoid entering the '\n' char
          print_m_array(multi,W_HEIGHT);
        }
        
        //Check if the user's won the game
        if(count[0]=='0')   
          draw_xy(4,50,multi,"Spiacente, hai perso!");
    
        if(!strcmp(impiccato,parola) && count[0]>'0')      
          draw_xy(4,50,multi,"Complimenti, hai vinto!");
    
        do
        {
          print_m_array(multi,W_HEIGHT);
          printf("Vuoi ancora giocare? [y/n]: ");
          scanf("%c",&scelta);
          printf("\n");
        } while(scelta!='y' && scelta!='n');
    
    
        c = getchar();
        free(impiccato);
      } while(scelta=='y');
    
    	
      return 0;
    }

  3. #3
    grazie, sta sera ci do uno sguardo
    Prima avevo adottato la tua soluzione con do while, poi per provare qualcosa di differente ho provato con la ricorsione.
    Grazie dei consigli, non sapevo che un operazione del genere potesse dare problemi (newbie hehe )
    Ti faccio ancora sapere, intanto grazie
    If today was perfect, there would be no need for tomorrow...
    Live as you want, the wildest way you can, till you're alive!!

  4. #4
    Ok, grazie mille
    Solo una cosa:non ho ben capito che problemi può dare il fatto di richiamare main() e soprattutto perche?

    Ciao
    If today was perfect, there would be no need for tomorrow...
    Live as you want, the wildest way you can, till you're alive!!

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Quando chiami una funzione viene eseguito il suo codice fino al suo termine, dopo di che la funzione termina e "ritorna" il controllo al chiamante.

    Se una funzione chiama se' stessa (come nel caso tuo in cui dalla main chiami la main ...) si parla di "ricorsione" che e' un concetto da applicare in determinate e specifiche situazioni.
    Nel tuo caso, la ricorsione non ha alcun senso.

    E poi, anche la ricorsione prevede, ad un certo punto, che le chiamate abbiano fine, cosa che non avviene nel tuo caso. Viene quindi impegnato in maniera indefinita lo stack che, essendo limitato, puo' determinare problemi ...

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.