Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    Problema gioco del Tris con Thread

    Salve a tutti ho un problema con questo programma in Java: quando vince il giocatore o vince il computer il settaggio della variabile "static boolean vinto" a true (così da non far più inserire nulla) non avviene, nonostante io richiami la funzione. Vi allego qui sotto le tre classi così da potermi aiutare a capire meglio:
    CLASSE PRINCIPALE (con main)
    codice:
    import java.io.*;
    public class Gioco {
        public static void main() {
            BufferedReader t=new BufferedReader(new InputStreamReader(System.in));
            char scelta, avv;
            int n=0, r, c, nav, ctTurni=0;
            System.out.println("Inserisci 0 per X, 1 per O: ");
            try {
                String s=t.readLine();
                n=Integer.parseInt(s);
            }
            catch (Exception e) {
                System.out.println("Errore, scelta non numerica!");
            }
            
            if(n==0) {
                scelta='X';
                avv='O';
                nav=1;
            }
            else {
                scelta='O';
                avv='X';
                nav=0;
            }
            
            
            Schema m=new Schema();
            
            do {
                ctTurni++;
                m.faiMossa(scelta);
                Thread Vince1[]=new Thread[8];
            
                for (int ct=0; ct<8; ct++) {
                    Vince1[ct]=new ThreadTris(n, m, scelta);
                    Vince1[ct].start();
                }
                //stampa status variabile vinto
                System.out.println(m.getVinto());
                if(m.getVinto()==false) {
                    ctTurni++;
                    m.mossaAvv(avv);
                
                    Thread Vince2[]=new Thread[8];
            
                    for (int ct=0; ct<8; ct++) {
                        Vince2[ct]=new ThreadTris(nav, m, avv);
                        Vince2[ct].start();
                    }
                }
                //System.out.println("\f");
                m.vedi();
            }while(m.getVinto()==false);
            
            
            System.out.println("\nVince "+m.getVincitore());
        }
    }
    CLASSE DI CONTROLLO (thread)
    codice:
    public class ThreadTris extends Thread {    int t, n;
        char scelta;
        protected Schema m=null;
        static char car[]=new char[2];
            
        public ThreadTris(int turno, Schema m, char s) {
            this.m=m;
            this.t=turno;
            this.scelta=s;
        }
        
        public void run() {
            if(m.getVinto()) {
                this.yield();
            }
            
            if(m.matrice[0][0]==m.matrice[0][1] && m.matrice[0][0]==m.matrice[0][2]) {
                vittoria();
            }
            
            if(m.matrice[1][0]==m.matrice[1][1] && m.matrice[1][0]==m.matrice[1][2]) {
                vittoria();
            }
            
            if(m.matrice[2][0]==m.matrice[2][1] && m.matrice[2][0]==m.matrice[2][2]) {
                vittoria();
            }
            
            if(m.matrice[0][0]==m.matrice[1][0] && m.matrice[0][0]==m.matrice[2][0]) {
                vittoria();
            }
            
            if(m.matrice[0][1]==m.matrice[1][1] && m.matrice[0][1]==m.matrice[2][1]) {
                vittoria();
            }
            
            if(m.matrice[0][2]==m.matrice[1][2] && m.matrice[0][2]==m.matrice[2][2]) {
                vittoria();
            }
            
            if(m.matrice[0][0]==m.matrice[1][1] && m.matrice[0][0]==m.matrice[2][2]) {
                vittoria();
            }
            
            if(m.matrice[0][2]==m.matrice[1][1] && m.matrice[0][2]==m.matrice[2][0]) {
                vittoria();
            }
        }
        
        public void vittoria() {
            m.setVincitore(scelta);
            m.setVinto();
        }
        
    }
    CLASSE DEL CAMPO
    codice:
    import java.util.Random;
    import java.io.*;
    public class Schema {
        static char matrice[][]=new char[3][3];
        static boolean vinto;
        static char vincitore;
        BufferedReader t=new BufferedReader(new InputStreamReader(System.in));
        
        public Schema() {
            matrice[0][0]='?';
            matrice[0][1]='?';
            matrice[0][2]='?';
            matrice[1][0]='?';
            matrice[1][1]='?';
            matrice[1][2]='?';
            matrice[2][0]='?';
            matrice[2][1]='?';
            matrice[2][2]='?';
            vinto=false;
            vedi();
        }
        
        public boolean getVinto() {
            return vinto;
        }
        
        public synchronized void setVinto() {
            this.vinto=vinto;
        }
        
        public synchronized void setVincitore(char segno) {
            this.vincitore=segno;
        }
        
        public char getVincitore() {
            return vincitore;
        }
        
        public void faiMossa(char scelta) {
            int r=0, c=0;
            
            do {
                
                System.out.println("\nInserisci la righa: ");
                try {
                    String s=t.readLine();
                    r=Integer.parseInt(s);
                }
                catch (Exception e) {
                    System.out.println("Errore, scelta non numerica!");
                }
                
                System.out.println("Inserisci la colonna: ");
                try {
                    String s=t.readLine();
                    c=Integer.parseInt(s);
                }
                
                catch (Exception e) {
                    System.out.println("Errore, scelta non numerica!");
                }
                
                if(matrice[r][c]!='?') {
                    System.out.println("Errore, casella occupata!");
                }
            }while(matrice[r][c]!='?');
            matrice[r][c]=scelta;
        }
        
        public void mossaAvv(char avv) {
            Random rnd=new Random();
            int r=0, c=0;
            do {
                r=rnd.nextInt(3);
                c=rnd.nextInt(3);
            }while(matrice[r][c]!='?');
            matrice[r][c]=avv;
        }
        
        public void vedi() {
            for(int r=0; r<3; r++) {
                for(int c=0; c<3; c++) {
                    System.out.print(" "+matrice[r][c]+" ");
                    if(c!=2) {
                        System.out.print("|");
                    }
                }
                if(r!=2) {
                    System.out.println("\n-----------");
                }
            }
        }
    }
    Grazie in anticipo a tutti per l'aiuto

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Io non capisco perchè la variabile "vinto" tu l'abbia dichiarata statica se poi la vai a riferire con un "this". Non che sia "sbagliato", semplicemente è privo di senso (e denota una non comprensione della differenza fra membri statici e non-statici).

    Poi, non ho capito questa parte, nel run() del thread:

    codice:
    if(m.getVinto()) {
       this.yield();
    }

    Perchè? Immagino che se qualcuno ha vinto, il gioco debba terminare... quindi, che senso ha mettere "temporaneamente in pausa" il thread?

    Poi, il lavoro che fa il thread è sbagliato: tu controlli solo che esista una riga o una colonna o una diagonale composta tutta dallo stesso segno... ma questo sarà vero fin dall'inizio... perchè tutte le celle contengono lo stesso segno: il punto di domanda! Non stai controllando che il segno sia diverso dal punto di domanda.

    Ma la cosa ovvia che non ti fa terminare il gioco è questa:


    codice:
    public synchronized void setVinto() {
       this.vinto=vinto;   // qui dovevi impostare true!!
    }

    Cioè, ogni volta che richiami il metodo "setVinto()" assegni alla variabile "vinto" il suo stesso valore... che è false.

    Rimane il fatto che non capisco perchè, ad ogni mossa, avvii ben 8 thread per controllare il vincitore... perchè?

    PS: il metodo main deve obbligatoriamente avere un array di String come parametro, altrimenti non è un punto di ingresso valido.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Hey, grazie mille della risposta
    Ho corretto i gli errori, e ora funziona, grazie
    A noi è stato insegnato che this.yield() non mette in pausa il thread, ma ne interrompe l'esecuzione (ovvero un this.stop() meno potente).

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da lovatof96 Visualizza il messaggio
    A noi è stato insegnato che this.yield() non mette in pausa il thread, ma ne interrompe l'esecuzione (ovvero un this.stop() meno potente).
    Dovrebbero però averti anche spiegato che yield() in realtà è solamente un "suggerimento" per lo scheduler. A seconda della implementazione dello scheduler, esso è assolutamente libero di ignorare lo yield.
    Quindi all'atto pratico yield() non è praticamente mai usato e se c'è del codice che lo usa allora o c'è una ragione davvero ben precisa oppure il codice è molto dubbio ...
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Tra parentesi, la documentazione è cambiata tra la versione 6 e la 7.
    La versione 6 dice:

    Causes the currently executing thread object to temporarily pause and allow other threads to execute

    Mentre la descrizione data nella versione 7 è più articolata, ma comunque non parla affatto di interruzione:

    A hint to the scheduler that the current thread is willing to yield its current use of a processor.
    [...]
    Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.