Fondamenti di Informatica 1 - Compito A

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