Codice:
/*
Prima di partire con la scrittura del codice c, ho provveduto a studiare per bene il procedimento
che avrei dovuto attuare per la buona riuscita del programma.
Per iniziare ho voluto chiedere il nome ai due giocatori. Il nome verrà salvato all'interno di una variabile
giocatore, che ho definito con uno struct all'inizio. Oltre al nome, questa variabile conterrà anche il punteggio.
Chiedo poi al giocatore 1 di inserire la prima parola, che viene salvata all'interno di parola.
A questo punto si entra in una iterazione, che mi permette di mostrare il menu' ogni volta che un'operazione
viene completata. Tramite uno switch potrò compiere una diversa azione in base alla scelta del giocatore.
L'interfaccia è contenuta nella funzione interfaccia().
Non vi è nessun controllo sulla correttezza delle parole inserite dai giocatori, dato che si presuppone che
le parole inserite siano presenti sul dizionario, e non inventate. Ho inserito inoltre l'opportunità di poter passare il turno.
Se i giocatori riescono ad inserire una lettera, allora riceveranno 1 punto, se la tolgono ne perderanno una, se passano
riceveranno una penalità maggiore. Se infine propongono una parola già scritta, la penalità sarà di 1 punto per ogni lettera della nuova parola.
Per controllare se la nuova parola non fosse già stata scritta, ho creato una lista dinamica, in cui viene aggiunta una cella
ogni qualvolta si ha una nuova parola.
Vi è un punteggio massimo da raggiungere, e il giocatore che lo raggiunge per primo ottiene la vittoria.Il punteggio da raggiungere
è 10.
Quando un giocatore vuole aggiungere una parola, semplicemente gli verrà chiesto in quale posizione inserire la nuova lettera,
e quale lettera inserire. 1 punto verrà aggiungo al giocatore e si proseguirà con la nuova parola.
Se invece si vuole togliere una lettera, verrà chiesta la posizione della lettera e verrà tolto 1 punto.
Alla fine vengono controllati i punteggi dei giocatori, e se nessuno dei due ha raggiunto il punteggio che ho stabilito,
allora il ciclo ricomincerà, cambiando però il turno.
Quando devo passare valori alle funzioni, che dovranno essere modificati, allora uso il passaggio per indirizzo
e non per valore, perchè quest'ultimo mi permetterebbe solo di usare ciò che gli passo, ma non di modificarlo.
Cambiamento di turno: il cambiamento di turno viene gestito dalla variabile turno. La inizializzo a 2, e ogni volta effettuo un controllo
se turno%2==0 ( cioè è pari), allora tocca al giocatore 2. Viceversa tocca al secondo. E finita la mossa del giocatore, turno viene aumentato di 1.
Questo è turnoUp. turnoDown invece viene utilizzato quando si decide di togliere una lettera, e quindi bisogna togliere 1 punto, non aggiungerlo.
Ogni volta che si ha una nuova parola, devo provvedere a salvarla in memoria. Questo per permettere il controllo sulle nuove parole inserite,
nel caso siano già state inserite in precedenza.
Per memorizzare, mi avvalgo di una lista dinamica. Ogni nuova parola sarà una nuova cella in questa lista. Ogni controllo verrà effettuato
scansionando questa lista con un puntatore temp. Nel caso la nuova parola sia uguale a una già inserita in precedenza, allora
verranno tolti tanti punti al giocatore quanto il numero delle lettere della nuova parola.
Per tenere conto delle mosse totali effettuate, semplicemente pongo una variabile mosse = 0. Poi faccio in modo che
alla fine di ogni iterazione del ciclo while nel main, essa aumenti di 1. Alla fine, quando uno dei due giocatori
raggiunge i 10 punti, allora mostro la variabile.
Il codice verrà spiegato più approfonditamente mentre lo si legge.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_ELE 30
struct giocatore{
char nome[MAX_ELE];//Abbiamo qua lo struct giocatore
int punteggio;// che conterrà nome e punteggio dei giocatore
};
struct cella{
/*struct cella indica come deve essere ogni singola cella della lista*/
char parmem[MAX_ELE];
struct cella *next; /* attua al salvataggio in memoria delle parole precedentemente scritte.*/
};
struct cella *testa = NULL;
struct cella *nuovo = NULL;
struct giocatore a,b;
/* Ottengo così i 2 giocatori. */
int scelta;
int i , turno=2,mosse=0; // turno mi sarà utile a controllare l'alternarsi dei turni, mosse per calcolare il totale delle mosse
char parola[MAX_ELE], sup[MAX_ELE];
void salvare(char *, struct cella *);
void togliLettera(char *);//void perchè non c'è alcun return, e char * perchè dovrò passare alla funzione la stringa parola, per indirizzo.
void aggiungiLettera(char *);// come sopra.
void saltaTurno(int *, struct giocatore *, struct giocatore *);
int interfaccia(int,int, int *);//Creo una funzione per l'interfaccia di gioco, in modo da risparmiare spazio nel main.
void vincitore(int *,struct giocatore *, struct giocatore *,int *);
void fturnoUp(int *,struct giocatore *,struct giocatore *);
void fturnoDown(int *,struct giocatore *,struct giocatore *);
int main()
{
a.punteggio=0;
b.punteggio=0;// entrambi i giocatori partono con punteggio 0.
printf("Nome del giocatore 1 : ");
for(i=0;(a.nome[i]=getchar())!='\n';i++)//Semplicemente chiedo i nomi ai 2 giocatori, e li memorizzo
; //all'interno dell'array di caratteri che ho creato nello struct giocatore
a.nome[i]='\0';
printf("Nome del giocatore 2 : ");
for(i=0;(b.nome[i]=getchar())!='\n';i++)
;
b.nome[i]='\0';
printf("Primo giocatore, inserisci la parola : ");
for(i=0;(parola[i]=getchar())!='\n';i++)//E ora salvo anche la parola.
;
parola[i]='\0';
while(1 && (a.punteggio!= 2 && b.punteggio!=2 ))//entro in un ciclo sempre vero, che mi permette di mostrare il menù ogni qual volta iene portata a termine una mossa
{ //e di controllare che non sia stato raggiunto il punteggio massimo
system("cls");
printf("\n\t\t===================================================\n");
printf("\n\t\t===================================================\n");
printf("\n\t\tParola attuale : %s.\n",parola);
printf("\t\tE\' il turno del giocatore %d.\n",turno);//Approfitto dell'oscillazione della variabile turno tra 1 e 2, per indicare a chi tocca giocare
switch(interfaccia(a.punteggio,b.punteggio,&scelta))//Mostro così l'interfaccia(commento nella funzione)
{
case '1':
aggiungiLettera(parola);//nel caso prema 1, allora entrerà in gioco la funzione che si occupa dell'aggiunta di una lettera
printf("%s.\n",testa->parmem);
system("pause");
break;
case '2':
togliLettera(parola);// con 2 si potrà togliere una lettera
break;
case '3':
saltaTurno(&turno, &a, &b);
break;
case '0':
exit(0);
system("pause");
break;
}
mosse++;
}
vincitore(&turno, &a,&b,&mosse);
system("pause");
return 0;
}
/*
aggiungiLettera()
funzione che entra in gioco nel caso il giocatore decida di aggiungere una lettera alla parola.Il funzionamento
è spiegato nel codice.Alla fine richiamo fturnoUp(), per agire sui punteggi e sul turno.
Parametri in ingresso:
la stringa parola, perchè devo mostrarla al giocatore.
Parametri restituiti:
Nessuno.
*/
void aggiungiLettera(char *parola)
{
system("cls");
int i=0,j=0,posiz;
char let;
/*
i,j : utili per passare nelle varie celle delle stringhe.
posiz : posizione nella quale voglio inserire la lettera.
let : lettera da aggiungere alla parola nella posizione desiderata.
*/
for(i=0;parola[i]!='\0';i++)
{
printf("(%d)",i+1); //In questo modo mostro le varie lettere, e numero i vari
printf("%c",parola[i]); //spazi nei quali è inseribile la nuova lettera.
}
printf("(%d)\n",i+1);
do{
printf("\nIn quale posizione vuoi aggiungere una lettera?\n");
scanf("%d",&posiz);//mi salvo così la posizione dove vuole aggiungere una lettera
}while(posiz<1 || posiz>(i+1));//controllo sulla validità dell'inserimento
do{
printf("Quale lettera vuoi aggiungere?\n");
let=getch();// e la lettera da aggiungere
}while(let<65 || let >122);// altro controllo per l'inserimento della lettera
for(i=0;parola[i]!='\0';i++,j++)
{
if(i==(posiz-1)) //se la posizione è quella scelta
{
sup[j]=let; // utilizzo una stringa di supporto. Vi copio mano mano le lettere di
j++; // parola. Ma quando arrivo alla lettera da aggiungere, l'aggiungo nella
} //fino a che la sto trattando con una lettera della parola // stringa di supporto, e vado avanti di 1, continuando a copiare le altre lettere di parola.
sup[j]=parola[i]; //In questo modo stringa conterrà la vecchia parola + la nuova lettera.
}
if(i==(posiz-1)) //se la posizione è quella scelta
{
sup[j]=let; // Riscrivo il tutto un' ulteriore volta, poichè mi serve nel caso l'inserimento debba avvenire
j++; // in fondo alla parola. in tal caso, l'if dentro il while non viene considerato, perchè il ciclo while termina prima.
}
sup[j]='\0';
strcpy(parola,sup); //E alla fine copio la nuova parola ottenuta in parola
fturnoUp(&turno, &a , &b);//vado ad agire sul turno, cambiando il punteggio dei giocatori e cambiando il valore di turno
salvare(parola, testa);
}
/*
togliLettera()
funzione che entra in gioco nel caso l'utente scelga di togliere una lettera alla parola.
Viene mostrata la parola al giocatore. Egli sceglie la posizione della lettera e questa viene cancellata
(procedimento spiegato nel codice).Alla fine viene richiamata la funzione fturnoDown(), in modo da modificare i punteggi e il turno,e anche
salvare(), in modo da conservare in memoria anche questa nuova parola.
Parametri passati:
La stringa parola, perchè devo mostrarla al giocatore.
Parametri restituiti:
Nessuno.
*/
void togliLettera(char *parola)
{
system("cls");
int num,j=0,i=0;
/*
num : Questa variabile mi sarà utile ad immaggazinare il numero della lettera che voglio cancellare.
j,i : Utilizzate per scorrere le varie celle delle stringhe sup e parola.
*/
printf("Parola : ");
for(i=0;parola[i]!='\0';i++)
{
printf("%c",parola[i]);
}/*mostro la parola al giocatore.*/
printf("\n");
printf("Numero della lettera da togliere : ");
scanf("%d",&num);
/*Dovrà scegliere il numero della lettera che desidera togliere e lo salvo in una variabile */
for(i=0,j=0;parola[i]!='\0';i++,j++)
{
if(i == (num-1))/*quando parola[i] contiene la parola da togliere, allora faccio i++. In pratica salto la cella che contiene la parola*/
i++;
sup[j] = parola[i];/*E salvo tutto sulla stringa di supporto , senza la lettera che volevamo eliminare.*/
}
sup[j]='\0';
strcpy(parola,sup); /* così parola conterrà la nuova parola */
fturnoDown(&turno, &a , &b); /* e vado all'istruzione del turno per togliere punti */
salvare(parola, testa);
}
/*
saltaTurno()
funzione che permette all'utente di saltare il turno, nel caso non riesca a trovare una nuova parola.
Il giocatore riceve però una penalità di 3 punti.
Si basa sul valore di turno per decidere di chi,tra i 2 giocatori, è il turno. Capito questo,
si va nel suo struct giocatore, in punteggio, e gli si sottrae 3. Alla fine turno viene modificato in modo
che spetti all'altro giocatore.
Parametri passati:
turno, per riferimento, utile come spiegato sopra.
2 struct giocatore, che indicano i 2 giocatori. Agiremo infatti sul valore punteggio di ognuno di essi.
Parametri restituiti : Nessuno.
*/
void saltaTurno(int *turno, struct giocatore *x, struct giocatore *y)
{
if((*turno)%2==0)
{
y->punteggio -= 3;
(*turno)--;
}
else
{
x->punteggio -= 3;
(*turno)++;
}
}
/*
interfaccia()
Serve a richiamare di volta in volta l'interfaccia del gioco, dove è possibile effettuare le varie scelte.
Parametri in ingresso :
x e y indicano i punteggi dei 2 giocatori. Infatti nel main richiamo la funzione passandole come valori a.punteggio e b.punteggio.
Infine scelta è un int che viene passato per riferimento alla funzione, che servirà ad immaggazinare la scelta dell'utente.
Parametri restituiti:
scelta, che indica appunto la scelta effettuata dal giocatore nel menù di gioco.
*/
int interfaccia(int x,int y, int *scelta)
{
printf("\t\t===================================================\n");
printf("\t\t===================================================\n");
printf("\t\t\n\t\t MENU DI GIOCO \n");
printf("\t\t1) Aggiungi una lettera alla parola(+1 punto).\n");
printf("\t\t2) Togli una lettera alla parola (-1 punto).\n");
printf("\t\t3) Passa il turno ( -3 punti).\n");
printf("\t\t0) Esci.\n\n");
printf("\t\tPunteggio giocatore 1 - %s : %d\\10 \n\t\tPunteggio giocatore 2 - %s : %d\\10 \n",a.nome,x,b.nome,y);
printf("\t\t===================================================\n");
printf("\t\t===================================================\n");
(*scelta) = getch();
return (*scelta);
/*Mostro l'interfaccia di gioco. Ho scritto int interfaccia, perchè la funzione deve ritornare un valore intero,
cioè scelta, che sarà poi utilizzato nello switch. x e y in questo caso sono utili per dare a ogni chiamata
dell'interfaccia il resoconto dei punti. prima infatti ho richiamato interfaccia, passandogli come x e y i punteggi dei due giocatori. */
}
void salvare(char *parola, struct cella *testa)
{
/* allocazione di una nuova cella in memoria */
nuovo=(struct cella *)malloc(sizeof(struct cella));
nuovo->next = testa;
testa = nuovo;
strcpy(nuovo->parmem,parola);
}
/*
vincitore()
funzione posta alla fine del programma, che serve ad indicare chi dei due è il vincitore. Si basa sul valore assunto in quel momento da turno.
Paremetri in ingresso:
turno, passato per indirizzo, che mi è utile per dire chi ha vinto.
x e y, due struct giocatore che mi permettono di indicare il nome dei due giocatori.
mosse, per indirizzo, che tiene conto delle mosse totali effettuate
Parametri restituiti:
Nessuno
*/
void vincitore(int *turno, struct giocatore *x,struct giocatore *y,int *mosse)
{
system("cls");
if((*turno)%2 != 0)
{
printf("\t\t===================================================\n");
printf("\t\t===================================================\n");
printf("\t\tIl giocatore n.%d e\' il vincitore!!!!!\n",(*turno)+1);
printf("\n\t\tMosse totali nel gioco : %d.\n",*mosse);
printf("\n\t\tCongratulazioni %s!!!",y->nome);
}
if((*turno)%2 == 0)
{
printf("\t\t===================================================\n");
printf("\t\t===================================================\n");
printf("\t\tIl giocatore n.%d e\' il vincitore!!!!!\n",(*turno)-1);
printf("\n\t\tMosse totali nel gioco : %d.\n",*mosse);
printf("\n\t\tCongratulazioni %s!!!",x->nome);
}
}
/*
fturnoUp()
funzione che mi permette di alternare il turno tra i due giocatori,e nello stesso momento aumentare i punteggi dei giocatori.
Viene richiamata se l'utente ha scelto di aggiungere una lettera.
Parametri passati alla funzione:
turno, passato per indirizzo, che mi è utile per gestire l'alternanza.
2 struct giocatore, passate per indirizzo perchè devo modificarne il punteggio.
Parametri restituiti:
Nessuno
*/
void fturnoUp(int *turno, struct giocatore *x, struct giocatore *y)
{
if((*turno)%2 == 0)
{
y->punteggio += 1;
(*turno)--;//quindi il turno diventa dispari, verificando alla prossima iterazione l'else
}
else
{
x->punteggio += 1;
(*turno)++;//e il turno ridiventa pari
}
}
/*
fturnoDown()
funzione che mi permette di alternare il turno tra i due giocatori,e nello stesso momento diminuire i punteggi dei giocatori.
Viene richiamata se l'utente ha scelto di togliere una lettera.
Parametri passati alla funzione:
turno, passato per indirizzo, che mi è utile per gestire l'alternanza.
2 struct giocatore, passate per indirizzo perchè devo modificarne il punteggio.
Parametri restituiti:
Nessuno
*/
void fturnoDown(int *turno, struct giocatore *x, struct giocatore *y)
{
if((*turno)%2 == 0)
{
y->punteggio -= 1;
(*turno)--;
/*quindi il turno diventa dispari, verificando l'else,alla prossima iterazione */
}
else
{
x->punteggio -= 1;
(*turno)++;
/* e così il turno ridiventa pari */
}
}