venerdì 3 ottobre 2008

Il famoso FILETTO

Arieccomi di nuovo a scrivere sul blog.

Questa volta è per postare la mia soluzione del famoso programma del filetto, che ho opportunamente farcito di commenti su commenti per rendere più chiaro possibile il metodo che ho adottato. Allego anche alcuni screen del funzionamento di questo allegro giochino.

In particolare, evidenzio la board da me utilizzata, formata dalla combinazione dei segni "+", "_" e "-". L'aspetto della board è questo:












e, tradotto nella printf del linguaggio C, viene convertito così: printf("_____________\n \n \n---+---+---\n \n \n---+---+---\n \n_________\n");

Poi, all'interno di ogni casella, ho inserito il riferimento ad una variabile char, in quanto dovrà contenere la "x" o la "o". Inoltre, siccome nella mia soluzione ho assegnato il contenuto di ogni casella alla cella di un array (ovvero char board[9] , con 9 caselle), ad ogni %c faccio corrispondere la casella corrispondente dell'array. Il risultato è il seguente:



printf("_____________\n \n %c %c %c \n---+---+---\n \n %c %c %c \n---+---+---\n %c %c %c \n_________\n",board[0],board[1],board[2],board[3],board[4],board[5],board[6],board[7],board[8]);


----------------------------------------------------------------------


Per far comprendere al giocatore il numero della casella in cui vuole inserire la "x", all'inizio del programma ho creato un printf("_____________\n \n 1 2 3 \n---+---+---\n \n 4 5 6 \n---+---+---\n 7 8 9 \n_________\n"); , sostituendo i %c al numero della casella corrispondente. Il risultato è il seguente:





Il codice sorgente dell'intero programma è il seguente:

/*gioco del TRIS in linguaggio C. Written by Doctor Vel, 19.09.2008. Tutti i diritti riservati*/



#include <stdio.h>

#include <stdlib.h>

char board[9]; /*contiene i simboli di gioco delle 9 caselle*/

char symbol[3]= {' ','x','o'}; /*contiene la raccolta dei simboli di gioco usati*/

int i=0;

int mossaGiocatore_1;
/*contiene la casella selezionata dal giocatore*/

int mossaPc; /*contiene la casella scelta dal PC*/

int sw_occupato=1; /*serve per verificare se la casella scelta dal PC è occupata o no*/

int gioca_ancora=1; /*permette di loopare l'esecuzione del gioco, quando questo finisce*/



/*funzione per vedere se la casella è già occupata. Se occupato=1, la casella è occupata. Se occupato=0, la casella è vuota*/

int occupato(int scelta_casella, char board[9]) {

int ok=
1;

if(board[scelta_casella]==
' ') {

ok=
0;

}

return ok;

}



/*funzione per raccogliere la mossa del giocatore*/

int mossaGiocatore() {

int casella=
0; /*azzero la variabile casella, non si sa mai...*/

int sw=1; /*permette di agevolare la fase di verifica dell'esattezza del numero di casella. Quando sw=0, la casella è giusta e si va avanti*/

while(sw==1) {

printf(
"\nImmetti il numero della casella e premi INVIO : ");

scanf(
"%d",&casella);

if( (casella>
0)&&(casella<10) ) {

sw=
0; /*parte di controllo della validità*/

}

}

return (casella-
1); /*perchè la numerazione delle caselle, nell'array, parte da 0*/

}



/*funzione per la stampa della board con le mosse fatte via via*/

void stampa(char board[9]) {

printf(
"_____________\n \n %c %c %c \n---+---+---\n \n %c %c %c \n---+---+---\n %c %c %c \n_________\n",

board[
0],board[1],board[2],board[3],board[4],board[5],board[6],board[7],board[8]);

}



/*funzione per azzerare il contenuto dell'array contenente la board*/

void azzera(char board[9]) {

for(i=
0;i<9;i++) {

board[i]=symbol[
0];

}

}



/*funzione per la creazione di numeri casuali compresi tra 0 e 9 (necessari per il riempimento automatico delle caselle da parte del PC*/

int casuale() {

double numero=
0;

numero=(
10*(rand()/(RAND_MAX+1.0)) ); /*il numero assumerà valori compresi tra 1 e 9*/

return (int)numero; /*deve essere convertito in int, dato che 1.0 è un double*/

}



/*funzione per verificare chi ha vinto*/

int vincitore(char board[9]) { /*stampa direttamente chi è il vincitore, e restituisce il comando che permette di chiudere il gioco. Se il comando non è restituito, è una patta*/

char segno; /*contiene il segno del vincitore*/

int fine=0; /*comanda la chiusura del gioco appena qualcuno ha vinto. Se assume valore 1, il gioco chiede se chiudere*/



/*controlli orizzontali*/

if(board[0]==board[1] && board[1]==board[2]) { segno=board[0]; }

if(board[
3]==board[4] && board[4]==board[5]) { segno=board[3]; }

if(board[
6]==board[7] && board[7]==board[8]) { segno=board[6]; }

/*controlli verticali*/

if(board[0]==board[3] && board[3]==board[6]) { segno=board[0]; }

if(board[
1]==board[4] && board[4]==board[7]) { segno=board[1]; }

if(board[
2]==board[5] && board[5]==board[8]) { segno=board[2]; }

/*controlli diagonali*/

if(board[0]==board[4] && board[4]==board[8]) { segno=board[0]; }

if(board[
2]==board[4] && board[4]==board[6]) { segno=board[2]; }



/*ora bisogna escludere lo ' ', altrimenti quando la board è vuota ci sarebbe lo stesso un vincitore*/

if(segno=='x') {

printf(
"\nHAI VINTO !!! =) =)\n"); /*se vince l'umano*/

fine=1;

}

if(segno==
'o') {

printf(
"\nHAI PERSO... =( =(\n"); /*se vince il PC*/

fine=1;

}

return fine;

}



/*funzione principale*/

main() {

printf(
"--------------- A DOCTOR VEL 2008 PRODUCTION ---------------\n\n----- GIOCO DEL FILETTO Vs. PC -----\n\nLa tua mossa sara' identificata dalla 'x'. Il PC rispondera' con una mossa indicata dalla 'o'.\n");

system(
"PAUSE");

printf(
"_____________\n \n 1 2 3 \n---+---+---\n \n 4 5 6 \n---+---+---\n 7 8 9 \n_________\n\nQuesto e' il tavolo da gioco. Per fare la tua mossa dovrai immettere il numero della casella dove vuoi porre la 'x'. PRONTI...VIA !!!\n");

system(
"PAUSE");

azzera(board);
/*viene azzerata la tavola di gioco*/



while(gioca_ancora==1) {

/*richiamo la funzione per l'inserimento della mossa (del PC o del giocatore)*/

for(i=0;i<9;i++) { /*le caselle sono 9 => ci sono 9 mosse*/

printf("\nMOSSA N. %d\n",(i+1));



if(i%
2==0) {

/*ogni due volte TOCCA ALL'UMANO inserire la casella, le altre volte tocca al PC*/

mossaGiocatore_1=mossaGiocatore(); /*viene caricata la casella selezionata*/

if( occupato(mossaGiocatore_1,board)==0 ) {

/*verifico che la casella sia vuota*/

board[mossaGiocatore_1]=symbol[1]; /*la 'x' viene posta in corrispondenza del numero di casella immesso*/

stampa(board); /*dopo ogni mossa, questa viene stampata insieme a quelle già fatte, se la casella è vuota*/

}

else {

printf(
"\nHai scelto una casella gia' occupata. Esci dal gioco e ricomincia.\n");

break;

}

}

else {
/*TOCCA AL PC*/

while(sw_occupato==1) {

mossaPc=casuale();

sw_occupato=occupato(mossaPc,board);
/*si esce dalla while quando la casella è libera, ovvero mossaPc è valida => sw_occupato non è più uguale a 1*/

} /*il PC produce numeri random fino ad ottenerne uno rappresentante una casella ancora libera*/

board[mossaPc]=symbol[2];

stampa(board);
/*stampa della board, con la mossa del PC appena fatta*/

sw_occupato=1; /*rimetto a 1 lo sw_occupato, sennò il ciclo della while non verrà più considerato*/

}

if( vincitore(board)==
1 ) {

break;
/*se ha vinto qualcuno, il gioco non prosegue*/

}

}
/*chiudo la for*/

if( vincitore(board)==0 ) {

printf(
"\nNESSUN VINCITORE\n");

}

printf(
"\n---------------------------\n\nVuoi giocare di nuovo? (SI=1, NO=2) ");

scanf(
"%d",&gioca_ancora);

if(gioca_ancora==
1) {

azzera(board);

}
/*l'array va riazzerato!*/

} /*chiudo la prima while*/

printf("\n---------------------------\n\n");

system(
"PAUSE");

}



PS_per includere il sorgente tale e quale a come è visualizzato nel DevCpp, l'ho esportato in HTML e l'ho aggiunto (ovviamente togliendo intestazioni e altre robe HTML) dalla scheda "Modifica HTML".
Arvedecce a tutti =) ...