Aggiornamento maggiore

*Spostate le funzioni in un file esterno(tris.c);
*Rimosse cose inutili dalla licenza;
*Risolto un bug nella funzione int controlla(int giocatore);
*Aggiunti nuovi commenti;
*Riordinate le funzioni;
*Aggiornato il makefile;
*Aggiornato il README.md.
This commit is contained in:
Rnhmjoj 2012-11-20 22:59:25 +01:00
parent e77fc8be1f
commit 3af7a536c4
6 changed files with 321 additions and 297 deletions

View File

@ -17,10 +17,7 @@ Link: http://github.com/adoxa/ansicon
### Installazione ### Installazione
Per compilare il programma su UNIX usa _make_. Per compilare il programma su UNIX usa _make_.
Su windows si può usare MinGW. Scrivi: Su windows usa un compilatore qualisasi o _make_ se hai MinGW
gcc -std=c99 -c main.c -o "Tris in Stile C"
Link: http://www.mingw.org Link: http://www.mingw.org
### Istruzioni ### Istruzioni

View File

@ -5,10 +5,6 @@
* singolo contro il computer(3 difficoltà a scelta basate * singolo contro il computer(3 difficoltà a scelta basate
* sulla profondità dell'algoritmo minimax). * sulla profondità dell'algoritmo minimax).
* *
* Richiede un terminale con supporto alle sequenze di
* escape ANSI. Per windows è possible usare ANSIcon:
* https://github.com/adoxa/ansicon
*
* Dual licensed under the MIT and GPL licenses: * Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php * http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html * http://www.gnu.org/licenses/gpl.html

2
main.c
View File

@ -2,6 +2,8 @@
int main (){ int main (){
int vittoria; int vittoria;
int difficolta; int difficolta;
tastierino=0;
a='a';
do{ do{
giocatore=1,vittoria=0; giocatore=1,vittoria=0;
scelta=0,difficolta=0,mossa=0; scelta=0,difficolta=0,mossa=0;

View File

@ -1,4 +1,7 @@
Tris-in-stile-c : main.c tris.h SHELL = /bin/sh
gcc -std=c99 -c main.c -o "Tris in Stile C" .SUFFIXES:
.SUFFIXES: .c .o
Tris-in-stile-c : main.c tris.c tris.h
gcc -std=c99 main.c tris.c -o "Tris in stile C"

307
tris.c Executable file
View File

@ -0,0 +1,307 @@
#include "tris.h"
/*Funzioni*/
/*Legge dalla tastiera senza usare il buffer*/
int mgetchar(){
char buf=0;
struct termios old={0};
if(tcgetattr(0,&old)<0)
perror("tcsetattr()");
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0,TCSANOW,&old)<0)
perror("tcsetattr ICANON");
if(read(0,&buf,1)<0)
perror("read()");
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0,TCSADRAIN,&old)<0)
perror("tcsetattr ~ICANON");
return (buf);
}
/*Stampa la tabella del tris*/
void stampa(){
int i,k;
printf("\n\n\n");
for(i=0;i<M;i++) {
printf(RESET" ");
for(k=0;k<M;k++) {
if(tabella[i][k]==1)
printf(GIALLO" O ");
else {
if(tabella[i][k]==2)
printf(ROSSO" X ");
else
printf(BIANCO" . ");
}
}
printf("\n\n");
}
printf("\n");
}
/*Cancella la tabella del tris*/
void vuota() {
for(i=0;i<M;i++) {
for(k=0;k<M;k++)
tabella[i][k]=0;
}
}
/*Legge la mossa del giocatore*/
void leggimossa(){
int tasto=0;
fflush(stdin);
/*Se è attivo il tastierino*/
if(tastierino==1){
do{
tasto=0;
fflush(stdin);
/*2 giocatori*/
if(scelta==2)
printf(GIALLO" Fai la tua mossa:\n"RESET BIANCO);
else
printf(GIALLO" Gioca il giocatore %d.\n Fai la tua mossa:\n"RESET BIANCO,giocatore);
if(os)
tasto=mgetchar();
else
do{
tasto=getch();
}while(kbhit());
switch(tasto){
case 49:{
i=2;
k=0;
break;
}
case 50:{
i=2;
k=1;
break;
}
case 51:{
i=2;
k=2;
break;
}
case 52:{
i=1;
k=0;
break;
}
case 53:{
i=1;
k=1;
break;
}
case 54:{
i=1;
k=2;
break;
}
case 55:{
i=0;
k=0;
break;
}
case 56:{
i=0;
k=1;
break;
}
case 57:{
i=0;
k=2;
break;
}
}
if(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M){
system(clear);
stampa();
printf(GRASSETTO ROSSO"\n Mossa non valida,riprova.\n\n"RESET BIANCO);
}
}while(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M);
}
/*Mossa con coordinate*/
else{
do{
/*Giocatore singolo*/
if(scelta==2)
printf(GIALLO" Tocca a te.\n Inserisci coordinate della mossa"ROSSO"[Riga,colonna]:\n" RESET BIANCO);
/*2 giocatori*/
else
printf(GIALLO" Gioca il giocatore %d.\n Inserisci coordinate della mossa"ROSSO"[Riga,colonna]:\n" RESET BIANCO,giocatore);
scanf("%d,%d",&i,&k);
if(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M){
system(clear);
stampa();
printf(GRASSETTO ROSSO"\n\n Coordinate non valide,riprova.\n\n\n"RESET BIANCO);
}
}while(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M);
system(clear);
}
}
/*Controlla se il giocatore ha vinto*/
int controlla(int giocatore){
/*Diagonali*/
for(i=0;i<M;i++){
for(k=M;k>=0;k--)
if(tabella[i][k]==giocatore&&tabella[i+1][k-1]==giocatore&&tabella[i+1][k-2]==giocatore)
return 1;
for(k=0;k<M;k++)
if(tabella[i][k]==giocatore&&tabella[i+1][k+1]==giocatore&&tabella[i+2][k+2]==giocatore)
return 1;
}
/*Righe e colonne*/
for(i=0;i<M;i++){
for(k=0;k<M;k++)
if(tabella[i][k]==giocatore&&tabella[i][k+1]==giocatore&&tabella[i][k+2]==giocatore)
return 1;
for(k=0;k<M;k++)
if(tabella[k][i]==giocatore&&tabella[k+1][i]==giocatore&&tabella[k+2][i]==giocatore)
return 1;
}
return 0;
}
/*Minimax*/
int minimax(int giocatore, int profondita){
if(controlla(2))
return INT_MAX;
if(mossa==M*M)
return 0;
int res,tmp;
if(giocatore==1){
res=1;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=1;
if(controlla(1)&&!profondita==20){
tabella[i][k]=0;
return INT_MIN;
}
else if((tmp=minimax(2,profondita-1))<res)
res=tmp;
else
res-=2;
tabella[i][k]=0;
}
}
}
}
else{
res=-1;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
if(controlla(2))
res+=2;
else if((tmp=minimax(1,profondita-1))>res)
res=tmp;
tabella[i][k]=0;
}
}
}
}
return res;
}
/*Mossa del computer a difficoltà facile*/
void facile() {
int a,b;
do{
randomize;
a=random(M);
b=random(M);
}while(tabella[a][b]==1||tabella[a][b]==2);
tabella[a][b]=2;
}
/*Mossa del computer a difficoltà media*/
void medio(){
int max=INT_MIN,mi=1,mk=1,t;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
t=minimax(1, 10);
if(t>max){
max=t;
mi=i;
mk=k;
}
tabella[i][k]=0;
}
}
}
stampa();
tabella[mi][mk]=2;
}
/*Mossa del computer a difficoltà difficile*/
void difficile(){
int max=INT_MIN,mi=1,mk=1,t;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
t=minimax(1,20);
if(t>max){
max=t;
mi=i;
mk=k;
}
tabella[i][k]=0;
}
}
}
tabella[mi][mk]=2;
}
/* Blocca l'esecuzione finchè non viene premuto invio*/
void pausa() {
do
getchar();
while ((c= getchar()) != '\n' && c!= EOF);
}
/*Replica di Sleep()*/
void aspetta(int t){
time_t Ti,Tf;
time(&Ti);
do{
time(&Tf);
}while(difftime(Tf,Ti)<t);
}
/*Caricamento stile Ajax*/
void spinner(int tempo) {
char spinner[] = "/-\\|";
printf(GIALLO"\n ");
for (int i=0; i<(tempo*10);i++){
putchar(spinner[i%4]);
fflush(stdout);
usleep(200000);
putchar('\b');
}
printf(RESET);
putchar(' ');
}
/*Beep*/
void beep(int t){
for(i=0;i<t*100;i++)
putchar('\a');
}

291
tris.h
View File

@ -37,309 +37,28 @@
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
int mgetchar(void); int mgetchar(void);
int mgetchar(){
char buf=0;
struct termios old={0};
if(tcgetattr(0,&old)<0)
perror("tcsetattr()");
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0,TCSANOW,&old)<0)
perror("tcsetattr ICANON");
if(read(0,&buf,1)<0)
perror("read()");
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0,TCSADRAIN,&old)<0)
perror("tcsetattr ~ICANON");
return (buf);
}
#endif #endif
/*Prototipi*/ /*Prototipi*/
void vuota(void);
void stampa(void); void stampa(void);
void vuota(void);
void leggimossa(void);
int controlla(int giocatore); int controlla(int giocatore);
void spinner(int tempo);
int minimax(int giocatore, int profondita); int minimax(int giocatore, int profondita);
void facile(void); void facile(void);
void medio(void); void medio(void);
void difficile(void); void difficile(void);
void pausa(void); void pausa(void);
void leggimossa(void); void spinner(int tempo);
void aspetta(int t); void aspetta(int t);
void beep(int t); void beep(int t);
/*Variabili globali*/ /*Variabili globali*/
char a='a',c; char a,c;
int i,k; int i,k;
int giocatore,scelta,mossa; int giocatore,scelta,mossa;
int tabella[M][M]; int tabella[M][M];
int tastierino=0; int tastierino;
/*Funzioni*/
void stampa(){
int i,k;
printf("\n\n\n");
for(i=0;i<M;i++) {
printf(RESET" ");
for(k=0;k<M;k++) {
if(tabella[i][k]==1)
printf(GIALLO" O ");
else {
if(tabella[i][k]==2)
printf(ROSSO" X ");
else
printf(BIANCO" . ");
}
}
printf("\n\n");
}
printf("\n");
}
int controlla(int giocatore){
for(i=0;i<M;i++){
if(tabella[i][i]==giocatore&&tabella[i+1][i+1]==giocatore&&tabella[i+2][i+2]==giocatore)
return 1;
if(tabella[i+2][i]==giocatore&&tabella[i+1][i+1]==giocatore&&tabella[i][i+2]==giocatore)
return 1;
}
for(i=0;i<M;i++){
for(k=0;k<M;k++)
if(tabella[i][k]==giocatore&&tabella[i][k+1]==giocatore&&tabella[i][k+2]==giocatore)
return 1;
for(k=0;k<M;k++)
if(tabella[k][i]==giocatore&&tabella[k+1][i]==giocatore&&tabella[k+2][i]==giocatore)
return 1;
}
return 0;
}
int minimax(int giocatore, int profondita){
if(controlla(2))
return INT_MAX;
if(mossa==M*M)
return 0;
int res,tmp;
if(giocatore==1){
res=1;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=1;
if(controlla(1)&&!profondita==20){
tabella[i][k]=0;
return INT_MIN;
}
else if((tmp=minimax(2,profondita-1))<res)
res=tmp;
else
res-=2;
tabella[i][k]=0;
}
}
}
}
else{
res=-1;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
if(controlla(2))
res+=2;
else if((tmp=minimax(1,profondita-1))>res)
res=tmp;
tabella[i][k]=0;
}
}
}
}
return res;
}
void facile() {
int a,b;
do{
randomize;
a=random(M);
b=random(M);
}while(tabella[a][b]==1||tabella[a][b]==2);
tabella[a][b]=2;
}
void medio(){
int max=INT_MIN,mi=1,mk=1,t;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
t=minimax(1, 10);
if(t>max){
max=t;
mi=i;
mk=k;
}
tabella[i][k]=0;
}
}
}
stampa();
tabella[mi][mk]=2;
}
void difficile(){
int max=INT_MIN,mi=1,mk=1,t;
for(i=0;i<M;i++){
for(k=0;k<M;k++){
if(!tabella[i][k]){
tabella[i][k]=2;
t=minimax(1,20);
if(t>max){
max=t;
mi=i;
mk=k;
}
tabella[i][k]=0;
}
}
}
tabella[mi][mk]=2;
}
void pausa() {
do{
getchar();
}while ((c= getchar()) != '\n' && c!= EOF);
}
void vuota() {
for(i=0;i<M;i++) {
for(k=0;k<M;k++)
tabella[i][k]=0;
}
}
void leggimossa(){
int tasto=0;
fflush(stdin);
if(tastierino==1){
do{
tasto=0;
fflush(stdin);
if(scelta==2)
printf(GIALLO" Fai la tua mossa:\n"RESET BIANCO);
else
printf(GIALLO" Gioca il giocatore %d.\n Fai la tua mossa:\n"RESET BIANCO,giocatore);
if(os)
tasto=mgetchar();
else
do{
tasto=getch();
}while(kbhit());
switch(tasto){
case 49:{
i=2;
k=0;
break;
}
case 50:{
i=2;
k=1;
break;
}
case 51:{
i=2;
k=2;
break;
}
case 52:{
i=1;
k=0;
break;
}
case 53:{
i=1;
k=1;
break;
}
case 54:{
i=1;
k=2;
break;
}
case 55:{
i=0;
k=0;
break;
}
case 56:{
i=0;
k=1;
break;
}
case 57:{
i=0;
k=2;
break;
}
}
if(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M){
system(clear);
stampa();
printf(GRASSETTO ROSSO"\n Mossa non valida,riprova.\n\n"RESET BIANCO);
}
}while(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M);
}
else{
do{
if(scelta==2)
printf(GIALLO" Tocca a te.\n Inserisci coordinate della mossa"ROSSO"[Riga,colonna]:\n" RESET BIANCO);
else
printf(GIALLO" Gioca il giocatore %d.\n Inserisci coordinate della mossa"ROSSO"[Riga,colonna]:\n" RESET BIANCO,giocatore);
scanf("%d,%d",&i,&k);
if(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M){
system(clear);
stampa();
printf(GRASSETTO ROSSO"\n\n Coordinate non valide,riprova.\n\n\n"RESET BIANCO);
}
}while(tabella[i][k]==1||tabella[i][k]==2||i<0||k<0||i>=M||k>=M);
system(clear);
}
}
void aspetta(int t){
time_t Ti,Tf;
time(&Ti);
do{
time(&Tf);
}while(difftime(Tf,Ti)<t);
}
void spinner(int tempo) {
char spinner[] = "/-\\|";
printf(GIALLO"\n ");
for (int i=0; i<(tempo*10);i++){
putchar(spinner[i%4]);
fflush(stdout);
usleep(200000);
putchar('\b');
}
printf(RESET);
putchar(' ');
}
void beep(int t){
for(i=0;i<t*100;i++)
putchar('\a');
}
#endif #endif