Merge remote-tracking branch 'origin/UI' into UI

# Conflicts:
#	app/src/main/java/org/toop/app/GameType.java
#	app/src/main/java/org/toop/app/layer/layers/GameLayer.java
This commit is contained in:
Ticho Hidding
2025-10-05 18:22:10 +02:00
55 changed files with 1638 additions and 1143 deletions

2
.idea/misc.xml generated
View File

@@ -13,7 +13,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -1,8 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ResourceBundleManager">
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Arabic.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Georgian.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Hindi.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Japanese.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Korean.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_Russian.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ar.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_de.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_en.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_es.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_fr.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_hi.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_it.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ja.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ka.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ko.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_nl.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ru.properties" />
<file url="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_zh.properties" />
<custom-resource-bundle>
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/Localization.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/Localization_de.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/Localization_es.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/Localization_fr.properties" />
@@ -11,5 +29,21 @@
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/Localization_zh.properties" />
<base-name>localization</base-name>
</custom-resource-bundle>
<custom-resource-bundle>
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ar.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_de.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_en.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_es.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_fr.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_hi.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_it.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ja.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ka.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ko.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_nl.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_ru.properties" />
<file value="file://$PROJECT_DIR$/app/src/main/resources/assets/localization/localization_zh.properties" />
<base-name>localization</base-name>
</custom-resource-bundle>
</component>
</project>

View File

@@ -19,7 +19,11 @@
<artifactId>spotless-maven-plugin</artifactId>
<version>2.46.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.toop</groupId>
<artifactId>pism_framework</artifactId>

View File

@@ -1,23 +1,30 @@
package org.toop.app;
import org.toop.app.canvas.GameCanvas;
import org.toop.app.layer.Layer;
import org.toop.app.layer.layers.MainLayer;
import org.toop.app.layer.layers.QuitLayer;
import org.toop.framework.asset.ResourceManager;
import org.toop.framework.asset.resources.CssAsset;
import org.toop.framework.asset.resources.SettingsAsset;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import org.toop.local.AppContext;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.toop.local.AppSettings;
import java.util.Stack;
public final class App extends Application {
private static Stage stage;
private static StackPane root;
private static int width;
private static Stack<Layer> stack;
private static int height;
private static int width;
private static SettingsAsset settingsAsset;
private static boolean isQuitting;
@@ -27,12 +34,19 @@ public final class App extends Application {
@Override
public void start(Stage stage) throws Exception {
App.stage = stage;
final StackPane root = new StackPane();
App.root = root;
App.stack = new Stack<>();
AppSettings settings = new AppSettings();
settings.applySettings();
final Scene scene = new Scene(root);
scene.getStylesheets().add(ResourceManager.get(CssAsset.class, "app.css").getUrl());
scene.getStylesheets().add(ResourceManager.<CssAsset>get("app.css").getUrl());
stage.setTitle("pism");
stage.setTitle(AppContext.getString("appTitle"));
stage.setWidth(1080);
stage.setHeight(720);
@@ -51,12 +65,14 @@ public final class App extends Application {
App.stage = stage;
App.root = root;
App.stack = new Stack<>();
App.width = (int)stage.getWidth();
App.height = (int)stage.getHeight();
App.width = (int) stage.getWidth();
App.height = (int) stage.getHeight();
App.isQuitting = false;
new EventFlow().addPostEvent(new AudioEvents.StartBackgroundMusic()).asyncPostEvent();
activate(new MainLayer());
}
@@ -67,15 +83,14 @@ public final class App extends Application {
public static void push(Layer layer) {
root.getChildren().addLast(layer.getLayer());
stack.push(layer);
}
public static void pop() {
root.getChildren().removeLast();
isQuitting = false;
}
stack.pop();
public static void pushCanvas(GameCanvas canvas) {
root.getChildren().addLast(canvas.getCanvas());
isQuitting = false;
}
public static void popAll() {
@@ -84,6 +99,8 @@ public final class App extends Application {
for (int i = 0; i < childrenCount; i++) {
root.getChildren().removeLast();
}
stack.removeAllElements();
}
public static void quitPopup() {
@@ -95,6 +112,28 @@ public final class App extends Application {
stage.close();
}
public static int getWidth() { return width; }
public static int getHeight() { return height; }
public static void reloadAll() {
stage.setTitle(AppContext.getString("appTitle"));
for (final Layer layer : stack) {
layer.reload();
}
}
public static void setFullscreen(boolean fullscreen) {
stage.setFullScreen(fullscreen);
width = (int) stage.getWidth();
height = (int) stage.getHeight();
reloadAll();
}
public static int getWidth() {
return width;
}
public static int getHeight() {
return height;
}
}

View File

@@ -0,0 +1,5 @@
package org.toop.app;
public record GameInformation(String[] playerName, boolean[] isPlayerHuman, int[] computerDifficulty,
boolean isConnectionLocal, String serverIP, String serverPort) {
}

View File

@@ -3,31 +3,49 @@ package org.toop.app.canvas;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color;
import java.util.function.Consumer;
public abstract class GameCanvas {
protected record Cell(float x, float y, float width, float height) {}
protected final int width;
protected final int height;
protected record Cell(float x, float y, float width, float height) {
}
protected final Canvas canvas;
protected final GraphicsContext graphics;
protected final Color color;
protected int width;
protected int height;
protected final int rows;
protected final int columns;
protected final int gapSize;
protected final boolean edges;
protected final Cell[] cells;
protected GameCanvas(int width, int height, int rows, int columns, int gapSize) {
final Canvas canvas = new Canvas(width, height);
final GraphicsContext graphics = canvas.getGraphicsContext2D();
protected GameCanvas(Color color, int width, int height, int rows, int columns, int gapSize, boolean edges, Consumer<Integer> onCellClicked) {
canvas = new Canvas(width, height);
graphics = canvas.getGraphicsContext2D();
final Cell[] cells = new Cell[rows * columns];
this.color = color;
final float cellWidth = ((float)width - (rows - 1) * gapSize) / rows;
final float cellHeight = ((float)height - (columns - 1) * gapSize) / columns;
this.width = width;
this.height = height;
this.rows = rows;
this.columns = columns;
this.gapSize = gapSize;
this.edges = edges;
cells = new Cell[rows * columns];
final float cellWidth = ((float) width - (rows - 1) * gapSize) / rows;
final float cellHeight = ((float) height - (columns - 1) * gapSize) / columns;
for (int y = 0; y < columns; y++) {
final float startY = y * cellHeight + y * gapSize;
@@ -39,39 +57,67 @@ public abstract class GameCanvas {
}
canvas.setOnMouseClicked(event -> {
final MouseButton button = event.getButton();
if (button != MouseButton.PRIMARY && button != MouseButton.SECONDARY) {
if (event.getButton() != MouseButton.PRIMARY) {
return;
}
final int column = (int)((event.getX() / width) * rows);
final int row = (int)((event.getY() / height) * columns);
final int column = (int) ((event.getX() / width) * rows);
final int row = (int) ((event.getY() / height) * columns);
event.consume();
onCellClicked(row * rows + column, button == MouseButton.PRIMARY);
onCellClicked.accept(row * rows + column);
});
render();
}
public void clear() {
graphics.clearRect(0, 0, width, height);
}
public void render() {
graphics.setFill(color);
for (int x = 1; x < rows; x++) {
graphics.fillRect(cells[x].x() - gapSize, 0, gapSize, height);
}
for (int y = 1; y < columns; y++) {
graphics.fillRect(0, cells[y * rows].y() - gapSize, width, gapSize);
}
if (edges) {
graphics.fillRect(-gapSize, 0, gapSize, height);
graphics.fillRect(0, -gapSize, width, gapSize);
graphics.fillRect(width - gapSize, 0, gapSize, height);
graphics.fillRect(0, height - gapSize, width, gapSize);
}
}
public void draw(Color color, int cell) {
final float x = cells[cell].x() + gapSize;
final float y = cells[cell].y() + gapSize;
final float width = cells[cell].width() - gapSize * 2;
final float height = cells[cell].height() - gapSize * 2;
graphics.setFill(color);
graphics.fillRect(x, y, width, height);
}
public void resize(int width, int height) {
canvas.setWidth(width);
canvas.setHeight(height);
this.width = width;
this.height = height;
this.canvas = canvas;
this.graphics = graphics;
this.rows = rows;
this.columns = columns;
this.gapSize = gapSize;
this.cells = cells;
clear();
render();
}
protected void clearCell(int cell) {
assert cell >= 0 && cell < cells.length;
graphics.clearRect(cells[cell].x(), cells[cell].y(), cells[cell].width(), cells[cell].height());
public Canvas getCanvas() {
return canvas;
}
protected abstract void onCellClicked(int cell, boolean primary);
public Canvas getCanvas() { return canvas; }
}

View File

@@ -1,30 +1,16 @@
package org.toop.app.canvas;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.game.Game;
import org.toop.game.tictactoe.TicTacToe;
import java.util.function.Consumer;
public class TicTacToeCanvas extends GameCanvas {
private final TicTacToe game;
public TicTacToeCanvas() {
super(App.getHeight(), App.getHeight(), 3, 3, 10);
game = new TicTacToe();
graphics.setFill(Color.CYAN);
for (int x = 1; x < rows; x++) {
graphics.fillRect(cells[x].x() - gapSize, 0, gapSize, height);
public TicTacToeCanvas(Color color, int width, int height, Consumer<Integer> onCellClicked) {
super(color, width, height, 3, 3, 10, false, onCellClicked);
}
for (int y = 1; y < columns; y++) {
graphics.fillRect(0, cells[y * rows].y() - gapSize, width, gapSize);
}
}
public void placeX(int cell) {
graphics.setStroke(Color.ORANGERED);
public void drawX(Color color, int cell) {
graphics.setStroke(color);
graphics.setLineWidth(gapSize);
final float x = cells[cell].x() + gapSize;
@@ -37,8 +23,8 @@ public class TicTacToeCanvas extends GameCanvas {
graphics.strokeLine(x + width, y, x, y + height);
}
public void placeO(int cell) {
graphics.setStroke(Color.DEEPSKYBLUE);
public void drawO(Color color, int cell) {
graphics.setStroke(color);
graphics.setLineWidth(gapSize);
final float x = cells[cell].x() + gapSize;
@@ -49,33 +35,4 @@ public class TicTacToeCanvas extends GameCanvas {
graphics.strokeOval(x, y, width, height);
}
@Override
protected void onCellClicked(int cell, boolean primary) {
for (final Game.Move move : game.getLegalMoves()) {
if (move.position() == cell) {
if (move.value() == 'X') {
placeX(cell);
} else {
placeO(cell);
}
final Game.State state = game.play(move);
if (state == Game.State.WIN) {
for (int i = 0; i < game.board.length; i++) {
if (game.board[i] != move.value()) {
clearCell(i);
}
}
graphics.setFill(Color.GREEN);
graphics.fillRect(cells[4].x(), cells[4].y(), cells[4].width(), cells[4].height());
} else if (state == Game.State.DRAW) {
graphics.setFill(Color.DARKORANGE);
graphics.fillRect(cells[4].x(), cells[4].y(), cells[4].width(), cells[4].height());
}
}
}
}
}

View File

@@ -4,9 +4,5 @@ import org.toop.framework.eventbus.events.EventWithoutSnowflake;
import org.toop.framework.eventbus.events.EventsBase;
public class AppEvents extends EventsBase {
public record OnNodeHover() implements EventWithoutSnowflake {}
public record OnNodeClick() implements EventWithoutSnowflake {}
public record OnLanguageChange(String language) implements EventWithoutSnowflake {}
}

View File

@@ -1,13 +1,14 @@
package org.toop.app.layer;
import org.toop.app.events.AppEvents;
import org.toop.framework.eventbus.GlobalEventBus;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
@@ -18,53 +19,51 @@ public abstract class Container {
public abstract Region getContainer();
public abstract void addNode(Node node);
public abstract void addContainer(Container container, boolean fill);
public void addText(String cssClass, String x, boolean wrap) {
public Text addText(String cssClass, String x, boolean wrap) {
final Text element = new Text(x);
element.getStyleClass().add(cssClass);
if (wrap) {
addNode(new TextFlow(element));
} else { addNode(element); }
} else {
addNode(element);
}
public void addText(String x, boolean wrap) {
addText("text", x, wrap);
return element;
}
public void addButton(String cssClass, String x, Runnable runnable) {
public Text addText(String x, boolean wrap) {
return addText("text", x, wrap);
}
public Label addButton(String cssClass, String x, Runnable runnable) {
final Label element = new Label(x);
element.getStyleClass().add(cssClass);
element.setOnMouseEntered(_ -> {
GlobalEventBus.post(new AppEvents.OnNodeHover());
});
element.setOnMouseClicked(_ -> {
GlobalEventBus.post(new AppEvents.OnNodeClick());
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
runnable.run();
});
addNode(element);
return element;
}
public void addButton(String x, Runnable runnable) {
addButton("button", x, runnable);
public Label addButton(String x, Runnable runnable) {
return addButton("button", x, runnable);
}
public void addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
final Label element = new Label(toggled? x2 : x1);
public Label addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
final Label element = new Label(toggled ? x2 : x1);
element.getStyleClass().add(cssClass);
final BooleanProperty checked = new SimpleBooleanProperty(toggled);
element.setOnMouseEntered(_ -> {
GlobalEventBus.post(new AppEvents.OnNodeHover());
});
element.setOnMouseClicked(_ -> {
GlobalEventBus.post(new AppEvents.OnNodeClick());
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
checked.set(!checked.get());
if (checked.get()) {
@@ -77,18 +76,46 @@ public abstract class Container {
});
addNode(element);
return element;
}
public void addToggle(String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
addToggle("toggle", x1, x2, toggled, consumer);
public Label addToggle(String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
return addToggle("toggle", x1, x2, toggled, consumer);
}
public void addInput(String cssClass, String input, Consumer<String> consumer) {
public Slider addSlider(String cssClass, int max, int initial, Consumer<Integer> consumer) {
final Slider element = new Slider(0, max, initial);
element.getStyleClass().add(cssClass);
element.setMinorTickCount(0);
element.setMajorTickUnit(1);
element.setBlockIncrement(1);
element.setSnapToTicks(true);
element.setShowTickLabels(true);
element.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
element.valueProperty().addListener((_, _, newValue) -> {
consumer.accept(newValue.intValue());
});
addNode(element);
return element;
}
public Slider addSlider(int max, int initial, Consumer<Integer> consumer) {
return addSlider("slider", max, initial, consumer);
}
public TextField addInput(String cssClass, String input, Consumer<String> consumer) {
final TextField element = new TextField(input);
element.getStyleClass().add(cssClass);
element.setOnMouseEntered(_ -> {
GlobalEventBus.post(new AppEvents.OnNodeHover());
element.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
element.textProperty().addListener((_, _, newValue) -> {
@@ -96,9 +123,43 @@ public abstract class Container {
});
addNode(element);
return element;
}
public void addInput(String input, Consumer<String> consumer) {
addInput("input", input, consumer);
public TextField addInput(String input, Consumer<String> consumer) {
return addInput("input", input, consumer);
}
public <T> ChoiceBox<T> addChoiceBox(String cssClass, Consumer<T> consumer) {
final ChoiceBox<T> element = new ChoiceBox<>();
element.getStyleClass().add(cssClass);
element.setOnMouseClicked(_ -> {
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
});
element.valueProperty().addListener((_, _, newValue) -> {
consumer.accept(newValue);
});
addNode(element);
return element;
}
public <T> ChoiceBox<T> addChoiceBox(Consumer<T> consumer) {
return addChoiceBox("choicebox", consumer);
}
public Separator addSeparator(String cssClass, boolean horizontal) {
final Separator element = new Separator(horizontal ? Orientation.HORIZONTAL : Orientation.VERTICAL);
element.getStyleClass().add(cssClass);
element.setMinSize(50, 50);
addNode(element);
return element;
}
public Separator addSeparator(boolean horizontal) {
return addSeparator("separator", horizontal);
}
}

View File

@@ -13,22 +13,17 @@ public abstract class Layer {
protected StackPane layer;
protected Region background;
protected Layer(String cssFile, String backgroundCssClass) {
protected Layer(String cssFile) {
layer = new StackPane();
layer.setPickOnBounds(false);
layer.getStylesheets().add(ResourceManager.get(CssAsset.class, cssFile).getUrl());
layer.getStylesheets().add(ResourceManager.<CssAsset>get(cssFile).getUrl());
background = new Region();
background.getStyleClass().add("background");
background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
background.getStyleClass().add(backgroundCssClass);
layer.getChildren().addLast(background);
}
protected Layer(String cssFile) {
this(cssFile, "background");
}
protected void addContainer(Container container, Pos position, int xOffset, int yOffset, int widthPercent, int heightPercent) {
StackPane.setAlignment(container.getContainer(), position);
@@ -37,11 +32,15 @@ public abstract class Layer {
if (widthPercent > 0) {
container.getContainer().setMaxWidth(widthPercent * widthUnit);
} else { container.getContainer().setMaxWidth(Region.USE_PREF_SIZE); }
} else {
container.getContainer().setMaxWidth(Region.USE_PREF_SIZE);
}
if (heightPercent > 0) {
container.getContainer().setMaxHeight(heightPercent * heightUnit);
} else { container.getContainer().setMaxHeight(Region.USE_PREF_SIZE); }
} else {
container.getContainer().setMaxHeight(Region.USE_PREF_SIZE);
}
container.getContainer().setTranslateX(xOffset * widthUnit);
container.getContainer().setTranslateY(yOffset * heightUnit);
@@ -49,20 +48,12 @@ public abstract class Layer {
layer.getChildren().addLast(container.getContainer());
}
protected void addCanvas(GameCanvas canvas, Pos position, int xOffset, int yOffset, int widthPercent, int heightPercent) {
protected void addGameCanvas(GameCanvas canvas, Pos position, int xOffset, int yOffset) {
StackPane.setAlignment(canvas.getCanvas(), position);
final double widthUnit = App.getWidth() / 100.0;
final double heightUnit = App.getHeight() / 100.0;
if (widthPercent > 0) {
canvas.getCanvas().setWidth(widthPercent * widthUnit);
} else { canvas.getCanvas().setWidth(Region.USE_PREF_SIZE); }
if (heightPercent > 0) {
canvas.getCanvas().setHeight(heightPercent * heightUnit);
} else { canvas.getCanvas().setHeight(Region.USE_PREF_SIZE); }
canvas.getCanvas().setTranslateX(xOffset * widthUnit);
canvas.getCanvas().setTranslateY(yOffset * heightUnit);
@@ -85,8 +76,9 @@ public abstract class Layer {
}
}
public StackPane getLayer() { return layer; }
public Region getBackground() { return background; }
public StackPane getLayer() {
return layer;
}
public abstract void reload();
}

View File

@@ -21,7 +21,9 @@ public final class HorizontalContainer extends Container {
}
@Override
public Region getContainer() { return container; }
public Region getContainer() {
return container;
}
@Override
public void addNode(Node node) {
@@ -51,7 +53,7 @@ public final class HorizontalContainer extends Container {
for (final Node child : children) {
if (child instanceof Region) {
((Region)child).setPrefWidth(widthPerChild);
((Region) child).setPrefWidth(widthPerChild);
}
}
}

View File

@@ -21,7 +21,9 @@ public final class VerticalContainer extends Container {
}
@Override
public Region getContainer() { return container; }
public Region getContainer() {
return container;
}
@Override
public void addNode(Node node) {
@@ -51,7 +53,7 @@ public final class VerticalContainer extends Container {
for (final Node child : children) {
if (child instanceof Region) {
((Region)child).setPrefHeight(heightPerChild);
((Region) child).setPrefHeight(heightPerChild);
}
}
}

View File

@@ -0,0 +1,73 @@
package org.toop.app.layer.layers;
import org.toop.app.App;
import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.HorizontalContainer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.local.AppContext;
import javafx.animation.PauseTransition;
import javafx.animation.TranslateTransition;
import javafx.geometry.Pos;
import javafx.util.Duration;
public final class CreditsLayer extends Layer {
private final int lineHeight = 100;
CreditsLayer() {
super("credits.css");
reload();
}
@Override
public void reload() {
popAll();
final String[] credits = {
AppContext.getString("scrumMaster") + ": Stef",
AppContext.getString("productOwner") + ": Omar",
AppContext.getString("mergeCommander") + ": Bas",
AppContext.getString("localization") + ": Ticho",
AppContext.getString("ai") + ": Michiel",
AppContext.getString("developers") + ": Michiel, Bas, Stef, Omar, Ticho",
AppContext.getString("moralSupport") + ": Wesley",
AppContext.getString("opengl") + ": Omar"
};
final Container creditsContainer = new HorizontalContainer(0);
final Container animatedContainer = new VerticalContainer("animated_credits_container", lineHeight);
creditsContainer.addContainer(animatedContainer, true);
for (final String credit : credits) {
animatedContainer.addText("credit-text", credit, false);
}
final Container controlContainer = new VerticalContainer(5);
controlContainer.addButton(AppContext.getString("back"), () -> {
App.activate(new MainLayer());
});
addContainer(creditsContainer, Pos.CENTER, 0, 0, 50, 100);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
playCredits(animatedContainer, App.getHeight());
}
private void playCredits(Container container, double sceneLength) {
container.getContainer().setTranslateY(-sceneLength);
final TranslateTransition scrollCredits = new TranslateTransition(Duration.seconds(20), container.getContainer());
scrollCredits.setFromY(-sceneLength - lineHeight);
scrollCredits.setToY(sceneLength + lineHeight);
scrollCredits.setOnFinished(_ -> {
final PauseTransition pauseCredits = new PauseTransition(Duration.seconds(3));
pauseCredits.setOnFinished(_ -> playCredits(container, sceneLength));
pauseCredits.play();
});
scrollCredits.play();
}
}

View File

@@ -1,10 +1,12 @@
package org.toop.app.layer.layers;
import org.toop.app.App;
import org.toop.app.GameType;
import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.game.othello.Othello;
import org.toop.game.tictactoe.TicTacToe;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
@@ -19,15 +21,30 @@ public final class MainLayer extends Layer {
popAll();
final Container gamesContainer = new VerticalContainer(5);
gamesContainer.addButton("Tic Tac Toe", () -> { App.activate(new MultiplayerLayer(GameType.TICTACTOE)); });
gamesContainer.addButton("Othello", () -> { App.activate(new MultiplayerLayer(GameType.OTHELLO)); });
gamesContainer.addButton(AppContext.getString("tictactoe"), () -> {
App.activate(new MultiplayerLayer());
});
gamesContainer.addButton(AppContext.getString("othello"), () -> {
App.activate(new MultiplayerLayer());
});
final Container controlContainer = new VerticalContainer(5);
controlContainer.addButton("Credits", () -> {});
controlContainer.addButton("Options", () -> {});
controlContainer.addButton("Quit", () -> { App.quitPopup(); });
addContainer(gamesContainer, Pos.TOP_LEFT, 2, 2, 25, 0);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 25, 0);
controlContainer.addButton(AppContext.getString("credits"), () -> {
App.activate(new CreditsLayer());
});
controlContainer.addButton(AppContext.getString("options"), () -> {
App.activate(new OptionsLayer());
});
controlContainer.addButton(AppContext.getString("quit"), () -> {
App.quitPopup();
});
addContainer(gamesContainer, Pos.TOP_LEFT, 2, 2, 20, 0);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 20, 0);
}
}

View File

@@ -1,22 +1,31 @@
package org.toop.app.layer.layers;
import org.toop.app.App;
import org.toop.app.GameType;
import org.toop.app.canvas.TicTacToeCanvas;
import org.toop.app.GameInformation;
import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.HorizontalContainer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.app.layer.layers.game.TicTacToeLayer;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
public class MultiplayerLayer extends Layer {
boolean isConnectionLocal = true;
public final class MultiplayerLayer extends Layer {
private boolean isConnectionLocal = true;
boolean isPlayer1Human = true;
boolean isPlayer2Human = true;
private boolean isPlayer1Human = true;
private String player1Name = "";
private int computer1Difficulty = 0;
protected MultiplayerLayer(GameType type) {
private boolean isPlayer2Human = true;
private String player2Name = "";
private int computer2Difficulty = 0;
private String serverIP = "";
private String serverPort = "";
public MultiplayerLayer() {
super("multiplayer.css");
reload();
}
@@ -26,64 +35,87 @@ public class MultiplayerLayer extends Layer {
popAll();
final Container mainContainer = new VerticalContainer(5);
mainContainer.addToggle("Local", "Server", !isConnectionLocal, (server) -> {
mainContainer.addToggle(AppContext.getString("local"), AppContext.getString("server"), !isConnectionLocal, (server) -> {
isConnectionLocal = !server;
reload();
});
final Container playersContainer = new HorizontalContainer(50);
mainContainer.addContainer(playersContainer, true);
final Container player1Container = new VerticalContainer("player_container", 5);
playersContainer.addContainer(player1Container, true);
playersContainer.addText("VS", false);
final Container player2Container = new VerticalContainer("player_container", 5);
playersContainer.addContainer(player2Container, true);
if (isConnectionLocal) {
mainContainer.addButton("Start", () -> {});
} else {
mainContainer.addButton("Connnect", () -> { App.activate(new GameLayer()); });
}
mainContainer.addButton(isConnectionLocal? AppContext.getString("start") : AppContext.getString("connect"), () -> {
App.activate(new TicTacToeLayer(new GameInformation(
new String[] { player1Name, player2Name },
new boolean[] { isPlayer1Human, isPlayer2Human },
new int[] { computer1Difficulty, computer2Difficulty },
isConnectionLocal, serverIP, serverPort)));
});
player1Container.addToggle("Human", "Computer", !isPlayer1Human, (computer) -> {
player1Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer1Human, (computer) -> {
isPlayer1Human = !computer;
reload();
});
if (isPlayer1Human) {
player1Container.addText("player is human", true);
player1Container.addText("input player name here: ...", true);
player1Container.addText(AppContext.getString("playerName"), true);
player1Container.addInput(player1Name, (name) -> {
player1Name = name;
});
} else {
player1Container.addText("playing against ai", true);
player1Container.addToggle("Easy", "Hard", false, (hard) -> {});
player1Container.addText(AppContext.getString("computerDifficulty"), true);
player1Container.addSlider(5, computer1Difficulty, (difficulty) -> {
computer1Difficulty = difficulty;
});
}
if (isConnectionLocal) {
player2Container.addToggle("Human", "Computer", !isPlayer2Human, (computer) -> {
player2Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer2Human, (computer) -> {
isPlayer2Human = !computer;
reload();
});
if (isPlayer2Human) {
player2Container.addText("player is human", true);
player2Container.addText("input player name here: ...", true);
player2Container.addText(AppContext.getString("playerName"), true);
player2Container.addInput(player2Name, (name) -> {
player2Name = name;
});
} else {
player2Container.addText("playing against ai", true);
player2Container.addToggle("Easy", "Hard", false, (hard) -> {});
player2Container.addText(AppContext.getString("computerDifficulty"), true);
player2Container.addSlider(5, computer2Difficulty, (difficulty) -> {
computer2Difficulty = difficulty;
});
}
} else {
player2Container.addText("Server IP", true);
player2Container.addInput("", (input) -> {});
player2Container.addText(AppContext.getString("serverIP"), true);
player2Container.addInput(serverIP, (ip) -> {
serverIP = ip;
});
player2Container.addText("Server Port", true);
player2Container.addInput("", (input) -> {});
player2Container.addSeparator(true);
player2Container.addText(AppContext.getString("serverPort"), true);
player2Container.addInput(serverPort, (port) -> {
serverPort = port;
});
}
final Container controlContainer = new VerticalContainer(5);
controlContainer.addButton("Back", () -> { App.activate(new MainLayer()); });
controlContainer.addButton(AppContext.getString("back"), () -> {
App.activate(new MainLayer());
});
addContainer(mainContainer, Pos.CENTER, 0, 0, 75, 75);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);

View File

@@ -0,0 +1,105 @@
package org.toop.app.layer.layers;
import org.toop.app.App;
import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.framework.asset.resources.SettingsAsset;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
import javafx.scene.control.ChoiceBox;
import org.toop.local.AppSettings;
import java.util.Locale;
public final class OptionsLayer extends Layer {
AppSettings appSettings = new AppSettings();
SettingsAsset settings = appSettings.getPath();
private int currentVolume = settings.getVolume();
private boolean isWindowed = !(settings.getFullscreen());
OptionsLayer() {
super("options.css");
reload();
}
@Override
public void reload() {
popAll();
final Container optionsContainer = new VerticalContainer(5);
optionsContainer.addText(AppContext.getString("language"), false);
addLanguageBox(optionsContainer);
optionsContainer.addSeparator(true);
optionsContainer.addText(AppContext.getString("volume"), false);
addVolumeSlider(optionsContainer);
optionsContainer.addSeparator(true);
addFullscreenToggle(optionsContainer);
final Container mainContainer = new VerticalContainer(50);
mainContainer.addText(AppContext.getString("options"), false);
mainContainer.addContainer(optionsContainer, true);
final Container controlContainer = new VerticalContainer(5);
controlContainer.addButton(AppContext.getString("back"), () -> {
App.activate(new MainLayer());
});
addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 60);
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
}
private void addLanguageBox(Container container) {
assert AppContext.getLocalization() != null;
final ChoiceBox<Locale> languageBox = container.addChoiceBox((locale) -> {
if (locale == AppContext.getLocale()) {
return;
}
AppContext.setLocale(locale);
settings.setLocale(locale.toString());
App.reloadAll();
});
for (final Locale localeFile : AppContext.getLocalization().getAvailableLocales()) {
languageBox.getItems().add(localeFile);
}
languageBox.setConverter(new javafx.util.StringConverter<>() {
@Override
public String toString(Locale locale) {
return AppContext.getString(locale.getDisplayName().toLowerCase());
}
@Override
public Locale fromString(String string) {
return null;
}
});
languageBox.setValue(AppContext.getLocale());
}
private void addVolumeSlider(Container container) {
container.addSlider(100, currentVolume, (volume) -> {
currentVolume = volume;
settings.setVolume(volume);
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(volume.doubleValue())).asyncPostEvent();
});
}
private void addFullscreenToggle(Container container) {
container.addToggle(AppContext.getString("windowed"), AppContext.getString("fullscreen"), !isWindowed, (fullscreen) -> {
isWindowed = !fullscreen;
App.setFullscreen(fullscreen);
settings.setFullscreen(fullscreen);
});
}
}

View File

@@ -5,12 +5,13 @@ import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.HorizontalContainer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.local.AppContext;
import javafx.geometry.Pos;
public final class QuitLayer extends Layer {
public QuitLayer() {
super("quit.css", "quit_background");
super("quit.css");
reload();
}
@@ -19,13 +20,19 @@ public final class QuitLayer extends Layer {
popAll();
final Container mainContainer = new VerticalContainer(30);
mainContainer.addText("Are you sure?", false);
mainContainer.addText(AppContext.getString("quitSure"), false);
final Container controlContainer = new HorizontalContainer(30);
mainContainer.addContainer(controlContainer, false);
controlContainer.addButton("Yes", () -> { App.quit(); });
controlContainer.addButton("No", () -> { App.pop(); });
controlContainer.addButton(AppContext.getString("yes"), () -> {
App.quit();
});
controlContainer.addButton(AppContext.getString("no"), () -> {
App.pop();
});
addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 30);
}

View File

@@ -0,0 +1,146 @@
package org.toop.app.layer.layers.game;
import javafx.geometry.Pos;
import javafx.scene.paint.Color;
import org.toop.app.App;
import org.toop.app.GameInformation;
import org.toop.app.canvas.TicTacToeCanvas;
import org.toop.app.layer.Container;
import org.toop.app.layer.Layer;
import org.toop.app.layer.containers.VerticalContainer;
import org.toop.app.layer.layers.MainLayer;
import org.toop.game.Game;
import org.toop.game.tictactoe.TicTacToe;
import org.toop.game.tictactoe.TicTacToeAI;
import org.toop.local.AppContext;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public final class TicTacToeLayer extends Layer {
private TicTacToeCanvas canvas;
private TicTacToe ticTacToe;
private TicTacToeAI ticTacToeAI;
private GameInformation information;
private final BlockingQueue<Game.Move> playerMoveQueue = new LinkedBlockingQueue<>();
public TicTacToeLayer(GameInformation information) {
super("game.css");
canvas = new TicTacToeCanvas(Color.WHITE, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> {
try {
if (information.isConnectionLocal()) {
if (ticTacToe.getCurrentTurn() == 0) {
playerMoveQueue.put(new Game.Move(cell, 'X'));
} else {
playerMoveQueue.put(new Game.Move(cell, 'O'));
}
} else {
if (ticTacToe.getCurrentTurn() == 0) {
// Todo: identify if we are x or o and put in queue
}
}
} catch (InterruptedException e) {
return;
}
});
ticTacToe = new TicTacToe();
ticTacToeAI = new TicTacToeAI();
this.information = information;
if (information.isConnectionLocal()) {
new Thread(this::localGameThread).start();
} else {
new Thread(this::serverGameThread).start();
}
reload();
}
@Override
public void reload() {
popAll();
canvas.resize((App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75);
for (int i = 0; i < ticTacToe.board.length; i++) {
final char value = ticTacToe.board[i];
if (value == 'X') {
canvas.drawX(Color.RED, i);
} else if (value == 'O') {
canvas.drawO(Color.BLUE, i);
}
}
final Container controlContainer = new VerticalContainer(5);
if (information.isPlayerHuman()[0] || information.isConnectionLocal() && information.isPlayerHuman()[1]) {
controlContainer.addButton(AppContext.getString("hint"), () -> {
});
}
controlContainer.addButton(AppContext.getString("back"), () -> {
App.activate(new MainLayer());
});
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
addGameCanvas(canvas, Pos.CENTER, 0, 0);
}
private int compurterDifficultyToDepth(int maxDifficulty, int difficulty) {
return (int) (((float) maxDifficulty / difficulty) * 9);
}
private void localGameThread() {
boolean running = true;
while (running) {
final int currentPlayer = ticTacToe.getCurrentTurn();
Game.Move move = null;
if (information.isPlayerHuman()[currentPlayer]) {
try {
move = playerMoveQueue.take();
} catch (InterruptedException exception) {
return;
}
} else {
move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(5, information.computerDifficulty()[currentPlayer]));
}
assert move != null;
final Game.State state = ticTacToe.play(move);
if (move.value() == 'X') {
canvas.drawX(Color.RED, move.position());
} else if (move.value() == 'O') {
canvas.drawO(Color.BLUE, move.position());
}
if (state != Game.State.NORMAL) {
if (state == Game.State.WIN) {
// Win logic
} else if (state == Game.State.DRAW) {
// Draw logic
}
running = false;
}
}
}
private void serverGameThread() {
boolean running = true;
while (running) {
final int currentPlayer = ticTacToe.getCurrentTurn();
}
}
}

View File

@@ -1,100 +0,0 @@
// package org.toop.app.menu;
//
// import javafx.animation.Interpolator;
// import javafx.animation.PauseTransition;
// import javafx.animation.TranslateTransition;
// import javafx.application.Platform;
// import javafx.geometry.Pos;
// import javafx.scene.control.Button;
// import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane;
// import javafx.scene.layout.VBox;
// import javafx.util.Duration;
// import org.toop.app.App;
// import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext;
// import org.toop.local.LocalizationEvents;
//
// import java.util.Locale;
//
// public final class CreditsMenu extends Menu { ;
// private Locale currentLocale = AppContext.getLocale();
// private LocalizationAsset loc = ResourceManager.get("localization_en_us.properties");
//
// String[] credits = {
// "Scrum Master: Stef",
// "Product Owner: Omar",
// "Merge Commander: Bas",
// "Localization: Ticho",
// "AI: Michiel",
// "Developers: Michiel, Bas, Stef, Omar, Ticho",
// "Moral Support: Wesley (voor 1 week)",
// "OpenGL: Omar"
// };
//
// double scrollDuration = 20.0;
// double lineHeight = 40.0;
//
// public CreditsMenu() {
// VBox creditsBox = new VBox(lineHeight / 2);
// for (int i = credits.length - 1; i >= 0; i--) {
// creditsBox.getChildren().add(createText(credits[i]));
// creditsBox.setAlignment(Pos.CENTER);
// }
//
// Button exit = new Button("<");
// exit.setStyle(
// "-fx-background-color: transparent;" +
// "-fx-text-fill: white;" +
// "-fx-font-size: 72px;" +
// "-fx-padding: 10 20 10 20;"
// );
// exit.setOnAction(e -> App.pop());
//
// final Region background = createBackground();
// StackPane.setAlignment(exit, Pos.TOP_LEFT);
// pane = new StackPane(background, creditsBox, exit);
//
// Platform.runLater(() -> playCredits(creditsBox, 800));
//
// try {
// new EventFlow()
// .listen(this::handleChangeLanguage);
//
// }catch (Exception e){
// System.out.println("Something went wrong while trying to change the language.");
// throw e;
// }
// }
//
// public void playCredits(VBox creditsBox, double sceneLength) {
// double height = (credits.length * lineHeight);
// double startY = -sceneLength;
// double endY = height;
//
// creditsBox.setTranslateY(startY);
//
// TranslateTransition scrollCredits = new TranslateTransition();
// scrollCredits.setNode(creditsBox);
// scrollCredits.setFromY(startY);
// scrollCredits.setToY(endY / 2 - 200);
// scrollCredits.setDuration(Duration.seconds(scrollDuration));
// scrollCredits.setInterpolator(Interpolator.LINEAR);
//
// scrollCredits.setOnFinished(e -> {
// PauseTransition pauseCredits = new PauseTransition(Duration.seconds(5));
// pauseCredits.setOnFinished(a -> playCredits(creditsBox, sceneLength));
// pauseCredits.play();
// });
//
// scrollCredits.play();
// }
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// Platform.runLater(() -> {
// currentLocale = AppContext.getLocale();
// //credits.setText(loc.getString("credits",currentLocale));
// });
// }
// }

View File

@@ -1,66 +0,0 @@
// package org.toop.app.menu;
//
// import javafx.application.Platform;
// import javafx.scene.control.ComboBox;
// import javafx.scene.control.TextField;
// import javafx.scene.layout.HBox;
// import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane;
// import javafx.scene.layout.VBox;
// import org.toop.app.GameType;
// import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext;
//
// import java.util.Locale;
//
// public class GameSelectMenu extends Menu {
// private Locale currentLocale = AppContext.getLocale();
// private final LocalizationAsset loc = ResourceManager.get("localization");
//
// final ComboBox<String> selectedMode, selectedGame;
// final TextField serverIpField;
//
// public GameSelectMenu(GameType type) {
// final Region background = createBackground();
//
// selectedGame = new ComboBox<>();
// selectedGame.getItems().add(GameType.toName(GameType.TICTACTOE));
// selectedGame.getItems().add(GameType.toName(GameType.REVERSI));
// selectedGame.setValue(GameType.toName(type));
//
// selectedMode = new ComboBox<>();
// selectedMode.getItems().add("Local");
// selectedMode.getItems().add("Online");
// selectedMode.setValue("Local");
//
// final HBox selectedContainer = new HBox(10, selectedGame, selectedMode);
//
// serverIpField = new TextField();
// serverIpField.setPromptText(loc.getString("gameSelectMenuEnterIP",currentLocale));
//
// VBox box = new VBox(selectedContainer, serverIpField);
// pane = new StackPane(background, box);
// try {
// new EventFlow()
// .listen(this::handleChangeLanguage);
//
// }catch (Exception e){
// System.out.println("Something went wrong while trying to change the language.");
// throw e;
// }
//
// }
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// Platform.runLater(() -> {
// currentLocale = AppContext.getLocale();
// serverIpField.setPromptText(loc.getString("gameSelectMenuEnterIP",currentLocale));
// selectedGame.getItems().set(0, loc.getString("mainMenuSelectTicTacToe",currentLocale));
// selectedGame.getItems().set(1, loc.getString("mainMenuSelectReversi",currentLocale));
// selectedMode.getItems().set(0, loc.getString("gameSelectMenuLocal",currentLocale));
// selectedMode.getItems().set(1, loc.getString("gameSelectMenuOnline",currentLocale));
// });
//
// }
// }

View File

@@ -1,69 +0,0 @@
// package org.toop.app.menu;
//
// import javafx.application.Platform;
// import org.toop.app.App;
// import org.toop.app.GameType;
//
// import javafx.geometry.Pos;
// import javafx.scene.control.Button;
// import javafx.scene.layout.*;
// import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.eventbus.EventFlow;
// import org.toop.game.tictactoe.TicTacToe;
// import org.toop.local.AppContext;
// import org.toop.local.LocalizationEvents;
//
// import java.util.Locale;
//
// public final class MainMenu extends Menu {
// private Locale currentLocale = AppContext.getLocale();
// private final LocalizationAsset loc = ResourceManager.get("localization");
// private final Button tictactoe,reversi,credits,options,quit;
// public MainMenu() {
// final Region background = createBackground();
//
// tictactoe = createButton(
// loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); });
// reversi = createButton(
// loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); });
//
// final VBox gamesBox = new VBox(10, tictactoe, reversi);
// gamesBox.setAlignment(Pos.TOP_LEFT);
// gamesBox.setPickOnBounds(false);
// gamesBox.setTranslateY(50);
// gamesBox.setTranslateX(25);
//
// credits = createButton(loc.getString("mainMenuSelectCredits",currentLocale), () -> { App.push(new CreditsMenu()); });
// options = createButton(loc.getString("mainMenuSelectOptions",currentLocale), () -> { App.push(new OptionsMenu()); });
// quit = createButton(loc.getString("mainMenuSelectQuit",currentLocale), () -> { App.quitPopup(); });
//
// final VBox controlBox = new VBox(10, credits, options, quit);
// controlBox.setAlignment(Pos.BOTTOM_LEFT);
// controlBox.setPickOnBounds(false);
// controlBox.setTranslateY(-50);
// controlBox.setTranslateX(25);
//
// pane = new StackPane(background, gamesBox, controlBox);
// try {
// new EventFlow()
// .listen(this::handleChangeLanguage);
//
// }catch (Exception e){
// System.out.println("Something went wrong while trying to change the language.");
// throw e;
// }
//
// }
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// Platform.runLater(() -> {
// currentLocale = AppContext.getLocale();
// tictactoe.setText(loc.getString("mainMenuSelectTicTacToe",currentLocale));
// reversi.setText(loc.getString("mainMenuSelectReversi",currentLocale));
// credits.setText(loc.getString("mainMenuSelectCredits",currentLocale));
// options.setText(loc.getString("mainMenuSelectOptions",currentLocale));
// quit.setText(loc.getString("mainMenuSelectQuit",currentLocale));
// });
//
// }
// }

View File

@@ -1,51 +0,0 @@
package org.toop.app.menu;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
public abstract class Menu {
protected Pane pane;
public Pane getPane() { return pane; }
public Region createBackground(String css) {
final Region background = new Region();
background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
background.getStyleClass().add(css);
return background;
}
public Region createBackground() {
return createBackground("background");
}
public Text createText(String css, String x) {
final Text text = new Text(x);
text.getStyleClass().add(css);
return text;
}
public Text createText(String x) {
return createText("text", x);
}
public Button createButton(String css, String x, Runnable runnable) {
final Button button = new Button(x);
button.setOnAction(_ -> {
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
runnable.run();
});
button.getStyleClass().add(css);
return button;
}
public Button createButton(String x, Runnable runnable) {
return createButton("button", x, runnable);
}
}

View File

@@ -1,174 +0,0 @@
// package org.toop.app.menu;
//
// import javafx.geometry.Pos;
// import javafx.scene.control.*;
// import javafx.scene.control.Button;
// import javafx.scene.control.Label;
// import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane;
// import javafx.scene.layout.VBox;
// import org.toop.app.App;
// import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.audio.events.AudioEvents;
// import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext;
//
// import java.awt.*;
// import java.util.Locale;
//
// public final class OptionsMenu extends Menu {
// private Locale currentLocale = AppContext.getLocale();
// private LocalizationAsset loc = ResourceManager.get("localization");
// private GraphicsDevice currentScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0];
//
// public OptionsMenu() {
// final Label selectLanguageLabel = new Label(
// loc.getString("optionsMenuLabelSelectLanguage", currentLocale)
// );
//
// final Button exitOptionsButton = createButton("Exit Options", () -> { App.pop(); } );
//
// final VBox optionsBox = new VBox(10,
// selectLanguageLabel,
// languageSelectorCreation(),
// screenDeviceSelectorCreation(),
// displayModeSelectorCreation(),
// selectFullscreenCreation(),
// volumeSelectorCreation(),
// exitOptionsButton);
//
// optionsBox.setAlignment(Pos.CENTER);
// optionsBox.setPickOnBounds(false);
// optionsBox.setTranslateY(50);
// optionsBox.setTranslateX(25);
//
// pane = new StackPane(optionsBox);
//
// }
//
// private ChoiceBox<Locale> languageSelectorCreation() {
// final ChoiceBox<Locale> selectLanguage = new ChoiceBox<>();
// selectLanguage.setValue(currentLocale);
//
// for (Locale locFile : loc.getAvailableLocales()) {
// selectLanguage.getItems().add(locFile);
// }
//
// selectLanguage.setConverter(new javafx.util.StringConverter<>() {
// @Override
// public String toString(Locale locale) {
// return locale.getDisplayName();
// }
//
// @Override
// public Locale fromString(String string) {
// return null;
// }
// });
//
// selectLanguage.setOnShowing(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// });
//
// selectLanguage.setOnAction(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// Locale selectedLocale = selectLanguage.getSelectionModel().getSelectedItem();
// if (selectedLocale != null) {
// AppContext.setLocale(selectedLocale);
// App.pop();
// App.push(new OptionsMenu());
// }
// });
//
// return selectLanguage;
// }
//
// private ChoiceBox<GraphicsDevice> screenDeviceSelectorCreation() {
// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice[] devices = ge.getScreenDevices();
// final ChoiceBox<GraphicsDevice> selectScreen = new ChoiceBox<>();
// for (GraphicsDevice screen : devices) {
// selectScreen.getItems().add(screen);
// }
//
// selectScreen.setOnShowing(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// });
//
// selectScreen.setOnAction(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// int selectedIndex = selectScreen.getSelectionModel().getSelectedIndex();
// Object selectedItem = selectScreen.getSelectionModel().getSelectedItem();
//
// System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
// System.out.println(" ChoiceBox.getValue(): " + selectScreen.getValue());
// });
// return selectScreen;
// }
//
// private ChoiceBox<DisplayMode> displayModeSelectorCreation() {
// final ChoiceBox<DisplayMode> selectWindowSize = new ChoiceBox<>();
// for (DisplayMode displayMode : currentScreenDevice.getDisplayModes()) {
// selectWindowSize.getItems().add(displayMode);
// }
// selectWindowSize.setOnShowing(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// });
// selectWindowSize.setOnAction(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// int selectedIndex = selectWindowSize.getSelectionModel().getSelectedIndex();
// Object selectedItem = selectWindowSize.getSelectionModel().getSelectedItem();
//
// System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
// System.out.println(" ChoiceBox.getValue(): " + selectWindowSize.getValue());
// });
// return selectWindowSize;
// }
//
// private CheckBox selectFullscreenCreation() {
// final CheckBox setFullscreen = new CheckBox("Fullscreen");
// setFullscreen.setSelected(App.isFullscreen());
// setFullscreen.setOnAction(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// boolean isSelected = setFullscreen.isSelected();
// App.setFullscreen(isSelected);
// });
// return setFullscreen;
// }
//
// private Slider volumeSelectorCreation() {
// Slider volumeSlider = new Slider(0, 100, 50);
// new EventFlow()
// .addPostEvent(AudioEvents.GetCurrentVolume.class)
// .onResponse(AudioEvents.GetCurrentVolumeReponse.class, event -> {
// volumeSlider.setValue(event.currentVolume() * 100);
// }, true).asyncPostEvent();
// volumeSlider.setShowTickLabels(true);
// volumeSlider.setShowTickMarks(true);
// volumeSlider.setMajorTickUnit(25);
// volumeSlider.setMinorTickCount(4);
// volumeSlider.setBlockIncrement(5);
// volumeSlider.setMaxWidth(225);
//
// Label valueLabel = new Label(String.valueOf((int) volumeSlider.getValue()));
//
// final long[] lastPlayed = {0};
// final long cooldown = 50;
// volumeSlider.valueProperty().addListener((obs, oldVal, newVal) -> {
// long now = System.currentTimeMillis();
//
// if (now - lastPlayed[0] >= cooldown) {
// lastPlayed[0] = now;
// // new EventFlow().addPostEvent(new AudioEvents.clickButton())
// // .asyncPostEvent(); // TODO: creates double sound bug, WHYYY????
// }
// valueLabel.setText(String.valueOf(newVal.intValue()));
// new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newVal.doubleValue()/100.0))
// .asyncPostEvent();
// });
//
// return volumeSlider;
// }
//
// }

View File

@@ -1,127 +0,0 @@
// package org.toop.app.menu.game;
//
// import javafx.application.Platform;
// import javafx.geometry.Pos;
// import javafx.scene.canvas.Canvas;
// import javafx.scene.canvas.GraphicsContext;
// import javafx.scene.control.Button;
// import javafx.scene.layout.HBox;
// import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane;
// import javafx.scene.layout.VBox;
// import javafx.scene.text.Text;
// import org.toop.app.App;
// import org.toop.app.menu.MainMenu;
// import org.toop.app.menu.Menu;
// import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext;
//
// import java.util.Locale;
//
// public abstract class GameMenu extends Menu {
// protected final class Cell {
// public float x;
// public float y;
//
// public float width;
// public float height;
//
// public Cell(float x, float y, float width, float height) {
// this.x = x;
// this.y = y;
//
// this.width = width;
// this.height = height;
// }
//
// public boolean check(float x, float y) {
// return x >= this.x && y >= this.y && x <= this.x + width && y <= this.y + height;
// }
// }
//
// protected final int size;
//
// protected final Canvas canvas;
// protected final GraphicsContext graphics;
//
// protected final int rows;
// protected final int columns;
//
// protected final int gapSize;
//
// protected final Cell[] cells;
//
// private Locale currentLocale = AppContext.getLocale();
// private final LocalizationAsset loc = ResourceManager.get("localization");
// private final Button hint,back;
// protected GameMenu(int rows, int columns, int gapSize) {
//
// final int size = Math.min(App.getWidth(), App.getHeight()) / 5 * 4;
//
// final Canvas canvas = new Canvas(size, size);
//
// final GraphicsContext graphics = canvas.getGraphicsContext2D();
//
// this.size = size;
//
// this.canvas = canvas;
// this.graphics = graphics;
//
// this.rows = rows;
// this.columns = columns;
//
// this.gapSize = gapSize;
//
// cells = new Cell[rows * columns];
//
// final float cellWidth = ((float)size - (rows - 1) * gapSize) / rows;
// final float cellHeight = ((float)size - (columns - 1) * gapSize) / rows;
//
// for (int y = 0; y < columns; y++) {
// final float startY = y * cellHeight + y * gapSize;
//
// for (int x = 0; x < rows; x++) {
// final float startX = x * cellWidth + x * gapSize;
// cells[y * rows + x] = new Cell(startX, startY, cellWidth, cellHeight);
// }
// }
//
// final Region background = createBackground();
//
// final Text player1 = createText("player_1", "Player 1");
// final Text player2 = createText("player_2", "Player 2");
//
// final HBox playersContainer = new HBox(100, player1, player2);
// playersContainer.setAlignment(Pos.TOP_CENTER);
// playersContainer.setPickOnBounds(false);
// playersContainer.setTranslateY(50);
//
// hint = createButton(loc.getString("gameMenuHint",currentLocale), () -> {});
// back = createButton(loc.getString("gameMenuBack",currentLocale), () -> { App.activate(new MainMenu()); });
//
// final VBox controlContainer = new VBox(hint, back);
// StackPane.setAlignment(controlContainer, Pos.BOTTOM_LEFT);
// controlContainer.setPickOnBounds(false);
//
// pane = new StackPane(background, canvas, playersContainer, controlContainer);
// try {
// new EventFlow()
// .listen(this::handleChangeLanguage);
//
// }catch (Exception e){
// System.out.println("Something went wrong while trying to change the language.");
// throw e;
// }
//
// }
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// Platform.runLater(() -> {
// currentLocale = AppContext.getLocale();
// hint.setText(loc.getString("gameMenuHint",currentLocale));
// back.setText(loc.getString("gameMenuBack",currentLocale));
// });
//
// }
// }

View File

@@ -1,24 +1,28 @@
package org.toop.local;
import org.toop.app.events.AppEvents;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.asset.ResourceManager;
import org.toop.framework.asset.resources.LocalizationAsset;
import java.util.Locale;
public class AppContext {
private static Locale currentLocale = Locale.getDefault();
private static final LocalizationAsset localization = ResourceManager.get("localization");
private static Locale locale = Locale.forLanguageTag("en");
public static void setLocale(Locale locale) {
currentLocale = locale;
new EventFlow().addPostEvent(new AppEvents.OnLanguageChange(locale.getLanguage())).asyncPostEvent();
public static LocalizationAsset getLocalization() {
return localization;
}
public static void setCurrentLocale(Locale locale) {
currentLocale = locale;
new EventFlow().addPostEvent(new AppEvents.OnLanguageChange(locale.getLanguage())).asyncPostEvent();
public static void setLocale(Locale locale) {
AppContext.locale = locale;
}
public static Locale getLocale() {
return currentLocale;
return locale;
}
public static String getString(String key) {
assert localization != null;
return localization.getString(key, locale);
}
}

View File

@@ -0,0 +1,50 @@
package org.toop.local;
import org.toop.app.App;
import org.toop.framework.asset.resources.SettingsAsset;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.settings.Settings;
import java.io.File;
import java.util.Locale;
public class AppSettings {
private SettingsAsset settingsAsset;
public void applySettings() {
SettingsAsset settings = getPath();
if (!settings.isLoaded()) {
settings.load();
}
Settings settingsData = settings.getContent();
AppContext.setLocale(Locale.of(settingsData.locale));
App.setFullscreen(settingsData.fullScreen);
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(settingsData.volume)).asyncPostEvent();
}
public SettingsAsset getPath() {
if (this.settingsAsset == null) {
String os = System.getProperty("os.name").toLowerCase();
String basePath;
if (os.contains("win")) {
basePath = System.getenv("APPDATA");
if (basePath == null) {
basePath = System.getProperty("user.home");
}
} else if (os.contains("mac")) {
basePath = System.getProperty("user.home") + "/Library/Application Support";
} else {
basePath = System.getProperty("user.home") + "/.config";
}
File settingsFile = new File(basePath + File.separator + "ISY1" + File.separator + "settings.json");
this.settingsAsset = new SettingsAsset(settingsFile);
}
return this.settingsAsset;
}
}

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 KiB

View File

@@ -0,0 +1,47 @@
ai=\u0627\u0644\u0630\u0643\u0627\u0621 \u0627\u0644\u0635\u0646\u0627\u0639\u064a
appTitle=\u0645\u062e\u062a\u0627\u0631 \u0623\u0644\u0639\u0627\u0628 ISY
back=\u0631\u062c\u0648\u0639
computer=\u0627\u0644\u062d\u0627\u0633\u0648\u0628
computerDifficulty=\u0635\u0639\u0648\u0628\u0629 \u0627\u0644\u062d\u0627\u0633\u0648\u0628
connect=\u0627\u062a\u0635\u0644
credits=\u0627\u0644\u0634\u0643\u0631 \u0648\u0627\u0644\u062a\u0642\u062f\u064a\u0631
developers=\u0627\u0644\u0645\u0637\u0648\u0631\u0648\u0646
fullscreen=\u0643\u0627\u0645\u0644 \u0627\u0644\u0634\u0627\u0634\u0629
hint=\u062a\u0644\u0645\u064a\u062d
human=\u0627\u0644\u0625\u0646\u0633\u0627\u0646
language=\u0627\u0644\u0644\u063a\u0629
local=\u0645\u062d\u0644\u064a
localization=\u062a\u0648\u0645\u064a\u0645 \u0627\u0644\u0644\u063a\u0629
mergeCommander=\u0642\u0627\u0626\u062f \u0627\u0644\u062f\u0645\u062c
moralSupport=\u062f\u0639\u0645 \u0645\u0639\u0646\u0648\u064a
no=\u0644\u0627
opengl=OpenGL
options=\u0627\u0644\u062e\u064a\u0627\u0631\u0627\u062a
othello=\u0623\u0648\u062a\u064a\u0644\u0648
playerName=\u0627\u0633\u0645 \u0627\u0644\u0644\u0627\u0639\u0628
productOwner=\u0645\u0627\u0644\u0643 \u0627\u0644\u0645\u0646\u062a\u062c
quit=\u062e\u0631\u0648\u062c
quitSure=\u0647\u0644 \u0623\u0646\u062a \u0645\u062a\u0623\u0643\u062f\u061f
scrumMaster=\u0645\u062f\u064a\u0631 \u0627\u0644\u0633\u0643\u0631\u0645
server=\u062e\u0627\u062f\u0645
serverIP=IP \u0627\u0644\u062e\u0627\u062f\u0645
serverPort=\u0645\u0646\u0641\u0630 \u0627\u0644\u062e\u0627\u062f\u0645
start=\u0627\u0628\u062f\u0623
tictactoe=\u062a\u064a\u0643 \u062a\u0627\u0643 \u062a\u0648
volume=\u0627\u0644\u0635\u0648\u062a
windowed=\u0646\u0627\u0641\u0630\u064a
yes=\u0646\u0639\u0645
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629
chinese=\u4e2d\u6587 (\u0627\u0644\u0635\u064a\u0646\u064a\u0629)
dutch=Nederlands (\u0627\u0644\u0647\u0648\u0644\u0646\u062f\u064a\u0629)
english=English (\u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629)
french=Fran\u00e7ais (\u0627\u0644\u0641\u0631\u0646\u0633\u064a\u0629)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u0627\u0644\u062c\u0648\u0631\u062c\u064a\u0629)
german=Deutsch (\u0627\u0644\u0623\u0644\u0645\u0627\u0646\u064a\u0629)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u0627\u0644\u0647\u0646\u062f\u064a\u0629)
italian=Italiano (\u0627\u0644\u0625\u064a\u0637\u0627\u0644\u064a\u0629)
japanese=\u65e5\u672c\u8a9e (\u0627\u0644\u064a\u0627\u0628\u0627\u0646\u064a\u0629)
korean=\ud55c\uad6d\uc5b4 (\u0627\u0644\u0643\u0648\u0631\u064a\u0629)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u0627\u0644\u0631\u0648\u0633\u064a\u0629)
spanish=Espa\u00f1ol (\u0627\u0644\u0625\u0633\u0628\u0627\u0646\u064a\u0629)

View File

@@ -1,40 +1,47 @@
# Window title
windowTitle=ISY Spiele-Auswahl
ai=K\u00fcnstliche Intelligenz
appTitle=ISY Spieleauswahl
back=Zur\u00fcck
computer=Computer
computerDifficulty=Computerschwierigkeit
connect=Verbinden
credits=Credits
developers=Entwickler
fullscreen=Vollbild
hint=Hinweis
human=Mensch
language=Sprache
local=Lokal
localization=Lokalisierung
mergeCommander=Merge-Kommandant
moralSupport=Mentale Unterst\u00fctzung
no=Nein
opengl=OpenGL
options=Optionen
othello=Othello
playerName=Spielername
productOwner=Produktverantwortlicher
quit=Beenden
quitSure=Bist du dir sicher?
scrumMaster=Scrum Master
server=Server
serverIP=Server-IP
serverPort=Server-Port
start=Start
tictactoe=Tic Tac Toe
volume=Lautst\u00e4rke
windowed=Fenstermodus
yes=Ja
# Main Menu buttons
mainMenuSelectTicTacToe=Tic Tac Toe
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Flottenman\u00F6ver
mainMenuSelectOther=Andere
mainMenuSelectCredits=Credits
mainMenuSelectOptions=Optionen
mainMenuSelectQuit=Beenden
# Quit Menu text and buttons
quitMenuTextSure=Bist du sicher?
quitMenuButtonYes=Ja
quitMenuButtonNo=Nein
# Language menu
languageChangeText=Sprache w\u00E4hlen.
languageEnglish=Englisch
languageDutch=Niederl\u00E4ndisch
languageGerman=Deutsch
languageFrench=Franz\u00F6sisch
languageItalian=Italienisch
languageSpanish=Spanisch
languageChinese=Chinesisch
# Game select menu
gameSelectMenuLocal=Lokal
gameSelectMenuOnline=Online
gameSelectMenuEnterIP=Gib hier deine IP-Adresse ein:
# Game Menu
gameMenuHint=Tipp
gameMenuBack=Zur\u00FCck
# Options menu
optionsMenuLabelSelectLanguage=Sprache:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch)
chinese=\u4e2d\u6587 (Chinesisch)
dutch=Nederlands (Niederl\u00e4ndisch)
english=English (Englisch)
french=Fran\u00e7ais (Franz\u00f6sisch)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgisch)
german=Deutsch
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano (Italienisch)
japanese=\u65e5\u672c\u8a9e (Japanisch)
korean=\ud55c\uad6d\uc5b4 (Koreanisch)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russisch)
spanish=Espa\u00f1ol (Spanisch)

View File

@@ -0,0 +1,47 @@
ai=Artificial Intelligence
appTitle=ISY Games Selector
back=Back
computer=Computer
computerDifficulty=Computer Difficulty
connect=Connect
credits=Credits
developers=Developers
fullscreen=Fullscreen
hint=Hint
human=Human
language=Language
local=Local
localization=Localization
mergeCommander=Merge Commander
moralSupport=Moral Support
no=No
opengl=OpenGL
options=Options
othello=Othello
playerName=Player Name
productOwner=Product Owner
quit=Quit
quitSure=Are you sure?
scrumMaster=Scrum Master
server=Server
serverIP=Server IP
serverPort=Server Port
start=Start
tictactoe=Tic Tac Toe
volume=Volume
windowed=Windowed
yes=Yes
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic)
chinese=\u4e2d\u6587 (Chinese)
dutch=Nederlands (Dutch)
english=English
french=Fran\u00e7ais (French)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgian)
german=Deutsch (German)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano (Italian)
japanese=\u65e5\u672c\u8a9e (Japanese)
korean=\ud55c\uad6d\uc5b4 (Korean)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russian)
spanish=Espa\u00f1ol (Spanish)

View File

@@ -1,39 +0,0 @@
# Window title
windowTitle=ISY Games Selector
# Main Menu buttons
mainMenuSelectTicTacToe=Tic Tac Toe
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Battleship
mainMenuSelectOther=Other
mainMenuSelectCredits=Credits
mainMenuSelectOptions=Options
mainMenuSelectQuit=Quit
# Quit Menu text and buttons
quitMenuTextSure=Are you sure?
quitMenuButtonYes=Yes
quitMenuButtonNo=No
# Language menu
languageChangeText=Choose a language.
languageEnglish=English
languageDutch=Dutch
languageGerman=German
languageFrench=French
languageItalian=Italian
languageSpanish=Spanish
languageChinese=Chinese
# Game select menu
gameSelectMenuLocal=Local
gameSelectMenuOnline=Online
gameSelectMenuEnterIP=Enter your IP address here:
# Game Menu
gameMenuHint=Hint
gameMenuBack=Back
# Options menu
optionsMenuLabelSelectLanguage=Language:

View File

@@ -1,40 +1,47 @@
# Window title
windowTitle=Selector de juegos ISY
ai=Inteligencia Artificial
appTitle=Selector de Juegos ISY
back=Atr\u00e1s
computer=Ordenador
computerDifficulty=Dificultad del Ordenador
connect=Conectar
credits=Cr\u00e9ditos
developers=Desarrolladores
fullscreen=Pantalla completa
hint=Pista
human=Humano
language=Idioma
local=Local
localization=Localizaci\u00f3n
mergeCommander=Comandante de Merge
moralSupport=Apoyo moral
no=No
opengl=OpenGL
options=Opciones
othello=Othello
playerName=Nombre del Jugador
productOwner=Propietario del Producto
quit=Salir
quitSure=\u00BFAst\u00e1s seguro?
scrumMaster=Scrum Master
server=Servidor
serverIP=Servidor-IP
serverPort=Servidor-puerto
start=Iniciar
tictactoe=Tres en Raya
volume=Volumen
windowed=Ventana
yes=S\u00ed
# Main Menu buttons
mainMenuSelectTicTacToe=Tres en raya
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Batalla naval
mainMenuSelectOther=Otros
mainMenuSelectCredits=Cr\u00E9ditos
mainMenuSelectOptions=Opciones
mainMenuSelectQuit=Salir
# Quit Menu text and buttons
quitMenuTextSure=\u00BFEst\u00E1s seguro?
quitMenuButtonYes=S\u00ED
quitMenuButtonNo=No
# Language menu
languageChangeText=Elige un idioma.
languageEnglish=Ingl\u00E9s
languageDutch=Neerland\u00E9s
languageGerman=Alem\u00E1n
languageFrench=Franc\u00E9s
languageItalian=Italiano
languageSpanish=Espa\u00F1ol
languageChinese=Chino
# Game select menu
gameSelectMenuLocal=Local
gameSelectMenuOnline=En l\u00EDnea
gameSelectMenuEnterIP=Introduce aqu\u00ED tu direcci\u00F3n IP:
# Game Menu
gameMenuHint=Pista
gameMenuBack=Atr\u00E1s
# Options menu
optionsMenuLabelSelectLanguage=Idioma:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Ar\u00e1bigo)
chinese=\u4e2d\u6587 (Chino)
dutch=Nederlands (Neerland\u00e9s)
english=English (Ingl\u00e9s)
french=Fran\u00e7ais (Franc\u00e9s)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgiano)
german=Deutsch (Alem\u00e1n)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano (Italiano)
japanese=\u65e5\u672c\u8a9e (Japon\u00e9s)
korean=\ud55c\uad6d\uc5b4 (Coreano)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Ruso)
spanish=Espa\u00f1ol

View File

@@ -1,40 +1,47 @@
# Window title
windowTitle=S\u00E9lecteur de jeux ISY
ai=Intelligence Artificielle
appTitle=S\u00e9lecteur de Jeux ISY
back=Retour
computer=Ordinateur
computerDifficulty=Difficult\u00e9 de l'Ordinateur
connect=Connecter
credits=Cr\u00e9dits
developers=D\u00e9veloppeurs
fullscreen=Plein \u00e9cran
hint=Indice
human=Humain
language=Langue
local=Local
localization=Localisation
mergeCommander=Commandant de Merge
moralSupport=Soutien moral
no=Non
opengl=OpenGL
options=Options
othello=Othello
playerName=Nom du joueur
productOwner=Responsable du produit
quit=Quitter
quitSure=Es-tu s\u00fbr ?
scrumMaster=Scrum Master
server=Serveur
serverIP=Serveur-IP
serverPort=Serveur-Port
start=D\u00e9marrer
tictactoe=Morpion
volume=Volume
windowed=Fen\u00eatre
yes=Oui
# Main Menu buttons
mainMenuSelectTicTacToe=Morpion
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Bataille navale
mainMenuSelectOther=Autres
mainMenuSelectCredits=Cr\u00E9dits
mainMenuSelectOptions=Options
mainMenuSelectQuit=Quitter
# Quit Menu text and buttons
quitMenuTextSure=\u00CAtes-vous s\u00FBr?
quitMenuButtonYes=Oui
quitMenuButtonNo=Non
# Language menu
languageChangeText=Choisissez une langue.
languageEnglish=Anglais
languageDutch=N\u00E9erlandais
languageGerman=Allemand
languageFrench=Fran\u00E7ais
languageItalian=Italien
languageSpanish=Espagnol
languageChinese=Chinois
# Game select menu
gameSelectMenuLocal=Local
gameSelectMenuOnline=En ligne
gameSelectMenuEnterIP=Entrez votre adresse IP ici :
# Game Menu
gameMenuHint=Indice
gameMenuBack=Retour
# Options menu
optionsMenuLabelSelectLanguage=Langue:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabe)
chinese=\u4e2d\u6587 (Chinois)
dutch=Nederlands (N\u00e9erlandais)
english=English (Anglais)
french=Fran\u00e7ais
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (G\u00e9orgien)
german=Deutsch (Allemand)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano (Italien)
japanese=\u65e5\u672c\u8a9e (Japonais)
korean=\ud55c\uad6d\uc5b4 (Cor\u00e9en)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russe)
spanish=Espa\u00f1ol (Espagnol)

View File

@@ -0,0 +1,47 @@
ai=\u092a\u094d\u0930\u0924\u093f\u092a\u094d\u0930\u0923\u093e\u0924\u094d\u092e\u093e\u0928 \u092a\u094d\u0930\u092c\u094d\u0939\u093e\u0935\u0924\u094d\u0924\u093e
appTitle=ISY \u0917\u0947\u092e \u0938\u0947\u0932\u0947\u0915\u094d\u091f\u0930
back=\u092a\u093f\u091a\u093e\u0932
computer=\u0915\u092e\u092a\u094d\u092f\u0942\u091f\u0930
computerDifficulty=\u0915\u092e\u092a\u094d\u092f\u0942\u091f\u0930 \u092a\u094d\u0930\u092f\u093e\u0938
connect=\u091c\u0942\u0921\u094d\u0921 \u0915\u0930\u0947\u0902
credits=\u0916\u094d\u092f\u093e\u0924\u0947
developers=\u0935\u093f\u0915\u0938\u093f\u0915\u0930
fullscreen=\u092a\u0942\u0930\u094d\u0923 \u0938\u0915\u0940\u0928\u093e
hint=\u0938\u0902\u0917\u094d\u0917
human=\u092e\u093e\u0928\u0935
language=\u092d\u093e\u0937\u093e
local=\u0938\u094d\u0925\u093e\u0928\u093f\u092f
localization=\u0938\u094d\u0925\u093e\u0928\u093f\u092f\u0915\u0930\u0923
mergeCommander=\u092e\u0930\u094d\u091c \u0915\u092e\u0902\u0921\u0930
moralSupport=\u0928\u094d\u092e\u093e\u0928\u093f\u0915 \u0938\u092e\u0930\u094d\u0925\u0928
no=\u0928\u0939\u0940\u0902
opengl=OpenGL
options=\u0935\u093f\u0915\u0932\u094d\u092a
othello=\u0913\u0925\u0940\u0932\u094b
playerName=\u0915\u0941\u0930\u093e\u0930\u0940 \u0928\u093e\u092e
productOwner=\u0906\u092f\u0947\u0915\u093e \u092e\u093e\u0932\u093f\u0915
quit=\u0938\u094e\u091c\u094d
quitSure=\u0915\u094d\u092f\u093e \u0915\u094d\u092f\u093e \u091f\u0940\u091f \u0939\u0948\u0902?
scrumMaster=\u0938\u094d\u0915\u094d\u0930\u0941\u092e \u092e\u093e\u0938\u094d\u091f\u0930
server=\u0938\u0930\u094d\u0935\u0930
serverIP=\u0938\u0930\u094d\u0935\u0930 IP
serverPort=\u0938\u0930\u094d\u0935\u0930 \u092a\u094b\u0930\u094d\u091f
start=\u092b\u093f\u0930\u0942
tictactoe=\u091f\u093f\u0915 \u091f\u0948\u0915 \u091f\u094b
volume=\u0935\u0949\u0932\u094d\u092f\u0947\u092e
windowed=\u0915\u094d\u0930\u094d\u0939 \u092e\u0947\u0902
yes=\u0939\u093e\u0907
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0905\u0930\u092c\u0940)
chinese=\u4e2d\u6587 (\u091a\u0940\u0928\u0940)
dutch=Nederlands (\u0921\u091a)
english=English (\u0905\u0902\u0917\u094d\u0930\u0947\u091c\u0940)
french=Fran\u00e7ais (\u092b\u094d\u0930\u0947\u0902\u091a)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u091c\u094d\u091c\u094b\u0930\u094d\u091c\u093f\u092f\u0928)
german=Deutsch (\u091c\u0930\u094d\u092e\u0928)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940
italian=Italiano (\u0907\u091f\u093e\u0932\u093f\u092f\u0928)
japanese=\u65e5\u672c\u8a9e (\u091c\u093e\u092a\u093e\u0928\u0940)
korean=\ud55c\uad6d\uc5b4 (\u0915\u094b\u0930\u093f\u092f\u0928)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u0930\u0942\u0938\u0940)
spanish=Espa\u00f1ol (\u0938\u094d\u092a\u0947\u0928\u093f\u0936)

View File

@@ -1,41 +1,47 @@
# Window title
windowTitle=Selettore giochi ISY
ai=Intelligenza Artificiale
appTitle=Selettore di Giochi ISY
back=Indietro
computer=Computer
computerDifficulty=Difficolt\u00e0 del computer
connect=Connetti
credits=Crediti
developers=Sviluppatori
fullscreen=Schermo intero
hint=Suggerimento
human=Umano
language=Lingua
local=Locale
localization=Localizzazione
mergeCommander=Comandante di Merge
moralSupport=Supporto morale
no=No
opengl=OpenGL
options=Opzioni
othello=Othello
playerName=Nome del giocatore
productOwner=Proprietario del prodotto
quit=Uscire
quitSure=Sei sicuro?
scrumMaster=Scrum Master
server=Server
serverIP=Server-IP
serverPort=Porta del server
start=Inizia
tictactoe=Tic Tac Toe
volume=Volume
windowed=Finestra
yes=S\u00ec
# Main Menu buttons
mainMenuSelectTicTacToe=Tris
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Battaglia navale
mainMenuSelectOther=Altro
mainMenuSelectCredits=Crediti
mainMenuSelectOptions=Opzioni
mainMenuSelectQuit=Esci
# Quit Menu text and buttons
quitMenuTextSure=Sei sicuro?
quitMenuButtonYes=S\u00EC
quitMenuButtonNo=No
# Language menu
languageChangeText=Scegli una lingua.
languageEnglish=Inglese
languageDutch=Olandese
languageGerman=Tedesco
languageFrench=Francese
languageItalian=Italiano
languageSpanish=Spagnolo
languageChinese=Cinese
# Game select menu
gameSelectMenuLocal=Locale
gameSelectMenuOnline=Online
gameSelectMenuEnterIP=Inserisci qui il tuo indirizzo IP:
# Game Menu
gameMenuHint=Suggerimento
gameMenuBack=Indietro
# Options menu
optionsMenuLabelSelectLanguage=Lingua:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabo)
chinese=\u4e2d\u6587 (Cinese)
dutch=Nederlands (Olandese)
english=English (Inglese)
french=Fran\u00e7ais (Francese)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgiano)
german=Deutsch (Tedesco)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano
japanese=\u65e5\u672c\u8a9e (Giapponese)
korean=\ud55c\uad6d\uc5b4 (Coreano)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russo)
spanish=Espa\u00f1ol (Spagnolo)

View File

@@ -0,0 +1,47 @@
ai=\u4eba\u5de5\u77e5\u80fd
appTitle=ISY \u30b2\u30fc\u30e0\u30bb\u30ec\u30af\u30bf\u30fc
back=\u623b\u308b
computer=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc
computerDifficulty=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u96e3\u6613\u5ea6
connect=\u63a5\u7d9a
credits=\u30af\u30ec\u30b8\u30c3\u30c8
developers=\u958b\u767a\u8005
fullscreen=\u5168\u753b\u9762
hint=\u30d2\u30f3\u30c8
human=\u4eba\u9593
language=\u8a00\u8a9e
local=\u5730\u57df
localization=\u30ed\u30fc\u30ab\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3
mergeCommander=\u30de\u30fc\u30b8\u30b3\u30de\u30f3\u30c0\u30fc
moralSupport=\u6c17\u529b\u652f\u63f4
no=\u3044\u3044\u3048
opengl=OpenGL
options=\u30aa\u30d7\u30b7\u30e7\u30f3
othello=\u30aa\u30bb\u30ed
playerName=\u30d7\u30ec\u30a4\u30e4\u30fc\u540d
productOwner=\u30d7\u30ed\u30c0\u30af\u30c8\u30aa\u30fc\u30ca\u30fc
quit=\u7d42\u4e86
quitSure=\u672c\u5f53\u306b\u7d42\u4e86\u3057\u307e\u3059\u304b\uff1f
scrumMaster=\u30b9\u30af\u30e9\u30e0\u30de\u30b9\u30bf\u30fc
server=\u30b5\u30fc\u30d0\u30fc
serverIP=\u30b5\u30fc\u30d0\u30fc IP
serverPort=\u30b5\u30fc\u30d0\u30fc \u30dd\u30fc\u30c8
start=\u59cb\u307e\u308a
tictactoe=\u30bf\u30a4\u30af\u30bf\u30c3\u30c8\u30c8\u30a6
volume=\u30dc\u30ea\u30e5\u30fc\u30e0
windowed=\u30a6\u30a3\u30f3\u30c9\u30a6
yes=\u306f\u3044
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u30a2\u30e9\u30d3\u30a2\u8a9e)
chinese=\u4e2d\u6587 (\u4e2d\u6587)
dutch=Nederlands (\u30aa\u30e9\u30f3\u30c0\u8a9e)
english=English (\u82f1\u8a9e)
french=Fran\u00e7ais (\u30d5\u30e9\u30f3\u30b9\u8a9e)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u30b0\u30eb\u30b8\u30a2\u8a9e)
german=Deutsch (\u30c9\u30a4\u30c4\u8a9e)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u30d2\u30f3\u30c7\u30a3\u8a9e)
italian=Italiano (\u30a4\u30bf\u30ea\u30a2\u8a9e)
japanese=\u65e5\u672c\u8a9e
korean=\ud55c\uad6d\uc5b4 (\u97d3\u56fd\u8a9e)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u30ed\u30b7\u30a2\u8a9e)
spanish=Espa\u00f1ol (\u30b9\u30da\u30a4\u30f3\u8a9e)

View File

@@ -0,0 +1,47 @@
ai=\u10e1\u10d0\u10e0\u10d7\u10d5\u10d4\u10d9\u10d8 \u10d8\u10e0\u10d5\u10d5\u10e0\u10d8\u10d2\u10d4\u10d1\u10d0
appTitle=ISY \u10d2\u10d4\u10db\u10d3\u10d8 \u10e1\u10d4\u10da\u10d4\u10ea\u10d9\u10d4\u10da\u10d0
back=\u10db\u10d0\u10d2\u10d0\u10dc\u10d0
computer=\u10e2\u10d0\u10db\u10d7\u10d8\u10d2\u10d3\u10d0\u10e0\u10d8
computerDifficulty=\u10e8\u10d0\u10d5\u10d0\u10e0\u10d8 \u10e2\u10d0\u10db\u10d7\u10d8\u10d2\u10d3\u10d0\u10e0\u10d8
connect=\u10d7\u10d0\u10db\u10d0\u10d4\u10e0\u10d7\u10d8
credits=\u10d9\u10d0\u10e0\u10d4\u10d3\u10d0\u10e0\u10d8
developers=\u10db\u10d0\u10e0\u10e3\u10d1\u10d7\u10d0\u10ea\u10d4\u10da\u10d8
fullscreen=\u10e1\u10d0\u10e5\u10d8 \u10d8\u10e0\u10e2\u10d8\u10d5\u10d0\u10e0\u10d8
hint=\u10db\u10d8\u10e0\u10d7\u10d4\u10da\u10d8
human=\u10db\u10d4\u10db\u10d0\u10dc\u10d8
language=\u10dc\u10d0\u10db\u10d0
local=\u10db\u10d4\u10e0\u10d7\u10d4\u10da\u10d0\u10e0\u10d8
localization=\u10d0\u10e1\u10d5\u10e0\u10d0\u10e2\u10d4\u10da\u10d0\u10e0\u10d8
mergeCommander=\u10db\u10d4\u10e0\u10d7\u10d4\u10da\u10d8 \u10d9\u10d0\u10dc\u10d3\u10d0\u10e0\u10d8
moralSupport=\u10db\u10d0\u10e0\u10d4\u10dc\u10d8 \u10d3\u10d0\u10db\u10d4\u10d4\u10da\u10d4\u10da\u10d0
no=\u10dc\u10d4
opengl=OpenGL
options=\u10e3\u10e0\u10d5\u10d4\u10da\u10d8
othello=\u10d0\u10e2\u10e5\u10d4\u10da\u10d8
playerName=\u10dc\u10d0\u10e0\u10d4 \u10db\u10d0\u10e5\u10d3\u10d0\u10e0\u10d8
productOwner=\u10db\u10d0\u10e0\u10e3\u10d1\u10d7\u10d0\u10e0\u10d8 \u10db\u10d0\u10dc\u10e2\u10d0\u10e0\u10d8
quit=\u10db\u10d0\u10e0\u10d7\u10d4\u10da\u10d8
quitSure=\u10ec\u10d7\u10d0 \u10db\u10d0\u10e0 \u10db\u10d0\u10e0\u10d7\u10d4\u10da\u10d8?
scrumMaster=\u10e1\u10e0\u10d9\u10d3 \u10db\u10d0\u10e1\u10d7\u10d0\u10e0\u10d8
server=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8
serverIP=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8 IP
serverPort=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8 \u10e2\u10dd\u10e0\u10d7\u10d0
start=\u10e0\u10d0\u10d3\u10d4\u10e1
tictactoe=\u10e2\u10d8\u10d9\u10d8 \u10e2\u10d8\u10e9\u10d8 \u10e2\u10d8
volume=\u10d7\u10d0\u10e7\u10d8
windowed=\u10e1\u10d0\u10db\u10d7\u10d8
yes=\u10d3\u10d0
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u10d0\u10e0\u10d0\u10d1\u10d8\u10d1\u10d3\u10d3\u10d4\u10da\u10d8)
chinese=\u4e2d\u6587 (\u10d9\u10d8\u10e2\u10d8\u10e1\u10d8)
dutch=Nederlands (\u10db\u10d4\u10d3\u10d0\u10da\u10d0\u10dc\u10d3\u10d8)
english=English (\u10d2\u10d0\u10e0\u10d7\u10d8\u10e1\u10d8)
french=Fran\u00e7ais (\u10e4\u10e0\u10d0\u10dc\u10d9\u10e3\u10e1\u10d8)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8
german=Deutsch (\u10db\u10d4\u10db\u10d4\u10e6\u10d8)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u10f0\u10d4\u10dc\u10d3\u10d8)
italian=Italiano (\u10d7\u10d4\u10ea\u10d0\u10da\u10d8)
japanese=\u65e5\u672c\u8a9e (\u10d9\u10d0\u10e7\u10d0\u10dc\u10d8)
korean=\ud55c\uad6d\uc5b4 (\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u10e0\u10e3\u10e1\u10e1\u10d8\u10d5\u10d4\u10d1\u10d8)
spanish=Espa\u00f1ol (\u10e1\u10da\u10d0\u10dc\u10d8)

View File

@@ -0,0 +1,47 @@
ai=\uc778\uacf5 \uc9c0\ub2a5
appTitle=ISY \uac8c\uc784 \uc120\ud0dd\uae30
back=\ub4a4\ub85c
computer=\uce74\ud14c\uae4c
computerDifficulty=\uce74\ud14c\uae4c \ub2e8\uacc4
connect=\uc5f0\uacb0
credits=\uac10\uc0ac
developers=\uac1c\ubc1c\uc790
fullscreen=\uc804\uccb4 \ud654\uba74
hint=\ud78c\ud2b8
human=\uc778\uac04
language=\uc5b8\uc5b4
local=\ub85c\uceec
localization=\uc5b8\uc5b4\ud654
mergeCommander=\uba54\uc9c0 \ucea0\ub9ac\ub354
moralSupport=\uc815\uc2e0\uc801 \uc9c0\uc6d0
no=\uc544\ub2c8\uc624
opengl=OpenGL
options=\uc635\uc158
othello=\uc624\ud14c\ub85c
playerName=\ud50c\ub808\uc774\uc5b4 \uc774\ub984
productOwner=\uc81c\ud488 \uad00\ub9ac\uc790
quit=\uc885\ub8cc
quitSure=\uc815\ub9d0 \uc885\ub8cc\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
scrumMaster=\uc2a4\ud06c\ub7fc \ub9c8\uc2a4\ud130
server=\uc11c\ubc84
serverIP=\uc11c\ubc84 IP
serverPort=\uc11c\ubc84 \ud3ec\ud2b8
start=\uc2dc\uc791
tictactoe=\ud2f0\ud06c\ud0d0\ud1a0
volume=\ubcf4\ub7ec\uc6b4
windowed=\ucc3d \ubaa8\ub4dc
yes=\ub124
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0639\u0631\u0628\u064a\u0629)
chinese=\u4e2d\u6587 (\u4e2d\u6587)
dutch=Nederlands (\ub3c4\ucc99)
english=English (\uc601\uad6d\uc5b4)
french=Fran\u00e7ais (\ud504\ub791\uc81c\uc2a4\ucf54)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\uac8c\uc774\uc874)
german=Deutsch (\ub3c4\ucf54)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\ud567\ub9ac)
italian=Italiano (\uc774\ud0c0\ub9ac\uc5b4\ub098)
japanese=\u65e5\u672c\u8a9e (\uc65c\uc790\ub9ac\uc5b4)
korean=\ud55c\uad6d\uc5b4
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\ub85c\uc6b0\uc2a4\uc544\uc774\ucf58)
spanish=Espa\u00f1ol (\uc2a4\ud398\ub974\uc2a4\uc544\uc774\ucf58)

View File

@@ -1,40 +1,47 @@
# Window title
windowTitle=ISY Spellen Kiezer
ai=Kunstmatige Intelligentie
appTitle=ISY Spel Kiezer
back=Terug
computer=Computer
computerDifficulty=Computermoeilijkheid
connect=Verbinden
credits=Credits
developers=Ontwikkelaars
fullscreen=Volledig scherm
hint=Hint
human=Mens
language=Taal
local=Lokaal
localization=Lokalisatie
mergeCommander=Merge-commandant
moralSupport=Moraalsteun
no=Nee
opengl=OpenGL
options=Opties
othello=Othello
playerName=Spelernaam
productOwner=Producteigenaar
quit=Afsluiten
quitSure=Weet je het zeker?
scrumMaster=Scrum Master
server=Server
serverIP=Server-IP
serverPort=Serverpoort
start=Start
tictactoe=Boter Kaas en Eieren
volume=Volume
windowed=Venstermodus
yes=Ja
# Main Menu buttons
mainMenuSelectTicTacToe=Boter Kaas En Eieren
mainMenuSelectReversi=Reversi
mainMenuSelectSudoku=Sudoku
mainMenuSelectBattleship=Zeeslag
mainMenuSelectOther=Anders
mainMenuSelectCredits=Credits
mainMenuSelectOptions=Opties
mainMenuSelectQuit=Afsluiten
# Quit Menu text and buttons
quitMenuTextSure=Weet je het zeker?
quitMenuButtonYes=Ja
quitMenuButtonNo=Nee
# Language menu
languageChangeText=Kies een taal.
languageEnglish=Engels
languageDutch=Nederlands
languageGerman=Duits
languageFrench=Frans
languageItalian=Italiaans
languageSpanish=Spaans
languageChinese=Chinees
# Game select menu
gameSelectMenuLocal=Lokaal
gameSelectMenuOnline=Online
gameSelectMenuEnterIP=Voer hier je IP-adres in:
# Game Menu
gameMenuHint=Hint
gameMenuBack=Terug
# Options menu
optionsMenuLabelSelectLanguage=Taal:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch)
chinese=\u4e2d\u6587 (Chinees)
dutch=Nederlands
english=English (Engels)
french=Fran\u00e7ais (Frans)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgisch)
german=Deutsch (Duits)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi)
italian=Italiano (Italiaans)
japanese=\u65e5\u672c\u8a9e (Japans)
korean=\ud55c\uad6d\uc5b4 (Koreaans)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russisch)
spanish=Espa\u00f1ol (Spaans)

View File

@@ -0,0 +1,47 @@
ai=\u0418\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442
appTitle=ISY \u0412\u044b\u0431\u043e\u0440 \u0438\u0433\u0440
back=\u041d\u0430\u0437\u0430\u0434
computer=\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440
computerDifficulty=\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430
connect=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f
credits=\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438
developers=\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438
fullscreen=\u041f\u043e\u043b\u043d\u043e\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c
hint=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430
human=\u0427\u0435\u043b\u043e\u0432\u0435\u043a
language=\u042f\u0437\u044b\u043a
local=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439
localization=\u041b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
mergeCommander=\u041a\u043e\u043c\u0430\u043d\u0434\u0435\u0440 \u0441\u043b\u0438\u044f\u043d\u0438\u044f
moralSupport=\u041c\u043e\u0440\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430
no=\u041d\u0435\u0442
opengl=OpenGL
options=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
othello=\u041e\u0442\u0435\u043b\u043b\u043e
playerName=\u0418\u043c\u044f \u0438\u0433\u0440\u043e\u043a\u0430
productOwner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430
quit=\u0412\u044b\u0445\u043e\u0434
quitSure=\u0423\u0432\u0435\u0440\u0435\u043d\u044b \u043b\u0438?
scrumMaster=\u041c\u0430\u0441\u0442\u0435\u0440 Scrum
server=\u0421\u0435\u0440\u0432\u0435\u0440
serverIP=\u0418\u043f\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
serverPort=\u041f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
start=\u0421\u0442\u0430\u0440\u0442
tictactoe=\u041a\u0440\u0435\u0441\u0442\u0438\u043a\u0438
volume=\u0413\u0440\u0430\u043c\u043c\u043e\u0444\u043e\u043d
windowed=\u041e\u043a\u043d\u043e
yes=\u0414\u0430
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0410\u0440\u0430\u0431\u0441\u043a\u0438\u0439)
chinese=\u4e2d\u6587 (\u041a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439)
dutch=Nederlands (\u041d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u0441\u043a\u0438\u0439)
english=English (\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439)
french=Fran\u00e7ais (\u0424\u0440\u0430\u043d\u0446\u0443\u0437\u0441\u043a\u0438\u0439)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u0413\u0440\u0443\u0437\u0438\u043d\u0441\u043a\u0438\u0439)
german=Deutsch (\u041d\u0435\u043c\u0435\u0446\u043a\u0438\u0439)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u0425\u0438\u043d\u0434\u0438)
italian=Italiano (\u0418\u0442\u0430\u043b\u044c\u044f\u043d\u0441\u043a\u0438\u0439)
japanese=\u65e5\u672c\u8a9e (\u042f\u043f\u043e\u043d\u0441\u043a\u0438\u0439)
korean=\ud55c\uad6d\uc5b4 (\u041a\u043e\u0440\u0435\u0439\u0441\u043a\u0438\u0439)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439
spanish=Espa\u00f1ol (\u0418\u0441\u043f\u0430\u043d\u0441\u043a\u0438\u0439)

View File

@@ -1,52 +1,47 @@
# suppress inspection "LossyEncoding" for whole file
# Window title
windowTitle=ISY \u6E38\u620F\u9009\u62E9\u5668
# ?????
ai=\u4eba\u5de5\u667a\u80fd
appTitle=ISY \u6e38\u620f\u9009\u62e9\u5668
back=\u8fd4\u56de
computer=\u8ba1\u7b97\u673a
computerDifficulty=\u8ba1\u7b97\u673a\u96be\u5ea6
connect=\u8fde\u63a5
credits=\u6b23\u8d4f
developers=\u5f00\u53d1\u8005
fullscreen=\u5168\u5c4f
hint=\u63d0\u793a
human=\u4eba
language=\u8bed\u8a00
local=\u672c\u5730
localization=\u6d88\u606f\u5c55\u793a / \u672c\u5730\u5316
mergeCommander=Merge \u63a7\u4e3b
moralSupport=\u795e\u7cbe\u652f\u6301
no=\u5426
opengl=OpenGL
options=\u9009\u9879
othello=Othello
playerName=\u73a9\u5bb6\u540d\u79f0
productOwner=\u54c1\u76d8\u4ea7\u54c1\u4eba
quit=\u9000\u51fa
quitSure=\u4f60\u786e\u5b9a\u5417?
scrumMaster=Scrum \u4f1a\u5458
server=\u670d\u52a1\u5668
serverIP=\u670d\u52a1\u5668 IP
serverPort=\u670d\u52a1\u5668 \u7aef\u53e3
start=\u5f00\u59cb
tictactoe=Tic Tac Toe
volume=\u97f3\u91cf
windowed=\u7a97\u53e3\u6a21\u5f0f
yes=\u662f
# Main Menu buttons
mainMenuSelectTicTacToe=\u4E95\u5B57\u68CB
# ???
mainMenuSelectReversi=\u9ED1\u767D\u68CB
# ???
mainMenuSelectSudoku=\u6570\u72EC
# ??
mainMenuSelectBattleship=\u6D77\u6218\u68CB
# ???
mainMenuSelectOther=\u5176\u4ED6
# ??
mainMenuSelectCredits=\u5236\u4F5C\u4EBA\u5458
# ????
mainMenuSelectOptions=\u9009\u9879
# ??
mainMenuSelectQuit=\u9000\u51FA
# ??
# Quit Menu text and buttons
quitMenuTextSure=\u4F60\u786E\u5B9A\u5417\uFF1F
# ?????
quitMenuButtonYes=\u662F
# ?
quitMenuButtonNo=\u5426
# ?
# Language menu
languageChangeText=\u9009\u62E9\u4E00\u79CD\u8BED\u8A00\u3002
languageEnglish=\u82F1\u8BED
languageDutch=\u8377\u5170\u8BED
languageGerman=\u5FB7\u8BED
languageFrench=\u6CD5\u8BED
languageItalian=\u610F\u5927\u5229\u8BED
languageSpanish=\u897F\u73ED\u7259\u8BED
languageChinese=\u4E2D\u6587
# Game select menu
gameSelectMenuLocal=\u672C\u5730
gameSelectMenuOnline=\u5728\u7EBF
gameSelectMenuEnterIP=\u5728\u6B64\u8F93\u5165\u4F60\u7684IP\u5730\u5740\uFF1A
# Game Menu
gameMenuHint=\u63D0\u793A
gameMenuBack=\u8FD4\u56DE
# Options menu
optionsMenuLabelSelectLanguage=\u8BED\u8A00:
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u963f\u62c9\u4f2f\u8bed)
chinese=\u4e2d\u6587
dutch=Nederlands (\u8377\u5170\u8bed)
english=English (\u82f1\u8bed)
french=Fran\u00e7ais (\u6cd5\u8bed)
georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u683c\u9c81\u5409\u4e9a\u8bed)
german=Deutsch (\u5fb7\u8bed)
hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u5370\u5ea6\u8bed)
italian=Italiano (\u610f\u5927\u5229\u8bed)
japanese=\u65e5\u672c\u8a9e (\u65e5\u8bed)
korean=\ud55c\uad6d\uc5b4 (\u97e9\u8bed)
russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u4fc4\u8bed)
spanish=Espa\u00f1ol (\u897f\u73ed\u7259\u8bed)

View File

@@ -2,19 +2,17 @@
-fx-background-color: linear-gradient(to bottom right, #21a7b2, #8f32b9);
}
.vertical_container, .horizontal_container {
.stack_container, .vertical_container, .horizontal_container {
-fx-padding: 10;
-fx-alignment: center;
-fx-text-alignment: center;
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
-fx-background-insets: 0, 2;
-fx-background-radius: 5;
}
.text, .button, .toggle, .input {
-fx-padding: 10;
.text, .button, .toggle {
-fx-padding: 5 10 5 10;
-fx-fill: white;
-fx-text-fill: white;
@@ -24,6 +22,7 @@
-fx-font-size: 20px;
-fx-background-color: transparent;
-fx-border-color: transparent;
}
@@ -36,10 +35,76 @@
-fx-effect: dropshadow(gaussian, #007fff, 10, 0.5, 0, 0);
}
.input {
-fx-padding: 10;
-fx-fill: white;
-fx-text-fill: white;
-fx-font-family: "Segoe UI", sans-serif;
-fx-font-weight: bold;
-fx-font-size: 20px;
-fx-background-color: transparent;
-fx-border-color: #7f7f7f;
}
.input:focused {
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
-fx-background-insets: 0, 2;
-fx-background-radius: 8;
-fx-border-color: transparent;
}
.slider {
-fx-padding: 10;
-fx-background-color: transparent;
}
.slider .track {
-fx-background-color: linear-gradient(to right, #00ff00, #ff0000);
-fx-background-radius: 2;
}
.slider .thumb {
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
}
.choicebox {
-fx-alignment: center;
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
-fx-background-insets: 0, 2;
-fx-background-radius: 8;
-fx-border-color: transparent;
}
.choicebox .label {
-fx-text-fill: white;
-fx-alignment: center;
-fx-padding: 5 10 5 10;
}
.choicebox .arrow {
-fx-background-color: transparent;
}
.choicebox .context-menu {
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
-fx-background-insets: 0, 2;
-fx-background-radius: 5;
}
.choicebox .menu-item:hover {
-fx-cursor: hand;
-fx-background-color: #ffffff11;
}
.separator {
-fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d;
}

View File

@@ -6,13 +6,7 @@
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.7), 4, 0, 2, 2);
}
.button.exit-button {
-fx-background-color: #3498db;
-fx-text-fill: white;
-fx-font-size: 72px;
-fx-padding: 10 20 10 20;
-fx-background-radius: 5;
}
.button.exit-button:hover {
-fx-background-color: #2980b9;
.animated_credits_container {
-fx-padding: 10;
-fx-alignment: center;
}

View File

@@ -1,3 +1,3 @@
.quit_background {
.background {
-fx-background-color: #0000007f;
}

View File

@@ -116,6 +116,12 @@
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -84,20 +84,10 @@ public class ResourceManager {
@SuppressWarnings("unchecked")
public static <T extends BaseResource> T get(String name) {
ResourceMeta<T> asset = (ResourceMeta<T>) assets.get(name);
if (asset == null) return null;
return asset.getResource();
if (asset == null) {
throw new TypeNotPresentException(name, new RuntimeException(String.format("Type %s not present", name))); // TODO: Create own exception, BAM
}
/**
* Retrieve the resource of a given name, cast to the expected type.
*
* @param name the asset name
* @param <T> the expected resource type
* @return the resource, or null if not found
*/
@SuppressWarnings("unchecked")
public static <T extends BaseResource> T get(Class<T> type, String name) {
return type.cast(assets.get(name).getResource());
return asset.getResource();
}
/**
@@ -134,26 +124,6 @@ public class ResourceManager {
return null;
}
/**
* Retrieve an asset by its name.
*
* @param name the asset name
* @return the asset, or null if not found
*/
public static ResourceMeta<? extends BaseResource> getByName(String name) {
return assets.get(name);
}
/**
* Attempt to find an asset by name, returning an {@link Optional}.
*
* @param name the asset name
* @return an Optional containing the asset if found
*/
public static Optional<ResourceMeta<? extends BaseResource>> findByName(String name) {
return Optional.ofNullable(assets.get(name));
}
/**
* Add a new asset to the manager.
*

View File

@@ -0,0 +1,75 @@
package org.toop.framework.asset.resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.toop.framework.asset.types.FileExtension;
import org.toop.framework.asset.types.LoadableResource;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
@FileExtension({"json"})
public class JsonAsset<T> extends BaseResource implements LoadableResource {
private T content;
private Class<T> type;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
public JsonAsset(File file, Class<T> type) {
super(file);
this.type = type;
}
@Override
public void load() {
File file = getFile();
if (!file.exists()) {
try {
// make a new file with the declared constructor (example: settings) if it doesn't exist
content = type.getDeclaredConstructor().newInstance();
save();
} catch (Exception e) {
throw new RuntimeException("Could not make default JSON settings for" + file, e);
}
} else {
// else open the file, try reading it using gson, and set it to loaded
try (FileReader reader = new FileReader(file)) {
content = gson.fromJson(reader, type);
this.isLoaded = true;
} catch(Exception e) {
throw new RuntimeException("Failed to load JSON asset" + getFile(), e);
}
}
}
@Override
public void unload() {
this.content = null;
this.isLoaded = false;
}
public T getContent() {
if (!isLoaded()) {
load();
}
return content;
}
public void save() {
File file = getFile();
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
}
try (FileWriter writer = new FileWriter(file)) {
gson.toJson(content, writer);
} catch (IOException e) {
throw new RuntimeException("Failed to save JSON asset" + getFile(), e);
}
}
@Override
public boolean isLoaded() {
return this.isLoaded;
}
}

View File

@@ -0,0 +1,41 @@
package org.toop.framework.asset.resources;
import org.toop.framework.settings.Settings;
import java.io.File;
import java.util.Locale;
public class SettingsAsset extends JsonAsset<Settings> {
public SettingsAsset(File file) {
super(file, Settings.class);
}
public int getVolume() {
return getContent().volume;
}
public Locale getLocale() {
return Locale.forLanguageTag(getContent().locale);
}
public boolean getFullscreen() {
return getContent().fullScreen;
}
public void setVolume(int volume) {
getContent().volume = volume;
save();
}
public void setLocale(String locale) {
getContent().locale = locale;
save();
}
public void setFullscreen(boolean fullscreen) {
getContent().fullScreen = fullscreen;
save();
}
}

View File

@@ -41,7 +41,7 @@ public class SoundManager {
.listen(this::handleMusicStart)
.listen(this::handleVolumeChange)
.listen(this::handleGetCurrentVolume)
.listen(AudioEvents.clickButton.class, _ -> {
.listen(AudioEvents.ClickButton.class, _ -> {
try {
playSound("medium-button-click.wav", false);
} catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
@@ -69,15 +69,16 @@ public class SoundManager {
}
private void handleVolumeChange(AudioEvents.ChangeVolume event) {
if (event.newVolume() > 1.0) this.volume = 1.0;
else this.volume = Math.max(event.newVolume(), 0.0);
double newVolume = event.newVolume() / 100;
if (newVolume > 1.0) this.volume = 1.0;
else this.volume = Math.max(newVolume, 0.0);
for (MediaPlayer mediaPlayer : this.activeMusic) {
mediaPlayer.setVolume(this.volume);
}
}
private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) {
new EventFlow().addPostEvent(new AudioEvents.GetCurrentVolumeReponse(volume, event.snowflakeId()))
new EventFlow().addPostEvent(new AudioEvents.GetCurrentVolumeReponse(volume * 100, event.snowflakeId()))
.asyncPostEvent();
}

View File

@@ -37,5 +37,5 @@ public class AudioEvents extends EventsBase {
return snowflakeId;
}
}
public record clickButton() implements EventWithoutSnowflake {}
public record ClickButton() implements EventWithoutSnowflake {}
}

View File

@@ -0,0 +1,9 @@
package org.toop.framework.settings;
import java.util.Locale;
public class Settings {
public boolean fullScreen = false;
public String locale = "en";
public int volume = 15;
}

View File

@@ -0,0 +1,19 @@
package org.toop.game.othello;
import org.toop.game.TurnBasedGame;
public final class Othello extends TurnBasedGame {
Othello() {
super(8, 8, 2);
}
@Override
public Move[] getLegalMoves() {
return new Move[0];
}
@Override
public State play(Move move) {
return null;
}
}

View File

@@ -0,0 +1,11 @@
package org.toop.game.othello;
import org.toop.game.AI;
import org.toop.game.Game;
public final class OthelloAI extends AI<Othello> {
@Override
public Game.Move findBestMove(Othello game, int depth) {
return null;
}
}