/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package tictactoecodingame; import java.util.ArrayList; /** * * @author franck.tempet */ public class GrilleTicTacToe9x9 extends Plateau { Jeton[][] grille9x9 = new Jeton[9][9]; Jeton[][] grille3x3 = new Jeton[3][3]; // indique si un joueur à gagné un case de la grande grille Jeton[][][] grille9x9Sav = new Jeton[100][9][9]; // Pour sauvegarder la position. 100 positions Max Jeton[][][] grille3x3Sav = new Jeton[100][3][3]; // Pour sauvegarder la position int nbPostionSauvegarde; CoupTicTacToe dernierCoup; CoupTicTacToe dernierCoupSav; Joueur vainqueur; boolean grilleGagnee , grilleGagneeSav; // vrai si dernier coup gagne une grille @Override public void init() { for (int c = 0; c < this.getNbColonnes(); c++) { for (int l = 0; l < this.getNbLignes(); l++) { grille9x9[c][l] = null; } } for (int c = 0; c < 3; c++) { for (int l = 0; l < 3; l++) { grille3x3[c][l] = null; } } dernierCoup = null; vainqueur = null; grilleGagnee = false; nbPostionSauvegarde = 0; } @Override public Piece getPiece(Case _case) { return grille9x9[_case.getColonne()][_case.getLigne()]; } @Override public void joueCoup(Coup _coup) { CoupTicTacToe coup = (CoupTicTacToe) _coup; grille9x9[coup.getColonne()][coup.getLigne()] = coup.getJeton(); dernierCoup = coup; int x0 = (coup.getColonne() / 3) * 3; int y0 = (coup.getLigne() / 3) * 3; // System.out.println("Test grande grille"); if (caseGagnante(grille9x9, x0, y0, coup.getColonne(), coup.getLigne())) { grille3x3[coup.getColonne() / 3][coup.getLigne() / 3] = coup.getJeton(); grilleGagnee = true; } } @Override public void annuleDernierCoup() { grille9x9[dernierCoup.getColonne()][dernierCoup.getLigne()] = null; dernierCoup = null; } @Override public int getNbColonnes() { return 9; } @Override public int getNbLignes() { return 9; } @Override public boolean partieTerminee() { if (vainqueur != null) { return true; } if (partieGagnee()) { return true; } return isGrillePleine(); } /** * Regarde si le joueur vient de gagner sur une case en 3x3 * * @param _grille soit la grille 9x9 soit la grille 3x3 * @param _x0 x min de la grille à analyser * @param _y0 y min de la grille à analyser * @param _coupX où le joueur a joué * @param _coupY * @return */ public boolean caseGagnante(Jeton[][] _grille, int _x0, int _y0, int _coupX, int _coupY) { int[][] dir = {{1, 0}, {1, 1}, {0, 1}, {1, -1}}; int[][] dirOps = {{-1, 0}, {-1, -1}, {0, -1}, {-1, 1}}; int xMax = _x0 + 3, yMax = _y0 + 3; int x, y; int nbJetonAligne; Joueur dernierJoueur = dernierCoup.getJeton().getJoueur(); /* Regarde si le dernier coup est gagnant */ for (int d = 0; d < 4; d++) { nbJetonAligne = 0; x = _coupX; y = _coupY; while (x < xMax && x >= _x0 && y < yMax && y >= _y0 && _grille[x][y] != null && _grille[x][y].getJoueur() == dernierJoueur) { nbJetonAligne++; if (nbJetonAligne >= 3) { return true; } x += dir[d][0]; y += dir[d][1]; } //regarde dans la direction opposée x = _coupX; y = _coupY; nbJetonAligne--; while (x < xMax && x >= _x0 && y < yMax && y >= _y0 && _grille[x][y] != null && _grille[x][y].getJoueur() == dernierJoueur) { nbJetonAligne++; if (nbJetonAligne >= 3) { return true; } x += dirOps[d][0]; y += dirOps[d][1]; } } return false; } @Override public boolean partieGagnee() { if (dernierCoup == null) { return false; } if ( grilleGagnee) { // si le dernier coup a gagne une grille on regarde si on gagne sur la grande grille if (caseGagnante(grille3x3, 0, 0, dernierCoup.getColonne() / 3, dernierCoup.getLigne() / 3)) { vainqueur = dernierCoup.getJeton().getJoueur(); return true; } } // Compte le nombre de cases remportées par chaque joueur if (isGrillePleine()) { int[] nbCase = new int[2]; Joueur[] joueur = new Joueur[2]; for (int c = 0; c < 3; c++) { for (int l = 0; l < 3; l++) { if (grille3x3[c][l] != null) { nbCase[grille3x3[c][l].getJoueur().getIdJoueur()]++; joueur[grille3x3[c][l].getJoueur().getIdJoueur()] = grille3x3[c][l].getJoueur(); } } } if (nbCase[0] > nbCase[1]) { vainqueur = joueur[0]; return true; } if (nbCase[1] > nbCase[0]) { vainqueur = joueur[1]; return true; } vainqueur = null; return true; } return false; } @Override public boolean partieNulle() { if (vainqueur != null) { return false; } if (partieGagnee()) { return false; } return isGrillePleine(); } @Override public ArrayList<Coup> getListeCoups(Joueur _joueur) { ArrayList<Coup> listeCoups = new ArrayList<Coup>(); if (dernierCoup != null) { int x0 = (dernierCoup.getColonne() % 3) * 3; int y0 = (dernierCoup.getLigne() % 3) * 3; for (int c = x0; c < x0 + 3; c++) { for (int l = y0; l < y0 + 3; l++) { if ( grille3x3[(c/3)][(l/3)] != null ) continue; // on ne peut pas jouer dans une grille gagnée if (grille9x9[c][l] == null) { listeCoups.add(new CoupTicTacToe(c, l, new Jeton(_joueur))); } } } } if (listeCoups.isEmpty()) { for (int c = 0; c < this.getNbColonnes(); c++) { for (int l = 0; l < this.getNbLignes(); l++) { if ( grille3x3[(c/3)][(l/3)] != null ) continue; // on ne peut pas jouer dans une grille gagnée if (grille9x9[c][l] == null) { listeCoups.add(new CoupTicTacToe(c, l, new Jeton(_joueur))); } } } } return listeCoups; } @Override public boolean isValide(Coup _coup) { CoupTicTacToe coup = (CoupTicTacToe) _coup; if ( grille9x9[coup.getColonne()][coup.getLigne()] != null ) return false; if ( dernierCoup == null ) return true; int x0 = (dernierCoup.getColonne() % 3 ) * 3; int y0 = (dernierCoup.getLigne() % 3 ) * 3; boolean grillePleine = true; for (int c = x0; c < x0+3 ; c++) { for (int l = y0; l < y0+3 ; l++) { if ( grille3x3[c/3][l/3] != null ) continue; // les grilles gagneés sont pleines if ( grille9x9[c][l] == null ) { grillePleine = false; break; } } } if ( grillePleine ) { return true; } return ( coup.getColonne() >= x0 && coup.getColonne() < x0+3 && coup.getLigne()>= y0 && coup.getLigne() < y0+3 ); } @Override public Coup stringToCoup(String _coup, Joueur _joueur) { int colonne = Integer.valueOf(_coup.charAt(0) + ""); int ligne = Integer.valueOf(_coup.charAt(1) + ""); return new CoupTicTacToe(colonne, ligne, new Jeton(_joueur)); } @Override public void sauvegardePosition(int _index ) { for (int c = 0; c < this.getNbColonnes(); c++) { for (int l = 0; l < this.getNbLignes(); l++) { grille9x9Sav[_index][c][l] = grille9x9[c][l]; } } for (int c = 0; c < 3; c++) { for (int l = 0; l < 3; l++) { grille3x3Sav[_index][c][l] = grille3x3[c][l]; } } dernierCoupSav = dernierCoup; grilleGagneeSav = grilleGagnee; } @Override public void restaurePosition( int _index ) { for (int c = 0; c < this.getNbColonnes(); c++) { for (int l = 0; l < this.getNbLignes(); l++) { grille9x9[c][l] = grille9x9Sav[_index][c][l]; } } for (int c = 0; c < 3; c++) { for (int l = 0; l < 3; l++) { grille3x3[c][l] = grille3x3Sav[_index][c][l]; } } vainqueur = null; dernierCoup = dernierCoupSav; grilleGagnee = grilleGagneeSav; } private boolean isGrillePleine() { for (int c = 0; c < this.getNbColonnes(); c++) { for (int l = 0; l < this.getNbLignes(); l++) { if ( grille3x3[c/3][l/3] != null ) continue; // les grilles gagnées sont pleines if (grille9x9[c][l] == null) { return false; } } } return true; } @Override public Joueur vainqueur() { return vainqueur; } void trace() { for (int l = 2; l >= 0; l--) { for (int c = 0; c < 3; c++) { System.out.print(grille3x3[c][l] + " "); } System.out.println(""); } } @Override public Coup getDernierCoup() { return dernierCoup; } }