/* * Gioco_Impiccato.c * Esercizio * * Created by Mattia Natali on 24/10/09. * Copyright 2009 Mattia Natali. All rights reserved. * */ #include #include #include #include #include #define MAX_VETTORE 640 #define MAX_TENTATIVI 10 #define MAX_VETTORE_ALFABETO 26 #define LETTERA_GIA_INSERITA -2 #define DIZ_PATH "Dizionario.txt" /***************************** * Creazione dei vari RECORD * *****************************/ typedef enum {NASCOSTO, TROVATO, ND} stato; typedef struct { char carattere; stato statoCella; } cella; typedef cella parolaSegreta[MAX_VETTORE]; typedef cella vettoreAlfabeto[MAX_VETTORE_ALFABETO]; /********************************** * Prototipi delle varie funzioni * **********************************/ // Funzione che inserisce la parola scelta a caso nel dizionario in "segreto" che è di tipo parolaSegreta void inserimentoParola(parolaSegreta segreto); // Apre e chiude lo stream FILE per prendere la parola dal dizionario void nuovaParolaDizionario(char *ptrParola); // Restituisce 0 se nn è stata trovata nessuna lettera, // altrimenti dice quante ne sono state trovate, -2 = LETTERA_GIA_INSERITA = lettera già inserita. // Inoltre questa funzione visualizza il numero di tentativi ancora a disposizione e le lettere già inserite int richiestaLettera(parolaSegreta segreto, int tentativi, vettoreAlfabeto vetAlfabeto); // Visualizza la parola con gli * se non sono state trovare alcune lettere void visualizzaParola(parolaSegreta segreto); // Verifica se la parola è stata completamente svelata, in caso affermativo la funzione restituisce 2, // altrimenti restituisce 1: il gioco continua. int verificaVittoria(parolaSegreta segreto); //Svela la parola quando si perde il gioco void svelaParola(parolaSegreta segreto); //Crea il vettore contenente tutte le lettere dell'alfabeto void inizializzaVetAlfabeto(vettoreAlfabeto vetAlfabeto); //Visualizza le lettere che sono state già utilizzate void visualizzaAlfabeto(parolaSegreta vetAlfabeto); /******************************** * Inizio Programma * ********************************/ int main() { // Dichiarazione del RECORD in cui inserire la parola dell'utente parolaSegreta parolaDaTrovare; // Dichiarazione e Inizializzazione del vettore Alfabeto vettoreAlfabeto vetAlfabeto; inizializzaVetAlfabeto(vetAlfabeto); // trovataLettera contiene il risultato della funzione richiestaLettera: // 0 = la lettera non è giusta // LETTERA_GIA_INSERITA = la lettera era già stata usata // in tutti gli altri casi indica il numero di lettere trovate nella parola nascosta int tentativi = 0, trovataLettera; int statoPartita = 1; //1 continua, 0 perso, 2 vinto inserimentoParola(parolaDaTrovare); visualizzaParola(parolaDaTrovare); while (statoPartita == 1) { trovataLettera = richiestaLettera(parolaDaTrovare, tentativi, vetAlfabeto); // Ripulisce lo schermo system("clear"); // Verifica se è stata trovata una lettera switch (trovataLettera) { case 0: tentativi++; printf("Non hai trovato la lettera giusta mi spiace...\n\n"); visualizzaParola(parolaDaTrovare); visualizzaAlfabeto(vetAlfabeto); if (tentativi >= MAX_TENTATIVI) { printf("Mi spiace... Hai utilizzato tutti i tentativi a disposizione!\n\n"); statoPartita = 0; //perso } break; case LETTERA_GIA_INSERITA: printf("La lettera che hai inserito l'avevi gia' inserita!\n\n"); visualizzaParola(parolaDaTrovare); visualizzaAlfabeto(vetAlfabeto); break; default: printf("Bravo! Hai trovato %d lettera/e!\n\n", trovataLettera); visualizzaParola(parolaDaTrovare); visualizzaAlfabeto(vetAlfabeto); break; } if (statoPartita != 0) statoPartita = verificaVittoria(parolaDaTrovare); // 1 = continua, 2 = vinto } // Stampa il messaggio appropiato switch (statoPartita) { case 0: printf("Hai perso! La parola da trovare era: "); svelaParola(parolaDaTrovare); printf("\n\n"); break; case 2: printf("Complimenti hai vinto!!\n\n"); break; } return 0; } void inserimentoParola(parolaSegreta segreto) { char parola[MAX_VETTORE]; int i = 0; // ricordati l'inizializzazione /* * Ora utilizzo il dizionario * printf("Inserisci la parola da trovare: "); * fpurge(stdin); //Svuota buffer stdin (tastiera) * scanf("%s", parola); * system("clear"); //Pulisce il terminale, così da non vedere la parola inserita */ nuovaParolaDizionario(parola); // Inizializzazione segreto for (i = 0; i < MAX_VETTORE; i++) { segreto[i].carattere = ' '; segreto[i].statoCella = ND; } // Inserimento della parola digitata in segreto, lo stato sarà NASCOSTO i = 0; while (parola[i] != '\n' && parola[i] != '\0') { segreto[i].carattere = toupper(parola[i]); segreto[i].statoCella = NASCOSTO; i++; } } int richiestaLettera(parolaSegreta segreto, int tentativi, vettoreAlfabeto vetAlfabeto) { char lettera; int i, trovataLettera = 0; printf("Numero di tentativi rimasti: %d\n", (MAX_TENTATIVI - tentativi)); printf("Inserisci una lettera: "); fpurge(stdin); //fseek(stdin, 0, SEEK_SET); //fflush a me non funziona... Boh. fseek è un altro possibile metodo scanf(" %c", &lettera); lettera = toupper(lettera); //Rende la lettera maiuscola // Algoritmo per verificare se la lettera era già stata inserita, in caso contrario svela la lettera corrispondente for (i = 0; i < MAX_VETTORE_ALFABETO; i++) { if ((vetAlfabeto[i].carattere == lettera) && (vetAlfabeto[i].statoCella == TROVATO)) return LETTERA_GIA_INSERITA; else if ((vetAlfabeto[i].carattere == lettera) && (vetAlfabeto[i].statoCella == NASCOSTO)) { vetAlfabeto[i].statoCella = TROVATO; break; // Esci dal ciclo... Tanto la lettera nell'alfabeto è solo 1 } } // Algoritmo per svelare la lettera nella parola nascostra, sempre se la lettera sia contenuta nella parola i = 0; while (segreto[i].statoCella != ND) { if (segreto[i].carattere == lettera) { segreto[i].statoCella = TROVATO; trovataLettera++; } i++; } return trovataLettera; } void visualizzaParola(parolaSegreta segreto) { int i = 0; printf("Stato partita: "); // Algoritmo per visualizzare la parola: // se lo stato è NASCOSTO visualizza un '*' al posto della lettera effettiva while (segreto[i].statoCella != ND) { if (segreto[i].statoCella == TROVATO) printf("%c", segreto[i].carattere); else { printf("*"); } i++; // RICORDATI di incrementare il contatore!! } printf("\n"); } int verificaVittoria(parolaSegreta segreto) { int i = 0; // 2 nessuna cella nascosta = vinto!, 1 almeno una cella nascosta = continua a giocare while (segreto[i].statoCella != ND) { if (segreto[i].statoCella == NASCOSTO) return 1; i++; } return 2; } void svelaParola(parolaSegreta segreto) { int i = 0; while (segreto[i].statoCella != ND) { printf("%c", segreto[i].carattere); i++; } } void inizializzaVetAlfabeto(vettoreAlfabeto vetAlfabeto) { int i; for (i = 0; i < MAX_VETTORE_ALFABETO; i++) { // Riempio il vettore alfabeto dalla A alla lettera ('A' + numLettere) vetAlfabeto[i].carattere = ('A' + i); vetAlfabeto[i].statoCella = NASCOSTO; } } void visualizzaAlfabeto(parolaSegreta vetAlfabeto) { int i; printf("\nLe lettere che hai gia' inserito sono: "); for (i = 0; i < MAX_VETTORE_ALFABETO; i++) { if (vetAlfabeto[i].statoCella == TROVATO) { printf("%c ", vetAlfabeto[i].carattere); } } printf("\n"); } void nuovaParolaDizionario(char *ptrParola) { FILE *fp; int numCasuale, numRighe = 0; char parola[MAX_VETTORE]; // Apriamo lo stream file del dizionario fp = fopen(DIZ_PATH, "r"); srand(time(NULL)); if (fp == NULL) { printf("C'e' stato un'errore nell'apertura del file Dizionario...\n\n"); exit(1); } else { // Determino il numero delle righe del dizionario for (numRighe = 0; (fgets(parola, MAX_VETTORE, fp) != NULL); numRighe++); // Ritorno all'inizio del file rewind(fp); // Trovo una parola a caso, per far ciò trovo un numero compreso tra 0 e il num max delle righe del dizionario // In ogni riga del file dizionario c'è una parola numCasuale = rand() % numRighe; // Porto il "cursore" alla riga interessata for (numRighe = 0; (fgets(parola, MAX_VETTORE, fp) != NULL) && (numRighe < numCasuale); numRighe++); // Copio la parola contenuta nel dizionario in parola fgets(parola, MAX_VETTORE, fp); fclose(fp); // Copio la parola al puntatore alla stringa che abbiamo ricevuto come parametro strcpy(ptrParola, parola); } }