Fondamenti di Informatica 1 - Compito A Prof. Marco Gavanelli 13 Settembre 2007 Esercizio (17 punti) Si scriva un programma in linguaggio C che serve per giocare al gioco descritto di seguito. Inizialmente, il programma sceglie una parola a caso, poi l’utente cerca di indovinare la parola selezionata. Per indovinare la parola, l’utente inserisce una lettera. Se la lettera appartiene alla parola, il programma visualizza in quali posizioni si trova la lettera. Altrimenti (se la lettera non compare nella parola), viene segnalato un tentativo di insuccesso. Dopo 5 tentativi infruttuosi, l’utente perde. Se, invece, riesce ad indovinare tutte le lettere della parola, vince. Per selezionare la parola, il programma usa un file di testo parole.txt che contiene un elenco di parole rappresentate da: lunghezza (int) indica la lunghezza della parola stringa (stringa di al massimo 20 caratteri incluso il terminatore, senza spazi) contiene la parola vera e propria Per eseguire il gioco, il programma usa il seguente algoritmo: 1. Legge dal file di testo parole.txt ed inserisce in un array tutte le parole che vi sono contenute. Si supponga che non ci siano più di 700 parole. 2. Seleziona una parola a caso. Per fare questo, si selezioni l’elemento di indice rand()*n/RAND MAX dell’array creato al punto 1, dove rand() e RAND MAX sono definite in stdlib.h e n è il numero di elementi dell’array. 3. Invoca una procedura o funzione gioca. Si definisca tale procedura o funzione. gioca deve gestire una stringa che contiene le lettere che sono già state indovinate: inizialmente sarà la stringa vuota; quando l’utente indovina una lettera, si aggiunge la lettera alla stringa. La lettera può essere memorizzata come stringa di 1 carattere (+ il terminatore): in tal caso per aggiungere la lettera alla stringa si può usare la strcat. gioca deve eseguire le seguenti operazioni, finché il gioco non termina (come si diceva in precedenza, il gioco termina o perché la parola è stata indovinata, oppure perché ci sono stati 5 tentativi errati): 1 (a) Visualizzare lo stato della parola: una procedura (o funzione) stampa parola visualizza la parola sostituendo un carattere ’-’ alle lettere che non sono ancora state indovinate. Per fare questo, si utilizzi una funzione presente che verifica se un carattere è presente in una stringa. (b) Chiedere l’inserimento di una lettera (c) Verificare se la lettera appartiene alla parola. Per fare questo, si definisca (ed invochi) una opportuna procedura o funzione. In questa fase è utile di nuovo la funzione presente Alla fine del gioco, gioca deve visualizzare se il giocatore ha vinto o perso. Esempio : -----Inserisci -e---Inserisci -e-a-Inserisci -e-arInserisci -e-aro Inserisci -e-aro Inserisci -eparo Inserisci separo Hai vinto lettera: e lettera: a lettera: r lettera: o lettera: b lettera: p lettera: s Facoltativo (Punti 2) Si modifichi il programma in modo che inizialmente legga da tastiera il numero di lettere della parola. In seguito, al punto 1, si carichino nell’array le sole parole che hanno la lunghezza richiesta dall’utente. 2 Soluzione # include < stdio .h > # include < string .h > # include < stdlib .h > # define MAX 30 # define N 1000 # define MAX_TENTATIVI 5 typedef struct { char s [ MAX ]; int lung ; } parola ; /* NOTA : al posto di questa funzione si puo ‘ anche usare la funzione strchr della libreria delle stringhe */ int presente ( char c , char s []) { int i =0; while (( s [ i ]) && ( c != s [ i ])) i ++; return ( c == s [ i ]); } int stampa_parola ( parola p , char scoperte [] , int ns ) { int i =0 , finito =1; while ( p . s [ i ]) { if ( presente ( p . s [ i ] , scoperte )) printf ( " % c " ,p . s [ i ]); else { printf ( " -" ); finito =0; } i ++; } printf ( " \ n " ); return finito ; } void gioca ( parola p ) { char scoperte [27]= " " ; char l [2]= " w " ; /* memorizzo il carattere inserito dall ’ utente in una stringa lunga 1 cosi ‘ posso usarlo sia come carattere ( l [0]) , sia come stringa ( l ) */ int ns =0 , finito =0 , tentativi =0; finito = stampa_parola (p , scoperte , ns ); 3 do { printf ( " Inserisci lettera : " ); scanf ( " %1 s " ,l ); if (! presente ( l [0] , scoperte )) strcat ( scoperte , l ); if (! presente ( l [0] , p . s )) tentativi ++; finito = stampa_parola (p , scoperte , ns ); } while ((! finito ) && ( tentativi <= MAX_TENTATIVI )); if ( finito ) printf ( " Hai vinto " ); else printf ( " Hai perso " ); } int leggi_file ( parola parole [] , int len ) { int i =0; FILE * fp ; fp = fopen ( " parole . txt " ," rt " ); if ( fp == NULL ) { printf ( " Errore apertura del file \ n " ); exit ( -1); } while (! feof ( fp )) { fscanf ( fp , " % d % s " ,& parole [ i ]. lung , parole [ i ]. s ); if ( parole [ i ]. lung == len ) i ++; } fclose ( fp ); return i ; } void scegli_parola ( parola *p , parola parole [] , int n ) { int i ; i = rand ()* n / RAND_MAX ; * p = parole [ i ]; } main () { int len , n ; parola parole [ N ] , p ; printf ( " Inserisci lunghezza : " ); scanf ( " % d " ,& len ); n = leggi_file ( parole , len ); scegli_parola (& p , parole , n ); gioca ( p ); } 4