added sync before determining trump

main
Jonah Bauer 3 years ago
parent 65e50db2ae
commit f5c54bffaf

@ -1,26 +1,17 @@
package eu.jonahbauer.wizard.core.machine.states.round;
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
import eu.jonahbauer.wizard.common.model.Card;
import eu.jonahbauer.wizard.core.machine.states.GameData;
import eu.jonahbauer.wizard.core.machine.Game;
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
import eu.jonahbauer.wizard.common.messages.observer.TrumpMessage;
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
import eu.jonahbauer.wizard.common.messages.player.PickTrumpMessage;
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
import eu.jonahbauer.wizard.core.machine.GameState;
import eu.jonahbauer.wizard.core.model.card.GameCards;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.PICK_TRUMP;
public final class DeterminingTrump extends RoundState {
private transient UUID player;
private transient boolean werewolf;
public DeterminingTrump(GameData data) {
super(data.require(TRUMP_CARD).requireEach(PLAYERS, HANDS));
@ -35,74 +26,31 @@ public final class DeterminingTrump extends RoundState {
var player = entry.getKey();
var hand = entry.getValue();
if (hand.contains(Card.WEREWOLF)) {
this.player = player;
this.werewolf = true;
game.notify(new TrumpMessage(trumpCard, null));
game.notify(new TrumpMessage(Card.WEREWOLF, null));
game.notify(new UserInputMessage(this.player, PICK_TRUMP, getTimeout(game, true)));
return timeout(game);
var data = getData().with(CURRENT_PLAYER, player);
return sync(data, DeterminingTrumpUserInput::new);
}
}
// default trump handling
Card.Suit trumpSuit = trumpCard != null ? GameCards.get(trumpCard).getTrumpSuit() : Card.Suit.NONE;
if (trumpSuit == null) {
this.player = getDealer();
var player = getDealer();
game.notify(new TrumpMessage(trumpCard, null));
game.notify(new UserInputMessage(this.player, PICK_TRUMP, getTimeout(game, true)));
return timeout(game);
} else {
return transition(game, trumpSuit);
}
}
@Override
public Optional<GameState> onTimeout(Game game) {
game.notify(new TimeoutMessage());
Card.Suit[] suits;
if (werewolf) {
suits = new Card.Suit[]{Card.Suit.BLUE, Card.Suit.GREEN, Card.Suit.RED, Card.Suit.YELLOW, Card.Suit.NONE};
} else {
suits = new Card.Suit[]{Card.Suit.BLUE, Card.Suit.GREEN, Card.Suit.RED, Card.Suit.YELLOW};
}
return transition(game, suits[game.getRandom().nextInt(suits.length)]);
}
@Override
public Optional<GameState> onMessage(Game game, UUID player, PlayerMessage message) {
if (this.player.equals(player) && message instanceof PickTrumpMessage trumpMessage) {
checkTrumpSuit(trumpMessage.getTrumpSuit());
return transition(game, trumpMessage.getTrumpSuit());
var data = getData().with(CURRENT_PLAYER, player);
return sync(data, DeterminingTrumpUserInput::new);
} else {
return super.onMessage(game, player, message);
}
}
var data = getData().with(
TRUMP_SUIT, trumpSuit,
CURRENT_PLAYER, getNextPlayer(getDealer())
);
private void checkTrumpSuit(Card.Suit suit) {
if (!werewolf && suit == Card.Suit.NONE) {
throw new IllegalArgumentException("Trump suit must not be " + Card.Suit.NONE + ".");
} else if (suit == null) {
throw new IllegalArgumentException("Trump suit must not be null.");
}
}
private Optional<GameState> transition(Game game, @NotNull Card.Suit trumpSuit) {
GameData data = getData().with(
TRUMP_SUIT, trumpSuit,
CURRENT_PLAYER, getNextPlayer(getDealer())
);
if (werewolf) {
var mutableHands = new HashMap<>(get(HANDS));
var mutableHand = new ArrayList<>(mutableHands.get(player));
mutableHand.set(mutableHand.indexOf(Card.WEREWOLF), get(TRUMP_CARD));
mutableHands.put(player, List.copyOf(mutableHand));
data = data.with(HANDS, Map.copyOf(mutableHands));
game.notify(new TrumpMessage(Card.WEREWOLF, trumpSuit));
game.notify(player, new HandMessage(player, mutableHands.get(player)));
} else {
game.notify(new TrumpMessage(get(TRUMP_CARD), trumpSuit));
return sync(data, Predicting::new);
}
return sync(data, Predicting::new);
}
}

@ -0,0 +1,89 @@
package eu.jonahbauer.wizard.core.machine.states.round;
import eu.jonahbauer.wizard.common.messages.observer.HandMessage;
import eu.jonahbauer.wizard.common.messages.observer.TimeoutMessage;
import eu.jonahbauer.wizard.common.messages.observer.TrumpMessage;
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
import eu.jonahbauer.wizard.common.messages.player.PickTrumpMessage;
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
import eu.jonahbauer.wizard.common.model.Card;
import eu.jonahbauer.wizard.core.machine.Game;
import eu.jonahbauer.wizard.core.machine.GameState;
import eu.jonahbauer.wizard.core.machine.states.GameData;
import eu.jonahbauer.wizard.core.machine.states.TransientState;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import static eu.jonahbauer.wizard.common.messages.observer.UserInputMessage.Action.PICK_TRUMP;
import static eu.jonahbauer.wizard.core.machine.states.GameData.*;
import static eu.jonahbauer.wizard.core.machine.states.GameData.TRUMP_CARD;
public final class DeterminingTrumpUserInput extends RoundState implements TransientState {
private final transient UUID player;
private final transient boolean werewolf;
public DeterminingTrumpUserInput(GameData data) {
super(data.require(TRUMP_CARD).requireEach(PLAYERS, HANDS).require(CURRENT_PLAYER));
this.player = get(CURRENT_PLAYER);
this.werewolf = get(HANDS).get(this.player).contains(Card.WEREWOLF);
}
@Override
public Optional<GameState> onEnter(Game game) {
game.notify(new UserInputMessage(this.player, PICK_TRUMP, getTimeout(game, true)));
return timeout(game);
}
@Override
public Optional<GameState> onTimeout(Game game) {
game.notify(new TimeoutMessage());
Card.Suit[] suits;
if (werewolf) {
suits = new Card.Suit[] {Card.Suit.BLUE, Card.Suit.GREEN, Card.Suit.RED, Card.Suit.YELLOW, Card.Suit.NONE};
} else {
suits = new Card.Suit[] {Card.Suit.BLUE, Card.Suit.GREEN, Card.Suit.RED, Card.Suit.YELLOW};
}
return transition(game, suits[game.getRandom().nextInt(suits.length)]);
}
@Override
public Optional<GameState> onMessage(Game game, UUID player, PlayerMessage message) {
if (this.player.equals(player) && message instanceof PickTrumpMessage trumpMessage) {
checkTrumpSuit(trumpMessage.getTrumpSuit());
return transition(game, trumpMessage.getTrumpSuit());
} else {
return super.onMessage(game, player, message);
}
}
private void checkTrumpSuit(Card.Suit suit) {
if (!werewolf && suit == Card.Suit.NONE) {
throw new IllegalArgumentException("Trump suit must not be " + Card.Suit.NONE + ".");
} else if (suit == null) {
throw new IllegalArgumentException("Trump suit must not be null.");
}
}
private Optional<GameState> transition(Game game, @NotNull Card.Suit trumpSuit) {
GameData data = getData().with(
TRUMP_SUIT, trumpSuit,
CURRENT_PLAYER, getNextPlayer(getDealer())
);
if (werewolf) {
var mutableHands = new HashMap<>(get(HANDS));
var mutableHand = new ArrayList<>(mutableHands.get(player));
mutableHand.set(mutableHand.indexOf(Card.WEREWOLF), get(TRUMP_CARD));
mutableHands.put(player, List.copyOf(mutableHand));
data = data.with(HANDS, Map.copyOf(mutableHands));
game.notify(new TrumpMessage(Card.WEREWOLF, trumpSuit));
game.notify(player, new HandMessage(player, mutableHands.get(player)));
} else {
game.notify(new TrumpMessage(get(TRUMP_CARD), trumpSuit));
}
return sync(data, Predicting::new);
}
}

@ -38,7 +38,7 @@ public class DeterminingTrumpTest {
@SuppressWarnings("SameParameterValue")
private Game performTest(GameConfiguration configuration, int round, Map<UUID, List<Card>> hands, Card trumpCard, MessageQueue queue) {
Game game = spy(new Game(configuration, queue));
doFinish().when(game).transition(any(SyncState.class));
doFinish().when(game).transition(argThat(argument -> argument instanceof SyncState && argument.getData().has(TRUMP_SUIT)));
queue.setGame(game);
var playerList = List.of(players);
@ -92,7 +92,8 @@ public class DeterminingTrumpTest {
);
// play cards in given order
MessageQueue queue = new MessageQueue();
MessageQueue queue = new MessageQueue()
.sync(players);
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.GREEN_JESTER, queue);
@ -117,6 +118,7 @@ public class DeterminingTrumpTest {
// play cards in given order
MessageQueue queue = new MessageQueue()
.sync(players)
.addPickTrump(players[0], Card.Suit.GREEN);
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.BLUE_WIZARD, queue);
@ -144,6 +146,7 @@ public class DeterminingTrumpTest {
// play cards in given order
MessageQueue queue = new MessageQueue()
.sync(players)
.addPickTrump(players[3], Card.Suit.YELLOW);
Game game = performTest(Configurations.ANNIVERSARY_2021, 0, hands, Card.GREEN_1, queue);

@ -148,10 +148,11 @@ public class RoundTest {
@Test
public void run_Anniversary() throws ExecutionException, InterruptedException {
MessageQueue queue = new MessageQueue()
.sync(players)
.sync(players)
.sync(players) // starting_round
.sync(players) // dealing
.sync(players) // determining_trump
.addPickTrump(players[2], Card.Suit.YELLOW)
.sync(players)
.sync(players) // determining_trump
.addPrediction(players[3], 2)
.addPrediction(players[0], 2)
.addPrediction(players[1], 2)

Loading…
Cancel
Save