diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Game.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Game.java index d7f923a..b632900 100644 --- a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Game.java +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Game.java @@ -40,14 +40,14 @@ public class Game { private Stack topBehavior = new Stack<>(); public Game(String gameId, List players) { - playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(null, this), this), this), this), this); + playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(new RepeatingCrossbowBehaviorHandler(null, this), this), this), this), this), this); setGameId(gameId); setPlayers(players); enterPhase(new Initial(this)); } public Game() { - playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(null,this), this), this), this), this); + playCardHandler = new DyingAskPeachBehaviorHandler(new PeachBehaviorHandler(new NormalActiveKillBehaviorHandler(new MinusMountsBehaviorHandler(new PlusMountsBehaviorHandler(new RepeatingCrossbowBehaviorHandler(null, this),this), this), this), this), this); } diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Round.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Round.java index f30a0e3..8b02cec 100644 --- a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Round.java +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/Round.java @@ -2,6 +2,7 @@ import com.gaas.threeKingdoms.handcard.HandCard; import com.gaas.threeKingdoms.handcard.basiccard.Kill; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; import com.gaas.threeKingdoms.player.Player; import lombok.Data; @@ -26,7 +27,9 @@ public boolean isPlayedValidCard(String cardId) { if (handCardOptional.isEmpty()) return false; HandCard handCard = handCardOptional.get(); - if (handCard instanceof Kill && isShowKill) { + if (handCard instanceof Kill && currentRoundPlayer.getEquipmentArmorCard() instanceof RepeatingCrossbowArmorCard) { + isShowKill = false; + } else if (handCard instanceof Kill && isShowKill) { throw new IllegalStateException("Player already played Kill Card"); } else if (handCard instanceof Kill) { isShowKill = true; diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/behavior/RepeatingCrossbowBehavior.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/behavior/RepeatingCrossbowBehavior.java new file mode 100644 index 0000000..0c7bc2f --- /dev/null +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/behavior/RepeatingCrossbowBehavior.java @@ -0,0 +1,50 @@ +package com.gaas.threeKingdoms.behavior.behavior; + +import com.gaas.threeKingdoms.Game; +import com.gaas.threeKingdoms.Round; +import com.gaas.threeKingdoms.behavior.Behavior; +import com.gaas.threeKingdoms.events.*; +import com.gaas.threeKingdoms.handcard.HandCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.ArmorCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.PlusMountsCard; +import com.gaas.threeKingdoms.player.Player; + +import java.util.List; + +public class RepeatingCrossbowBehavior extends Behavior { + public RepeatingCrossbowBehavior(Game game, Player behaviorPlayer, List reactionPlayers, Player currentReactionPlayer, String cardId, String playType, HandCard card) { + super(game, behaviorPlayer, reactionPlayers, currentReactionPlayer, cardId, playType, card, false, true); + } + + @Override + public List askTargetPlayerPlayCard() { + playerPlayCard(behaviorPlayer, behaviorPlayer, cardId); + ArmorCard armorCard = behaviorPlayer.getEquipment().getArmor(); + String originEquipmentId = ""; + if (armorCard != null) { + originEquipmentId = armorCard.getId(); + } + card.effect(behaviorPlayer); + + Round currentRound = game.getCurrentRound(); + RoundEvent roundEvent = new RoundEvent(currentRound); + List playerEvents = game.getPlayers().stream().map(PlayerEvent::new).toList(); + return List.of(new PlayCardEvent( + "出牌", + behaviorPlayer.getId(), + behaviorPlayer.getId(), + cardId, + playType, + game.getGameId(), + playerEvents, + roundEvent, + game.getGamePhase().getPhaseName()), + new PlayEquipmentCardEvent(behaviorPlayer.getId(), cardId, originEquipmentId)); + } + + @Override + protected List doAcceptedTargetPlayerPlayCard(String playerId, String targetPlayerId, String cardId, String playType) { + return null; + } +} diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/handler/RepeatingCrossbowBehaviorHandler.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/handler/RepeatingCrossbowBehaviorHandler.java new file mode 100644 index 0000000..17e24c3 --- /dev/null +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/behavior/handler/RepeatingCrossbowBehaviorHandler.java @@ -0,0 +1,41 @@ +package com.gaas.threeKingdoms.behavior.handler; + +import com.gaas.threeKingdoms.Game; +import com.gaas.threeKingdoms.behavior.Behavior; +import com.gaas.threeKingdoms.behavior.PlayCardBehaviorHandler; +import com.gaas.threeKingdoms.behavior.behavior.PlusMountsBehavior; +import com.gaas.threeKingdoms.handcard.HandCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; +import com.gaas.threeKingdoms.player.Player; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.stream.Collectors; + +public class RepeatingCrossbowBehaviorHandler extends PlayCardBehaviorHandler { + + public RepeatingCrossbowBehaviorHandler(PlayCardBehaviorHandler next, Game game) { + super(next, game); + } + + @Override + protected boolean match(String playerId, String cardId, List targetPlayerId, String playType) { + Player player = getPlayer(playerId); + Optional card = getCard(cardId, player); + return card.filter(handCard -> handCard instanceof RepeatingCrossbowArmorCard).isPresent(); + } + + @Override + protected Behavior doHandle(String playerId, String cardId, List targetPlayerId, String playType) { + Player player = game.getPlayer(playerId); + + List players = game.getPlayers().stream() + .map(Player::getId) + .collect(Collectors.toList()); + + HandCard card = player.getHand().getCard(cardId).orElseThrow(NoSuchElementException::new); + + return new PlusMountsBehavior(game, player, players, player, cardId, playType, card); + } +} diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/Deck.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/Deck.java index 42ed329..0f416ab 100644 --- a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/Deck.java +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/Deck.java @@ -3,6 +3,7 @@ import com.gaas.threeKingdoms.handcard.basiccard.Dodge; import com.gaas.threeKingdoms.handcard.basiccard.Kill; import com.gaas.threeKingdoms.handcard.basiccard.Peach; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.RedRabbitHorse; import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.ShadowHorse; import lombok.AllArgsConstructor; @@ -15,6 +16,8 @@ import java.util.stream.IntStream; import java.util.stream.Stream; +import static com.gaas.threeKingdoms.handcard.PlayCard.ECA066; + @Data @AllArgsConstructor public class Deck { @@ -28,6 +31,7 @@ public Deck() { cardDeck.add(new Dodge(PlayCard.BHK039)); cardDeck.add(new RedRabbitHorse(PlayCard.EH5044)); cardDeck.add(new ShadowHorse(PlayCard.ES5018)); + cardDeck.add(new RepeatingCrossbowArmorCard(ECA066)); }); shuffle(); } diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/ArmorCard.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/ArmorCard.java index c0d87a4..21a2a17 100644 --- a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/ArmorCard.java +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/ArmorCard.java @@ -2,10 +2,20 @@ import com.gaas.threeKingdoms.handcard.equipmentcard.EquipmentCard; import com.gaas.threeKingdoms.handcard.PlayCard; +import com.gaas.threeKingdoms.player.Player; +/** + * 諸葛連弩 + * */ public abstract class ArmorCard extends EquipmentCard { public ArmorCard(PlayCard playCard) { super(playCard); } + + @Override + public void effect(Player player) { + player.getEquipment().setArmor(this); + } + } diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/RepeatingCrossbowArmorCard.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/RepeatingCrossbowArmorCard.java new file mode 100644 index 0000000..9202c19 --- /dev/null +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/handcard/equipmentcard/armorcard/RepeatingCrossbowArmorCard.java @@ -0,0 +1,9 @@ +package com.gaas.threeKingdoms.handcard.equipmentcard.armorcard; + +import com.gaas.threeKingdoms.handcard.PlayCard; + +public class RepeatingCrossbowArmorCard extends ArmorCard { + public RepeatingCrossbowArmorCard(PlayCard playCard) { + super(playCard); + } +} diff --git a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/player/Player.java b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/player/Player.java index 1138054..c5d873c 100644 --- a/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/player/Player.java +++ b/LegendsOfTheThreeKingdoms/domain/src/main/java/com/gaas/threeKingdoms/player/Player.java @@ -3,6 +3,7 @@ import com.gaas.threeKingdoms.generalcard.GeneralCard; import com.gaas.threeKingdoms.handcard.HandCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.ArmorCard; import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.MinusMountsCard; import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.PlusMountsCard; import com.gaas.threeKingdoms.rolecard.RoleCard; @@ -55,6 +56,10 @@ public MinusMountsCard getEquipmentMinusOneMountsCard() { return equipment.getMinusOne(); } + public ArmorCard getEquipmentArmorCard() { + return equipment.getArmor(); + } + public void damage(int i) { bloodCard.setHp(getHP() - i); } diff --git a/LegendsOfTheThreeKingdoms/domain/src/test/java/com/gaas/threeKingdoms/PlayRepeatingCrossbowTest.java b/LegendsOfTheThreeKingdoms/domain/src/test/java/com/gaas/threeKingdoms/PlayRepeatingCrossbowTest.java new file mode 100644 index 0000000..94a862e --- /dev/null +++ b/LegendsOfTheThreeKingdoms/domain/src/test/java/com/gaas/threeKingdoms/PlayRepeatingCrossbowTest.java @@ -0,0 +1,266 @@ +package com.gaas.threeKingdoms; + +import com.gaas.threeKingdoms.builders.PlayerBuilder; +import com.gaas.threeKingdoms.gamephase.Normal; +import com.gaas.threeKingdoms.generalcard.General; +import com.gaas.threeKingdoms.generalcard.GeneralCard; +import com.gaas.threeKingdoms.handcard.basiccard.Dodge; +import com.gaas.threeKingdoms.handcard.basiccard.Kill; +import com.gaas.threeKingdoms.handcard.basiccard.Peach; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; +import com.gaas.threeKingdoms.player.*; +import com.gaas.threeKingdoms.rolecard.Role; +import com.gaas.threeKingdoms.rolecard.RoleCard; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static com.gaas.threeKingdoms.handcard.PlayCard.*; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PlayRepeatingCrossbowTest { + + @DisplayName(""" + Given + A的回合 + A有一張諸葛連弩 + + + When + A出諸葛連弩 + + Then + A玩家裝備卡有諸葛連弩 + """) + @Test + public void givenPlayerAHaveRepeatingCrossbow_WhenPlayerAPlayRepeatingCrossbow_ThenPlayerAEquipRepeatingCrossbow() { + Game game = new Game(); + + Player playerA = PlayerBuilder + .construct() + .withId("player-a") + .withHand(new Hand()) + .withBloodCard(new BloodCard(4)) + .withEquipment(new Equipment()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + playerA.getHand().addCardToHand(Arrays.asList(new Kill(BS8008), new Kill(BS8009), new Peach(BH3029), new Peach(BH4030), new Dodge(BH2028), new RepeatingCrossbowArmorCard(ECA066))); + + Player playerB = PlayerBuilder.construct() + .withId("player-b") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withEquipment(new Equipment()) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + + Player playerC = PlayerBuilder.construct() + .withId("player-c") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + Player playerD = PlayerBuilder.construct() + .withId("player-d") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + List players = asList( + playerA, playerB, playerC, playerD); + game.setPlayers(players); + game.enterPhase(new Normal(game)); + game.setCurrentRound(new Round(playerA)); + + //When + game.playerPlayCard(playerA.getId(), ECA066.getCardId(), playerA.getId(), "active"); + + //Then + assertEquals(ECA066.getCardId(), game.getPlayer("player-a").getEquipmentArmorCard().getId()); + } + + @DisplayName(""" + Given + 玩家ABCD + A的回合 + A有二張殺 + A有一張諸葛連弩 + B沒有閃 B HP =4 + D沒有閃 D HP =4 + + When + A對B出殺 + A對D出殺 + + Then + B HP=3 + D HP=3 + """) + @Test + public void givenPlayerAHaveRepeatingCrossbow_WhenPlayerAPlayKillToBAndD_ThenPlayerBandDHPEqualThree() { + Game game = new Game(); + + Equipment equipment = new Equipment(); + equipment.setArmor(new RepeatingCrossbowArmorCard(ECA066)); + + Player playerA = PlayerBuilder + .construct() + .withId("player-a") + .withHand(new Hand()) + .withBloodCard(new BloodCard(4)) + .withEquipment(equipment) + .withGeneralCard(new GeneralCard(General.劉備)) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + playerA.getHand().addCardToHand(Arrays.asList(new Kill(BS8008), new Kill(BS8009), new Peach(BH3029), new Peach(BH4030), new Dodge(BH2028))); + + Player playerB = PlayerBuilder.construct() + .withId("player-b") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withEquipment(new Equipment()) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + + Player playerC = PlayerBuilder.construct() + .withId("player-c") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + Player playerD = PlayerBuilder.construct() + .withId("player-d") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + List players = asList( + playerA, playerB, playerC, playerD); + game.setPlayers(players); + game.enterPhase(new Normal(game)); + game.setCurrentRound(new Round(playerA)); + + //When + game.playerPlayCard(playerA.getId(), BS8008.getCardId(), playerB.getId(), "active"); + game.playerPlayCard(playerB.getId(), "", playerA.getId(), "skip"); + + game.playerPlayCard(playerA.getId(), BS8009.getCardId(), playerD.getId(), "active"); + game.playerPlayCard(playerD.getId(), "", playerA.getId(), "skip"); + + //Then + assertEquals(3, game.getPlayer("player-b").getHP()); + assertEquals(3, game.getPlayer("player-d").getHP()); + } + + @DisplayName(""" + Given + A的回合 + A已經裝備諸葛連弩 + A有四張殺 + B玩家沒有閃 + B玩家HP=4 + + When + A對B出殺四次 + + + Then + B玩家HP=0 + + """) + @Test + public void givenPlayerAHaveRepeatingCrossbow_WhenPlayerAPlayKillToBFourTimesAndD_ThenPlayerBHPEqualZero() { + Game game = new Game(); + + Equipment equipment = new Equipment(); + equipment.setArmor(new RepeatingCrossbowArmorCard(ECA066)); + + Player playerA = PlayerBuilder + .construct() + .withId("player-a") + .withHand(new Hand()) + .withBloodCard(new BloodCard(4)) + .withEquipment(equipment) + .withGeneralCard(new GeneralCard(General.劉備)) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + playerA.getHand().addCardToHand(Arrays.asList(new Kill(BS8008), new Kill(BS8009), new Kill(BS8010), new Kill(BS7020), new Dodge(BH2028))); + + Player playerB = PlayerBuilder.construct() + .withId("player-b") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withEquipment(new Equipment()) + .withRoleCard(new RoleCard(Role.MONARCH)) + .build(); + + Player playerC = PlayerBuilder.construct() + .withId("player-c") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + Player playerD = PlayerBuilder.construct() + .withId("player-d") + .withBloodCard(new BloodCard(4)) + .withHand(new Hand()) + .withGeneralCard(new GeneralCard(General.劉備)) + .withHealthStatus(HealthStatus.ALIVE) + .withRoleCard(new RoleCard(Role.TRAITOR)) + .withEquipment(new Equipment()) + .build(); + + List players = asList( + playerA, playerB, playerC, playerD); + game.setPlayers(players); + game.enterPhase(new Normal(game)); + game.setCurrentRound(new Round(playerA)); + + //When + game.playerPlayCard(playerA.getId(), BS8008.getCardId(), playerB.getId(), "active"); + game.playerPlayCard(playerB.getId(), "", playerA.getId(), "skip"); + + game.playerPlayCard(playerA.getId(), BS8009.getCardId(), playerB.getId(), "active"); + game.playerPlayCard(playerB.getId(), "", playerA.getId(), "skip"); + + game.playerPlayCard(playerA.getId(), BS8010.getCardId(), playerB.getId(), "active"); + game.playerPlayCard(playerB.getId(), "", playerA.getId(), "skip"); + + game.playerPlayCard(playerA.getId(), BS7020.getCardId(), playerB.getId(), "active"); + game.playerPlayCard(playerB.getId(), "", playerA.getId(), "skip"); + + //Then + assertEquals(0, game.getPlayer("player-b").getHP()); + } + +} diff --git a/LegendsOfTheThreeKingdoms/spring/src/test/java/com/gaas/threeKingdoms/e2e/equipment/RepeatingCrossbowTest.java b/LegendsOfTheThreeKingdoms/spring/src/test/java/com/gaas/threeKingdoms/e2e/equipment/RepeatingCrossbowTest.java new file mode 100644 index 0000000..7d1f12a --- /dev/null +++ b/LegendsOfTheThreeKingdoms/spring/src/test/java/com/gaas/threeKingdoms/e2e/equipment/RepeatingCrossbowTest.java @@ -0,0 +1,141 @@ +package com.gaas.threeKingdoms.e2e.equipment; + +import com.gaas.threeKingdoms.e2e.JsonFileValidateHelper; +import com.gaas.threeKingdoms.e2e.MockMvcUtil; +import com.gaas.threeKingdoms.e2e.WebsocketUtil; +import com.gaas.threeKingdoms.generalcard.General; +import com.gaas.threeKingdoms.handcard.basiccard.Dodge; +import com.gaas.threeKingdoms.handcard.basiccard.Kill; +import com.gaas.threeKingdoms.handcard.basiccard.Peach; +import com.gaas.threeKingdoms.handcard.equipmentcard.armorcard.RepeatingCrossbowArmorCard; +import com.gaas.threeKingdoms.handcard.equipmentcard.mountscard.ShadowHorse; +import com.gaas.threeKingdoms.outport.GameRepository; +import com.gaas.threeKingdoms.player.HealthStatus; +import com.gaas.threeKingdoms.player.Player; +import com.gaas.threeKingdoms.rolecard.Role; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import static com.gaas.threeKingdoms.e2e.MockUtil.createPlayer; +import static com.gaas.threeKingdoms.e2e.MockUtil.initGame; +import static com.gaas.threeKingdoms.handcard.PlayCard.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@DirtiesContext +@AutoConfigureMockMvc +public class RepeatingCrossbowTest { + + @MockBean + private GameRepository repository; + + @Autowired + private MockMvc mockMvc; + + private MockMvcUtil mockMvcUtil; + + private JsonFileValidateHelper helper; + + private WebsocketUtil websocketUtil; + + @Value(value = "${local.server.port}") + private Integer port; + private final String gameId = "my-id"; + + @BeforeEach + public void setup() throws Exception { + mockMvcUtil = new MockMvcUtil(mockMvc); + websocketUtil = new WebsocketUtil(port, gameId); + helper = new JsonFileValidateHelper(websocketUtil); + } + + @Test + public void testPlayerAPlayRepeatingCrossbow() throws Exception { + //Given A玩家有諸葛連弩 + givenPlayerAPlayCardStatus(); + + // When A 玩家出諸葛連弩 + String currentPlayer = "player-a"; + String targetPlayerId = "player-a"; + String playedCardId = "ECA066"; + + mockMvcUtil.playCard(gameId, currentPlayer, targetPlayerId, playedCardId, "active") + .andExpect(status().isOk()).andReturn(); + + //Then A裝備有諸葛連弩 + String playerAPlayPeachJsonForA = websocketUtil.getValue("player-a"); + Path path = Paths.get("src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_a.json"); + String expectedJson = Files.readString(path); + assertEquals(expectedJson, playerAPlayPeachJsonForA); + + String playerAPlayPeachJsonForB = websocketUtil.getValue("player-b"); + path = Paths.get("src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_b.json"); + expectedJson = Files.readString(path); + assertEquals(expectedJson, playerAPlayPeachJsonForB); + + String playerAPlayPeachJsonForC = websocketUtil.getValue("player-c"); + path = Paths.get("src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_c.json"); + expectedJson = Files.readString(path); + assertEquals(expectedJson, playerAPlayPeachJsonForC); + + String playerAPlayPeachJsonForD = websocketUtil.getValue("player-d"); + path = Paths.get("src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_d.json"); + expectedJson = Files.readString(path); + assertEquals(expectedJson, playerAPlayPeachJsonForD); + } + + private void givenPlayerAPlayCardStatus() { + Player playerA = createPlayer( + "player-a", + 4, + General.劉備, + HealthStatus.ALIVE, + Role.MONARCH, + new Kill(BS8008), new Peach(BH3029), new Dodge(BH2028), new Dodge(BHK039), new ShadowHorse(ES5018), new RepeatingCrossbowArmorCard(ECA066) + ); + + Player playerB = createPlayer("player-b", + 4, + General.劉備, + HealthStatus.ALIVE, + Role.MINISTER, + new Kill(BS8008), new Peach(BH3029), new Peach(BH4030), new Dodge(BH2028) + ); + + Player playerC = createPlayer( + "player-c", + 4, + General.劉備, + HealthStatus.ALIVE, + Role.REBEL, + new Kill(BS8008), new Peach(BH3029), new Dodge(BH2028), new Dodge(BHK039) + ); + + Player playerD = createPlayer( + "player-d", + 4, + General.劉備, + HealthStatus.ALIVE, + Role.TRAITOR, + new Kill(BS8008), new Peach(BH3029), new Dodge(BH2028), new Dodge(BHK039) + ); + List players = Arrays.asList(playerA, playerB, playerC, playerD); + Mockito.when(repository.findById(gameId)).thenReturn(initGame(gameId, players, playerA)); + } + +} diff --git a/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_a.json b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_a.json new file mode 100644 index 0000000..891efa6 --- /dev/null +++ b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_a.json @@ -0,0 +1,78 @@ +{ + "events" : [ { + "event" : "PlayCardEvent", + "data" : { + "playerId" : "player-a", + "targetPlayerId" : "player-a", + "cardId" : "ECA066", + "playType" : "active" + }, + "message" : "出牌" + }, { + "event" : "PlayEquipmentEvent", + "data" : { + "playerId" : "player-a", + "cardId" : "ECA066", + "deprecatedCardId" : "" + }, + "message" : "玩家出裝備卡" + } ], + "data" : { + "seats" : [ { + "id" : "player-a", + "generalId" : "SHU001", + "roleId" : "Monarch", + "hp" : 4, + "hand" : { + "size" : 5, + "cardIds" : [ "BS8008", "BH3029", "BH2028", "BHK039", "ES5018" ] + }, + "equipments" : [ "", "", "ECA066", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-b", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-c", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-d", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + } ], + "round" : { + "roundPhase" : "Judgement", + "currentRoundPlayer" : "player-a", + "activePlayer" : "player-a", + "dyingPlayer" : "", + "showKill" : false + }, + "gamePhase" : "Normal" + }, + "message" : "出牌", + "gameId" : "my-id", + "playerId" : "player-a" +} \ No newline at end of file diff --git a/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_b.json b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_b.json new file mode 100644 index 0000000..060d0c1 --- /dev/null +++ b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_b.json @@ -0,0 +1,78 @@ +{ + "events" : [ { + "event" : "PlayCardEvent", + "data" : { + "playerId" : "player-a", + "targetPlayerId" : "player-a", + "cardId" : "ECA066", + "playType" : "active" + }, + "message" : "出牌" + }, { + "event" : "PlayEquipmentEvent", + "data" : { + "playerId" : "player-a", + "cardId" : "ECA066", + "deprecatedCardId" : "" + }, + "message" : "玩家出裝備卡" + } ], + "data" : { + "seats" : [ { + "id" : "player-a", + "generalId" : "SHU001", + "roleId" : "Monarch", + "hp" : 4, + "hand" : { + "size" : 5, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "ECA066", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-b", + "generalId" : "SHU001", + "roleId" : "Minister", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ "BS8008", "BH3029", "BH4030", "BH2028" ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-c", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-d", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + } ], + "round" : { + "roundPhase" : "Judgement", + "currentRoundPlayer" : "player-a", + "activePlayer" : "player-a", + "dyingPlayer" : "", + "showKill" : false + }, + "gamePhase" : "Normal" + }, + "message" : "出牌", + "gameId" : "my-id", + "playerId" : "player-b" +} \ No newline at end of file diff --git a/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_c.json b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_c.json new file mode 100644 index 0000000..3ee5318 --- /dev/null +++ b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_c.json @@ -0,0 +1,78 @@ +{ + "events" : [ { + "event" : "PlayCardEvent", + "data" : { + "playerId" : "player-a", + "targetPlayerId" : "player-a", + "cardId" : "ECA066", + "playType" : "active" + }, + "message" : "出牌" + }, { + "event" : "PlayEquipmentEvent", + "data" : { + "playerId" : "player-a", + "cardId" : "ECA066", + "deprecatedCardId" : "" + }, + "message" : "玩家出裝備卡" + } ], + "data" : { + "seats" : [ { + "id" : "player-a", + "generalId" : "SHU001", + "roleId" : "Monarch", + "hp" : 4, + "hand" : { + "size" : 5, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "ECA066", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-b", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-c", + "generalId" : "SHU001", + "roleId" : "Rebel", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ "BS8008", "BH3029", "BH2028", "BHK039" ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-d", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + } ], + "round" : { + "roundPhase" : "Judgement", + "currentRoundPlayer" : "player-a", + "activePlayer" : "player-a", + "dyingPlayer" : "", + "showKill" : false + }, + "gamePhase" : "Normal" + }, + "message" : "出牌", + "gameId" : "my-id", + "playerId" : "player-c" +} \ No newline at end of file diff --git a/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_d.json b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_d.json new file mode 100644 index 0000000..5e177be --- /dev/null +++ b/LegendsOfTheThreeKingdoms/spring/src/test/resources/TestJsonFile/EquipmentTest/PlayRepeatingCrossbow/player_a_playrepeatingcrossbow_for_player_d.json @@ -0,0 +1,78 @@ +{ + "events" : [ { + "event" : "PlayCardEvent", + "data" : { + "playerId" : "player-a", + "targetPlayerId" : "player-a", + "cardId" : "ECA066", + "playType" : "active" + }, + "message" : "出牌" + }, { + "event" : "PlayEquipmentEvent", + "data" : { + "playerId" : "player-a", + "cardId" : "ECA066", + "deprecatedCardId" : "" + }, + "message" : "玩家出裝備卡" + } ], + "data" : { + "seats" : [ { + "id" : "player-a", + "generalId" : "SHU001", + "roleId" : "Monarch", + "hp" : 4, + "hand" : { + "size" : 5, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "ECA066", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-b", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-c", + "generalId" : "SHU001", + "roleId" : "", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + }, { + "id" : "player-d", + "generalId" : "SHU001", + "roleId" : "Traitor", + "hp" : 4, + "hand" : { + "size" : 4, + "cardIds" : [ "BS8008", "BH3029", "BH2028", "BHK039" ] + }, + "equipments" : [ "", "", "", "" ], + "delayScrolls" : [ ] + } ], + "round" : { + "roundPhase" : "Judgement", + "currentRoundPlayer" : "player-a", + "activePlayer" : "player-a", + "dyingPlayer" : "", + "showKill" : false + }, + "gamePhase" : "Normal" + }, + "message" : "出牌", + "gameId" : "my-id", + "playerId" : "player-d" +} \ No newline at end of file