/** * Cette methode compte le nombre d'indications requises pour * la ligne l. */ private int countIndicationsL(int l) { int i = 0, n = 0; // i parcourt les cases de la ligne et n parcourt les index // des indications while (i < nbC - 1) { if (grid[l][i] == Noir || grid[l][i + 1] == Noir) i++; else { n++; while (i < nbC && grid[l][i] != Noir) i++; } } return n; } /** * Cette methode compte le nombre d'indications requises pour * la colonne c. */ private int countIndicationsC(int c) { int i = 0, n = 0; // i parcourt les cases de la colonne et n parcourt les index // des indications while (i < nbL - 1) { if (grid[i][c] == Noir || grid[i + 1][c] == Noir) i++; else { n++; while (i < nbL && grid[i][c] != Noir) i++; } } return n; } /** Teste si la chaine s est marqueur de ligne ou de colonne. */ private static boolean locationSymbol(String s) { return s.startsWith("<") && s.endsWith(">"); } /** Renvoie l'indication signifiée par la chaine s. (seulement un entier pour l'instant) @return un entier strictement positif pour une indication facteur, et -1 dans les autres cas (indication inconnue) */ private static int indicationParser(String s) { if (s.equals("carre")) return -1; // TODO pour l'instant carre n'est pas reconnu else if (s.startsWith("fact=")) return Integer.valueOf(s.substring(5)).intValue(); return -1; } /** * Lecture de la grille a partir d'un fichier. Dans le cas ou * la lecture echoue, il se peut que les donnees contenues dans * l'objet courrant soit partiellement modifiees. * @param filename le chemin du fichier qu'il faut lire * @return true si la lecture s'est bien passee, * false sinon * @throws IOException */ public boolean load(String filename) throws IOException { /* Prepare la lecture du fichier */ Reader r = new FileReader(filename); Scanner s = new Scanner(r); try { /* Lecture nombre de lignes et de colonnes */ if (s.hasNextInt()) nbL = s.nextInt(); else return false; if (s.hasNextInt()) nbC = s.nextInt(); else return false; grid = new int[nbL][nbC]; /* Lecture grille */ for (int l = 0; l < nbL; l++) for (int c = 0; c < nbC; c++) { if (s.hasNextInt()) grid[l][c] = s.nextInt(); else { String e = s.next(); if (e.equals("X")) grid[l][c] = Noir; else if (e.equals("-")) grid[l][c] = Inconnu; else return false; } } /* Initialisation des tableaux d'indications */ indL = new int[nbL][]; for (int l = 0; l < nbL; l++) indL[l] = new int[countIndicationsL(l)]; indC = new int[nbC][]; for (int c = 0; c < nbC; c++) indC[c] = new int[countIndicationsC(c)]; /* Lecture indications lignes */ for (int l = 0; l < nbL; l++) { if (!locationSymbol(s.next())) return false; for (int i = 0; i < countIndicationsL(l); i++) { int indication = indicationParser(s.next()); indL[l][i] = indication; } } /* Lecture indications colonnes */ for (int c = 0; c < nbC; c++) { if (!locationSymbol(s.next())) return false; for (int i = 0; i < countIndicationsC(c); i++) { int indication = indicationParser(s.next()); indC[c][i] = indication; } } } catch (java.util.NoSuchElementException e) { System.err.println("Grille.load: fichier grille non termine"); return false; } catch (java.lang.NumberFormatException e) { System.err.println("Grille.load: format de nombre incorrect"); return false; } finally { s.close(); } return true; }