/**
* 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;
}