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

main
Jonah Bauer 3 years ago
commit 61a4b2b5ec

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -6,6 +6,7 @@ import eu.jonahbauer.wizard.common.machine.TimeoutContext;
import eu.jonahbauer.wizard.common.messages.client.ClientMessage; import eu.jonahbauer.wizard.common.messages.client.ClientMessage;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import java.util.Optional; import java.util.Optional;
@ -20,6 +21,10 @@ public class Client extends TimeoutContext<ClientState, Client> {
@Getter @Getter
private ClientSocket socket; private ClientSocket socket;
@Getter
@Setter
public boolean isError = false;
public Client(WizardGame game) { public Client(WizardGame game) {
super(new Menu()); super(new Menu());
this.game = game; this.game = game;

@ -0,0 +1,70 @@
package eu.jonahbauer.wizard.client.libgdx.screens;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager;
import eu.jonahbauer.wizard.client.libgdx.state.BaseState;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.client.libgdx.state.Session;
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
public class ErrorScreen extends MenuScreen {
private final String labelText;
private TextButton buttonBack;
private final ChangeListener listener = new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonBack) {
sfxClick();
}
}
};
public ErrorScreen(WizardGame game, Client client, NackMessage message) {
super(game);
labelText = switch (message.getCode()) {
case NackMessage.GAME_ALREADY_STARTED -> messages.get("menu.error.game_already_started");
case NackMessage.SESSION_FULL -> messages.get("menu.error.session_full");
case NackMessage.SESSION_NOT_FOUND -> messages.get("menu.error.session_not_found");
case NackMessage.PLAYER_NAME_TAKEN -> messages.get("menu.error.player_name_taken");
case NackMessage.PLAYER_NAME_NOT_ALLOWED -> messages.get("menu.error.player_name_not_allowed");
case NackMessage.SESSION_NAME_TAKEN -> messages.get("menu.error.session_name_taken");
case NackMessage.SESSION_NAME_NOT_ALLOWED -> messages.get("menu.error.session_name_not_allowed");
case NackMessage.MALFORMED_MESSAGE -> messages.get("menu.error.malformed_message");
case NackMessage.UNEXPECTED_MESSAGE -> messages.get("menu.error.unexpected_message");
case NackMessage.ILLEGAL_ARGUMENT -> messages.get("menu.error.illegal_argument");
case NackMessage.NOT_FOUND -> messages.get("menu.error.not_found");
case NackMessage.ALREADY_CONNECTED -> messages.get("menu.error.already_connected");
case NackMessage.GAME_NOT_YET_STARTED -> messages.get("menu.error.game_not_yet_started");
case NackMessage.PLAYER_NOT_FOUND -> messages.get("menu.error.player_not_found");
case NackMessage.ILLEGAL_STATE -> messages.get("menu.error.illegal_state");
case NackMessage.BAD_REQUEST -> messages.get("menu.error.bad_request");
default -> "Something went terribly wrong :(";
};
}
@Override
public void show() {
super.show();
var buttonBack = new TextButton(messages.get("menu.error.back"), skin);
var label = new Label(labelText, skin);
var content = new VerticalGroup();
content.setPosition(WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT*0.5f);
content.addActor(label);
content.addActor(buttonBack);
buttonBack.addListener(listener);
stage.addActor(content);
stage.addCaptureListener(new KeyboardFocusManager(buttonBack));
}
}

@ -0,0 +1,223 @@
package eu.jonahbauer.wizard.client.libgdx.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.GameAtlas;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.actors.CardActor;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
import eu.jonahbauer.wizard.common.model.Card;
public class InstructionScreen extends MenuScreen {
private TextButton buttonOK;
private VerticalGroup content;
private ScrollPane scrollPane;
private Label title;
private TextButton nextPageButton;
private TextButton previousPageButton;
private HorizontalGroup horizontalButtonGroup;
private int pagecounter = 0;
private TextureAtlas atlas;
private CardActor card;
private final ChangeListener listener = new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonOK) {
game.getClient().execute(Menu.class, Menu::showMenuScreen);
sfxClick();
} else if (actor == nextPageButton) {
switch(pagecounter) {
case 0: pagecounter++; showSecondPage(); break;
case 1: pagecounter++; showThirdPage(); break;
default: throw new IllegalStateException();
}
} else if (actor == previousPageButton) {
switch(pagecounter) {
case 1: pagecounter--; showFirstPage(); break;
case 2: pagecounter--; showSecondPage(); break;
default: throw new IllegalStateException();
}
}
}
};
public InstructionScreen(WizardGame game) {
super(game);
}
@Override
public void show() {
super.show();
prepareScreen();
previousPageButton = new TextButton(messages.get("menu.instruction.previousPageButton"), skin);
nextPageButton = new TextButton(messages.get("menu.instruction.nextPageButton"), skin);
horizontalButtonGroup = new HorizontalGroup();
buttonOK = new TextButton(messages.get("menu.main.ok"), skin);
scrollPane = new ScrollPane(content, skin);
scrollPane.setFadeScrollBars(true);
scrollPane.setOverscroll(false,false);
scrollPane.setPosition(corners[0].getWidth() + 5, 0);
scrollPane.setSize(WizardGame.WIDTH - (2 * corners[0].getWidth() + 5), WizardGame.HEIGHT);
scrollPane.setColor(new Color(0, 0, 0, 0.75f));
showFirstPage();
Gdx.input.setInputProcessor(stage);
stage.addActor(scrollPane);
buttonOK.addListener(listener);
nextPageButton.addListener(listener);
previousPageButton.addListener(listener);
}
private void prepareScreen() {
atlas = new TextureAtlas(Gdx.files.internal(GameAtlas.$PATH));
content = new VerticalGroup();
}
private void clearContent() {
while(content.getChildren().size > 0) {
content.removeActorAt(0, false);
}
horizontalButtonGroup.clear();
}
private void addButtons() {
if(pagecounter != 0) {
horizontalButtonGroup.addActor(previousPageButton);
}
if(pagecounter != 2) {
horizontalButtonGroup.addActor(nextPageButton);
}
horizontalButtonGroup.space(10);
content.addActor(horizontalButtonGroup);
content.addActor(buttonOK);
}
private void showFirstPage() {
clearContent();
title = new Label(messages.get("menu.instruction.main"), skin, "enchanted");
content.addActor(title);
Label maintext1 = new Label(messages.get("menu.instruction.main.text1"), skin);
maintext1.setFontScale(2.0f);
content.addActor(maintext1);
Label maintext2 = new Label(messages.get("menu.instruction.main.text2"), skin);
content.addActor(maintext2);
Label general = new Label(messages.get("menu.instruction.general"), skin, "enchanted");
content.addActor(general);
Label introduction1 = new Label(messages.get("menu.instruction.introduction1"), skin);
content.addActor(introduction1);
Label introduction2 = new Label(messages.get("menu.instruction.introduction2"), skin);
content.addActor(introduction2);
Label headingStandardGame = new Label(messages.get("menu.instruction.standardgameheading"), skin, "enchanted");
content.addActor(headingStandardGame);
Label standardGame1 = new Label(messages.get("menu.instruction.standardgame1"), skin);
content.addActor(standardGame1);
Label standardGame2 = new Label(messages.get("menu.instruction.standardgame2"), skin);
content.addActor(standardGame2);
Label standardGame3 = new Label(messages.get("menu.instruction.standardgame3"), skin);
content.addActor(standardGame3);
HorizontalGroup colors = new HorizontalGroup();
colors.space(10);
for(Card.Suit suit : Card.Suit.values()) {
if (suit != Card.Suit.NONE) {
VerticalGroup cardColor = new VerticalGroup();
cardColor.space(10);
card = new CardActor(Card.Suit.values()[suit.ordinal()], atlas);
cardColor.addActor(card);
Label colorLabel = new Label(suit.toString(), skin);
cardColor.addActor(colorLabel);
colors.addActor(cardColor);
}
}
content.addActor(colors);
Label standardGame4 = new Label(messages.get("menu.instruction.standardgame4"), skin);
content.addActor(standardGame4);
HorizontalGroup wizardJester = new HorizontalGroup();
wizardJester.padTop(5);
wizardJester.space(10);
VerticalGroup wizardVerticalGroup = new VerticalGroup();
wizardVerticalGroup.space(10);
card = new CardActor(Card.values()[Card.BLUE_WIZARD.ordinal()], atlas);
wizardVerticalGroup.addActor(card);
Label wizardLabel = new Label(messages.get("menu.instruction.wizard"), skin);
wizardVerticalGroup.addActor(wizardLabel);
wizardJester.addActor(wizardVerticalGroup);
VerticalGroup jesterVerticalGroup = new VerticalGroup();
jesterVerticalGroup.space(10);
card = new CardActor(Card.values()[Card.BLUE_JESTER.ordinal()], atlas);
jesterVerticalGroup.addActor(card);
Label jesterLabel = new Label(messages.get("menu.instruction.jester"), skin);
jesterVerticalGroup.addActor(jesterLabel);
wizardJester.addActor(jesterVerticalGroup);
content.addActor(wizardJester);
Label standardGame5 = new Label(messages.get("menu.instruction.standardgame5"), skin);
content.addActor(standardGame5);
Label standardGame6 = new Label(messages.get("menu.instruction.standardgame6"), skin);
standardGame6.setFontScale(2.0f);
content.addActor(standardGame6);
Label standardGame7 = new Label(messages.get("menu.instruction.standardgame7"), skin);
content.addActor(standardGame7);
Label standardGame8 = new Label(messages.get("menu.instruction.standardgame8"), skin);
standardGame8.setFontScale(2.0f);
content.addActor(standardGame8);
Label standardGame9 = new Label(messages.get("menu.instruction.standardgame9"), skin);
content.addActor(standardGame9);
Label scoring = new Label(messages.get("menu.instruction.scoring"), skin, "enchanted");
content.addActor(scoring);
Label standardGame10 = new Label(messages.get("menu.instruction.standardgame10"), skin);
content.addActor(standardGame10);
addButtons();
}
private void showSecondPage() {
clearContent();
title.setText(messages.get("menu.instruction.variant.title"));
content.addActor(title);
Label variantsIntro = new Label(messages.get("menu.instruction.variant.intro"), skin);
content.addActor(variantsIntro);
Table table = new Table(skin);
table.defaults().space(15.0f).left().pad(25.0f);
table.add(messages.get("menu.instruction.variant.default"));
table.add(messages.get("menu.instruction.variant.default.description")).left();
table.row();
table.add(messages.get("menu.instruction.variant.defaultpm1"));
table.add(messages.get("menu.instruction.variant.defaultpm1.description"));
table.row();
table.add(messages.get("menu.instruction.variant.anniversary2016"));
table.add(messages.get("menu.instruction.variant.anniversary2016.description"));
table.row();
table.add(messages.get("menu.instruction.variant.anniversary2016pm1"));
table.add(messages.get("menu.instruction.variant.anniversary2016pm1.description"));
table.row();
table.add(messages.get("menu.instruction.variant.anniversary2021"));
table.add(messages.get("menu.instruction.variant.anniversary2021.description"));
table.row();
table.add(messages.get("menu.instruction.variant.anniversary2021pm1"));
table.add(messages.get("menu.instruction.variant.anniversary2021pm1.description"));
table.row();
content.addActor(table);
addButtons();
scrollPane.setScrollY(0);
}
private void showThirdPage() {
clearContent();
title.setText(messages.get("menu.instruction.special_card.title"));
content.addActor(title);
addButtons();
}
}

@ -7,6 +7,7 @@ import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager; import eu.jonahbauer.wizard.client.libgdx.listeners.KeyboardFocusManager;
import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener; import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby; import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
import eu.jonahbauer.wizard.common.messages.data.SessionData; import eu.jonahbauer.wizard.common.messages.data.SessionData;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;

@ -14,6 +14,7 @@ public class MainMenuScreen extends MenuScreen {
private TextButton buttonPlay; private TextButton buttonPlay;
private TextButton buttonQuit; private TextButton buttonQuit;
private TextButton buttonInstruction;
private final ChangeListener listener = new ChangeListener() { private final ChangeListener listener = new ChangeListener() {
@Override @Override
@ -24,6 +25,9 @@ public class MainMenuScreen extends MenuScreen {
} else if (actor == buttonQuit) { } else if (actor == buttonQuit) {
sfxClick(); sfxClick();
Gdx.app.exit(); Gdx.app.exit();
} else if (actor == buttonInstruction) {
game.getClient().execute(Menu.class, Menu::showInstructionScreen);
sfxClick();
} }
} }
}; };
@ -54,18 +58,22 @@ public class MainMenuScreen extends MenuScreen {
} }
buttonPlay = new TextButton(messages.get("menu.main.play"), skin); buttonPlay = new TextButton(messages.get("menu.main.play"), skin);
buttonPlay.setPosition((WizardGame.WIDTH - buttonPlay.getWidth()) / 2f, 192 + 504 - 120f - 125f); buttonPlay.setPosition((WizardGame.WIDTH - buttonPlay.getWidth()) / 2f, 170 + 504 - 125f);
buttonPlay.addListener(listener); buttonPlay.addListener(listener);
buttonInstruction = new TextButton(messages.get("menu.instruction.main"), skin);
buttonInstruction.setPosition((WizardGame.WIDTH - buttonInstruction.getWidth()) / 2f, 170 + 494 - 189.5f - 125f + buttonInstruction.getHeight() / 2f);
buttonInstruction.addListener(listener);
buttonQuit = new TextButton(messages.get("menu.main.quit"), skin); buttonQuit = new TextButton(messages.get("menu.main.quit"), skin);
buttonQuit.setPosition((WizardGame.WIDTH - buttonQuit.getWidth()) / 2f, 192 + 120f); buttonQuit.setPosition((WizardGame.WIDTH - buttonQuit.getWidth()) / 2f, 170 + 120f);
buttonQuit.addListener(listener); buttonQuit.addListener(listener);
stage.addActor(buttonPlay); stage.addActor(buttonPlay);
stage.addActor(buttonInstruction);
stage.addActor(buttonQuit); stage.addActor(buttonQuit);
stage.addCaptureListener(new KeyboardFocusManager(buttonPlay, buttonQuit)); stage.addCaptureListener(new KeyboardFocusManager(buttonPlay, buttonQuit));
buttonPlay.setName("button_player"); buttonPlay.setName("button_player");
buttonInstruction.setName("button_instruction");
buttonQuit.setName("button_quit"); buttonQuit.setName("button_quit");
} }
} }

@ -9,7 +9,7 @@ import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
public abstract class MenuScreen extends WizardScreen { public abstract class MenuScreen extends WizardScreen {
private Image[] corners; protected Image[] corners;
@Getter(value = AccessLevel.PROTECTED, lazy = true) @Getter(value = AccessLevel.PROTECTED, lazy = true)
private final HorizontalGroup buttonGroup = createButtonGroup(); private final HorizontalGroup buttonGroup = createButtonGroup();

@ -56,7 +56,7 @@ public abstract class WizardScreen implements Screen {
stage = new Stage(viewport); stage = new Stage(viewport);
stage.addListener(new ButtonKeyListener()); stage.addListener(new ButtonKeyListener());
stage.addListener(new AutoFocusListener()); stage.addListener(new AutoFocusListener());
stage.setDebugAll(WizardGame.DEBUG); //stage.setDebugAll(WizardGame.DEBUG);
Gdx.input.setInputProcessor(stage); Gdx.input.setInputProcessor(stage);

@ -28,4 +28,6 @@ public final class AwaitingConnection extends Awaiting {
log.error("Connection could not be established. (code={}, reason={}, remote={})", code, reason, remote); log.error("Connection could not be established. (code={}, reason={}, remote={})", code, reason, remote);
return Optional.of(new Menu()); return Optional.of(new Menu());
} }
//public Optional<ClientState> showErrorScreen(Client client, )
} }

@ -1,6 +1,9 @@
package eu.jonahbauer.wizard.client.libgdx.state; package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.screens.ErrorScreen;
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
@ -34,4 +37,12 @@ public abstract class BaseState implements ClientState {
log.fatal("Unexpected message {}. Returning to menu.", message); log.fatal("Unexpected message {}. Returning to menu.", message);
return Optional.of(new Menu()); return Optional.of(new Menu());
} }
public Optional<ClientState> showErrorScreen(Client client, NackMessage nack) {
WizardGame game = client.getGame();
client.setError(true);
game.setScreen(new ErrorScreen(game, client, nack));
return Optional.of(new Menu(client));
}
} }

@ -1,9 +1,8 @@
package eu.jonahbauer.wizard.client.libgdx.state; package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.CreateGameScreen; import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.screens.LobbyScreen; import eu.jonahbauer.wizard.client.libgdx.screens.*;
import eu.jonahbauer.wizard.client.libgdx.screens.RejoinScreen;
import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage; import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage; import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.RejoinMessage; import eu.jonahbauer.wizard.common.messages.client.RejoinMessage;
@ -19,6 +18,8 @@ import static eu.jonahbauer.wizard.client.libgdx.state.AwaitingJoinSession.Sourc
public final class Lobby extends BaseState { public final class Lobby extends BaseState {
private final Map<UUID, SessionData> sessions = new HashMap<>(); private final Map<UUID, SessionData> sessions = new HashMap<>();
private Client client;
private LobbyScreen lobbyScreen; private LobbyScreen lobbyScreen;
public Lobby(Collection<SessionData> list) { public Lobby(Collection<SessionData> list) {
@ -28,6 +29,7 @@ public final class Lobby extends BaseState {
@Override @Override
public Optional<ClientState> onEnter(Client client) { public Optional<ClientState> onEnter(Client client) {
showListScreen(client); showListScreen(client);
this.client = client;
return super.onEnter(client); return super.onEnter(client);
} }

@ -3,6 +3,7 @@ package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client; import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.ClientSocket; import eu.jonahbauer.wizard.client.libgdx.ClientSocket;
import eu.jonahbauer.wizard.client.libgdx.screens.ConnectScreen; import eu.jonahbauer.wizard.client.libgdx.screens.ConnectScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.InstructionScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen; import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage; import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -21,10 +22,17 @@ public final class Menu extends BaseState {
if (client.getSocket() != null && client.getSocket().isOpen()) { if (client.getSocket() != null && client.getSocket().isOpen()) {
client.getSocket().close(CloseFrame.GOING_AWAY); client.getSocket().close(CloseFrame.GOING_AWAY);
} }
showMenuScreen(client);
return super.onEnter(client); return super.onEnter(client);
} }
public Menu(Client client) {
if(client.isError) {
//showErrorScreen(client);
}
}
public Menu() {}
@Override @Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) { public Optional<ClientState> onMessage(Client client, ServerMessage message) {
// it is possible that there are messages still queued after // it is possible that there are messages still queued after
@ -51,6 +59,12 @@ public final class Menu extends BaseState {
return Optional.empty(); return Optional.empty();
} }
public Optional<ClientState> showInstructionScreen(Client client) {
var game = client.getGame();
game.setScreen(new InstructionScreen(game));
return Optional.empty();
}
public Optional<ClientState> connect(Client client, URI uri) { public Optional<ClientState> connect(Client client, URI uri) {
ClientSocket socket = new ClientSocket(uri); ClientSocket socket = new ClientSocket(uri);
client.setSocket(socket); client.setSocket(socket);

@ -1,6 +1,80 @@
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
menu.main.play=Play menu.main.play=Play
menu.main.quit=Close menu.main.quit=Close
menu.main.ok=OK
menu.instruction.nextPageButton=Next Page
menu.instruction.previousPageButton=Previous Page
menu.instruction.wizard=Wizard
menu.instruction.jester=Jester
menu.instruction.main=Instruction of the game
menu.instruction.main.text1=Welcome
menu.instruction.main.text2=On this page you will find the rules of the basic game and the scoring system.\n\
On the second page is an overview of the possible game variants \nand on the third an overview of the special cards.
menu.instruction.general=In General
menu.instruction.introduction1=Wizard is a trick game with the goal of predicting the exact number of self-winning tricks in each round.
menu.instruction.introduction2=For correct predictions each player gets points and in the end the player with the highest score wins.
menu.instruction.standardgameheading=Standard Game
menu.instruction.standardgame1=In the basis game there are 60 different cards.
menu.instruction.standardgame2=52 of these cards are distributed among the following four suits.
menu.instruction.standardgame3=The highest card is 13, the lowest card is 1.
menu.instruction.standardgame4=The 8 remaining cards are divided equally between Wizards and Jesters and have no suit.\n\
The four wizards have a higher value than all other cards and the four jesters have a lower value.
menu.instruction.standardgame5=For each round count: the number of rounds equals the number of cards per player equals and the number of tricks\n\
the cards are dealt virtually as the dealer one of the players.\n\
After the cards are dealt, a trump suit is determined. It corresponds to the suit of the card\n\
which is displayed in the bottom left corner of the game screen.\n\
A trump is any card of the trump suit and higher than all cards of the other suits.\n\
Important. If the card determining the trump is a jester, there is no trump in this round.\n\
If the trump card is a Wizard, the dealer chooses a trump suit.\n\
Once the trump suit is determined, each player states how many tricks they want to make in the round.\n\
Tip for newcomers: A good hand for many tricks has wizards, trump cards and high suit cards.\n
menu.instruction.standardgame6=The process of a trick
menu.instruction.standardgame7=The first card of a trick is played at the first trick by the dealer's virtual left neighbor.\n\
All further tricks are opened by the player who won the last trick.\n\
After that, all players play one card in clockwise order.\n\
To the suit of the first card must be added. This means that if a player has a suit of this card\n\
he must play it and must not play a card of any other suit.\n\
Exceptions to this are wizards and jesters. These cards may always be played!\n\
The trick is won by the player with the highest card.\nThe following descending rank for the highest card applies:\n\
+The first wizard in a trick\n\
+The highest trump card\n\
+The highest suit card of the played suit.
menu.instruction.standardgame8=Special cases
menu.instruction.standardgame9=If a player starts a trick with a wizard, the other players may play any\n\
cards, including any other Wizards or Jesters.\nThe trick goes to the first Wizard in any case.\n\n\
If a player opens a trick with a Jester, any cards may be played\n\
until an another player plays a wizard or a number card. If it is a number card,\n\
all further cards must be added to its suit.\n\
If it is a wizard, any cards may be played.\n\
In the rare case that only jesters are in the trick, the first jester wins.
menu.instruction.scoring=Scoring
menu.instruction.standardgame10=If the prediction is correct, 10 points are awarded for each trick made plus\n\
20 points as a basic amount.\nIf the prediction is wrong, -10 points are awarded for each deviating trick and the player\n\
does not receive any basic amount.\n\
The score is then offset against a player's previous score.
menu.instruction.special_card.title=Special cards
menu.instruction.variant.title=Variants of the game
menu.instruction.variant.intro=When creating a new game, the following 6 variants can be selected.
menu.instruction.variant.default=1) Default
menu.instruction.variant.default.description=The basic game with the basic rules.
menu.instruction.variant.defaultpm1=2) Default PM1
menu.instruction.variant.defaultpm1.description=The basic game with the additional condition that the prediction\n\
must not correspond to the number of rounds.\n\
This means: the tip of at least one player is wrong
menu.instruction.variant.anniversary2016=3) Anniversary 2016
menu.instruction.variant.anniversary2016.description=The basic game with the basic rules and the special cards of the anniversary edition 2016.
menu.instruction.variant.anniversary2016pm1=4) Anniversary 2016 PM1
menu.instruction.variant.anniversary2016pm1.description=The basic game with the special cards of the anniversary edition 2016, with the\n\
additional condition that the prediction must not correspond to the number of rounds.
menu.instruction.variant.anniversary2021=5) Anniversary 2021
menu.instruction.variant.anniversary2021.description=The basic game with the basic rules and the special cards of the anniversary edition 2021.
menu.instruction.variant.anniversary2021pm1=6) Anniversary 2021 PM1
menu.instruction.variant.anniversary2021pm1.description=The basic game with the special cards of the 2021 anniversary edition, with the\n\
additional condition that the prediction must not correspond to the number of rounds.
menu.connect.connect=Connect menu.connect.connect=Connect
menu.connect.back=Back menu.connect.back=Back
@ -46,6 +120,25 @@ menu.waiting.session_name.label=Session Name
menu.waiting.session_uuid.label=Session UUID menu.waiting.session_uuid.label=Session UUID
menu.waiting.session_configuration.label=Configuration menu.waiting.session_configuration.label=Configuration
menu.error.malformed_message=Error: Malformed Message
menu.error.unexpected_message=Error: Unexpected Message
menu.error.illegal_argument=Error: Illegal Argument
menu.error.not_found=Error: Not Found
menu.error.session_not_found=Error: Session Not Found
menu.error.player_not_found=Error: Player Not Found
menu.error.player_name_taken=Error: Playername Already Taken
menu.error.player_name_not_allowed=Error: Playername Not Allowed
menu.error.session_name_taken=Error: Sessionname Already Taken
menu.error.session_name_not_allowed=Error: Sessionname Not Allowed
menu.error.illegal_state=Error: Illegal State
menu.error.game_already_started=Error: Game Already Started
menu.error.game_not_yet_started=Error: Game Not Yet Started
menu.error.session_full=Error: Session Is Full
menu.error.already_connected=Error: Already Connected
menu.error.bad_request=Error: Bad Request
menu.error.back=Back
game.message.literal={0} game.message.literal={0}
game.message.play_card.other=It is {0}'s turn to play a card game.message.play_card.other=It is {0}'s turn to play a card

@ -1,6 +1,80 @@
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
menu.main.play=Spiel beitreten menu.main.play=Spiel beitreten
menu.main.quit=Verlassen menu.main.quit=Verlassen
menu.main.ok=OK
menu.instruction.nextPageButton=Nächste Seite
menu.instruction.previousPageButton=Vorherige Seite
menu.instruction.wizard=Zauberer
menu.instruction.jester=Narr
menu.instruction.main=Spielanleitung
menu.instruction.main.text1=Willkommen
menu.instruction.main.text2=Auf dieser Seite findest du die Regeln des Grundspiels und zur Punktewertung.\n\
Auf der zweiten Seite befindet sich eine Übersicht über die möglichen Spielvarianten \nundauf der dritten eine Übersicht der Sonderkarten.
menu.instruction.general=Grundlegendes
menu.instruction.introduction1=Wizard ist ein Stichspiel mit dem Ziel in jeder Runde die genau Anzahl der selbstgewonnen\
Stiche vorherzusagen.
menu.instruction.introduction2=Für richtige Vorhersagen erhält jeder Spieler Punkte und am Ende gewinnt der Spieler mit\
der höchsten Punktzahl.
menu.instruction.standardgameheading=Grundspiel
menu.instruction.standardgame1=Im Grundspiel gibt es 60 Karten
menu.instruction.standardgame2=52 dieser Karten verteilen sich auf die folgenden vier Farben.
enu.instruction.standardgame3=Die jeweils höchste Karte ist die 13, die jeweils niedrigste Karte ist die 1.
menu.instruction.standardgame4=Die 8 verbleibenden Karten verteilen sich hälftig auf Zauberer und Narren und haben keine Farbe.\n\
Die vier Zauberer haben einen höheren Wert als alle anderen Karten und die vier Narren einen niedrigeren.
menu.instruction.standardgame5=Für jede Runde gilt: Rundenzahl gleich Anzahl der Karten pro Spieler gleich Anzahl der Stiche\n\
die Karten verteilt virtuell als Geber einer der Spieler.\n\n\
Nach dem Verteilen der Karten wird eine Trumpffarbe bestimmt. Sie entspricht der Farber der Karte\n\
Die im Spielbildschrim links unten angezeigt wird.\n\
Ein Trumpf ist jede Karte der Trumpffarbe und höher als alle Karten der anderen Farben.\n\
Wichtig! Ist die trumpfbestimmende Karte ein Narr gibt es in dieser Runde keinen Trumpf.\n\
Wichig!Ist die trumpbestimmende Karte ein Zauberer wählt der Kartengeber eine Trumpffarbe.\n\n\
Ist die Trumpfarbe bestimmt, sagt jeder Spieler an, wie viele Stiche er in der Runde machen will.\n\
Tipp für Neulinge: Ein gutes Blatt für viele Stiche hat Zauberer, Trumpfkarten und hohe Farbkarten.\n
menu.instruction.standardgame6=Der Ablauf eine Stichs
menu.instruction.standardgame7=Die erste Karte eines Stichs spielt beim ersten Stich der virtuelle linke Nachbar des Gebers.\n\
Alle weiteren Stiche eröffnet der Spieler, der den letzten Stich gewonnen hat.\n\
Danach spielen alle Mitspieler im Uhzeigersinn eine Karte\n\
Zur Farbe der ersten Karte muss zugegeben werden. Das bedeutet: Hat ein Spieler eine Farbe dieser Karte\n\
muss er diese spielen und darf keine Karte einer anderen Farbe spielen.\n\
Ausnahme hiervon sind Zauberer und Narren. Diese Karten dürfen immer gespielt werden!\n\n\
Den Stich gewinnt der Spieler mit der höchsten Karte.\nFolgende absteigende Wertigkeit für die höchste Karte gilt:\n\
+Der erste Zauberer in einem Stich\n\
+Die höchste Trumpfkarte\n\
+Die höchste Farbkarte der angespielten Farbe
menu.instruction.standardgame8=Besonderheiten
menu.instruction.standardgame9=Eröffnet ein Spieler einen Stich mit einem Zauberer, dürfen die Mitspieler beliebige\n\
Karten spielen, einschließlich weiterer Zauberer oder Narren.\nDer Stich geht in jedem Fall an den ersten Zauberer.\n\n\
Eröffnet ein Spieler einen Stich mit einem Narren, dürfen beliebige Karten gespielt werden,\n\
bis ein Lehrling einen Zauberer oder eine Zahlenkarte spielt. Handelt es sich um eine Zahlenkarte,\n\
muss zu ihrer Farbe zugegeben werden.\n\
Handelt es sich um einen Zauberer, dürfen beliebige Karten gespielt werden.\n\
Im seltenen Fall, dass nur Narren im Stich liegen, gewinnt der erste Narr.
menu.instruction.scoring=Punktewertung
menu.instruction.standardgame10=Bei einer richtigen Vorhersage gibt es pro gemachten Stich 10 Punkte\n\
sowie 20 Punkte als Grundbetrag.\nBei einer falschen Vorhersage gibt es pro abweichendem Stich -10 Punke und keinen Grundbetrag.\n\
Die Punktzahl wird anschließend mit dem bisherigen Punktestand eines Spielers verrechnet.
menu.instruction.variant.title=Spielvarianten
menu.instruction.variant.intro=Bei der Erstellung eines neuen Spiels können folgende 6 Varianten ausgewählt werden.
menu.instruction.variant.default=1) Default
menu.instruction.variant.default.description=Das Grundspiel mit den Grundregeln.
menu.instruction.variant.defaultpm1=2) Default PM1
menu.instruction.variant.defaultpm1.description=Das Grundspiel mit der Zusatzbedingung, dass die Vorhersage\nnicht der Rundenanzahl entsprechen darf.\n\
Das bedeutet: Der Tipp mindestens eines Spielers ist falsch.
menu.instruction.variant.anniversary2016=3) Anniversary 2016
menu.instruction.variant.anniversary2016.description=Das Grundspiel mit den Grundregeln und den Sonderkarten der Jubiläumsedition 2016.
menu.instruction.variant.anniversary2016pm1=4) Anniversary 2016 PM1
menu.instruction.variant.anniversary2016pm1.description=Das Grundspiel mit den Sonderkarten der Jubiläumsedition 2016, mit der\n\
Zusatzbedingung, dass die Vorhersage nicht der Rundenanzahl entsprechen darf.
menu.instruction.variant.anniversary2021=5) Anniversary 2021
menu.instruction.variant.anniversary2021.description=Das Grundspiel mit den Grundregeln und den Sonderkarten der Jubiläumsedition 2021.
menu.instruction.variant.anniversary2021pm1=6) Anniversary 2021 PM1
menu.instruction.variant.anniversary2021pm1.description=Das Grundspiel mit den Sonderkarten der Jubiläumsedition 2021, mit der\n\
Zusatzbedingung, dass die Vorhersage nicht der Rundenanzahl entsprechen darf.
menu.instruction.special_card.title=Sonderkarten
menu.connect.connect=Verbinden menu.connect.connect=Verbinden
menu.connect.back=Zurück menu.connect.back=Zurück
@ -46,6 +120,23 @@ menu.waiting.session_name.label=Sitzungsname
menu.waiting.session_uuid.label=Sitzungs-ID menu.waiting.session_uuid.label=Sitzungs-ID
menu.waiting.session_configuration.label=Spielvariante menu.waiting.session_configuration.label=Spielvariante
menu.error.malformed_message=Fehler: Missgebildete Nachricht
menu.error.unexpected_message=Fehler: Unerwartete Nachricht
menu.error.illegal_argument=Fehler: Illegales Argument
menu.error.not_found=Fehler: Nicht gefunden
menu.error.session_not_found=Fehler: Session nicht gefunden
menu.error.player_not_found=Fehler: Spieler nicht gefunden
menu.error.player_name_taken=Fehler: Spielername bereits vergeben
menu.error.player_name_not_allowed=Fehler: Spielername nicht erlaubt
menu.error.session_name_taken=Fehler: Sessionname bereits vergeben
menu.error.session_name_not_allowed=Fehler: Sessionname nicht erlaubt
menu.error.illegal_state=Fehler: Illegaler Zustand
menu.error.game_already_started=Fehler: Spiel hat bereits begonnen
menu.error.game_not_yet_started=Fehler: Spiel hat noch nicht begonnen
menu.error.session_full=Fehler: Session ist voll
menu.error.already_connected=Fehler: Bereits verbunden
menu.error.bad_request=Fehler: Schlechte Anfrage
menu.error.back=Zurück
game.message.play_card.other={0} muss eine Karte spielen game.message.play_card.other={0} muss eine Karte spielen
game.message.play_card.all=Jeder muss eine Karte spielen game.message.play_card.all=Jeder muss eine Karte spielen

@ -17,6 +17,26 @@ public enum Card {
WEREWOLF; WEREWOLF;
public enum Suit { public enum Suit {
NONE, YELLOW, RED, GREEN, BLUE NONE,
YELLOW {
public String toString() {
return "Gelb";
}
},
RED {
public String toString() {
return "Rot";
}
},
GREEN {
public String toString() {
return "Grün";
}
},
BLUE {
public String toString() {
return "Blau";
}
}
} }
} }
Loading…
Cancel
Save