4 Commits

Author SHA1 Message Date
1e67e7a9d4 fix renderable multidoku max coords
All checks were successful
Linux arm64 / Build (push) Successful in 29s
2025-02-02 00:37:07 +01:00
Melvyn
70eef1646d refactor
All checks were successful
Linux arm64 / Build (push) Successful in 31s
2025-02-02 00:16:27 +01:00
5dfe4382fe feat: render new sudoku types
All checks were successful
Linux arm64 / Build (push) Successful in 27s
2025-02-02 00:10:25 +01:00
Melvyn
059886c2a4 feat : createPlusMMultidoku
All checks were successful
Linux arm64 / Build (push) Successful in 30s
2025-02-02 00:02:47 +01:00
19 changed files with 147 additions and 190 deletions

View File

@@ -2,10 +2,15 @@ package gui;
import gui.constants.Fonts; import gui.constants.Fonts;
import gui.constants.Images; import gui.constants.Images;
import gui.constants.Symbols;
import gui.menu.MainMenu; import gui.menu.MainMenu;
import gui.menu.StateMachine; import gui.menu.StateMachine;
import imgui.app.Application; import imgui.app.Application;
import imgui.app.Configuration; import imgui.app.Configuration;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Difficulty;
import sudoku.structure.MultiDoku;
import sudoku.structure.SudokuFactory;
public class Main extends Application { public class Main extends Application {
@@ -31,7 +36,7 @@ public class Main extends Application {
@Override @Override
protected void preRun() { protected void preRun() {
super.preRun(); super.preRun();
Images.reloadImages(); Images.loadImages();
} }
@Override @Override
@@ -41,6 +46,13 @@ public class Main extends Application {
} }
public static void main(String[] args) { public static void main(String[] args) {
launch(new Main()); MultiDoku doku = SudokuFactory.createBasicPlusShapedMultidoku(3, 3, SudokuFactory.DEFAULT_CONSTRAINTS);
try {
SudokuFactory.fillDoku(doku, Difficulty.Easy);
} catch (Exception e) {
throw new RuntimeException();
}
SudokuPrinter.printMultiDoku(doku, 3, 3, Symbols.Numbers);
//launch(new Main());
} }
} }

View File

@@ -90,29 +90,23 @@ public class RenderableMultidoku {
} }
private static Coordinate getMaxSudokuCoordinate(Map<Sudoku, Coordinate> sudokusOffset) { private static Coordinate getMaxSudokuCoordinate(Map<Sudoku, Coordinate> sudokusOffset) {
Coordinate maxCoordinate = null; int maxX = 0;
Sudoku maxSudoku = null; int maxY = 0;
float maxDistanceSquared = 0; Sudoku lastSudoku = null;
for (var entry : sudokusOffset.entrySet()) { for (var entry : sudokusOffset.entrySet()) {
Coordinate coordinate = entry.getValue(); Coordinate coordinate = entry.getValue();
float distanceSquared = coordinate.getX() * coordinate.getX() + coordinate.getY() * coordinate.getY(); if (coordinate.getX() > maxX)
if (maxCoordinate == null) { maxX = coordinate.getX();
maxCoordinate = coordinate; if (coordinate.getY() > maxY)
maxDistanceSquared = distanceSquared; maxY = coordinate.getY();
maxSudoku = entry.getKey(); lastSudoku = entry.getKey();
}
if (distanceSquared > maxDistanceSquared) {
maxDistanceSquared = distanceSquared;
maxSudoku = entry.getKey();
maxCoordinate = coordinate;
}
} }
int blockWidth = maxSudoku.getBlockWidth(); Coordinate maxCoordinate = new Coordinate(maxX, maxY);
int blockHeight = maxSudoku.getSize() / blockWidth; // tous les sudokus sont censés faire la même taille
int sudokuSize = lastSudoku.getSize();
return new Coordinate(maxCoordinate.getX() + maxSudoku.getSize(), maxCoordinate.getY() + maxSudoku.getSize()); return new Coordinate(maxCoordinate.getX() + sudokuSize, maxCoordinate.getY() + sudokuSize);
} }
public static RenderableMultidoku fromMultidoku(MultiDoku doku) { public static RenderableMultidoku fromMultidoku(MultiDoku doku) {

View File

@@ -32,8 +32,8 @@ public class Images {
return textureID; return textureID;
} }
public static void reloadImages() { public static void loadImages() {
BACKGROUND = loadTexture(Options.BackgroundPath); BACKGROUND = loadTexture("background.png");
} }
} }

View File

@@ -4,6 +4,5 @@ public class Options {
public static Symbols Symboles = Symbols.Numbers; public static Symbols Symboles = Symbols.Numbers;
public static float BackgroundSpeed = 1.0f; public static float BackgroundSpeed = 1.0f;
public static String BackgroundPath = "background.png";
} }

View File

@@ -14,10 +14,14 @@ public enum SudokuType {
(constraints, params) -> SudokuFactory.createBasicEmptyRectangleDoku(params[0], params[1], constraints)), (constraints, params) -> SudokuFactory.createBasicEmptyRectangleDoku(params[0], params[1], constraints)),
RandomBloc("Blocs aléatoires", 1, RandomBloc("Blocs aléatoires", 1,
(constraints, params) -> SudokuFactory.createBasicEmptyRandomBlockDoku(params[0], constraints)), (constraints, params) -> SudokuFactory.createBasicEmptyRandomBlockDoku(params[0], constraints)),
MultiDokuSquare("Multidoku carré (X)", 1, MultiDokuXSquare("Multidoku carré (X)", 1,
(constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], constraints)), (constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], constraints)),
MultidokuRectangle("Multidoku rectangle (X)", 2, MultidokuXRectangle("Multidoku rectangle (X)", 2,
(constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], params[1], constraints)); (constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], params[1], constraints)),
MultiDokuPSquare("Multidoku carré (+)", 1,
(constraints, params) -> SudokuFactory.createBasicPlusShapedMultidoku(params[0], constraints)),
MultiDokuPRectangle("Multidoku rectangle (+)", 2,
(constraints, params) -> SudokuFactory.createBasicPlusShapedMultidoku(params[0], params[1], constraints));
String displayName; String displayName;
SudokuMaker maker; SudokuMaker maker;

View File

@@ -14,12 +14,12 @@ public class ConnexionStatusView extends BaseView {
private String displayText = "Connecting ..."; private String displayText = "Connecting ...";
public ConnexionStatusView(StateMachine stateMachine, String pseudo, String address, short port) public ConnexionStatusView(StateMachine stateMachine, String address, short port)
throws UnknownHostException, IOException { throws UnknownHostException, IOException {
super(stateMachine); super(stateMachine);
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { try {
this.client = new Client(pseudo, address, port); this.client = new Client(address, port);
bindListeners(); bindListeners();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -29,13 +29,12 @@ public class ConnexionStatusView extends BaseView {
t.start(); t.start();
} }
public ConnexionStatusView(StateMachine stateMachine, String pseudo, short port) public ConnexionStatusView(StateMachine stateMachine, short port) throws UnknownHostException, IOException {
throws UnknownHostException, IOException {
super(stateMachine); super(stateMachine);
Thread t = new Thread(() -> { Thread t = new Thread(() -> {
try { try {
this.server = new Server(port); this.server = new Server(port);
this.client = new Client(pseudo, "localhost", port); this.client = new Client("localhost", port);
bindListeners(); bindListeners();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -1,7 +1,6 @@
package gui.menu; package gui.menu;
import java.io.IOException; import java.io.IOException;
import java.util.Random;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImVec2; import imgui.ImVec2;
@@ -12,7 +11,6 @@ public class MultiMenu extends BaseView {
private final ImInt port = new ImInt(25565); private final ImInt port = new ImInt(25565);
private final ImString address = new ImString("localhost"); private final ImString address = new ImString("localhost");
private final ImString pseudo = new ImString("Joueur" + new Random().nextInt());
public MultiMenu(StateMachine stateMachine) { public MultiMenu(StateMachine stateMachine) {
super(stateMachine); super(stateMachine);
@@ -24,10 +22,9 @@ public class MultiMenu extends BaseView {
ImGui.beginChild("##CreateGame", new ImVec2(displaySize.x / 2.0f, displaySize.y * 8.0f / 9.0f)); ImGui.beginChild("##CreateGame", new ImVec2(displaySize.x / 2.0f, displaySize.y * 8.0f / 9.0f));
if (ImGui.inputInt("Port", port)) if (ImGui.inputInt("Port", port))
port.set(Math.clamp(port.get(), 1, 65535)); port.set(Math.clamp(port.get(), 1, 65535));
ImGui.inputText("Pseudo", pseudo);
if (ImGui.button("Créer")) { if (ImGui.button("Créer")) {
try { try {
this.stateMachine.pushState(new ConnexionStatusView(stateMachine, pseudo.get(), (short) port.get())); this.stateMachine.pushState(new ConnexionStatusView(stateMachine, (short) port.get()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -41,7 +38,6 @@ public class MultiMenu extends BaseView {
ImGui.inputText("Adresse", address); ImGui.inputText("Adresse", address);
if (ImGui.inputInt("Port", port)) if (ImGui.inputInt("Port", port))
port.set(Math.clamp(port.get(), 1, 65535)); port.set(Math.clamp(port.get(), 1, 65535));
ImGui.inputText("Pseudo", pseudo);
if (ImGui.button("Rejoindre")) { if (ImGui.button("Rejoindre")) {
try { try {
this.stateMachine.pushState(new ConnexionStatusView(stateMachine, address.get(), (short) port.get())); this.stateMachine.pushState(new ConnexionStatusView(stateMachine, address.get(), (short) port.get()));

View File

@@ -78,9 +78,4 @@ public class MultiPlayerView extends BaseView {
renderGameStatus(); renderGameStatus();
} }
@Override
public void cleanResources() {
this.selector.clean();
}
} }

View File

@@ -1,56 +1,28 @@
package gui.menu; package gui.menu;
import gui.constants.Images;
import gui.constants.Options; import gui.constants.Options;
import gui.constants.Symbols; import gui.constants.Symbols;
import imgui.ImGui; import imgui.ImGui;
import imgui.extension.imguifiledialog.ImGuiFileDialog;
import imgui.extension.imguifiledialog.flag.ImGuiFileDialogFlags;
import imgui.type.ImInt; import imgui.type.ImInt;
public class OptionsMenu extends BaseView { public class OptionsMenu extends BaseView {
private ImInt currentValue = new ImInt(); private ImInt currentValue = new ImInt();
private float backgroundSpeed[] = new float[] { Options.BackgroundSpeed }; private float backgroundSpeed[] = new float[]{Options.BackgroundSpeed};
public OptionsMenu(StateMachine stateMachine) { public OptionsMenu(StateMachine stateMachine) {
super(stateMachine); super(stateMachine);
} }
private void renderImageSelectDialog() {
if (ImGuiFileDialog.display("browse-img", ImGuiFileDialogFlags.None)) {
if (ImGuiFileDialog.isOk()) {
var selection = ImGuiFileDialog.getSelection();
for (var entry : selection.entrySet()) {
try {
String filePath = entry.getValue();
Options.BackgroundPath = filePath;
Images.reloadImages();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ImGuiFileDialog.close();
}
}
private void renderImageSelectButton() {
if (ImGui.button("Changer de fond d'écran"))
ImGuiFileDialog.openDialog("browse-img", "Choisissez un fichier", ".png,.jpg,.jpeg", ".");
renderImageSelectDialog();
}
@Override @Override
public void render() { public void render() {
ImGui.text("Options"); ImGui.text("Options");
if (ImGui.combo("Jeu de symboles", currentValue, Symbols.getSymbolsNames())) { if(ImGui.combo("Jeu de symboles", currentValue, Symbols.getSymbolsNames())){
Options.Symboles = Symbols.values()[currentValue.get()]; Options.Symboles = Symbols.values()[currentValue.get()];
} }
if (ImGui.sliderFloat("Vitesse d'animation de l'arrière plan", backgroundSpeed, 0.0f, 10.0f)) { if(ImGui.sliderFloat("Vitesse d'animation de l'arrière plan", backgroundSpeed, 0.0f, 10.0f)){
Options.BackgroundSpeed = backgroundSpeed[0]; Options.BackgroundSpeed = backgroundSpeed[0];
} }
renderImageSelectButton();
renderReturnButton(); renderReturnButton();
} }

View File

@@ -25,9 +25,4 @@ public class SoloMenu extends BaseView {
renderReturnButton(); renderReturnButton();
} }
@Override
public void cleanResources() {
this.sudokuSelector.clean();
}
} }

View File

@@ -92,7 +92,6 @@ public class SudokuView extends BaseView {
} }
private void startSolve(Solver solver) { private void startSolve(Solver solver) {
this.doku.clearMutableCells();
resolveThread = new Thread(() -> { resolveThread = new Thread(() -> {
List<SolverStep> steps = new ArrayList<>(); List<SolverStep> steps = new ArrayList<>();
try { try {
@@ -159,8 +158,6 @@ public class SudokuView extends BaseView {
private void renderClearButton() { private void renderClearButton() {
if (centeredButton("Effacer")) { if (centeredButton("Effacer")) {
this.doku.clearMutableCells(); this.doku.clearMutableCells();
this.resolved = false;
this.unresolved = false;
} }
} }

View File

@@ -9,22 +9,13 @@ public class SmoothProgressBar {
private final float speed = 2.0f; private final float speed = 2.0f;
private final float clipConstant = 0.001f; private final float clipConstant = 0.001f;
private void updateProgress(float newProgress) { public void render(String label, ImVec2 size, float progress) {
float delta = newProgress - lastProgress; float delta = progress - lastProgress;
if (Math.abs(delta) < clipConstant) if (Math.abs(delta) < clipConstant)
lastProgress = newProgress; lastProgress = progress;
else else
lastProgress = lastProgress + delta * ImGui.getIO().getDeltaTime() * speed; lastProgress = lastProgress + delta * ImGui.getIO().getDeltaTime() * speed;
}
public void render(String label, ImVec2 size, float progress) {
updateProgress(progress);
ImGui.progressBar(lastProgress, size, label); ImGui.progressBar(lastProgress, size, label);
} }
public void render(float progress) {
updateProgress(progress);
ImGui.progressBar(lastProgress);
}
} }

View File

@@ -35,15 +35,10 @@ public class SudokuSelector {
private final String confirmMessage; private final String confirmMessage;
private Thread genThread = null;
private final SmoothProgressBar genProgressBar;
public SudokuSelector(boolean canGenEmptyGrid, String confirmMessage) { public SudokuSelector(boolean canGenEmptyGrid, String confirmMessage) {
this.canGenEmptyGrid = canGenEmptyGrid; this.canGenEmptyGrid = canGenEmptyGrid;
this.confirmMessage = confirmMessage; this.confirmMessage = confirmMessage;
initConstraints(); initConstraints();
this.genProgressBar = new SmoothProgressBar();
} }
private List<IConstraint> getConstraints() { private List<IConstraint> getConstraints() {
@@ -61,39 +56,16 @@ public class SudokuSelector {
} }
} }
private void stopGenThread() {
if (this.genThread != null) {
this.genThread.interrupt();
this.genThread = null;
}
}
private void renderGenProgress() {
if (ImGui.beginPopup("genProgress")) {
ImGui.text("Loading ...");
int filled = this.doku.getFilledCells().size();
int total = this.doku.getCells().size();
this.genProgressBar.render(filled / (float) total);
ImGui.endPopup();
} else {
stopGenThread();
}
}
private void selectSudoku(MultiDoku doku, boolean empty) { private void selectSudoku(MultiDoku doku, boolean empty) {
this.doku = doku; this.doku = doku;
ImGui.openPopup("genProgress"); if (!empty) {
this.genThread = new Thread(() -> { try {
if (!empty) { SudokuFactory.fillDoku(doku, Difficulty.values()[difficulty.get()]);
try { } catch (Exception e) {
SudokuFactory.fillDoku(doku, Difficulty.values()[difficulty.get()]); e.printStackTrace();
this.onSelect.emit(this.doku);
} catch (Exception e) {
e.printStackTrace();
}
} }
}); }
this.genThread.start(); this.onSelect.emit(this.doku);
} }
public void renderFileDialog() { public void renderFileDialog() {
@@ -159,12 +131,7 @@ public class SudokuSelector {
if (ImGui.button("À partir d'un fichier")) { if (ImGui.button("À partir d'un fichier")) {
ImGuiFileDialog.openDialog("browse-sudoku", "Choisissez un fichier", ".json", "."); ImGuiFileDialog.openDialog("browse-sudoku", "Choisissez un fichier", ".json", ".");
} }
renderGenProgress();
renderFileDialog(); renderFileDialog();
} }
public void clean() {
stopGenThread();
}
} }

View File

@@ -28,10 +28,12 @@ public class Client {
String disconnectReason = null; String disconnectReason = null;
public Client(String pseudo, String address, short port) throws UnknownHostException, IOException { public Client(String address, short port) throws UnknownHostException, IOException {
this.clientConnection = new ClientConnexion(address, port, this); this.clientConnection = new ClientConnexion(address, port, this);
this.game = new Game(); this.game = new Game();
login(pseudo); // temp
Random r = new Random();
login("Player" + r.nextInt());
} }
public void login(String pseudo) { public void login(String pseudo) {

View File

@@ -227,7 +227,7 @@ public class ConsoleInterface {
saveMultiDoku(doku); saveMultiDoku(doku);
break; break;
case "solution": case "solution":
solve(doku, listSymbols, width, height); solve(doku);
break; break;
case "exit": case "exit":
exit(); exit();
@@ -238,50 +238,19 @@ public class ConsoleInterface {
} }
} }
private void applyStep(SolverStep step) { private void solve(MultiDoku doku){
step.getCell().setSymbolIndex(step.getNewValue());
}
private boolean showStep(MultiDoku doku, List<String> listSymbols, int width, int height, SolverStep step) {
System.out.println("Here is the step : \n");
showMultidoku(doku, listSymbols, width, height);
applyStep(step);
System.out.println("\nTurns into :\n");
showMultidoku(doku, listSymbols, width, height);
System.out.println("Do you want to see the next step ? (y/n, default n)");
return reader.next().equals("y");
}
private void showSolveSteps(MultiDoku doku, List<String> listSymbols, int width, int height, List<SolverStep> steps) {
System.out.println("Would you like to see the steps of the solver ? (y/n, default n)");
doku.getStateManager().popState();
switch (reader.next()) {
case "y":
int stepCount = 0;
while(stepCount < steps.size() && showStep(doku, listSymbols, width, height, steps.get(stepCount))){stepCount++;}
break;
default:
break;
}
}
private void solve(MultiDoku doku, List<String> listSymbols, int width, int height){
System.out.println("Pick a solver to use : random ('random', default), human ('human') or mixed solver ('mixed')."); System.out.println("Pick a solver to use : random ('random', default), human ('human') or mixed solver ('mixed').");
List<SolverStep> steps = new ArrayList<>();
doku.getStateManager().pushState();
switch (reader.next()) { switch (reader.next()) {
case "human": case "human":
new HumanSolver().solve(doku, steps); new HumanSolver().solve(doku);
break; break;
case "mixed": case "mixed":
new MixedSolver().solve(doku, steps); new MixedSolver().solve(doku);
break; break;
default: default:
new RandomSolver().solve(doku, steps); new RandomSolver().solve(doku);
break; break;
} }
showSolveSteps(doku, listSymbols, width, height, steps);
} }
private void play(MultiDoku doku, List<String> listSymbols, int width, int height) { private void play(MultiDoku doku, List<String> listSymbols, int width, int height) {

View File

@@ -2,9 +2,13 @@ package sudoku.solver;
import java.util.List; import java.util.List;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import gui.constants.Symbols;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class HumanSolver implements Solver { public class HumanSolver implements Solver {
@@ -19,6 +23,13 @@ public class HumanSolver implements Solver {
if (Thread.interrupted()) if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(),
Symbols.Numbers));
if (doku.isSolved()) { if (doku.isSolved()) {
return true; return true;
} }

View File

@@ -3,9 +3,13 @@ package sudoku.solver;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import gui.constants.Symbols;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class MixedSolver implements Solver { public class MixedSolver implements Solver {
@@ -24,6 +28,14 @@ public class MixedSolver implements Solver {
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
} }
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(
sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(),
Symbols.Numbers));
if (doku.isSolved()) { if (doku.isSolved()) {
return true; return true;
} }

View File

@@ -3,9 +3,13 @@ package sudoku.solver;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import gui.constants.Symbols;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class RandomSolver implements Solver { public class RandomSolver implements Solver {
@@ -24,6 +28,13 @@ public class RandomSolver implements Solver {
if (Thread.interrupted()) if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(),
Symbols.Numbers));
if (doku.isSolved()) { if (doku.isSolved()) {
return true; return true;
} }

View File

@@ -234,24 +234,7 @@ public class SudokuFactory {
public static MultiDoku createBasicXShapedMultidoku(int size, List<IConstraint> constraints) { public static MultiDoku createBasicXShapedMultidoku(int size, List<IConstraint> constraints) {
assert (size > 1); assert (size > 1);
/* return createBasicXShapedMultidoku(size, size, constraints);
* 2 3
* 1
* 4 5
*/
Sudoku sudoku1 = createSquareSudoku(size, constraints);
Sudoku sudoku2 = createSquareSudoku(size, constraints);
Sudoku sudoku3 = createSquareSudoku(size, constraints);
Sudoku sudoku4 = createSquareSudoku(size, constraints);
Sudoku sudoku5 = createSquareSudoku(size, constraints);
linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size));
linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size));
linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1));
linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1));
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
} }
/** /**
@@ -287,6 +270,55 @@ public class SudokuFactory {
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
} }
/**
* TODO
* Créée un MultiDoku de Blocks carrés de taille size composé de cinq Sudokus,
* dont un central qui partage chacun de ses Blockss d'angle avec un autre
* Sudoku.
*
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
* @return MultiDoku, MultiDoku de forme X.
*/
public static MultiDoku createBasicPlusShapedMultidoku(int size, List<IConstraint> constraints) {
assert (size > 1);
return createBasicPlusShapedMultidoku(size, size, constraints);
}
/**
* TODO
* Créée un MultiDoku de Blocks rectangulaires de forme width par height composé
* de cinq Sudokus,
* dont un central qui partage chacun de ses Blocks d'angle avec un autre
* Sudoku.
*
* @param width int, largeur des Blocks unitraires des Sudokus à crééer.
* @param height int, hauteur des Blocks unitraires des Sudokus à crééer.
* @return MultiDoku, MultiDoku de forme X.
*/
public static MultiDoku createBasicPlusShapedMultidoku(int width, int height, List<IConstraint> constraints) {
assert (width > 1 && height > 1);
/*
* 3
* 2 1 4
* 5
*/
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
Sudoku sudoku3 = createRectangleSudoku(width, height, constraints);
Sudoku sudoku4 = createRectangleSudoku(width, height, constraints);
Sudoku sudoku5 = createRectangleSudoku(width, height, constraints);
linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - height, 0));
linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(0, 1 - width));
linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(height - 1, 0));
linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(0, width - 1));
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
}
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception { public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
Solver solver = new RandomSolver(); Solver solver = new RandomSolver();
solver.solve(doku); solver.solve(doku);
@@ -309,8 +341,7 @@ public class SudokuFactory {
public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List<IConstraint> constraints) { public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List<IConstraint> constraints) {
int blockCellCount = blockSize * blockSize; int blockCellCount = blockSize * blockSize;
List<Cell> cells = initCells(blockCellCount); List<Cell> cells = initCells(blockCellCount);
List<Cell> homeLessCells = new ArrayList<>(); List<Cell> homeLessCells = new ArrayList<>(cells);
homeLessCells.addAll(cells);
List<Block> blocks = new ArrayList<>(); List<Block> blocks = new ArrayList<>();
Random r = new Random(); Random r = new Random();
for (int i = 0; i < blockCellCount; i++) { for (int i = 0; i < blockCellCount; i++) {