Skip to content

Commit

Permalink
add new api of equipment effect
Browse files Browse the repository at this point in the history
  • Loading branch information
scolleyHuang committed May 7, 2024
1 parent c2b6479 commit 265cb32
Show file tree
Hide file tree
Showing 23 changed files with 573 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.gaas.threeKingdoms.usecase;

import com.gaas.threeKingdoms.Game;
import com.gaas.threeKingdoms.events.DomainEvent;
import com.gaas.threeKingdoms.handcard.EquipmentPlayType;
import com.gaas.threeKingdoms.outport.GameRepository;
import jakarta.inject.Named;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

import java.util.List;

@RequiredArgsConstructor
@Named
public class UseEquipmentUseCase {
private final GameRepository gameRepository;

public void execute(String gameId, UseEquipmentRequest request, UseEquipmentPresenter presenter) {
Game game = gameRepository.findById(gameId);
List<DomainEvent> events = game.playerUseEquipment(request.playerId, request.cardId, request.targetPlayerId, request.playType);
gameRepository.save(game);
presenter.renderEvents(events);
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class UseEquipmentRequest {
private String playerId;
private String targetPlayerId;
private String cardId;
private EquipmentPlayType playType;
}

public interface UseEquipmentPresenter<T> {
void renderEvents(List<DomainEvent> events);

T present();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
import com.gaas.threeKingdoms.behavior.Behavior;
import com.gaas.threeKingdoms.behavior.PlayCardBehaviorHandler;
import com.gaas.threeKingdoms.behavior.handler.*;
import com.gaas.threeKingdoms.effect.EffectHandler;
import com.gaas.threeKingdoms.effect.EightDiagramTacticEffectHandler;
import com.gaas.threeKingdoms.effect.EquipmentEffectHandler;
import com.gaas.threeKingdoms.effect.EightDiagramTacticEquipmentEffectHandler;
import com.gaas.threeKingdoms.events.*;
import com.gaas.threeKingdoms.gamephase.*;
import com.gaas.threeKingdoms.generalcard.GeneralCard;
import com.gaas.threeKingdoms.generalcard.GeneralCardDeck;
import com.gaas.threeKingdoms.handcard.Deck;
import com.gaas.threeKingdoms.handcard.Graveyard;
import com.gaas.threeKingdoms.handcard.HandCard;
import com.gaas.threeKingdoms.handcard.PlayType;
import com.gaas.threeKingdoms.handcard.*;
import com.gaas.threeKingdoms.player.BloodCard;
import com.gaas.threeKingdoms.player.Hand;
import com.gaas.threeKingdoms.player.HealthStatus;
Expand Down Expand Up @@ -40,10 +37,10 @@ public class Game {
private List<Player> winners;
private PlayCardBehaviorHandler playCardHandler;
private Stack<Behavior> topBehavior = new Stack<>();
private EffectHandler effectHandler;
private EquipmentEffectHandler equipmentEffectHandler;

public Game(String gameId, List<Player> players) {
effectHandler = new EightDiagramTacticEffectHandler(null, this);
equipmentEffectHandler = new EightDiagramTacticEquipmentEffectHandler(null, this);
playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(new RepeatingCrossbowBehaviorHandler(new EightDiagramTacticBehaviorHandler(null,this), this), this), this), this), this), this);
setGameId(gameId);
setPlayers(players);
Expand All @@ -52,7 +49,7 @@ public Game(String gameId, List<Player> players) {

public Game() {
playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(new RepeatingCrossbowBehaviorHandler(new EightDiagramTacticBehaviorHandler(null,this), this),this), this), this), this), this);
effectHandler = new EightDiagramTacticEffectHandler(null, this);
equipmentEffectHandler = new EightDiagramTacticEquipmentEffectHandler(null, this);
}


Expand Down Expand Up @@ -238,7 +235,7 @@ public List<DomainEvent> playerPlayCard(String playerId, String cardId, String t

if (!topBehavior.isEmpty()) {
Behavior behavior = topBehavior.peek();
List<DomainEvent> effectEvents = Optional.ofNullable(effectHandler.handle(playerId,cardId, targetPlayerId, PlayType.getPlayType(playType))).orElse(new ArrayList<>());
// List<DomainEvent> effectEvents = Optional.ofNullable(effectHandler.handle(playerId,cardId, targetPlayerId, PlayType.getPlayType(playType))).orElse(new ArrayList<>());
List<DomainEvent> acceptedEvent = behavior.acceptedTargetPlayerPlayCard(playerId, targetPlayerId, cardId, playType); //throw Exception When isNotValid
if (behavior.isOneRound()) {
topBehavior.pop();
Expand All @@ -247,8 +244,8 @@ public List<DomainEvent> playerPlayCard(String playerId, String cardId, String t
// 把新打出的牌加到 stack ,如果是使用裝備卡則不會放入
updateTopBehavior(playCardHandler.handle(playerId, cardId, List.of(targetPlayerId), playType));
}
effectEvents.addAll(acceptedEvent);
return effectEvents;
// effectEvents.addAll(acceptedEvent);
return acceptedEvent;
}
Behavior behavior = playCardHandler.handle(playerId, cardId, List.of(targetPlayerId), playType);
if (behavior.isTargetPlayerNeedToResponse()){
Expand All @@ -258,6 +255,10 @@ public List<DomainEvent> playerPlayCard(String playerId, String cardId, String t
return events;
}

public List<DomainEvent> playerUseEquipment(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType) {
return Optional.ofNullable(equipmentEffectHandler.handle(playerId,cardId, targetPlayerId, playType)).orElse(new ArrayList<>());
}

public void playerDeadSettlement() {
Player deathPlayer = currentRound.getDyingPlayer();
if (deathPlayer.getRoleCard().getRole().equals(Role.MONARCH)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ private boolean isSkip(String playType) {
return PlayType.SKIP.getPlayType().equals(playType);
}

private boolean executeEquipmentEffect(String playType) {
return PlayType.EQUIPMENT_ACTIVE.getPlayType().equals(playType);
}

private boolean skipEquipmentEffect(String playType) {
return PlayType.EQUIPMENT_SKIP.getPlayType().equals(playType);
}
// private boolean executeEquipmentEffect(String playType) {
// return PlayType.EQUIPMENT_ACTIVE.getPlayType().equals(playType);
// }
//
// private boolean skipEquipmentEffect(String playType) {
// return PlayType.EQUIPMENT_SKIP.getPlayType().equals(playType);
// }

private PlayerDamagedEvent createPlayerDamagedEvent(int originalHp, Player damagedPlayer) {
return new PlayerDamagedEvent(damagedPlayer.getId(), originalHp, damagedPlayer.getHP());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,55 @@
package com.gaas.threeKingdoms.effect;

import com.gaas.threeKingdoms.Game;
import com.gaas.threeKingdoms.Round;
import com.gaas.threeKingdoms.events.DomainEvent;
import com.gaas.threeKingdoms.events.EffectEvent;
import com.gaas.threeKingdoms.events.RoundEvent;
import com.gaas.threeKingdoms.handcard.EquipmentPlayType;
import com.gaas.threeKingdoms.handcard.HandCard;
import com.gaas.threeKingdoms.handcard.PlayType;
import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.ArmorCard;
import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.EightDiagramTactic;
import com.gaas.threeKingdoms.player.Player;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class EightDiagramTacticEffectHandler extends EffectHandler {
public class EightDiagramTacticEquipmentEffectHandler extends EquipmentEffectHandler {

public EightDiagramTacticEffectHandler(EffectHandler next, Game game) {
public EightDiagramTacticEquipmentEffectHandler(EquipmentEffectHandler next, Game game) {
super(next, game);
}

@Override
protected boolean match(String playerId, String cardId, String targetPlayerId, PlayType playType) {
protected boolean match(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType) {
Player player = getPlayer(playerId);
Optional<HandCard> card = Optional.ofNullable(player.getEquipmentArmorCard());
boolean isEightDiagramTactic = card.filter(armorCard -> armorCard instanceof EightDiagramTactic && cardId.equals(armorCard.getId())).isPresent();
boolean isEquipmentPlayType = playType.equals(PlayType.EQUIPMENT_ACTIVE) || playType.equals(PlayType.EQUIPMENT_SKIP);
return (isEightDiagramTactic && isEquipmentPlayType);
return card.filter(armorCard -> armorCard instanceof EightDiagramTactic && cardId.equals(armorCard.getId())).isPresent();
}

@Override
protected List<DomainEvent> doHandle(String playerId, String cardId, String targetPlayerId, PlayType playType) {
protected List<DomainEvent> doHandle(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType) {
if (skipEquipmentEffect(playType)) {
game.peekTopBehavior().setIsOneRound(false);
return new ArrayList<>();
}
Player player = getPlayer(playerId);
ArmorCard armorCard = player.getEquipment().getArmor();

List<DomainEvent> domainEvents = armorCard.equipmentEffect(game);

boolean isEightDiagramTacticEffectSuccess = domainEvents.stream()
.map(EffectEvent.class::cast)
.allMatch(EffectEvent::isSuccess);

game.peekTopBehavior().setIsOneRound(isEightDiagramTacticEffectSuccess);
return domainEvents;
}

private boolean skipEquipmentEffect(PlayType playType) {
return PlayType.EQUIPMENT_SKIP == playType;
private boolean skipEquipmentEffect(EquipmentPlayType equipmentPlayType) {
return equipmentPlayType.equals(EquipmentPlayType.SKIP);
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.gaas.threeKingdoms.effect;

import com.gaas.threeKingdoms.Game;
import com.gaas.threeKingdoms.behavior.Behavior;
import com.gaas.threeKingdoms.events.DomainEvent;
import com.gaas.threeKingdoms.events.EffectEvent;
import com.gaas.threeKingdoms.handcard.PlayType;
import com.gaas.threeKingdoms.handcard.EquipmentPlayType;
import com.gaas.threeKingdoms.player.Player;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
Expand All @@ -14,11 +12,11 @@

@AllArgsConstructor
@NoArgsConstructor
public abstract class EffectHandler {
protected EffectHandler next;
public abstract class EquipmentEffectHandler {
protected EquipmentEffectHandler next;
protected Game game;

public List<DomainEvent> handle(String playerId, String cardId, String targetPlayerId, PlayType playType) {
public List<DomainEvent> handle(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType) {
if (match(playerId, cardId, targetPlayerId, playType)) {
return doHandle(playerId, cardId, targetPlayerId, playType);
} else if (next != null) {
Expand All @@ -27,9 +25,9 @@ public List<DomainEvent> handle(String playerId, String cardId, String targetPla
return new ArrayList<>();
}

protected abstract boolean match(String playerId, String cardId, String targetPlayerId, PlayType playType);
protected abstract boolean match(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType);

protected abstract List<DomainEvent> doHandle(String playerId, String cardId, String targetPlayerId, PlayType playType);
protected abstract List<DomainEvent> doHandle(String playerId, String cardId, String targetPlayerId, EquipmentPlayType playType);

protected Player getPlayer(String playerId) {
return game.getPlayer(playerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ public class AskPlayEquipmentEffectEvent extends DomainEvent {
private final String playerId;
private final EquipmentCard equipmentCard;


// public AskPlayEquipmentEffectEvent(String playerId, String equipmentId, String equipmentName) {
public AskPlayEquipmentEffectEvent(String playerId, EquipmentCard equipmentCard) {
super("AskPlayEquipmentEffectEvent", String.format("請問是否要發動裝備卡%s的效果", equipmentCard.getName()));
this.playerId = playerId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@

import lombok.Getter;

import java.util.List;

@Getter
public class EffectEvent extends DomainEvent {
private final boolean isSuccess;
public EffectEvent(String name, String message, boolean isSuccess) {
private String gameId;
private List<PlayerEvent> seats;
private RoundEvent round;
private String gamePhase;

public EffectEvent(boolean isSuccess, String message, String gameId, List<PlayerEvent> seats, String name, RoundEvent round, String gamePhase) {
super(name, message);
this.isSuccess = isSuccess;
this.gameId = gameId;
this.seats = seats;
this.round = round;
this.gamePhase = gamePhase;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@

import lombok.Getter;

import java.util.List;

@Getter
public class EightDiagramTacticEffectEvent extends EffectEvent {
private final String drawCardId;

public EightDiagramTacticEffectEvent(String message, String drawCardId, boolean isSuccess) {
super("EightDiagramTacticEffectEvent", message, isSuccess);
public EightDiagramTacticEffectEvent(String message, boolean isSuccess,String drawCardId, String gameId, List<PlayerEvent> seats, RoundEvent round, String gamePhase) {
super(isSuccess, message, gameId, seats, "EightDiagramTacticEffectEvent", round, gamePhase);
this.drawCardId = drawCardId;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.gaas.threeKingdoms.handcard;

import java.util.Arrays;

public enum EquipmentPlayType {

ACTIVE("equipmentActive"),
SKIP("equipmentSkip");

private final String playType;

public String getPlayType() {
return playType;
}

EquipmentPlayType(String playType) {
this.playType = playType;
}

public static EquipmentPlayType getPlayType(String playType) {
return Arrays.stream(EquipmentPlayType.values()).filter(equipmentPlayType -> equipmentPlayType.getPlayType().equals(playType)).findFirst()
.orElseThrow();
}

public static void checkPlayTypeIsValid(String value) {
for (PlayType type : PlayType.values()) {
if (type.getPlayType().equals(value)) {
return;
}
}
throw new IllegalArgumentException(String.format("Play type [%s] not valid.", value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ public enum PlayType {

SKIP("skip"),
ACTIVE("active"),
INACTIVE("inactive"),
EQUIPMENT_ACTIVE("equipmentActive"),
EQUIPMENT_SKIP("equipmentSkip");
INACTIVE("inactive");

private final String playType;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.gaas.threeKingdoms.handcard.equipmentcard.armorcard;

import com.gaas.threeKingdoms.Game;
import com.gaas.threeKingdoms.Round;
import com.gaas.threeKingdoms.events.DomainEvent;
import com.gaas.threeKingdoms.events.EightDiagramTacticEffectEvent;
import com.gaas.threeKingdoms.events.PlayerEvent;
import com.gaas.threeKingdoms.events.RoundEvent;
import com.gaas.threeKingdoms.handcard.HandCard;
import com.gaas.threeKingdoms.handcard.PlayCard;
import com.gaas.threeKingdoms.handcard.Suit;
Expand All @@ -22,7 +25,13 @@ public List<DomainEvent> equipmentEffect(Game game) {
HandCard card = game.drawCardForEightDiagramTactic();
boolean isEffectSuccess = isEffectSuccess(card);
List<DomainEvent> events = new ArrayList<>();
events.add(new EightDiagramTacticEffectEvent("發動八卦陣效果", card.getId(), isEffectSuccess));
List<PlayerEvent> playerEvents = game.getPlayers().stream().map(PlayerEvent::new).toList();
Round currentRound = game.getCurrentRound();
if (isEffectSuccess) {
currentRound.setActivePlayer(currentRound.getCurrentRoundPlayer());
}
RoundEvent roundEvent = new RoundEvent(currentRound);
events.add(new EightDiagramTacticEffectEvent("發動八卦陣效果", isEffectSuccess, card.getId(),game.getGameId(), playerEvents, roundEvent, game.getGamePhase().getPhaseName()));
return events;
}

Expand Down
Loading

0 comments on commit 265cb32

Please sign in to comment.