Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755

    metodo per verificare il "quatris",gioco in java

    Salve,sto "costruendo" un gioco in java il "quatris" (una variante del tris)
    ho un pannello costituito da 16*16(256) quadratini che possono essere marcati come "crocette" e "rotondi" ognuno dei due simboli assegnati a uno dei due giocatori...
    Ecco un'immagine del gioco (ancora in erba,è solo agli inizi,poi prenderà forma ):



    Il mio problema è riuscire ad avere un metodo che mi controlli ad ogni sua invocazione se è stato fatto "quatris",cioè se vi sono quattro simboli uguali (crocette o rotondi) contigui (per contigui intendo che siano in fila o che siano in diagonale ecc ecc),ma al momento non saprei per bene come procedere per fare ciò,mi date una mano?

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    mi viene in mente una cosa del genere: innanzitutto, dovrai cercare dei "quatris" (d'ora in poi "Q") contenenti solo il simbolo ultimo inserito. Quindi a partire da quella posizione, andrai a testare nelle al massimo 8 direzioni possibili che si generano attorno a ciascuna casella.

    In particolare ti fermerai se:
    -la casella è vuota (o non esiste, perché hai raggiunto il bordo)
    -la casella contiene un simbolo diverso da quello analizzato.

    Puoi vedere il tabellone in questo modo:

    codice:
    0  0  0  0  0  0
    0 -1 -1  0  0  0
    0  1 -1 -1  0  0
    0  1  1  1  0  0
    Dove:
    0 --> casella vuota,
    1 --> X
    -1 -> O

    in quest'ottica, puoi alternativamente considerare il quadrato 7 x 7 (sempre con l'eccezione dei bordi...) contenente al centro il simbolo appena inserito e sviluppare un tuo algoritmo che sommi i gruppi di 4 elementi contenenti il simbolo inserito. Avrai un Q se la somma di almeno uno di questi gruppi sarà 4 o -4
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    mmm interessante,avevo in mente qualcosa del genere ma ero rimasto,ingenuamente,all'idea di dover scansionare le 8 direzioni per ogni simbolo,e non per l'ultimo inserito (in quel modo che lavoro che doveva compiere il programma ogni volta ahahahah),comunque ti ringrazio per l'illuminazione.Ora passo alla creazione dell'algoritmo e ti farò sapere l'esito e/o eventuali problemi

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    considera che è mezzanotte e qualcosa anche per me , che oggi ho lavorato e che non ho disdegnato una buona birrozza a cena
    quindi magari sono solo un mucchio di ca##ate
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    Bè per la birrozza mi hai quasi fatto venir voglia anche a me
    cmq non so,magari ci saranno procedimenti più semplici e meno impegnativi,ma io lo vedo come un buon algoritmo e abbastanza efficiente...certo è che l'implementazione non sarà così facile come il definirlo,vediamo cosa ne esce fuori

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    Purtroppo ancora non sono riuscito a implementare il metodo per il controllo del quatris.
    ho un array bidimensionale di interi,16*16 (256 celle) ognuna delle quali marcate con 0,1,2.
    0 indica che il quadratino che esso "riferisce" è vuoto,1 indica che il quadratino che esso iferisce è marcato col simbolo del giocatore 1,2indica che il quadratino a cui esso riferisce è marcato con il simbolo del giocatore 2.
    In pratica il metodo dovrebbe ad ogni inserimento del simbolo andare a controllare,a partire da esso,nelle quattro direzioni(o 8,come le si vuole definire) attorno ad esso,se vi sono 4 di quei simboli (cioè 4 uno o 4 due) consecutivi lungo una stessa direzione...
    le 4 direzioni che io intendo sono,quelle marcate con i vari 4 colori attorno all'1 nella seguente immagine:





    io avevo pensato di crare il metodo prendendo come parametro un'array bidimensionale di 256 celle,rappresentante la situazione attuale della griglia,e poi indicando con un int che varia i suoi valori tra {00,01,10,11} si muove (controlla) lungo la specificata direzione,andando a incrementare una variabile intera ogni qualvolta lungo la direzione specificata trova quel simbolo ripetuto,ovviamente quest'ultima variabile si azzera ogni qualvolta cambia direzione e quindi non trova il quatris...

    mi aiutate nell'implementazione del metodo?

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2011
    Messaggi
    16
    tenere in considerazione 8 direzioni come prima suggerito sembra essere una buona idea, ma cosa accadrebbe se l'ultimo segno non costituisce la fine di un quatris ?
    Allora io direi di scrivere un metodo che prende come parametro l'ultimo simbolo (oggetto) inserito nel gioco e:
    1-conti il numero di oggetti dello stesso tipo in una direzione ( if(oggetto instanceof cosaStiamoCercando) ) fino a che non ci siano altri 3 oggetti in quella direzione.
    2-Se non è possibile proseguire allora il conteggio deve continuare nel verso opposto,ma sempre sullo stesso asse.
    3-Se in quel'asse non si hanno 4 oggetti dello stesso tipo allineati (un oggetto avversario o si è fuori dalla tabella) allora bisogna considerare un'altro asse (dei 4).

    Se scrivi un metodo di controllo che tiene in considerazione tutta la tabella allora il tempo di esecuzione crescerà in maniera abnorme e questo significa che il computer perderà moltissimo tempo facendo dei calcoli inutili.

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    questo è quello che ho fatto,sicuramente molto farraginoso e decisamente migliorabilissimo,inoltre ancora devo provare la sua efficienza:

    innanzitutto ho considerato le direzioni secondo questa logica:


    codice:
    private static boolean èQuatris(int [][] mat,int q,int giocatore){
            boolean quatrisFatto=false;
            quatrisFatto=dir00(mat,q/16,q%16,giocatore);
            if(!quatrisFatto){
                quatrisFatto=dir01(mat,q/16,q%16,giocatore);
            }
            if(!quatrisFatto){
                quatrisFatto=dir10(mat,q/16,q%16,giocatore);
            }
            if(!quatrisFatto){
                quatrisFatto=dir11(mat,q/16,q%16,giocatore);
            }
            return quatrisFatto;
        }
        private static boolean dir00(int [][] mat,int riga,int colonna,int g){
            boolean quatrisFatto=false;
            int n1=0;
            int n2=0;
            int i=riga-1;
            int j=colonna;
            boolean esci=false;
            while(mat[i][j]==g && !esci && n1<4){
                n1++;
                if(i>0){
                    i--;
                }else{
                    esci=true;
                }
            }
            int i1=riga+1;
            int j1=colonna;
            boolean esci1=false;
            while(mat[i1][j1]==g && !esci1 && n2<4){
                n2++;
                if(i1<mat.length-1){
                    i1++;
                }else{
                    esci1=true;
                }
                
            }
            if((n1+n2+1)>=4){
                quatrisFatto=true;
            }
            return quatrisFatto;
        }
        private static boolean dir01(int [][] mat,int riga,int colonna,int g){
            boolean quatrisFatto=false;
            int n1=0;
            int n2=0;
            int i=riga-1;
            int j=colonna-1;
            boolean esci=false;
            while(mat[i][j]==g && !esci && n1<4){
                n1++;
                if(i>0 && j<mat[0].length-1){
                    i--;
                    j++;
                }else{
                    esci=true;
                }
            }
            int i1=riga+1;
            int j1=colonna+1;
            boolean esci1=false;
            while(mat[i1][j1]==g && !esci1 && n2<4){
                n2++;
                if(i<mat.length-1 && j>0){
                    i1++;
                    j1--;
                }else{
                    esci1=false;
                }
            }
            if((n1+n2+1)>=4){
                quatrisFatto=true;
            }
            return quatrisFatto;
        }
        private static boolean dir10(int [][] mat,int riga,int colonna,int g){
            boolean quatrisFatto=false;
            int n1=0;
            int n2=0;
            int i=riga;
            int j=colonna-1;
            boolean esci=false;
            while(mat[i][j]==g && !esci && n1<4){
                n1++;
                if(j>0){
                    j--;
                }else{
                    esci=true;
                }
            }
            int i1=riga;
            int j1=colonna+1;
            boolean esci1=false;
            while(mat[i1][j1]==g && !esci1 && n2<4){
                n2++;
                if(i<mat.length-1 && j<mat[0].length-1){
                    j1++;
                }else{
                    esci1=false;
                }
            }
            if((n1+n2+1)>=4){
                quatrisFatto=true;
            }
            return quatrisFatto;
        }
        private static boolean dir11(int [][] mat,int riga,int colonna,int g){
            boolean quatrisFatto=false;int n1=0;
            int n2=0;
            int i=riga-1;
            int j=colonna-1;
            boolean esci=false;
            while(mat[i][j]==g && !esci && n1<4){
                n1++;
                if(i>0 && j>0){
                    i--;
                    j--;
                }else{
                    esci=true;
                }
            }
            int i1=riga+1;
            int j1=colonna+1;
            boolean esci1=false;
            while(mat[i1][j1]==g && !esci1 && n2<4){
                n2++;
                if(i<mat.length-1 && j<mat[0].length-1){
                    i1++;
                    j1++;
                }else{
                    esci1=false;
                }
            }
            if((n1+n2+1)>=4){
                quatrisFatto=true;
            }
            return quatrisFatto;
        }
    dove mat è l'array che indica lo stato del gioco,q è il numero del quadratino corrente in cui è stato inserito l'ultimo simbolo,numero che segue questa logica:



    giocatore è un intero che può essere 1 o 2 in base che sia stato il turno del giocatore 1 o del giocatore 2 (quindi che abbia immesso nell'array il numero 1 o 2)


    comunque ora lo provo e vediamo se funge

  9. #9
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    non ho ottimizzato niente, ma questo sembra funzionare:
    codice:
    import java.io.*;
    /**
     *
     * @author Andrea
     */
    public class ForzaQuattro {
    
        private int[][] scheme;
    //metodo accessorio per la stampa dello schema
        public String toString() {
            StringBuffer buf = new StringBuffer();
            for (int i = 0; i < scheme.length; i++) {
                buf.append("[ ");
                for (int j = 0; j < scheme[0].length; j++) {
                    buf.append(scheme[i][j]+" ");
                }
                buf.append("]\n");
            }
            return buf.toString();
        }
    
    // crea la matrice pivot 7x7, con al centro l'ultima posizione inserita.
    // su questa matrice viene ricercata la posizione vincente.
    //l'eccezione gestisce l'array out of bound exception, mettendo di default a 0 tali elementi.    
        private int[][] createPivotMatrix(int x, int y) {
            int[][] temp = new int[7][7];
            for (int i = x-3; i <=x+3; i++) {
                for (int j = y-3; j <=y+3; j++) {
                    try {
                        temp[i-x+3][j-y+3] = scheme[i][j];
                    }
                    catch (Exception e) {
                        temp[i-x+3][j-y+3] = 0;
                    }
                }
            }
            
            return temp;
        }
    
        public void searchWinPosition(int sign, int x, int y) {
            int[][] temp = createPivotMatrix(x, y);
            int pivot;
    
            //diagonale principale (0,0)-->(6,6) (angolo in alto a sx - angolo in basso a dx
            pivot = 0;
            for (int i = 0; i < 7; i++) {
                if (pivot == sign*4) {
                    System.out.println("Ha vinto il giocatore "+(sign == 1 ? "1" : "2")+" Sulla diagonale principale");
                    return;
                }
                pivot += temp[i][i];
            }
    
            // verticale (0,3)-->(6,3)
            pivot = 0;
            for (int i = 0; i < 7; i++) {
                if (pivot == sign*4) {
                    System.out.println("Ha vinto il giocatore "+(sign == 1 ? "1" : "2")+" Sulla verticale");
                    return;
                }
                pivot += temp[i][3];
            }
    
            //diagonale secondaria (0,6)-->(6,0) angolo in basso a sx - angolo in alto a dx
            pivot = 0;
            for (int i = 6; i >= 0; i--) {
                if (pivot == sign*4) {
                    System.out.println("Ha vinto il giocatore "+(sign == 1 ? "1" : "2")+" Sulla diagonale secondaria");
                    return;
                }
                pivot += temp[6-i][i];
            }
    
            //orizzontale (3,0)-->(3,6)
            pivot = 0;
            for (int i = 0; i < 7; i++) {
                if (pivot == sign*4) {
                    System.out.println("Ha vinto il giocatore "+(sign == 1 ? "1" : "2")+" Sulla orizzontale");
                    return;
                }
                pivot += temp[3][i];
            }
        }
    
    
    //costruttore totalmente inutile nel tuo caso, definito solo per caricare una posizione da file 
       public ForzaQuattro(String path) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(path));
                String line;
                //Leggo dimensione
                line = br.readLine();
                int dim = Integer.parseInt(line);
                scheme = new int[dim][dim];
                String[] temp = new String[dim];
                int i = 0;
                while ((line = br.readLine()) != null) {
                    temp = line.split(" ");
                    for (int j = 0; j < dim; j++) {
                        scheme[i][j] = Integer.parseInt(temp[j]);
                    }
                    i++;
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main (String[] args) {
            ForzaQuattro fq = new ForzaQuattro("X:/Percorso/file/scheme.dat");
            System.out.println(fq);
            System.out.println("\n\n******************\n\n");
            fq.searchWinPosition(1, 5, 3);
            fq.searchWinPosition(-1, 11, 11);
            fq.searchWinPosition(-1, 11, 10);
            fq.searchWinPosition(-1, 11, 9);
        }
    }
    in scheme.dat c'è lo schema (non avevo voglia di fare l'interfaccia grafica etc): è 12 x 12 e la prima riga del file individua la dimensione, ma solo per il parsing del file senza gestire troppo le eccezioni
    codice:
    12
    0 -1 0 1 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 -1 0 1 0 0 0 0 0 0 0 0
    0 0 0 1 0 -1 0 0 0 0 0 0
    0 -1 0 1 0 0 0 0 0 0 0 0
    0 0 0 1 0 -1 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 -1 -1 -1 -1
    come vedi dalle ultime 3 chiamate a searchWinPosition (che riceve il simbolo ultimo inserito, e la sua posizione), non importa quale dei 4 sia stato inserito, la posizione (a dire il vero viene individuata la direzione vincente - l'effettiva ricerca della posizione attuale la lascio a te) viene comunque individuata.
    PS: ovviamente ho raccolto nello stesso schema un paio di posizioni vincenti e per entrambi i giocatori, situazione che nel gioco non si verificherà mai (è invece possibile che i verifichino più posizioni vincenti per lo stesso giocatore e in contemporanea...)
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

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 © 2026 vBulletin Solutions, Inc. All rights reserved.