12 Commits

Author SHA1 Message Date
b87bd5183e create package org.polytech.ryuk
All checks were successful
Linux arm64 / Build (push) Successful in 31s
2025-02-01 14:47:46 +01:00
a20a5387a7 chore: bundle deps in jar 2025-02-01 14:34:19 +01:00
a1032335a5 chore: remove unused deps 2025-02-01 14:10:15 +01:00
336d8378ae fix: slower background animation speed by default
All checks were successful
Linux arm64 / Build (push) Successful in 37s
2025-02-01 13:45:44 +01:00
c165ecdae5 Merge pull request 'Fixes #15' (#36) from multiplayer into master
All checks were successful
Linux arm64 / Build (push) Successful in 39s
Reviewed-on: #36
2025-02-01 12:43:13 +00:00
352aee49e4 feat: make timer stop game (Fixes #15)
All checks were successful
Linux arm64 / Build (push) Successful in 29s
2025-02-01 13:41:13 +01:00
f22debdf5f fix: score display
All checks were successful
Linux arm64 / Build (push) Successful in 28s
2025-02-01 12:54:11 +01:00
02089c649b feat: select game duration
All checks were successful
Linux arm64 / Build (push) Successful in 28s
2025-02-01 12:27:50 +01:00
e98199e1ec refactor: remove sysout
All checks were successful
Linux arm64 / Build (push) Successful in 25s
2025-02-01 11:59:05 +01:00
438252a8ca feat: first player progress display 2025-02-01 11:58:42 +01:00
Melvyn
b7f9ca8a98 fix : MixedSolver
All checks were successful
Linux arm64 / Build (push) Successful in 40s
2025-01-31 18:26:44 +01:00
f47e4cc309 feat: animated background
All checks were successful
Linux arm64 / Build (push) Successful in 10m56s
2025-01-30 22:28:26 +01:00
85 changed files with 633 additions and 446 deletions

View File

@@ -16,25 +16,14 @@ project.ext.os = System.properties['os.name'].toLowerCase().split(" ")[0]
repositories { repositories {
// Use Maven Central for resolving dependencies. // Use Maven Central for resolving dependencies.
mavenCentral() mavenCentral()
flatDir {
dirs("$rootProject.projectDir/libs")
}
} }
dependencies { dependencies {
// Use JUnit Jupiter for testing. // Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
// This dependency is used by the application.
implementation 'com.google.guava:guava:31.1-jre'
// uml
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.2'
implementation 'org.json:json:20250107' implementation 'org.json:json:20250107'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
implementation "io.github.spair:imgui-java-app:1.88.0" implementation "io.github.spair:imgui-java-app:1.88.0"
implementation "org.lwjgl:lwjgl-stb:3.3.4" implementation "org.lwjgl:lwjgl-stb:3.3.4"
@@ -44,12 +33,19 @@ dependencies {
application { application {
// Define the main class for the application. // Define the main class for the application.
mainClass = 'gui.Main' mainClass = 'org.polytech.ryuk.gui.Main'
} }
tasks.named('test') { // Add libraries into the final jar
// Use JUnit Platform for unit tests. jar {
useJUnitPlatform() archiveBaseName = rootProject.getName()
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes "Main-Class": application.mainClass
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
} }
run { run {

View File

@@ -1,31 +0,0 @@
package network.protocol;
import network.protocol.packets.ChangeCellPacket;
import network.protocol.packets.ConnexionInfoPacket;
import network.protocol.packets.DisconnectPacket;
import network.protocol.packets.EndGamePacket;
import network.protocol.packets.KeepAlivePacket;
import network.protocol.packets.LoginPacket;
import network.protocol.packets.PlayerJoinPacket;
import network.protocol.packets.PlayerLeavePacket;
import network.protocol.packets.StartGamePacket;
import network.protocol.packets.UpdatePlayerScorePacket;
public interface PacketVisitor {
default void visit(Packet packet) {
packet.accept(this);
}
void visitPacket(ConnexionInfoPacket packet);
void visitPacket(DisconnectPacket packet);
void visitPacket(KeepAlivePacket packet);
void visitPacket(LoginPacket packet);
void visitPacket(PlayerJoinPacket packet);
void visitPacket(PlayerLeavePacket packet);
void visitPacket(StartGamePacket packet);
void visitPacket(EndGamePacket packet);
void visitPacket(UpdatePlayerScorePacket packet);
void visitPacket(ChangeCellPacket packet);
}

View File

@@ -1,26 +0,0 @@
package network.protocol.packets;
import network.protocol.Packet;
import network.protocol.PacketVisitor;
import network.protocol.Packets;
public class EndGamePacket extends Packet {
static private final long serialVersionUID = Packets.EndGame.ordinal();
private final int winnerId;
public EndGamePacket(int winnerId) {
this.winnerId = winnerId;
}
public int getWinnerId() {
return winnerId;
}
@Override
public void accept(PacketVisitor packetVisitor) {
packetVisitor.visitPacket(this);
}
}

View File

@@ -1,4 +1,4 @@
package common; package org.polytech.ryuk.common;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@@ -1,4 +1,4 @@
package common; package org.polytech.ryuk.common;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@@ -1,4 +1,4 @@
package game; package org.polytech.ryuk.game;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
@@ -7,21 +7,20 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
public class Game { public class Game {
public static enum GameState { public static enum GameState {
GameNotStarted, GameGoing, GameEnd GameNotStarted, GameGoing
} }
public static final int GAME_DURATION = 10 * 60;
private final Map<Integer, Player> players; private final Map<Integer, Player> players;
private final List<Player> leaderboard; private final List<Player> leaderboard;
private GameState gameState; private GameState gameState;
private MultiDoku doku; private MultiDoku doku;
private Instant startTime = null; private Instant startTime = null;
private long gameDuration;
public Game() { public Game() {
this.players = new HashMap<>(); this.players = new HashMap<>();
@@ -38,10 +37,10 @@ public class Game {
leaderboard.add(player); leaderboard.add(player);
} }
public void setPlayerScore(Player player, int newScore) { public void setPlayerRemainingCells(Player player, int newScore) {
player.setScore(newScore); player.setRemainingCells(newScore);
Collections.sort(this.leaderboard, Collections.sort(this.leaderboard,
(player1, player2) -> Integer.compare(player1.getScore(), player2.getScore())); (player1, player2) -> Integer.compare(player1.getRemainingCells(), player2.getRemainingCells()));
} }
public void removePlayer(int id) { public void removePlayer(int id) {
@@ -53,10 +52,15 @@ public class Game {
return players; return players;
} }
public void startGame(MultiDoku doku, Instant startTime) { public void startGame(MultiDoku doku, Instant startTime, long gameDuration) {
this.doku = doku; this.doku = doku;
this.gameState = GameState.GameGoing; this.gameState = GameState.GameGoing;
this.startTime = startTime; this.startTime = startTime;
this.gameDuration = gameDuration;
}
public void stopGame() {
this.gameState = GameState.GameNotStarted;
} }
public GameState getGameState() { public GameState getGameState() {
@@ -75,4 +79,8 @@ public class Game {
return startTime; return startTime;
} }
public long getGameDuration() {
return gameDuration;
}
} }

View File

@@ -1,4 +1,4 @@
package game; package org.polytech.ryuk.game;
import java.io.Serializable; import java.io.Serializable;
@@ -16,11 +16,11 @@ public class Player implements Serializable {
this.score = 0; this.score = 0;
} }
public int getScore() { public int getRemainingCells() {
return score; return score;
} }
void setScore(int score) { void setRemainingCells(int score) {
this.score = score; this.score = score;
} }

View File

@@ -0,0 +1,30 @@
package org.polytech.ryuk.gui;
import imgui.ImGui;
import imgui.ImVec2;
import imgui.flag.ImGuiWindowFlags;
public class AnimatedBackground {
private float backgroundOffset = 0;
private static final float defaultSpeed = 0.05f;
public AnimatedBackground() {
}
public void render() {
backgroundOffset += ImGui.getIO().getDeltaTime() * defaultSpeed * Options.BackgroundSpeed;
var displaySize = ImGui.getIO().getDisplaySize();
ImGui.setNextWindowPos(new ImVec2(0.0f, 0.0f));
ImGui.setNextWindowSize(displaySize);
ImGui.begin("Background", null, ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove
| ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoBackground
| ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoInputs);
ImGui.image(Images.BACKGROUND, displaySize, new ImVec2(backgroundOffset, backgroundOffset),
new ImVec2(1.0f + backgroundOffset, 1.0f + backgroundOffset));
ImGui.end();
}
}

View File

@@ -1,4 +1,4 @@
package gui; package org.polytech.ryuk.gui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package gui; package org.polytech.ryuk.gui;
import imgui.ImFont; import imgui.ImFont;
import imgui.ImFontConfig; import imgui.ImFontConfig;

View File

@@ -1,4 +1,4 @@
package gui; package org.polytech.ryuk.gui;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;

View File

@@ -1,8 +1,8 @@
package gui; package org.polytech.ryuk.gui;
import org.polytech.ryuk.gui.menu.MainMenu;
import org.polytech.ryuk.gui.menu.StateMachine;
import gui.menu.MainMenu;
import gui.menu.StateMachine;
import imgui.ImGui;
import imgui.app.Application; import imgui.app.Application;
import imgui.app.Configuration; import imgui.app.Configuration;

View File

@@ -1,7 +1,8 @@
package gui; package org.polytech.ryuk.gui;
public class Options { public class Options {
public static Symbols Symboles = Symbols.Numbers; public static Symbols Symboles = Symbols.Numbers;
public static float BackgroundSpeed = 1.0f;
} }

View File

@@ -1,15 +1,15 @@
package gui; package org.polytech.ryuk.gui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import sudoku.structure.Block; import org.polytech.ryuk.sudoku.structure.Block;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.Coordinate; import org.polytech.ryuk.sudoku.structure.Coordinate;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class RenderableMultidoku { public class RenderableMultidoku {

View File

@@ -1,10 +1,10 @@
package gui; package org.polytech.ryuk.gui;
import java.util.List; import java.util.List;
import sudoku.constraint.Constraint; import org.polytech.ryuk.sudoku.constraint.Constraint;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.SudokuFactory;; import org.polytech.ryuk.sudoku.structure.SudokuFactory;;
public enum SudokuType { public enum SudokuType {

View File

@@ -1,4 +1,4 @@
package gui; package org.polytech.ryuk.gui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import imgui.ImGui; import imgui.ImGui;

View File

@@ -1,11 +1,12 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import java.io.IOException; import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import org.polytech.ryuk.network.client.Client;
import org.polytech.ryuk.network.server.Server;
import imgui.ImGui; import imgui.ImGui;
import network.client.Client;
import network.server.Server;
public class ConnexionStatusView extends BaseView { public class ConnexionStatusView extends BaseView {

View File

@@ -0,0 +1,50 @@
package org.polytech.ryuk.gui.menu;
import org.polytech.ryuk.game.Player;
import org.polytech.ryuk.gui.ColorGenerator;
import org.polytech.ryuk.gui.widget.SudokuRenderer;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import imgui.ImGui;
import imgui.ImVec4;
public class EndGameView extends BaseView {
private final Player winner;
private float time = 0;
private static final ImVec4 YELLOW = new ImVec4(1, 1, 0, 1);
private final SudokuRenderer sudokuRenderer;
public EndGameView(StateMachine stateMachine, MultiDoku resolved, Player winner) {
super(stateMachine);
this.winner = winner;
this.sudokuRenderer = new SudokuRenderer(resolved);
}
private ImVec4 getPseudoColor() {
time += ImGui.getIO().getDeltaTime();
float factor = (float) Math.cos(time);
var color = ColorGenerator.hslToRgb(factor * factor, 0.9f, 0.4f);
return new ImVec4(color.r, color.g, color.b, 1.0f);
}
private void renderWinText() {
String winText = " a gagné !";
String text = winner.getPseudo() + winText;
float textWidth = ImGui.calcTextSizeX(text);
ImGui.setCursorPosX(ImGui.getIO().getDisplaySizeX() / 2.0f - textWidth / 2.0f);
ImGui.textColored(getPseudoColor(), winner.getPseudo());
ImGui.sameLine();
ImGui.textColored(YELLOW, winText);
}
@Override
public void render() {
renderWinText();
this.sudokuRenderer.render();
renderReturnButton();
}
}

View File

@@ -1,4 +1,4 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImVec2; import imgui.ImVec2;

View File

@@ -1,4 +1,4 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import java.io.IOException; import java.io.IOException;

View File

@@ -1,13 +1,18 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import org.polytech.ryuk.game.Player;
import org.polytech.ryuk.gui.widget.LeaderboardRenderer;
import org.polytech.ryuk.gui.widget.MultiPlayerCompleteProgress;
import org.polytech.ryuk.gui.widget.SudokuRenderer;
import org.polytech.ryuk.gui.widget.TimerRenderer;
import org.polytech.ryuk.network.client.Client;
import org.polytech.ryuk.network.server.Server;
import org.polytech.ryuk.sudoku.solver.BacktrackingSolver;
import org.polytech.ryuk.sudoku.solver.Solver;
import org.polytech.ryuk.sudoku.structure.Cell;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import game.Game;
import gui.widget.LeaderboardRenderer;
import gui.widget.SudokuRenderer;
import gui.widget.TimerRenderer;
import imgui.ImGui; import imgui.ImGui;
import network.client.Client;
import network.server.Server;
import sudoku.structure.Cell;
public class MultiPlayerDokuView extends BaseView { public class MultiPlayerDokuView extends BaseView {
@@ -16,6 +21,7 @@ public class MultiPlayerDokuView extends BaseView {
private final SudokuRenderer sudokuRenderer; private final SudokuRenderer sudokuRenderer;
private final LeaderboardRenderer leaderboardRenderer; private final LeaderboardRenderer leaderboardRenderer;
private final TimerRenderer timerRenderer; private final TimerRenderer timerRenderer;
private final MultiPlayerCompleteProgress completeProgress;
public MultiPlayerDokuView(StateMachine stateMachine, Client client, Server server) { public MultiPlayerDokuView(StateMachine stateMachine, Client client, Server server) {
super(stateMachine); super(stateMachine);
@@ -25,7 +31,17 @@ public class MultiPlayerDokuView extends BaseView {
this.leaderboardRenderer = new LeaderboardRenderer(client.getGame(), client.getPlayer()); this.leaderboardRenderer = new LeaderboardRenderer(client.getGame(), client.getPlayer());
this.sudokuRenderer.onCellChange.connect(this::onCellChange); this.sudokuRenderer.onCellChange.connect(this::onCellChange);
this.client.onDisconnect.connect(this::onDisconnect); this.client.onDisconnect.connect(this::onDisconnect);
this.timerRenderer = new TimerRenderer(this.client.getGame().getStartTime(), Game.GAME_DURATION); this.client.onGameEnd.connect(this::onGameEnd);
this.timerRenderer = new TimerRenderer(this.client.getGame().getStartTime(), this.client.getGame().getGameDuration());
this.completeProgress = new MultiPlayerCompleteProgress(this.client.getGame());
}
private void onGameEnd(Player winner) {
MultiDoku doku = this.client.getGame().getDoku();
doku.clearMutableCells();
Solver solver = new BacktrackingSolver();
solver.solve(doku);
this.stateMachine.overrideState(new EndGameView(stateMachine, doku, winner));
} }
private void onCellChange(Cell cell) { private void onCellChange(Cell cell) {
@@ -42,6 +58,7 @@ public class MultiPlayerDokuView extends BaseView {
public void render() { public void render() {
this.timerRenderer.render(); this.timerRenderer.render();
this.leaderboardRenderer.render(); this.leaderboardRenderer.render();
this.completeProgress.render();
this.sudokuRenderer.render(); this.sudokuRenderer.render();
if (ImGui.button("Quitter")) { if (ImGui.button("Quitter")) {
this.client.stop(); this.client.stop();

View File

@@ -1,11 +1,13 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import org.polytech.ryuk.game.Player;
import org.polytech.ryuk.gui.widget.SudokuSelector;
import org.polytech.ryuk.network.client.Client;
import org.polytech.ryuk.network.server.Server;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import game.Player;
import gui.widget.SudokuSelector;
import imgui.ImGui; import imgui.ImGui;
import network.client.Client; import imgui.type.ImInt;
import network.server.Server;
import sudoku.structure.MultiDoku;
public class MultiPlayerView extends BaseView { public class MultiPlayerView extends BaseView {
@@ -14,6 +16,8 @@ public class MultiPlayerView extends BaseView {
private final SudokuSelector selector; private final SudokuSelector selector;
private ImInt gameDurationMinutes = new ImInt(10);
private MultiDoku doku = null; private MultiDoku doku = null;
public MultiPlayerView(StateMachine stateMachine, Client client, Server server) { public MultiPlayerView(StateMachine stateMachine, Client client, Server server) {
@@ -45,25 +49,32 @@ public class MultiPlayerView extends BaseView {
if (this.server == null) { if (this.server == null) {
ImGui.text("En attente de l'administrateur du serveur ..."); ImGui.text("En attente de l'administrateur du serveur ...");
} else { } else {
if (this.doku == null) renderTimer();
ImGui.beginDisabled(); ImGui.beginDisabled(this.doku == null);
if (ImGui.button("Démarrer")) { if (ImGui.button("Démarrer")) {
this.server.startGame(this.doku); this.server.startGame(this.doku, this.gameDurationMinutes.get() * 60);
} }
if (this.doku == null)
ImGui.endDisabled(); ImGui.endDisabled();
selector.render(); selector.render();
} }
} }
@Override private void renderPlayers() {
public void render() {
ImGui.text("Joueurs :"); ImGui.text("Joueurs :");
{ {
for (Player player : this.client.getGame().getPlayers().values()) { for (Player player : this.client.getGame().getPlayers().values()) {
ImGui.bulletText(player.getPseudo()); ImGui.bulletText(player.getPseudo());
} }
} }
}
private void renderTimer() {
ImGui.inputInt("Temps de la partie (minutes)", gameDurationMinutes);
}
@Override
public void render() {
renderPlayers();
renderGameStatus(); renderGameStatus();
} }

View File

@@ -1,13 +1,15 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import org.polytech.ryuk.gui.Options;
import org.polytech.ryuk.gui.Symbols;
import gui.Options;
import gui.Symbols;
import imgui.ImGui; import imgui.ImGui;
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};
public OptionsMenu(StateMachine stateMachine) { public OptionsMenu(StateMachine stateMachine) {
super(stateMachine); super(stateMachine);
@@ -19,6 +21,9 @@ public class OptionsMenu extends BaseView {
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)){
Options.BackgroundSpeed = backgroundSpeed[0];
}
renderReturnButton(); renderReturnButton();
} }

View File

@@ -1,8 +1,9 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import org.polytech.ryuk.gui.widget.SudokuSelector;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import gui.widget.SudokuSelector;
import imgui.ImGui; import imgui.ImGui;
import sudoku.structure.MultiDoku;
public class SoloMenu extends BaseView { public class SoloMenu extends BaseView {

View File

@@ -1,8 +1,9 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import java.util.Stack; import java.util.Stack;
import gui.Images; import org.polytech.ryuk.gui.AnimatedBackground;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImVec2; import imgui.ImVec2;
import imgui.flag.ImGuiKey; import imgui.flag.ImGuiKey;
@@ -11,9 +12,11 @@ import imgui.flag.ImGuiWindowFlags;
public class StateMachine { public class StateMachine {
private final Stack<BaseView> menus; private final Stack<BaseView> menus;
private final AnimatedBackground background;
public StateMachine() { public StateMachine() {
this.menus = new Stack<>(); this.menus = new Stack<>();
this.background = new AnimatedBackground();
} }
public void clear() { public void clear() {
@@ -27,6 +30,11 @@ public class StateMachine {
menus.add(menu); menus.add(menu);
} }
public void overrideState(BaseView menu) {
menus.getLast().cleanResources();
menus.set(menus.size() - 1, menu);
}
public void popState() { public void popState() {
menus.getLast().cleanResources(); menus.getLast().cleanResources();
menus.pop(); menus.pop();
@@ -40,12 +48,7 @@ public class StateMachine {
public void render() { public void render() {
var displaySize = ImGui.getIO().getDisplaySize(); var displaySize = ImGui.getIO().getDisplaySize();
ImGui.setNextWindowPos(new ImVec2(0.0f, 0.0f)); this.background.render();
ImGui.setNextWindowSize(displaySize);
ImGui.begin("Background", null, ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove
| ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoInputs);
ImGui.image(Images.BACKGROUND, displaySize, new ImVec2(0, 0));
ImGui.end();
ImGui.setNextWindowPos(new ImVec2(0.0f, 0.0f)); ImGui.setNextWindowPos(new ImVec2(0.0f, 0.0f));
ImGui.setNextWindowSize(displaySize); ImGui.setNextWindowSize(displaySize);
ImGui.begin("##Main Window", null, ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove ImGui.begin("##Main Window", null, ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove

View File

@@ -1,16 +1,17 @@
package gui.menu; package org.polytech.ryuk.gui.menu;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import gui.widget.SudokuRenderer; import org.polytech.ryuk.gui.widget.SudokuRenderer;
import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import org.polytech.ryuk.sudoku.solver.BacktrackingSolver;
import org.polytech.ryuk.sudoku.solver.HumanSolver;
import org.polytech.ryuk.sudoku.solver.MixedSolver;
import org.polytech.ryuk.sudoku.solver.Solver;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImGuiStyle; import imgui.ImGuiStyle;
import sudoku.io.SudokuSerializer;
import sudoku.solver.BacktrackingSolver;
import sudoku.solver.HumanSolver;
import sudoku.solver.MixedSolver;
import sudoku.solver.Solver;
import sudoku.structure.MultiDoku;
public class SudokuView extends BaseView { public class SudokuView extends BaseView {

View File

@@ -1,7 +1,8 @@
package gui.widget; package org.polytech.ryuk.gui.widget;
import org.polytech.ryuk.game.Game;
import org.polytech.ryuk.game.Player;
import game.Game;
import game.Player;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImVec2; import imgui.ImVec2;
import imgui.ImVec4; import imgui.ImVec4;
@@ -22,9 +23,12 @@ public class LeaderboardRenderer {
private final ImVec4 cellColorEnemy = new ImVec4(1.0f, 0.0f, 0.0f, 0.5f); private final ImVec4 cellColorEnemy = new ImVec4(1.0f, 0.0f, 0.0f, 0.5f);
private final int maxPlayersShowed = 2; private final int maxPlayersShowed = 2;
private final int emptyCellCount;
public LeaderboardRenderer(Game game, Player player) { public LeaderboardRenderer(Game game, Player player) {
this.game = game; this.game = game;
this.currentPlayer = player; this.currentPlayer = player;
this.emptyCellCount = game.getDoku().getEmptyCells().size();
} }
private void renderRank(int rank) { private void renderRank(int rank) {
@@ -48,7 +52,7 @@ public class LeaderboardRenderer {
ImGui.sameLine(); ImGui.sameLine();
renderName(player.getPseudo()); renderName(player.getPseudo());
ImGui.sameLine(); ImGui.sameLine();
renderScore(player.getScore()); renderScore(emptyCellCount - player.getRemainingCells());
ImGui.endChild(); ImGui.endChild();
ImGui.popStyleColor(3); ImGui.popStyleColor(3);
} }

View File

@@ -0,0 +1,29 @@
package org.polytech.ryuk.gui.widget;
import org.polytech.ryuk.game.Game;
import org.polytech.ryuk.game.Player;
import imgui.ImGui;
import imgui.ImVec2;
public class MultiPlayerCompleteProgress {
private final Game game;
private final int emptyCellCount;
private final ImVec2 progressSize = new ImVec2(700, 50);
private final SmoothProgressBar progressBar;
public MultiPlayerCompleteProgress(Game game) {
this.game = game;
this.emptyCellCount = game.getDoku().getEmptyCells().size();
this.progressBar = new SmoothProgressBar();
}
public void render() {
Player firstPlayer = game.getLeaderboard().getFirst();
ImGui.setCursorPosX(ImGui.getIO().getDisplaySizeX() / 2.0f - progressSize.x / 2.0f);
String progressText = firstPlayer.getPseudo() + " - " + (emptyCellCount - firstPlayer.getRemainingCells()) + "/" + emptyCellCount;
this.progressBar.render(progressText, progressSize, 1.0f - firstPlayer.getRemainingCells() / (float) emptyCellCount);
}
}

View File

@@ -0,0 +1,21 @@
package org.polytech.ryuk.gui.widget;
import imgui.ImGui;
import imgui.ImVec2;
public class SmoothProgressBar {
private float lastProgress = 0;
private final float speed = 2.0f;
private final float clipConstant = 0.001f;
public void render(String label, ImVec2 size, float progress) {
float delta = progress - lastProgress;
if (Math.abs(delta) < clipConstant)
lastProgress = progress;
else
lastProgress = lastProgress + delta * ImGui.getIO().getDeltaTime() * speed;
ImGui.progressBar(lastProgress, size, label);
}
}

View File

@@ -1,4 +1,4 @@
package gui.widget; package org.polytech.ryuk.gui.widget;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -6,24 +6,25 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import common.ConsumerSignal; import org.polytech.ryuk.common.ConsumerSignal;
import common.Signal; import org.polytech.ryuk.common.Signal;
import gui.ColorGenerator; import org.polytech.ryuk.gui.ColorGenerator;
import gui.Fonts; import org.polytech.ryuk.gui.ColorGenerator.Color;
import gui.Options; import org.polytech.ryuk.gui.Fonts;
import gui.RenderableMultidoku; import org.polytech.ryuk.gui.Options;
import gui.Symbols; import org.polytech.ryuk.gui.RenderableMultidoku;
import gui.ColorGenerator.Color; import org.polytech.ryuk.gui.Symbols;
import org.polytech.ryuk.sudoku.constraint.Constraint;
import org.polytech.ryuk.sudoku.structure.Block;
import org.polytech.ryuk.sudoku.structure.Cell;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import org.polytech.ryuk.sudoku.structure.Sudoku;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImVec2; import imgui.ImVec2;
import imgui.ImVec4; import imgui.ImVec4;
import imgui.flag.ImGuiCol; import imgui.flag.ImGuiCol;
import imgui.flag.ImGuiStyleVar; import imgui.flag.ImGuiStyleVar;
import sudoku.constraint.Constraint;
import sudoku.structure.Block;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class SudokuRenderer { public class SudokuRenderer {

View File

@@ -1,19 +1,20 @@
package gui.widget; package org.polytech.ryuk.gui.widget;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import common.ConsumerSignal; import org.polytech.ryuk.common.ConsumerSignal;
import gui.SudokuType; import org.polytech.ryuk.gui.SudokuType;
import org.polytech.ryuk.sudoku.constraint.Constraint;
import org.polytech.ryuk.sudoku.structure.Difficulty;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import org.polytech.ryuk.sudoku.structure.SudokuFactory;
import imgui.ImGui; import imgui.ImGui;
import imgui.extension.imguifiledialog.ImGuiFileDialog; import imgui.extension.imguifiledialog.ImGuiFileDialog;
import imgui.extension.imguifiledialog.flag.ImGuiFileDialogFlags; import imgui.extension.imguifiledialog.flag.ImGuiFileDialogFlags;
import imgui.type.ImBoolean; import imgui.type.ImBoolean;
import imgui.type.ImInt; import imgui.type.ImInt;
import sudoku.constraint.Constraint;
import sudoku.structure.Difficulty;
import sudoku.structure.MultiDoku;
import sudoku.structure.SudokuFactory;
public class SudokuSelector { public class SudokuSelector {

View File

@@ -1,4 +1,4 @@
package gui.widget; package org.polytech.ryuk.gui.widget;
import java.time.Instant; import java.time.Instant;
@@ -8,7 +8,7 @@ public class TimerRenderer {
private final long endTime; private final long endTime;
public TimerRenderer(Instant startTime, int duration) { public TimerRenderer(Instant startTime, long duration) {
this.endTime = startTime.getEpochSecond() + duration; this.endTime = startTime.getEpochSecond() + duration;
} }

View File

@@ -1,11 +1,11 @@
package network; package org.polytech.ryuk.network;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.net.Socket;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
public abstract class Connexion implements PacketVisitor { public abstract class Connexion implements PacketVisitor {

View File

@@ -1,9 +1,9 @@
package network; package org.polytech.ryuk.network;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
public class ConnexionThread extends Thread { public class ConnexionThread extends Thread {

View File

@@ -1,17 +1,18 @@
package network.client; package org.polytech.ryuk.network.client;
import java.io.IOException; import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Random; import java.util.Random;
import common.Signal; import org.polytech.ryuk.common.ConsumerSignal;
import game.Game; import org.polytech.ryuk.common.Signal;
import game.Player; import org.polytech.ryuk.game.Game;
import network.protocol.packets.ChangeCellPacket; import org.polytech.ryuk.game.Player;
import network.protocol.packets.LoginPacket; import org.polytech.ryuk.network.protocol.packets.ChangeCellPacket;
import sudoku.structure.Cell; import org.polytech.ryuk.network.protocol.packets.LoginPacket;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import org.polytech.ryuk.sudoku.structure.Sudoku;
public class Client { public class Client {
private final ClientConnexion clientConnection; private final ClientConnexion clientConnection;
@@ -21,6 +22,7 @@ public class Client {
public final Signal onDisconnect = new Signal(); public final Signal onDisconnect = new Signal();
public final Signal onClosed = new Signal(); public final Signal onClosed = new Signal();
public final Signal onGameStarted = new Signal(); public final Signal onGameStarted = new Signal();
public final ConsumerSignal<Player> onGameEnd = new ConsumerSignal<>();
Player player; Player player;

View File

@@ -1,22 +1,22 @@
package network.client; package org.polytech.ryuk.network.client;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import game.Player; import org.polytech.ryuk.game.Player;
import network.Connexion; import org.polytech.ryuk.network.Connexion;
import network.protocol.packets.ChangeCellPacket; import org.polytech.ryuk.network.protocol.packets.ChangeCellPacket;
import network.protocol.packets.ConnexionInfoPacket; import org.polytech.ryuk.network.protocol.packets.ConnexionInfoPacket;
import network.protocol.packets.DisconnectPacket; import org.polytech.ryuk.network.protocol.packets.DisconnectPacket;
import network.protocol.packets.EndGamePacket; import org.polytech.ryuk.network.protocol.packets.EndGamePacket;
import network.protocol.packets.KeepAlivePacket; import org.polytech.ryuk.network.protocol.packets.KeepAlivePacket;
import network.protocol.packets.LoginPacket; import org.polytech.ryuk.network.protocol.packets.LoginPacket;
import network.protocol.packets.PlayerJoinPacket; import org.polytech.ryuk.network.protocol.packets.PlayerJoinPacket;
import network.protocol.packets.PlayerLeavePacket; import org.polytech.ryuk.network.protocol.packets.PlayerLeavePacket;
import network.protocol.packets.StartGamePacket; import org.polytech.ryuk.network.protocol.packets.StartGamePacket;
import network.protocol.packets.UpdatePlayerScorePacket; import org.polytech.ryuk.network.protocol.packets.UpdatePlayerScorePacket;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.sudoku.io.SudokuSerializer;
public class ClientConnexion extends Connexion { public class ClientConnexion extends Connexion {
@@ -72,22 +72,22 @@ public class ClientConnexion extends Connexion {
@Override @Override
public void visitPacket(StartGamePacket packet) { public void visitPacket(StartGamePacket packet) {
this.client.getGame().startGame(SudokuSerializer.deserializeSudoku(packet.getSerializedSudoku()), this.client.getGame().startGame(SudokuSerializer.deserializeSudoku(packet.getSerializedSudoku()),
packet.getInstant()); packet.getInstant(), packet.getGameDuration());
this.client.onGameStarted.emit(); this.client.onGameStarted.emit();
} }
@Override @Override
public void visitPacket(EndGamePacket packet) { public void visitPacket(EndGamePacket packet) {
// TODO Auto-generated method stub Player winner = this.client.getGame().getLeaderboard().getFirst();
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); this.client.getGame().stopGame();
this.client.onGameEnd.emit(winner);
} }
@Override @Override
public void visitPacket(UpdatePlayerScorePacket packet) { public void visitPacket(UpdatePlayerScorePacket packet) {
Player player = this.client.getGame().getPlayerById(packet.getPlayerId()); Player player = this.client.getGame().getPlayerById(packet.getPlayerId());
assert (player != null); assert (player != null);
this.client.getGame().setPlayerScore(player, packet.getCellsLeft()); this.client.getGame().setPlayerRemainingCells(player, packet.getCellsLeft());
System.out.println("Score for " + player.getPseudo() + " : " + packet.getCellsLeft());
} }
@Override @Override

View File

@@ -1,4 +1,4 @@
package network.protocol; package org.polytech.ryuk.network.protocol;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -0,0 +1,31 @@
package org.polytech.ryuk.network.protocol;
import org.polytech.ryuk.network.protocol.packets.ChangeCellPacket;
import org.polytech.ryuk.network.protocol.packets.ConnexionInfoPacket;
import org.polytech.ryuk.network.protocol.packets.DisconnectPacket;
import org.polytech.ryuk.network.protocol.packets.EndGamePacket;
import org.polytech.ryuk.network.protocol.packets.KeepAlivePacket;
import org.polytech.ryuk.network.protocol.packets.LoginPacket;
import org.polytech.ryuk.network.protocol.packets.PlayerJoinPacket;
import org.polytech.ryuk.network.protocol.packets.PlayerLeavePacket;
import org.polytech.ryuk.network.protocol.packets.StartGamePacket;
import org.polytech.ryuk.network.protocol.packets.UpdatePlayerScorePacket;
public interface PacketVisitor {
default void visit(Packet packet) {
packet.accept(this);
}
void visitPacket(ConnexionInfoPacket packet);
void visitPacket(DisconnectPacket packet);
void visitPacket(KeepAlivePacket packet);
void visitPacket(LoginPacket packet);
void visitPacket(PlayerJoinPacket packet);
void visitPacket(PlayerLeavePacket packet);
void visitPacket(StartGamePacket packet);
void visitPacket(EndGamePacket packet);
void visitPacket(UpdatePlayerScorePacket packet);
void visitPacket(ChangeCellPacket packet);
}

View File

@@ -1,4 +1,4 @@
package network.protocol; package org.polytech.ryuk.network.protocol;
public enum Packets { public enum Packets {

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class ChangeCellPacket extends Packet { public class ChangeCellPacket extends Packet {

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class ConnexionInfoPacket extends Packet { public class ConnexionInfoPacket extends Packet {

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class DisconnectPacket extends Packet { public class DisconnectPacket extends Packet {

View File

@@ -0,0 +1,18 @@
package org.polytech.ryuk.network.protocol.packets;
import org.polytech.ryuk.network.protocol.Packet;
import org.polytech.ryuk.network.protocol.PacketVisitor;
import org.polytech.ryuk.network.protocol.Packets;
public class EndGamePacket extends Packet {
static private final long serialVersionUID = Packets.EndGame.ordinal();
public EndGamePacket() { }
@Override
public void accept(PacketVisitor packetVisitor) {
packetVisitor.visitPacket(this);
}
}

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class KeepAlivePacket extends Packet { public class KeepAlivePacket extends Packet {

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class LoginPacket extends Packet { public class LoginPacket extends Packet {

View File

@@ -1,9 +1,9 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import game.Player; import org.polytech.ryuk.game.Player;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class PlayerJoinPacket extends Packet{ public class PlayerJoinPacket extends Packet{

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class PlayerLeavePacket extends Packet{ public class PlayerLeavePacket extends Packet{

View File

@@ -1,10 +1,10 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import java.time.Instant; import java.time.Instant;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class StartGamePacket extends Packet { public class StartGamePacket extends Packet {
@@ -13,10 +13,12 @@ public class StartGamePacket extends Packet {
private final String serializedSudoku; private final String serializedSudoku;
// used to resume game // used to resume game
private final Instant instant; private final Instant instant;
private final long gameDuration;
public StartGamePacket(String serializedSudoku, Instant instant) { public StartGamePacket(String serializedSudoku, Instant instant, long gameDuration) {
this.serializedSudoku = serializedSudoku; this.serializedSudoku = serializedSudoku;
this.instant = instant; this.instant = instant;
this.gameDuration = gameDuration;
} }
public String getSerializedSudoku() { public String getSerializedSudoku() {
@@ -27,6 +29,10 @@ public class StartGamePacket extends Packet {
return instant; return instant;
} }
public long getGameDuration() {
return gameDuration;
}
@Override @Override
public void accept(PacketVisitor packetVisitor) { public void accept(PacketVisitor packetVisitor) {
packetVisitor.visitPacket(this); packetVisitor.visitPacket(this);

View File

@@ -1,8 +1,8 @@
package network.protocol.packets; package org.polytech.ryuk.network.protocol.packets;
import network.protocol.Packet; import org.polytech.ryuk.network.protocol.Packet;
import network.protocol.PacketVisitor; import org.polytech.ryuk.network.protocol.PacketVisitor;
import network.protocol.Packets; import org.polytech.ryuk.network.protocol.Packets;
public class UpdatePlayerScorePacket extends Packet { public class UpdatePlayerScorePacket extends Packet {

View File

@@ -1,8 +1,8 @@
package network.server; package org.polytech.ryuk.network.server;
import java.util.Random; import java.util.Random;
import network.protocol.packets.KeepAlivePacket; import org.polytech.ryuk.network.protocol.packets.KeepAlivePacket;
public class KeepAliveHandler { public class KeepAliveHandler {

View File

@@ -1,4 +1,4 @@
package network.server; package org.polytech.ryuk.network.server;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
@@ -6,12 +6,14 @@ import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import game.Game; import org.polytech.ryuk.game.Game;
import game.Player; import org.polytech.ryuk.game.Game.GameState;
import network.protocol.Packet; import org.polytech.ryuk.game.Player;
import network.protocol.packets.StartGamePacket; import org.polytech.ryuk.network.protocol.Packet;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.network.protocol.packets.EndGamePacket;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.network.protocol.packets.StartGamePacket;
import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
public class Server { public class Server {
@@ -38,7 +40,16 @@ public class Server {
} }
} }
public void update() { private void checkTimer() {
if (getGame() == null || getGame().getGameState() != GameState.GameGoing)
return;
long now = Instant.now().getEpochSecond();
long end = getGame().getStartTime().getEpochSecond() + getGame().getGameDuration();
if (now > end)
stopGame();
}
private void checkConnexions() {
for (var it = connexions.iterator(); it.hasNext();) { for (var it = connexions.iterator(); it.hasNext();) {
ServerConnexion connexion = it.next(); ServerConnexion connexion = it.next();
if (!connexion.update()) { if (!connexion.update()) {
@@ -49,6 +60,11 @@ public class Server {
} }
} }
public void update() {
checkTimer();
checkConnexions();
}
public void stop() { public void stop() {
this.acceptThread.cancel(); this.acceptThread.cancel();
this.logicThread.cancel(); this.logicThread.cancel();
@@ -69,13 +85,19 @@ public class Server {
return game; return game;
} }
public void startGame(MultiDoku doku) { public void startGame(MultiDoku doku, long gameDuration) {
Instant now = Instant.now(); Instant now = Instant.now();
this.game.startGame(doku, now); this.game.startGame(doku, now, gameDuration);
for (ServerConnexion connexion : this.connexions) { for (ServerConnexion connexion : this.connexions) {
connexion.setSudoku(doku.clone()); connexion.setSudoku(doku.clone());
} }
broadcastPacket(new StartGamePacket(SudokuSerializer.serializeSudoku(doku).toString(), now)); broadcastPacket(new StartGamePacket(SudokuSerializer.serializeSudoku(doku).toString(), now, gameDuration));
}
public void stopGame() {
// we don't need to specify the winner since it has to be the first
broadcastPacket(new EndGamePacket());
getGame().stopGame();
} }
} }

View File

@@ -1,4 +1,4 @@
package network.server; package org.polytech.ryuk.network.server;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;

View File

@@ -1,25 +1,25 @@
package network.server; package org.polytech.ryuk.network.server;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import game.Game; import org.polytech.ryuk.game.Game;
import game.Player; import org.polytech.ryuk.game.Game.GameState;
import game.Game.GameState; import org.polytech.ryuk.game.Player;
import network.Connexion; import org.polytech.ryuk.network.Connexion;
import network.protocol.packets.ChangeCellPacket; import org.polytech.ryuk.network.protocol.packets.ChangeCellPacket;
import network.protocol.packets.ConnexionInfoPacket; import org.polytech.ryuk.network.protocol.packets.ConnexionInfoPacket;
import network.protocol.packets.DisconnectPacket; import org.polytech.ryuk.network.protocol.packets.DisconnectPacket;
import network.protocol.packets.EndGamePacket; import org.polytech.ryuk.network.protocol.packets.EndGamePacket;
import network.protocol.packets.KeepAlivePacket; import org.polytech.ryuk.network.protocol.packets.KeepAlivePacket;
import network.protocol.packets.LoginPacket; import org.polytech.ryuk.network.protocol.packets.LoginPacket;
import network.protocol.packets.PlayerJoinPacket; import org.polytech.ryuk.network.protocol.packets.PlayerJoinPacket;
import network.protocol.packets.PlayerLeavePacket; import org.polytech.ryuk.network.protocol.packets.PlayerLeavePacket;
import network.protocol.packets.StartGamePacket; import org.polytech.ryuk.network.protocol.packets.StartGamePacket;
import network.protocol.packets.UpdatePlayerScorePacket; import org.polytech.ryuk.network.protocol.packets.UpdatePlayerScorePacket;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
public class ServerConnexion extends Connexion { public class ServerConnexion extends Connexion {
@@ -63,7 +63,7 @@ public class ServerConnexion extends Connexion {
for (Player p : this.server.getGame().getPlayers().values()) { for (Player p : this.server.getGame().getPlayers().values()) {
if (p.getId() != player.getId()) { if (p.getId() != player.getId()) {
sendPacket(new PlayerJoinPacket(p)); sendPacket(new PlayerJoinPacket(p));
sendPacket(new UpdatePlayerScorePacket(p.getId(), p.getScore())); sendPacket(new UpdatePlayerScorePacket(p.getId(), p.getRemainingCells()));
} }
} }
@@ -76,7 +76,7 @@ public class ServerConnexion extends Connexion {
setSudoku(game.getDoku().clone()); setSudoku(game.getDoku().clone());
sendPacket( sendPacket(
new StartGamePacket(SudokuSerializer.serializeSudoku(game.getDoku()).toString(), new StartGamePacket(SudokuSerializer.serializeSudoku(game.getDoku()).toString(),
game.getStartTime())); game.getStartTime(), game.getGameDuration()));
} }
} }
@@ -139,22 +139,29 @@ public class ServerConnexion extends Connexion {
} }
if (cell.getSymbolIndex() != Cell.NOSYMBOL && packet.getNewValue() == Cell.NOSYMBOL) { if (cell.getSymbolIndex() != Cell.NOSYMBOL && packet.getNewValue() == Cell.NOSYMBOL) {
cell.empty(); cell.empty();
this.server.getGame().setPlayerScore(player, player.getScore() + 1); this.server.getGame().setPlayerRemainingCells(player, player.getRemainingCells() + 1);
this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getScore())); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells()));
return; return;
} }
// on rajoute un chiffre à la grille // on rajoute un chiffre à la grille
if (cell.trySetValue(packet.getNewValue())) { if (cell.trySetValue(packet.getNewValue())) {
this.server.getGame().setPlayerScore(player, player.getScore() - 1); this.server.getGame().setPlayerRemainingCells(player, player.getRemainingCells() - 1);
this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getScore())); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells()));
}
checkWin();
}
private void checkWin() {
if (this.player.getRemainingCells() == 0) {
this.server.stopGame();
} }
} }
public void setSudoku(MultiDoku doku) { public void setSudoku(MultiDoku doku) {
this.doku = doku; this.doku = doku;
assert (player != null); assert (player != null);
this.server.getGame().setPlayerScore(player, this.doku.getEmptyCells().size()); this.server.getGame().setPlayerRemainingCells(player, this.doku.getEmptyCells().size());
this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getScore())); this.server.broadcastPacket(new UpdatePlayerScorePacket(player.getId(), player.getRemainingCells()));
} }
} }

View File

@@ -1,4 +1,4 @@
package network.server; package org.polytech.ryuk.network.server;
public class ServerLogicThread extends Thread { public class ServerLogicThread extends Thread {
@@ -19,7 +19,7 @@ public class ServerLogicThread extends Thread {
try { try {
Thread.sleep(50); Thread.sleep(50);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// e.printStackTrace(); e.printStackTrace();
break; break;
} }
} }

View File

@@ -1,9 +1,9 @@
/* /*
* This Java source file was generated by the Gradle 'init' task. * This Java source file was generated by the Gradle 'init' task.
*/ */
package sudoku; package org.polytech.ryuk.sudoku;
import sudoku.io.ConsoleInterface; import org.polytech.ryuk.sudoku.io.ConsoleInterface;
public class Main { public class Main {
public String getGreeting() { public String getGreeting() {

View File

@@ -1,7 +1,7 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import sudoku.structure.Block; import org.polytech.ryuk.sudoku.structure.Block;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class BlockConstraint implements IConstraint{ public class BlockConstraint implements IConstraint{

View File

@@ -1,7 +1,7 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class ColumnConstraint implements IConstraint { public class ColumnConstraint implements IConstraint {

View File

@@ -1,8 +1,8 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import java.util.List; import java.util.List;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public enum Constraint { public enum Constraint {

View File

@@ -1,6 +1,6 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class DiagonalConstraint implements IConstraint { public class DiagonalConstraint implements IConstraint {

View File

@@ -1,9 +1,9 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public interface IConstraint { public interface IConstraint {

View File

@@ -1,6 +1,6 @@
package sudoku.constraint; package org.polytech.ryuk.sudoku.constraint;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class LineConstraint implements IConstraint { public class LineConstraint implements IConstraint {

View File

@@ -1,15 +1,15 @@
package sudoku.io; package org.polytech.ryuk.sudoku.io;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Scanner; import java.util.Scanner;
import sudoku.constraint.Constraint; import org.polytech.ryuk.sudoku.constraint.Constraint;
import sudoku.solver.RandomSolver; import org.polytech.ryuk.sudoku.solver.RandomSolver;
import sudoku.structure.Difficulty; import org.polytech.ryuk.sudoku.structure.Difficulty;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
import sudoku.structure.SudokuFactory; import org.polytech.ryuk.sudoku.structure.SudokuFactory;
public class ConsoleInterface { public class ConsoleInterface {
public Scanner reader = new Scanner(System.in); public Scanner reader = new Scanner(System.in);

View File

@@ -0,0 +1,7 @@
package org.polytech.ryuk.sudoku.io;
public class SudokuFile {
}

View File

@@ -1,7 +1,7 @@
package sudoku.io; package org.polytech.ryuk.sudoku.io;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class SudokuPrinter { public class SudokuPrinter {

View File

@@ -1,4 +1,4 @@
package sudoku.io; package org.polytech.ryuk.sudoku.io;
public class SudokuSave { public class SudokuSave {

View File

@@ -1,4 +1,4 @@
package sudoku.io; package org.polytech.ryuk.sudoku.io;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@@ -10,12 +10,11 @@ import java.util.List;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.polytech.ryuk.sudoku.constraint.Constraint;
import sudoku.constraint.Constraint; import org.polytech.ryuk.sudoku.structure.Block;
import sudoku.structure.Block; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
import sudoku.structure.Sudoku;
public class SudokuSerializer { public class SudokuSerializer {

View File

@@ -1,10 +1,10 @@
package sudoku.solver; package org.polytech.ryuk.sudoku.solver;
import java.util.List; import java.util.List;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
public class BacktrackingSolver implements Solver { public class BacktrackingSolver implements Solver {

View File

@@ -1,13 +1,13 @@
package sudoku.solver; package org.polytech.ryuk.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 java.util.logging.Level;
import sudoku.io.SudokuPrinter; import org.polytech.ryuk.sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class HumanSolver implements Solver { public class HumanSolver implements Solver {

View File

@@ -1,14 +1,14 @@
package sudoku.solver; package org.polytech.ryuk.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 java.util.logging.Level;
import sudoku.io.SudokuPrinter; import org.polytech.ryuk.sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class MixedSolver implements Solver{ public class MixedSolver implements Solver{
@@ -17,8 +17,6 @@ public class MixedSolver implements Solver{
* backtracking. * backtracking.
* *
* @param doku MultiDoku, MultiDoku à résoudre. * @param doku MultiDoku, MultiDoku à résoudre.
* @param rand Random, pour tester aléatoirement les symboles, lors du
* backtracking.
* @return boolean, valant true si le MultiDoku est résolu, false sinon. * @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/ */
@Override @Override
@@ -40,28 +38,19 @@ public class MixedSolver implements Solver{
return true; return true;
} }
List<Cell> cellsToFill = doku.getEmptyCells(); Cell cellToFill = doku.getFirstEmptyCell();
if (cellsToFill.isEmpty()) { if (cellToFill == null) {
return false; return false;
} }
// Règles de déduction
for (Cell cellToFill : cellsToFill) {
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols(); List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.size() != 1) {
continue;
}
if (possibleSymbols.size() == 1) {
cellToFill.setSymbolIndex(possibleSymbols.getFirst()); cellToFill.setSymbolIndex(possibleSymbols.getFirst());
if (this.solve(doku)) {
return this.solve(doku); return true;
}
} }
// Si ça ne marche pas
// On fait du backtracking
Cell cellToFill = doku.getRandomEmptyCell(rand);
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
while (!possibleSymbols.isEmpty()) { while (!possibleSymbols.isEmpty()) {
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size()); int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
@@ -71,9 +60,9 @@ public class MixedSolver implements Solver{
if (this.solve(doku)) { if (this.solve(doku)) {
return true; return true;
} }
cellToFill.setSymbolIndex(Cell.NOSYMBOL); cellToFill.setSymbolIndex(Cell.NOSYMBOL);
possibleSymbols.remove(nextPossibleSymbolIndex); possibleSymbols.remove(nextPossibleSymbolIndex);
} }
return false; return false;

View File

@@ -1,14 +1,14 @@
package sudoku.solver; package org.polytech.ryuk.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 java.util.logging.Level;
import sudoku.io.SudokuPrinter; import org.polytech.ryuk.sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
public class RandomSolver implements Solver { public class RandomSolver implements Solver {

View File

@@ -1,10 +1,10 @@
package sudoku.solver; package org.polytech.ryuk.sudoku.solver;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import sudoku.structure.Cell; import org.polytech.ryuk.sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
public interface Solver { public interface Solver {

View File

@@ -1,9 +1,9 @@
package sudoku.solver; package org.polytech.ryuk.sudoku.solver;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import org.polytech.ryuk.sudoku.structure.Sudoku;
/** /**
* Class de test non utilisé * Class de test non utilisé

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
/** /**
* Représente les coordonnées d'une Cell * Représente les coordonnées d'une Cell

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
//TODO: melvyn va passer par //TODO: melvyn va passer par
public enum Difficulty { public enum Difficulty {

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@@ -6,7 +6,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.sudoku.io.SudokuSerializer;
/** /**
* @class MultiDoku * @class MultiDoku
@@ -183,6 +183,15 @@ public class MultiDoku {
return emptyCells.get(randomIndex); return emptyCells.get(randomIndex);
} }
public void clearMutableCells() {
for (Sudoku s : getSubGrids()) {
for (Cell cell : s.getCells()) {
if (cell.isMutable())
cell.clearCurrentSymbol();
}
}
}
public MultiDoku clone() { public MultiDoku clone() {
//TODO: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah //TODO: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah
return SudokuSerializer.deserializeSudoku(SudokuSerializer.serializeSudoku(this)); return SudokuSerializer.deserializeSudoku(SudokuSerializer.serializeSudoku(this));

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

View File

@@ -1,13 +1,10 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import sudoku.constraint.BlockConstraint;
import sudoku.constraint.Constraint;
import sudoku.constraint.IConstraint;
import sudoku.io.SudokuPrinter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.polytech.ryuk.sudoku.constraint.Constraint;
/** /**
* @class Sudoku * @class Sudoku
* @brief Représent un Sudoku * @brief Représent un Sudoku

View File

@@ -1,4 +1,4 @@
package sudoku.structure; package org.polytech.ryuk.sudoku.structure;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -9,10 +9,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import sudoku.constraint.Constraint; import org.polytech.ryuk.sudoku.constraint.Constraint;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import sudoku.solver.RandomSolver; import org.polytech.ryuk.sudoku.solver.RandomSolver;
import sudoku.solver.Solver; import org.polytech.ryuk.sudoku.solver.Solver;
public class SudokuFactory { public class SudokuFactory {
@@ -145,7 +145,7 @@ public class SudokuFactory {
cellsThatCanBeEmptied.remove(cellToEmpty); cellsThatCanBeEmptied.remove(cellToEmpty);
} }
return newDokuFromFilledOne(doku, --nbCellsToEmpty, solver); return false;
} }
/** /**
@@ -181,21 +181,22 @@ public class SudokuFactory {
* @param sudoku2 Sudoku, second sudoku à connecter. * @param sudoku2 Sudoku, second sudoku à connecter.
* @param offset Coordinate, décalage entre les deux Sudokus. * @param offset Coordinate, décalage entre les deux Sudokus.
*/ */
private static void linkSquareSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) { private static void linkRectangleSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) {
int blockWidth = sudoku1.getBlockWidth(); int blockWidth = sudoku1.getBlockWidth();
for (int dx = 0; dx < blockWidth; dx++) { int blockHeight = sudoku1.getSize() / blockWidth;
for (int dx = 0; dx < blockHeight; dx++) {
for (int dy = 0; dy < blockWidth; dy++) { for (int dy = 0; dy < blockWidth; dy++) {
int block1X = dx + offset.getX(); int block1X = dx + offset.getX();
int block1Y = dy + offset.getY(); int block1Y = dy + offset.getY();
int block2X = dx; int block2X = dx;
int block2Y = dy; int block2Y = dy;
if ((block1X < blockWidth) && (block1X >= 0) && (block1Y >= 0) && (block1Y < blockWidth)) { if ((block1X < blockHeight) && (block1X >= 0) && (block1Y >= 0) && (block1Y < blockWidth)) {
Block block1 = sudoku1.getBlocks().get(block1Y * blockWidth + block1X); Block block1 = sudoku1.getBlocks().get(block1Y * blockHeight + block1X);
Block block2 = sudoku2.getBlocks().get(block2Y * blockWidth + block2X); Block block2 = sudoku2.getBlocks().get(block2Y * blockHeight + block2X);
// on remplace le bloc // on remplace le bloc
sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1); sudoku2.getBlocks().set(block2Y * blockHeight + block2X, block1);
block1.getSudokus().add(sudoku2); block1.getSudokus().add(sudoku2);
// on remplace les cellules // on remplace les cellules
@@ -231,10 +232,10 @@ public class SudokuFactory {
Sudoku sudoku4 = createSquareSudoku(size, constraints); Sudoku sudoku4 = createSquareSudoku(size, constraints);
Sudoku sudoku5 = createSquareSudoku(size, constraints); Sudoku sudoku5 = createSquareSudoku(size, constraints);
linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size)); linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size));
linkSquareSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size)); linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size));
linkSquareSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1)); linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1));
linkSquareSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1)); linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1));
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
} }
@@ -263,10 +264,10 @@ public class SudokuFactory {
Sudoku sudoku4 = createRectangleSudoku(width, height, constraints); Sudoku sudoku4 = createRectangleSudoku(width, height, constraints);
Sudoku sudoku5 = createRectangleSudoku(width, height, constraints); Sudoku sudoku5 = createRectangleSudoku(width, height, constraints);
linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - width, 1 - height)); linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - height, 1 - width));
linkSquareSudokus(sudoku1, sudoku3, new Coordinate(width - 1, 1 - height)); linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(height - 1, 1 - width));
linkSquareSudokus(sudoku1, sudoku4, new Coordinate(1 - width, height - 1)); linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - height, width - 1));
linkSquareSudokus(sudoku1, sudoku5, new Coordinate(width - 1, height - 1)); linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(height - 1, width - 1));
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
} }
@@ -276,9 +277,6 @@ public class SudokuFactory {
solver.solve(doku); solver.solve(doku);
int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells());
boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver); boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver);
if (!successfull) {
throw new Exception("Canno't create this doku with this difficulty");
}
doku.setFilledCellsImmutable(); doku.setFilledCellsImmutable();
} }

View File

@@ -1,7 +0,0 @@
package sudoku.io;
public class SudokuFile {
}

View File

@@ -1,14 +0,0 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package sudoku;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
Main classUnderTest = new Main();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}

View File

@@ -8,11 +8,10 @@ import java.util.Random;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import sudoku.io.SudokuSerializer; import org.polytech.ryuk.sudoku.solver.RandomSolver;
import sudoku.solver.RandomSolver; import org.polytech.ryuk.sudoku.structure.MultiDoku;
import sudoku.structure.MultiDoku; import org.polytech.ryuk.sudoku.structure.SudokuFactory;
import sudoku.structure.SudokuFactory;
public class SudokuSerializerTest { public class SudokuSerializerTest {

View File

@@ -1,18 +1,19 @@
package sudoku.solver; package sudoku.solver;
import org.junit.jupiter.api.Test;
import sudoku.io.SudokuPrinter;
import sudoku.io.SudokuSerializer;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
import sudoku.structure.SudokuFactory;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.junit.jupiter.api.Test;
import org.polytech.ryuk.sudoku.io.SudokuPrinter;
import org.polytech.ryuk.sudoku.io.SudokuSerializer;
import org.polytech.ryuk.sudoku.solver.RandomSolver;
import org.polytech.ryuk.sudoku.structure.Cell;
import org.polytech.ryuk.sudoku.structure.MultiDoku;
import org.polytech.ryuk.sudoku.structure.Sudoku;
import org.polytech.ryuk.sudoku.structure.SudokuFactory;
class SolverTest { class SolverTest {
@Test @Test