Progetto tris esteso

di il
9 risposte

Progetto tris esteso

Salve a tutti,

sto scrivendo il giochino del tris.. ma esteso, quindi non il classico 3x3 ma estensibile fino a 10x10.
è possibile scegliere la dimensione della griglia, e i segni di fila per fare punto (nel tris è 3)..

ammetto che molte parti del codice l'ho copiato dal tris chiamato 'miniMAXTris' scritto da lorelapo del sito pierotofy però ho aggiunto e modificato molte parti di codice per adattarlo al mio Tris.

Ho dei problemi nel fare l'algoritmo che controlla se nelle diagonali si è fatto Tris..
Inoltre se si estende il tris più di 3x3 l'algoritmo del Minimax va in loop non so perchè..
AIUTO!!

questo è il sorgente:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <conio.h>
#include <ctype.h>

#define DIM 5 //dimensioni della griglia: 3x3 4x4 5x5.. massimo 10x10 (nel classico tris è 3)
#define NWIN 3 //numero di segni di fila per vincere (nel classico tris è 3)

void griglia(); //funzione per visualizzare la griglia.
void leggimossa(char wnr); //funzione per leggere mossa dell'utente.
int ctrlwin(char wnr); //funzione per controllo se ci sono tris (nelle righe, colonne e diagolali.)
int endgame(); //funzione per controllo se le caselle sono tutte occupate

/*Funzioni per l'intelligenza artificiale*/
int nvuote(void);
void move(void);
int valutamossa(char wnr, int deep);

char tris[DIM][DIM];


int main(int argc, char *argv[])
{
    int i, j, modalita, rigioco, giocatore; //giocatore 1 = utente, giocatore 0 = computer.
    char simbolo;
    
    repeat:

    printf("BENVENUTO NEL TRIS!!! BY Pnb2Frank \n\n");
    printf("1) 2 giocatori \n");
    printf("2) utente vs computer \n\n");
    printf("\t Scelta: ");
    scanf("%d", &modalita);
    
    /*inizializzazione della griglia*/
     for(i=0;i<DIM;i++)
          for(j=0;j<DIM;j++)
               tris[i][j]=' ';
    
    switch(modalita)
    {
        /*SE SI HA SCELTO 2 GIOCATORI*/
        case 1:
                for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                {
                    /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                    if(i%2==0)
                        simbolo = 'X';
                    else
                        simbolo = 'O';
                        
                    system("cls"); //pulisce lo schermo
                    griglia();
                    leggimossa(simbolo);
                    if(ctrlwin(simbolo))
                    {
                        system("cls"); //pulisce lo schermo
                        griglia();
                        printf("Il giocatore %c vince!! \n", simbolo);
                        break;
                    }
                    if(endgame())
                    {
                        system("cls"); //pulisce lo schermo
                        griglia();
                        printf("Parita!! \n");
                        break;
                    }
                }
                break; //uscita switch (fine case 1)
                
        /*SE SI HA SCELTO UTENTE VS PC*/  
        case 2:
                for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                {
                    /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                    // 1 = giocatore
                    // 0 = computer
                    if(i%2==0)
                    {
                        giocatore = 1;
                        simbolo = 'X';
                    }
                    else
                    {
                        giocatore = 0;
                        simbolo = 'O';
                    }
                        
                    system("cls"); //pulisce lo schermo
                    griglia();
                    
                    // se giocatore == utente..
                    if(giocatore==1)
                        leggimossa(simbolo);
                    //altrimenti se giocatore == computer..
                    else if(giocatore==0)
                        move();
                        
                    if(ctrlwin(simbolo))
                    {
                        system("cls"); //pulisce lo schermo
                        griglia();
                        if(giocatore==1)
                            printf("Hai vinto!! \n");
                        else if(giocatore==0)
                            printf("Il computer vince!!\n");
                        break;
                    }
                    if(endgame())
                    {
                        system("cls"); //pulisce lo schermo
                        griglia();
                        printf("Parita!! \n");
                        break;
                    }
                }
                break; //uscita switch (fine case 2)
        
        default:
                printf("ERROR: modalita' non valida \n");
    }
    
    system("PAUSE");       
    system("cls");
    
    do
    {
         printf("Premi INVIO per rigiocare. \n");
         printf("Premi ESC per chiudere \n");
         rigioco = getch();
         
         if(rigioco == 13)
         {
             system("cls");
             goto repeat;
         }
         if(rigioco == 27)
         	   return 0;
     }
     while(rigioco != 13 && rigioco != 27);
}



void griglia()
{
     register int i,j;
     
     printf("\n  ");
     for(i=0;i<DIM;i++)
          printf("  %d", i);
     putchar('\n');
     
     for(i=0;i<DIM;i++)
     {
          printf(" %c ", i+65);
          for(j=0;j<DIM;j++)
               printf("[%1c]",tris[i][j]);
          putchar('\n');
     }
}


void leggimossa(char wnr)
{
     /*
          Legge le mosse come coordinate es: a1, B2, c5.
          Funziona sia con le maiuscole che con le minuscole
          mossaX è orizzontale (numero)
          mossaY è verticale (lettera)
     */
     char mossaX, mossaY;
     
     do
     {
          printf("\nTocca a %c, inserisci la mossa: ", wnr);
          mossaY = toupper(getch()); //verticale quindi una lettera (toupper serve per convertirlo in maiuscola)
          mossaX = getch(); //orizzontale quindi numero
     }
     while(mossaX-48 >= DIM || mossaY-65 >= DIM);
     
     tris[mossaY-65][mossaX-48] = wnr;
}

int ctrlwin(char wnr)
{
    int count, i, j;
    
     /*Controllo righe*/
     for(i=0; i<DIM; i++)
     {
          count=0;
          for(j=0; j<DIM; j++)
               if(tris[i][j]==wnr)
                    count++;
          if(count==NWIN)
               return 1;
     }
     
     /*Controllo colonne*/
     for(j=0; j<DIM; j++)
     {
          count=0;
          for(i=0; i<DIM; i++)
               if(tris[i][j]==wnr)
                    count++;
          if(count==NWIN)
               return 1;
     }
     
     /*Controllo diagonali*/
     // COME SI FA???????
     
     return 0;
}


int endgame()
{
     int i, j;
     
     for(i=0; i<DIM; ++i) 
          for(j=0; j<DIM; j++)
          {
               if(tris[i][j] == ' ')
               return 0;
          }
     return 1;
}


/*FUNZIONI PER L'INTELLIGENZA ARTIFICIALE*/

int nvuote(void)
{
     int i,j,vuote=0;
     for(i=0;i<DIM;i++)
          for(j=0;j<DIM;j++)
               if(tris[i][j]==' ') vuote++;
     return vuote;
}
    
void move(void)
{
        int i,j;
        int max=INT_MIN,mi=1,mj=1,t;
        for(i=0;i<DIM;i++)
                for(j=0;j<DIM;j++)
                        if(tris[i][j]==' ')
                        {
                                tris[i][j]='O';
                                t=valutamossa('X', 20);
                                //printf("%d\n",t);
                                if(t>max)
                                {
                                        max=t;
                                        mi=i;
                                        mj=j;
                                }
                                tris[i][j]=' ';
                        }
               
        tris[mi][mj]='O';
}
 
int valutamossa(char wnr, int deep)//Minimax
{
        if(ctrlwin('O'))
                return INT_MAX;
        if(endgame())
                return 0;
        int i, j, res, tmp;
        if(wnr=='X')
        {
                res=1;
                for(i=0;i<DIM;i++)
                        for(j=0;j<DIM;j++)
                        {
                                if(tris[i][j]==' ')
                                {
                                        tris[i][j]='X';
                                        if(ctrlwin('X'))
                                                if(deep==20)
                                                {
                                                        tris[i][j]=' ';
                                                        return INT_MIN;
                                                }
                                                else
                                                        res-=2;
                                        else if((tmp=valutamossa('O', deep - 1))<res)
                                                res=tmp;
                                        tris[i][j]=' ';
                                }
                        }
        }
        else
        {
                res=-1;
                for(i=0;i<DIM;i++)
                        for(j=0;j<DIM;j++)
                        {
                                if(tris[i][j]==' ')
                                {
                                        tris[i][j]='O';
                                        if(ctrlwin('O'))
                                                res+=2;
                                        else if((tmp=valutamossa('X', deep - 1))>res)
                                                res=tmp;
                                        tris[i][j]=' ';
                                }
                        }
        }
        return res;
}

9 Risposte

  • Re: Progetto tris esteso

    In allegato dove?
  • Re: Progetto tris esteso

    barba59 ha scritto:


    In allegato dove?
    scusa.. adesso sono riuscito a caricarlo..
  • Re: Progetto tris esteso

    EDIT
    Cosi ad occhio direi che manca un controllo sul deep in 'valutamossa', se lo segui col debugger lo vedi diventare negativo.
  • Re: Progetto tris esteso

    Ho provato a scaricare il programma del tris dal sito che hai indicato, ma si incasina pure lui, a te funziona?
  • Re: Progetto tris esteso

    barba59 ha scritto:


    Ho provato a scaricare il programma del tris dal sito che hai indicato, ma si incasina pure lui, a te funziona?
    avevo modificato il deep per prova adesso che l'ho messo apposto le lo segna ancora?
    si a me funziona.. ma in che senso che si incasina?

    avete qualche idea per il controllo delle diagonali?
  • Re: Progetto tris esteso

    Il problema è divertente! Ho guardato l' algoritmo da cui sei partito e mi ha lasciato un po perplesso.
    Non credo che sia adatto a scacchiere grandi. Ad esempio guarda come è usato deep in 'valutamossa', non c' è nessun controllo se diventa negativo (problema che non si pone su una scacchiera piccola) e non viene usato per limitare la profondità dell' esplorazione.

    Poi per cercare le caselle vuote esamina sempre tutta la scacchiera, quando potrebbe tenere una lista delle caselle libere (il problema diventa importante su scacchiere grandi).

    L' agoritmo MinMax esamina tutte le mosse possibili, in una scacchiere 3*3 per ognuna delle 9 mosse possibili esamina le 8 contromosse dell' avversario, le tue altre 7 ecc. In pratica è il fattoriale del numero di caselle. È vero che non tutti i rami vengono esplorati perchè qualcuno termina con una vittoria o una perdita comunque i valori in gioco sono grandi:
    
    3*3=9        9!= 362.880
    4*4=16      16!= 20.922.789.888.000
    5*5=25      25!= 15.511.210.043.330.985.984.000.000
    10*10=100  100!= troppo per qualsiasi calcolatrice
    
    Per cui probabilmente il tuo programma sta funzionando ma richiede un tempo enorme di elaborazione. Ti consiglierei di limitare l' esplorazione in qualche modo, puoi usare la variabile 'deep' per fare questo. Inoltre non esaminare tutta la scacchiera ma teniti un elenco delle caselle libere.
  • Re: Progetto tris esteso

    E come si fa a limitare la profondità dell' esplorazione??
    scusa ma non capisco niente di teoria delle decisioni.. ho appena cominciato a programmare..
    ho provato a diminuire il deep ma non funziona lo stesso..

    questo è il codice coretto che tiene conto un elenco delle caselle libere..
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <conio.h>
    #include <ctype.h>
    
    #define DIM 4 //dimensioni della griglia: 3x3 4x4 5x5.. massimo 10x10 (nel classico tris è 3)
    #define NWIN 3 //numero di segni di fila per vincere (nel classico tris è 3)
    
    void griglia(); //funzione per visualizzare la griglia.
    void leggimossa(char wnr); //funzione per leggere mossa dell'utente.
    int ctrlwin(char wnr); //funzione per controllo se ci sono tris (nelle righe, colonne e diagolali.)
    int endgame(); //funzione per controllo se le caselle sono tutte occupate
    
    /*Funzioni per l'intelligenza artificiale*/
    void move(void);
    int valutamossa(char wnr, int deep);
    
    char tris[DIM][DIM];
    
    int main(int argc, char *argv[])
    {
        int i, j, modalita, rigioco, giocatore; //giocatore 1 = utente, giocatore 0 = computer.
        char simbolo;
        
        repeat:
    
        printf("BENVENUTO NEL TRIS!!! BY PHAM FRANCESCO \n\n");
        printf("1) 2 giocatori \n");
        printf("2) utente vs computer \n\n");
        printf("\t Scelta: ");
        scanf("%d", &modalita);
        
        /*Inizializzazione della scacchiera*/
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   tris[i][j]=' ';
        
        switch(modalita)
        {
            /*SE SI HA SCELTO 2 GIOCATORI*/
            case 1:
                    for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                    {
                        /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                        if(i%2==0)
                            simbolo = 'X';
                        else
                            simbolo = 'O';
                            
                        system("cls"); //pulisce lo schermo
                        griglia();
                        leggimossa(simbolo);
                        if(ctrlwin(simbolo))
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Il giocatore %c vince!! \n", simbolo);
                            break;
                        }
                        if(endgame())
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Parita!! \n");
                            break;
                        }
                    }
                    break; //uscita switch (fine case 1)
                    
            /*SE SI HA SCELTO UTENTE VS PC*/  
            case 2:
                    for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                    {
                        /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                        // 1 = giocatore
                        // 0 = computer
                        if(i%2==0)
                        {
                            giocatore = 1;
                            simbolo = 'X';
                        }
                        else
                        {
                            giocatore = 0;
                            simbolo = 'O';
                        }
                            
                        system("cls"); //pulisce lo schermo
                        griglia();
                        
                        // se giocatore == utente..
                        if(giocatore==1)
                            leggimossa(simbolo);
                        //altrimenti se giocatore == computer..
                        else if(giocatore==0)
                            move();
                        
                        if(ctrlwin(simbolo))
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            if(giocatore==1)
                                printf("Hai vinto!! \n");
                            else if(giocatore==0)
                                printf("Il computer vince!!\n");
                            break;
                        }
                        if(endgame())
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Parita!! \n");
                            break;
                        }
                    }
                    break; //uscita switch (fine case 2)
            
            default:
                    printf("ERROR: modalita' non valida \n");
        }
        
        system("PAUSE");       
        system("cls");
        
        do
        {
             printf("Premi INVIO per rigiocare. \n");
             printf("Premi ESC per chiudere \n");
             rigioco = getch();
             
             if(rigioco == 13)
             {
                 system("cls");
                 goto repeat;
             }
             if(rigioco == 27)
             	   return 0;
         }
         while(rigioco != 13 && rigioco != 27);
    }
    
    
    
    void griglia()
    {
         register int i,j;
         
         printf("\n  ");
         for(i=0;i<DIM;i++)
              printf("  %d", i);
         putchar('\n');
         
         for(i=0;i<DIM;i++)
         {
              printf(" %c ", i+65);
              for(j=0;j<DIM;j++)
                   printf("[%1c]",tris[i][j]);
              putchar('\n');
         }
    }
    
    
    void leggimossa(char wnr)
    {
         /*
              Legge le mosse come coordinate es: a1, B2, c5.
              Funziona sia con le maiuscole che con le minuscole
              mossaX è orizzontale (numero)
              mossaY è verticale (lettera)
         */
         char mossaX, mossaY;
         
         do
         {
              printf("\nTocca a %c, inserisci la mossa: ", wnr);
              mossaY = toupper(getch()); //verticale quindi una lettera (toupper serve per convertirlo in maiuscola)
              mossaX = getch(); //orizzontale quindi numero
         }
         while(tris[mossaY-65][mossaX-48] != ' ');
         
         tris[mossaY-65][mossaX-48] = wnr;
    }
    
    int ctrlwin(char wnr)
    {
        int count, i, j;
        
         /*Controllo righe*/
         for(i=0; i<DIM; i++)
         {
              count=0;
              for(j=0; j<DIM; j++)
                   if(tris[i][j]==wnr)
                        count++;
              if(count==NWIN)
                   return 1;
         }
         
         /*Controllo colonne*/
         for(j=0; j<DIM; j++)
         {
              count=0;
              for(i=0; i<DIM; i++)
                   if(tris[i][j]==wnr)
                        count++;
              if(count==NWIN)
                   return 1;
         }
         
         /*Controllo diagonali*/
         if(tris[0][0]==wnr&&tris[1][1]==wnr&&tris[2][2]==wnr) return 1;
         if(tris[2][0]==wnr&&tris[1][1]==wnr&&tris[0][2]==wnr) return 1;
         
         return 0;
    }
    
    
    int endgame()
    {
         register int i,j;
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   if(tris[i][j]==' ') return 0;
         return 1;
    }
    
    
    /*FUNZIONI PER L'INTELLIGENZA ARTIFICIALE*/
        
    void move(void)
    {
         int i,j;
         int max=INT_MIN, mi=1, mj=1, t;
         
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   if(tris[i][j]==' ')
                   {
                        tris[i][j]='O';
                        t=valutamossa('X', 20);
                        //printf("%d\n",t);
                        if(t>=max)
                        {
                             max=t;
                             mi=i;
                             mj=j;
                        }
                        tris[i][j]=' ';
                   }
         //system("PAUSE");
         tris[mi][mj]='O';
    }
     
    int valutamossa(char wnr, int deep)//Minimax
    {
            if(ctrlwin('O'))
                    return INT_MAX;
            if(endgame())
                    return 0;
            int i, j, res, tmp;
            if(wnr=='X')
            {
                    res=1;
                    for(i=0;i<DIM;i++)
                            for(j=0;j<DIM;j++)
                            {
                                    if(tris[i][j]==' ')
                                    {
                                            tris[i][j]='X';
                                            if(ctrlwin('X'))
                                                    if(deep==20)
                                                    {
                                                            tris[i][j]=' ';
                                                            return INT_MIN;
                                                    }
                                                    else
                                                            res-=2;
                                            else if((tmp=valutamossa('O', deep - 1))<res)
                                                    res=tmp;
                                            tris[i][j]=' ';
                                    }
                            }
            }
            else
            {
                    res=-1;
                    for(i=0;i<DIM;i++)
                            for(j=0;j<DIM;j++)
                            {
                                    if(tris[i][j]==' ')
                                    {
                                            tris[i][j]='O';
                                            if(ctrlwin('O'))
                                                    res+=2;
                                            else if((tmp=valutamossa('X', deep - 1))>res)
                                                    res=tmp;
                                            tris[i][j]=' ';
                                    }
                            }
            }
            return res;
    }
    
  • Re: Progetto tris esteso

    Se guardi bene l' algoritmo vedrai che il deep viene usato solo quando è uguale a 20, quando poi viene decrementato non viene più usato. Una delle condizioni di uscita di 'valutamossa' è 'if(engame)' che nel tuo caso viene raggiunto dopo svariati miliardi di cicli. Potresti fare un' uscita 'if(deep < qualcosa)'.

    Però non ho guardato l' algoritmo con cura, solo quel tanto per capire che non può funzionare, ma come farlo andare è un altro paio di maniche.

    Questo è un esercizio che stai facendo per divertimento ed hai tutto il tempo che vuoi o hai delle scadenze?
  • Re: Progetto tris esteso

    No.. lo sto facendo solo per divertimento.. sto imparando a programmare facendo l'autodidatta..

    P,S, Ci sono riuscito!!!
    Ho fatto come hai detto:
    invece di if(endgame()) ci ho messo
    if(deep <= 0 || endgame())
    e adesso va alla grande!!!
    sarebbe utile far aumentare il livello di profondità man mano che le celle vuote sono meno così sarebbe più efficiente.. per adesso il massimo che si può fare è dimensione 5x5 e deep 3..

    questo è il sorgente finalmente funzionante:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <conio.h>
    #include <ctype.h>
    
    #define DIM 5 //dimensioni della griglia: 3x3 4x4 5x5.. massimo 10x10 (nel classico tris è 3)
    #define NWIN 4 //numero di segni di fila per vincere (nel classico tris è 3)
    #define DEEP 3 //profondità
    
    void griglia(); //funzione per visualizzare la griglia.
    void leggimossa(char wnr); //funzione per leggere mossa dell'utente.
    int ctrlwin(char wnr); //funzione per controllo se ci sono tris (nelle righe, colonne e diagolali.)
    int endgame(); //funzione per controllo se le caselle sono tutte occupate
    
    /*Funzioni per l'intelligenza artificiale*/
    void move(void);
    int valutamossa(char wnr, int deep);
    
    char tris[DIM][DIM];
    
    int main(int argc, char *argv[])
    {
        int i, j, rigioco, giocatore; //giocatore 1 = utente, giocatore 0 = computer.
        char simbolo, modalita;
        
        repeat:
    
        printf("BENVENUTO NEL TRIS!!! BY PHAM FRANCESCO \n\n");
        printf("1) 2 giocatori \n");
        printf("2) utente vs computer \n\n");
        printf("\t Scelta: ");
        modalita = getch();
        
        /*Inizializzazione della scacchiera*/
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   tris[i][j]=' ';
        
        switch(modalita)
        {
            /*SE SI HA SCELTO 2 GIOCATORI*/
            case '1':
                    for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                    {
                        /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                        if(i%2==0)
                            simbolo = 'X';
                        else
                            simbolo = 'O';
                            
                        system("cls"); //pulisce lo schermo
                        griglia();
                        leggimossa(simbolo);
                        if(ctrlwin(simbolo))
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Il giocatore %c vince!! \n", simbolo);
                            break;
                        }
                        if(endgame())
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Parita!! \n");
                            break;
                        }
                    }
                    break; //uscita switch (fine case 1)
                    
            /*SE SI HA SCELTO UTENTE VS PC*/  
            case '2':
                    for(i=0;;++i) //ciclo apparentemente infinito ma viene chiuso dall'eventuale break
                    {
                        /*se nel ciclo i è pari tocca a X sennò tocca a O*/
                        // 1 = giocatore
                        // 0 = computer
                        if(i%2==0)
                        {
                            giocatore = 1;
                            simbolo = 'X';
                        }
                        else
                        {
                            giocatore = 0;
                            simbolo = 'O';
                        }
                            
                        system("cls"); //pulisce lo schermo
                        griglia();
                        
                        // se giocatore == utente..
                        if(giocatore==1)
                            leggimossa(simbolo);
                        //altrimenti se giocatore == computer..
                        else if(giocatore==0)
                            move();
                        
                        if(ctrlwin(simbolo))
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            if(giocatore==1)
                                printf("Hai vinto!! \n");
                            else if(giocatore==0)
                                printf("Il computer vince!!\n");
                            break;
                        }
                        if(endgame())
                        {
                            system("cls"); //pulisce lo schermo
                            griglia();
                            printf("Parita!! \n");
                            break;
                        }
                    }
                    break; //uscita switch (fine case 2)
            
            default:
                    printf("ERROR: modalita' non valida \n");
        }
        
        system("PAUSE");       
        system("cls");
        
        do
        {
             printf("Premi INVIO per rigiocare. \n");
             printf("Premi ESC per chiudere \n");
             rigioco = getch();
             
             if(rigioco == 13)
             {
                 system("cls");
                 goto repeat;
             }
             if(rigioco == 27)
             	   return 0;
         }
         while(rigioco != 13 && rigioco != 27);
    }
    
    
    
    void griglia()
    {
         int i,j;
         
         printf("\n  ");
         for(i=0;i<DIM;i++)
              printf("  %d", i);
         putchar('\n');
         
         for(i=0;i<DIM;i++)
         {
              printf(" %c ", i+65);
              for(j=0;j<DIM;j++)
                   printf("[%1c]",tris[i][j]);
              putchar('\n');
         }
    }
    
    
    void leggimossa(char wnr)
    {
         /*
              Legge le mosse come coordinate es: a1, B2, c5.
              Funziona sia con le maiuscole che con le minuscole
              mossaX è orizzontale (numero)
              mossaY è verticale (lettera)
         */
         char mossaX, mossaY;
         
         do
         {
              printf("\nTocca a %c, inserisci la mossa: ", wnr);
              mossaY = toupper(getch()); //verticale quindi una lettera (toupper serve per convertirlo in maiuscola)
              mossaX = getch(); //orizzontale quindi numero
         }
         while(tris[mossaY-65][mossaX-48] != ' ');
         
         tris[mossaY-65][mossaX-48] = wnr;
    }
    
    int ctrlwin(char wnr)
    {
        register int count, i, j;
        
         /*Controllo righe*/
         for(i=0; i<DIM; i++)
         {
              count=0;
              for(j=0; j<DIM; j++)
              {
                   if(tris[i][j]==wnr)
                   {
                        count++;
                        if(count==NWIN) return 1;
                   }
                   else
                        count=0;
              }
         }
         
         /*Controllo colonne*/
         for(j=0; j<DIM; j++)
         {
              count=0;
              for(i=0; i<DIM; i++)
              {
                   if(tris[i][j]==wnr)
                   {
                        count++;
                        if(count==NWIN) return 1;
                   }
                   else
                        count=0;
              }
         }
         
         /*Controllo diagonali*/
         //if(tris[0][0]==wnr&&tris[1][1]==wnr&&tris[2][2]==wnr) return 1;
         //if(tris[2][0]==wnr&&tris[1][1]==wnr&&tris[0][2]==wnr) return 1;
         
         return 0;
    }
    
    
    int endgame()
    {
         register int i, j;
         
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   if(tris[i][j]==' ') return 0;
         return 1;
    }
    
    
    /*FUNZIONI PER L'INTELLIGENZA ARTIFICIALE*/
        
    void move(void)
    {
         int i,j;
         int max=INT_MIN, mi=1, mj=1, t;
         
         for(i=0;i<DIM;i++)
              for(j=0;j<DIM;j++)
                   if(tris[i][j]==' ')
                   {
                        tris[i][j]='O';
                        t=valutamossa('X', DEEP);
                        printf("%d\n",t);
                        if(t>=max)
                        {
                             max=t;
                             mi=i;
                             mj=j;
                        }
                        tris[i][j]=' ';
                   }
         system("PAUSE");
         tris[mi][mj]='O';
    }
     
    int valutamossa(char wnr, int deep)//Minimax
    {
         register int i, j, res, tmp;
         
            if(ctrlwin('O'))
                    return INT_MAX;
            if(deep < 0 || endgame())
                    return 0;
            if(wnr=='X')
            {
                    res=1;
                    for(i=0;i<DIM;i++)
                            for(j=0;j<DIM;j++)
                            {
                                    if(tris[i][j]==' ')
                                    {
                                            tris[i][j]='X';
                                            if(ctrlwin('X'))
                                                    if(deep == DEEP)
                                                    {
                                                            tris[i][j]=' ';
                                                            return INT_MIN;
                                                    }
                                                    else
                                                            res-=2;
                                            else if((tmp=valutamossa('O', deep - 1))<res)
                                                    res=tmp;
                                            tris[i][j]=' ';
                                    }
                            }
            }
            else
            {
                    res=-1;
                    for(i=0;i<DIM;i++)
                            for(j=0;j<DIM;j++)
                            {
                                    if(tris[i][j]==' ')
                                    {
                                            tris[i][j]='O';
                                            if(ctrlwin('O'))
                                                    res+=2;
                                            else if((tmp=valutamossa('X', deep - 1))>res)
                                                    res=tmp;
                                            tris[i][j]=' ';
                                    }
                            }
            }
            return res;
    }
    
Devi accedere o registrarti per scrivere nel forum
9 risposte