giovedì 23 ottobre 2008

La PIRAMIDE ROVESCIATA

Buonasera (o meglio, buonanotte) a tutti i frequenti visitatori del mio blog.

Molto probabilmente, caro lettore, sei entrato nel blog per sgraffignare l'algoritmo del programma che ci è stato assegnato, ma credo che sia un po' tardi per mettersi a comprendere questo sorgente.
Comunque, mentre scrivo queste righe il mio orologio segna le 15:38...cioè l'intervento lo preparo, ma che sò così fesso da pubblicarlo subito, così tutti copiano? E no...

Questa volta, il sorgente che tra poco vi presenterò è inerente un giochino sconosciuto al 99% di noi giovani, che io ho chiamato "LA PIRAMIDE ROVESCIATA". Questo consiste in una piramide rivolta verso il basso (appunto), formata da simboli "". Lo scopo del gioco è barrare uno o più "" presenti su una riga, con lo scopo di lasciare l'avversario (in questo caso il pc) con un solo "" da barrare. Perde il giocatore che si ritrova da barrare l'ultimo "" residuo.

In questo caso, il pc risponde con una mossa semplicissima: barra soltanto la prima casella che ancora non è stata barrata.

Il gioco presenta la seguente interfaccia:







Ed ora, ecco il tanto atteso sorgente (come al solito farcito e stracondito di commenti) :

/*GIOCHINO SCONOSCIUTO, in linguaggio C

written by Doctor Vel, 20/10/2008, 17:50

finito alle 22:10 del 21/10/2008

Tutti i diritti riservati*/



#include <stdio.h>

char board[16]; /*tavola da gioco contenente i "" oppure i "+". L'array è da 16 elementi perchè sarà la funzione di stampa a provvedere all'allineamento centrale delle 4 righe, evitando così di utilizzare un array da ben 28 caselle*/

char symbol[2]= {'','+'}; /*contiene i due simboli di gioco*/

int i=0;

int gioco_finito=
0; /*quando assume valore 1, il gioco è finito*/

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



/*funzione di stampa*/

void stampa() { /*non vi sono parametri di input, dato che la board è una variabile globale*/

int j;

for(j=
0;j<7;j++) {

printf(
"%c",board[j]); /*le prime 7 caselle le stampo tutte in fila*/

}

printf(
"\n "); /*dopo le prime 7 caselle, vado a capo e lascio uno spazio, perchè la seconda fila di caselle è sfalsata di una posizione rispetto alla prima*/

for(j=7;j<12;j++) {

printf(
"%c",board[j]); /*seconda riga di caselle, tutte in fila*/

}

printf(
"\n "); /*vado a capo e lascio 2 spazi*/

for(j=12;j<15;j++) {

printf(
"%c",board[j]); /*terza riga di caselle, tutte in fila*/

}

printf(
"\n %c",board[15]); /*vado a capo e lascio 3 spazi, quindi stampo l'ultima casella*/

}



/*funzione di azzeramento della board*/

void azzera() {

int y;

for(y=
0;y<16;y++) {

board[y]=symbol[
0]; /*ad ogni casella assegno il simbolo di gioco ""*/

}

}



/*funzione per raccogliere la mossa del giocatore*/

void mossaGiocatore() { /*non restituisce niente perchè utilizza come output un array dichiarato come variabile globale*/

int b;

int casella_inizio=
0; /*inizio dell'intervallo*/

int casella_fine=0; /*fine dell'intervallo*/

int sw=1; /*permette di agevolare la fase di verifica dell'esattezza dell'intervallo di caselle. Quando sw=0, l'intervalloè giusto e si va avanti*/

while(sw==1) {

printf(
"\nImmetti il numero di casella da cui vuoi iniziare a barrare e premi INVIO : ");

scanf(
"%d",&casella_inizio);

printf(
"\nImmetti il numero dell'ultima casella da barrare e premi INVIO : ");

scanf(
"%d",&casella_fine);

if( (casella_inizio>
0)&&(casella_inizio<17) && /*controllo che le caselle facciano davvero parte della board*/

(casella_fine>0)&&(casella_fine<17) &&

(
/*inizio serie di OR*/

( (casella_inizio>0)&&(casella_inizio<8)&&(casella_fine<8) ) /*se la casella di inizio appartiene alla prima riga, anche la casella di fine deve appartenere alla prima riga, cioè deve essere minore di 8*/

( (casella_inizio>7)&&(casella_inizio<13)&&(casella_fine>7)&&(casella_fine<13) ) /*se la casella di inizio appartiene alla seconda riga, anche la casella di fine deve appartenere alla seconda riga, cioè deve essere maggiore di 7 e minore di 13*/

( (casella_inizio>12)&&(casella_inizio<16)&&(casella_fine>12)&&(casella_fine<16) ) /*se la casella di inizio appartiene alla terza riga, anche la casella di fine deve appartenere alla terza riga, cioè deve essere maggiore di 12 e minore di 16*/

( (casella_inizio==16)&&(casella_fine==16) ) /*se seleziono l'ultima casella per barrarla, la casella di inizio deve coincidere con quella della fine*/

) /*fine serie di OR*/

) {

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

}

}

for( b=(casella_inizio-
1);b<casella_fine;b++ ) {

board[b]=symbol[
1]; /*nell'intervallo selezionato, sostituisco il simbolo con il "+"*/

}

}



/*funzione mossa computer*/

void mossaPc() {

int a;

for(a=
0;a<16;a++) {

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

board[a]=
'+';

break;

}
/*la prima casella che trova ancora non barrata, la barra. Poi esce*/

}

}



/*funzione per vedere quando il gioco è finito*/

int fine_gioco() {

int conta_segni=
0; /*contiene il numero di "" residui*/

int fine=0;

int x;

for(x=
0;x<16;x++) {

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

conta_segni++;

}

}

if(conta_segni<=
1) {

fine=
1; /*il gioco resta attivo fin quando ci sono rimasti minimo 2 caselle da barrare*/

}

return fine;

}



/*funzione che stampa chi è il vincitore*/

void stampa_vincitore(int vincitore) {

int c;

int conta_barrate=
0;

for(c=
0;c<16;c++) {

if(board[c]==
'+') {

conta_barrate++;

if(conta_barrate==
16) { /*se tutte le caselle sono barrate, il gioco è finito ma non c'è nessun vincitore*/

printf("\nNESSUN VINCITORE...\n");

}

}
/*chiudo la if*/

else { /*cioè se non tutte le 16 caselle sono barrate, ovvero c'è un vincitore*/

vincitore=vincitore-1;

if(vincitore%
2==0) { /*ora stampo chi è il vincitore. Se la mossa vincente ha indice pari, ha vinto il giocatore. Altrimenti, ha vinto il computer*/

printf("\nHAI VINTO !!! =)\n");

}

else {

printf(
"\nHAI PERSO... =(\n");

}

}

}
/*chiudo la for*/

} /*chiudo la funzione*/



/*funzione principale*/

main() {



printf(
"------------- A DOCTOR VEL 2008 PRODUCTION -------------\n\n----- La PIRAMIDE ROVESCIATA -----\n\nQuesto gioco consiste nel barrare il maggior numero di caselle consecutive, sulla stessa riga. Perde il giocatore che si ritrova con una sola casella residua da barrare.\nPer specificare quali caselle si vogliono barrare, bisogna inserire l'intervallo di caselle di tipo DA...A.\nBuon divertimento !!!\n\n");

system(
"PAUSE");

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

azzera();

stampa();

printf(
"\n\nQuesta e' la tavola da gioco. I corrispondenti numeri delle caselle sono :\n\n");

printf(
"1 2 3 4 5 6 7\n\n 8 9 10 11 12\n\n 13 14 15\n\n 16\n\n"); /*stampo il numero di ogni casella*/

printf("Ora ti verra' richiesto di inserire l'intervallo di caselle da barrare.\n!!! ATTENZIONE !!! Immetti intervalli di caselle comprendenti la stessa riga !!!\nSe ti viene richiesto di immettere nuovamente l'intervallo, e' perche' hai commesso un errore, quindi controlla meglio e digita nuovamente l'intervallo.\n");

while(gioca_ancora==
1) { /*prima while*/



while(gioco_finito==0) { /*si alternano le mosse finchè rimane soltanto una casella non barrata. A quel punto, il gioco è finito*/

if(i%2==0) { /*ogni 2 volte, tocca al giocatore, che è il primo ad iniziare*/

printf("\nMossa GIOCATORE\n");

mossaGiocatore();

gioco_finito=fine_gioco();

i++;

printf(
"\n");

stampa();

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

}

else {

printf(
"\nMossa COMPUTER\n\n");

mossaPc();

gioco_finito=fine_gioco();

i++;

printf(
"\n");

stampa();

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

}

}

stampa_vincitore(i);

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

scanf(
"%d",&gioca_ancora);

if(gioca_ancora==
1) {

azzera();

i=
0;

gioco_finito=
0;

}
/*l'array va riazzerato!*/

} /*chiudo la prima while*/



printf("\n---------------------------\nEnJoY !!! =) (c) Doctor Vel 2008\n\n");

system(
"PAUSE");



}
/*fine main*/








Arvedecce e bonanotte a tutti!

lunedì 13 ottobre 2008

Il giochino sconosciuto...

Salve a tutti!

Mi sono appena alzato da tavola, dopo aver mangiato una porzione smisurata di pasta alla norcina. Oggi vi scrivo per postare la mia soluzione dell'esercizio n° 7 del compito di stamane, che la stampante si è *rifiutata* di stampare.


Il giochino inerente questo esercizio neanche mi ricordo come si chiama, ma poco importa...la cosa fondamentale è che il prof. veda l'esercizio per dargli una valutazione (sennò prendo 4 e sono CApperI amari, mooooolto amari).


Quindi, fatti e non parole: ecco il sorgente:

/*TOMMASO VELATTA*/
#include <stdio.h>
int board[29];
char symbol[
3]= {' ','','+'};
int i;

/*funzione per ottenere la piramide di ""*/
void azzera_board(int board[29]) {
int j;
for(j=
1;j<8;j++) {
board[j]=
1;
}
for(j=
9;j<14;j++) {
board[j]=
1;
}
for(j=
17;j<20;j++) {
board[j]=
1;
}
board[
25]=1;
}

/*funzione per stampare*/
void stampa(int array[29]) {
for(i=
1;i<29;i++) {
printf(
"%c",symbol[ array[i] ]);
if(i%
7==0) { /*ogni 7 caselle vado a capo*/
printf("\n");
}
}
}

/*funzione principale*/
main() {
azzera_board(board);
stampa(board);


system(
"PAUSE");
}

Ed ecco uno screen di come si presenta la stampa della tavola da gioco di questo giochino sconosciuto:




Buon proseguimento di giornata a tutti! E, come al solito, arvedecce!

PS_(solo per il 4ALE): non ve sfleshate troppo a studià diritto!

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 =) ...