This commit is contained in:
@@ -1,32 +1,99 @@
|
|||||||
package sudoku.structure;
|
package sudoku.structure;
|
||||||
|
|
||||||
|
import sudoku.io.SudokuSerializer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import sudoku.io.SudokuSerializer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class MultiDoku
|
* @class MultiDoku
|
||||||
* @brief Représente une grille de Multidoku.
|
* @brief Représente une grille de Multidoku.
|
||||||
* Une grille de sudoku est un multidoku avec un seul sous-sudoku
|
* Une grille de sudoku est un multidoku avec un seul sous-sudoku.
|
||||||
*/
|
*/
|
||||||
public class MultiDoku {
|
public class MultiDoku {
|
||||||
|
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="ATTRIBUTS">
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liste des sous-Sudoku contenue dans le multidoku.
|
* Liste des sous-Sudoku contenue dans le multidoku.
|
||||||
*/
|
*/
|
||||||
private final List<Sudoku> subGrids;
|
private final List<Sudoku> subGrids;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pile, qui contient des états du MultiDoku,
|
||||||
|
* utile pour la résolution.
|
||||||
|
*/
|
||||||
private final StateManager stateManager;
|
private final StateManager stateManager;
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="METHODES">
|
||||||
|
|
||||||
public MultiDoku(List<Sudoku> subGrids) {
|
public MultiDoku(List<Sudoku> subGrids) {
|
||||||
this.subGrids = subGrids;
|
this.subGrids = subGrids;
|
||||||
this.stateManager = new StateManager(this);
|
this.stateManager = new StateManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check si le MultiDoku est résolu, c'est à dire complet et cohérent avec ses contraintes.
|
||||||
|
*
|
||||||
|
* @return boolean, true s'il est résolu et false sinon.
|
||||||
|
*/
|
||||||
|
public boolean isSolved() {
|
||||||
|
for (Sudoku sudoku : this.subGrids) {
|
||||||
|
if (!sudoku.isSolved())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie la liste des Cells préalablement remplies du MultiDoku.
|
||||||
|
*
|
||||||
|
* @return List<Cell>, vide si aucune Cell n'est remplie.
|
||||||
|
*/
|
||||||
|
public List<Cell> getFilledCells() {
|
||||||
|
List<Cell> result = new ArrayList<>();
|
||||||
|
for (Cell cell : this.getCells()) {
|
||||||
|
if (!cell.isEmpty()) {
|
||||||
|
result.add(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie la liste des Cells vides du MultiDoku.
|
||||||
|
*
|
||||||
|
* @return List<Cell>, vide si aucune Cell ne l'est.
|
||||||
|
*/
|
||||||
|
public List<Cell> getEmptyCells() {
|
||||||
|
List<Cell> result = new ArrayList<>();
|
||||||
|
for (Cell cell : this.getCells()) {
|
||||||
|
if (cell.isEmpty()) {
|
||||||
|
result.add(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie la 1re Cell vide des sous-Sudoku.
|
||||||
|
*
|
||||||
|
* @return Cell, une Cell vide, ou null s'il n'y en a pas.
|
||||||
|
*/
|
||||||
|
public Cell getFirstEmptyCell() {
|
||||||
|
for (Sudoku sudoku : this.subGrids) {
|
||||||
|
Cell cellTmp = sudoku.getFirstEmptyCell();
|
||||||
|
if (cellTmp != null) {
|
||||||
|
return cellTmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie le nombre de sudoku contenu dans ce MultiDoku.
|
* Renvoie le nombre de sudoku contenu dans ce MultiDoku.
|
||||||
*
|
*
|
||||||
@@ -60,95 +127,6 @@ public class MultiDoku {
|
|||||||
return new ArrayList<>(cellsSet);
|
return new ArrayList<>(cellsSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Multidoku {");
|
|
||||||
for (Sudoku sudoku : subGrids) {
|
|
||||||
sb.append("\n\t").append(sudoku.toString());
|
|
||||||
}
|
|
||||||
sb.append("\n}");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renvoie les sous-Sudoku
|
|
||||||
*
|
|
||||||
* @return List<Sudoku>
|
|
||||||
*/
|
|
||||||
public List<Sudoku> getSubGrids() {
|
|
||||||
return this.subGrids;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check si le MultiDoku est résolu, c'est à dire complet et cohérent avec ses contraintes.
|
|
||||||
*
|
|
||||||
* @return boolean, true s'il est résolu et false sinon.
|
|
||||||
*/
|
|
||||||
public boolean isSolved() {
|
|
||||||
for (Sudoku sudoku : this.subGrids) {
|
|
||||||
if (!sudoku.isSolved())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renvoie la 1re Cell vide des sous-Sudoku.
|
|
||||||
*
|
|
||||||
* @return Cell, une Cell vide, ou null s'il n'y en a pas.
|
|
||||||
*/
|
|
||||||
public Cell getFirstEmptyCell() {
|
|
||||||
for (Sudoku sudoku : this.subGrids) {
|
|
||||||
Cell cellTmp = sudoku.getFirstEmptyCell();
|
|
||||||
if (cellTmp != null) {
|
|
||||||
return cellTmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renvoie la liste des Cells préalablement remplies du MultiDoku.
|
|
||||||
*
|
|
||||||
* @return List<Cell>, vide si aucune Cell n'est remplie.
|
|
||||||
*/
|
|
||||||
public List<Cell> getFilledCells() {
|
|
||||||
List<Cell> result = new ArrayList<>();
|
|
||||||
for (Cell cell : this.getCells()) {
|
|
||||||
if (!cell.isEmpty()) {
|
|
||||||
result.add(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renvoie la liste des Cells vides du MultiDoku.
|
|
||||||
*
|
|
||||||
* @return List<Cell>, vide si aucune Cell ne l'est.
|
|
||||||
*/
|
|
||||||
public List<Cell> getEmptyCells() {
|
|
||||||
List<Cell> result = new ArrayList<>();
|
|
||||||
for (Cell cell : this.getCells()) {
|
|
||||||
if (cell.isEmpty()) {
|
|
||||||
result.add(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vide une Cell donnée.
|
|
||||||
*
|
|
||||||
* @param cell Cell, à vider.
|
|
||||||
*/
|
|
||||||
public void empty(Cell cell) {
|
|
||||||
List<Cell> cells = getCells();
|
|
||||||
Cell cellToEmpty = cells.get(cells.indexOf(cell));
|
|
||||||
cellToEmpty.setSymbolIndex(Cell.NOSYMBOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie le nombre de Cell contenue dans le MultiDoku.
|
* Renvoie le nombre de Cell contenue dans le MultiDoku.
|
||||||
*
|
*
|
||||||
@@ -167,22 +145,9 @@ public class MultiDoku {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public StateManager getStateManager() {
|
|
||||||
return stateManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie une Cell vide choisie aléatoirement.
|
* Vide les Cells modifiable.
|
||||||
*
|
|
||||||
* @param rand Random, pour le choix aléatoire.
|
|
||||||
* @return Cell, une Cell vide.
|
|
||||||
*/
|
*/
|
||||||
public Cell getRandomEmptyCell(Random rand) {
|
|
||||||
List<Cell> emptyCells = getEmptyCells();
|
|
||||||
int randomIndex = rand.nextInt(emptyCells.size());
|
|
||||||
return emptyCells.get(randomIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearMutableCells() {
|
public void clearMutableCells() {
|
||||||
for (Sudoku s : getSubGrids()) {
|
for (Sudoku s : getSubGrids()) {
|
||||||
for (Cell cell : s.getCells()) {
|
for (Cell cell : s.getCells()) {
|
||||||
@@ -192,11 +157,23 @@ public class MultiDoku {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie les sous-Sudoku
|
||||||
|
*
|
||||||
|
* @return List<Sudoku>
|
||||||
|
*/
|
||||||
|
public List<Sudoku> getSubGrids() {
|
||||||
|
return this.subGrids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StateManager getStateManager() {
|
||||||
|
return stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (!(other instanceof MultiDoku))
|
if (!(other instanceof MultiDoku otherDoku))
|
||||||
return false;
|
return false;
|
||||||
MultiDoku otherDoku = (MultiDoku) other;
|
|
||||||
if (this.getNbSubGrids() != otherDoku.getNbSubGrids())
|
if (this.getNbSubGrids() != otherDoku.getNbSubGrids())
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < this.getNbSubGrids(); i++) {
|
for (int i = 0; i < this.getNbSubGrids(); i++) {
|
||||||
@@ -212,8 +189,21 @@ public class MultiDoku {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Multidoku {");
|
||||||
|
for (Sudoku sudoku : subGrids) {
|
||||||
|
sb.append("\n\t").append(sudoku.toString());
|
||||||
|
}
|
||||||
|
sb.append("\n}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public MultiDoku clone() {
|
public MultiDoku clone() {
|
||||||
// TODO: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah
|
// TODO: C'est pas dingue de le faire comme ça...
|
||||||
return SudokuSerializer.deserializeSudoku(SudokuSerializer.serializeSudoku(this));
|
return SudokuSerializer.deserializeSudoku(SudokuSerializer.serializeSudoku(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user