diff --git a/src/main/java/domain/EffectHandler.java b/src/main/java/domain/EffectHandler.java index 984786a..4a417d7 100644 --- a/src/main/java/domain/EffectHandler.java +++ b/src/main/java/domain/EffectHandler.java @@ -54,6 +54,20 @@ public void takeEffectGreen(Player turnPlayer, Bank bank, Establishment establis bank.payCoin(effectCoins); } + public void takeEffectPurple(Player turnPlayer, Player targetPlayer, int tradeEstablishmentIndex, int targetEstablishmentIndex, Establishment establishment, List players) { + if (establishment instanceof BusinessCenter) { + // 商業中心: 當你自己骰出這個數字時,你可以與其他玩家交換一間非[重要建築物 or 地標]的建築物。 + takeEffectBusinessCenter(turnPlayer, targetPlayer, tradeEstablishmentIndex, targetEstablishmentIndex); + } + if (establishment instanceof TvStation) { + // 電視台: 當你自己骰出這個數字時,你可以指定任意一位玩家給你5元。 + takeEffectTvStation(turnPlayer, targetPlayer); + } + if (establishment instanceof Stadium) { + // 體育館: 當你自己骰出這個數字時,每位玩家都必須給你2元。 + takeEffectStadium(turnPlayer, players); + } + } public void takeEffectBusinessCenter(Player turnPlayer, Player targetPlayer, int tradeEstablishmentIndex, int targetEstablishmentIndex) { // 商業中心: 當你自己骰出這個數字時,你可以與其他玩家交換一間非[重要建築物 or 地標]的建築物。 diff --git a/src/main/java/domain/Game.java b/src/main/java/domain/Game.java index 19f37fe..8892d77 100644 --- a/src/main/java/domain/Game.java +++ b/src/main/java/domain/Game.java @@ -26,7 +26,9 @@ public class Game { @Builder.Default private List dices = List.of(new Dice(), new Dice()); private int currentDicePoint = 0; + private int targetEstablishmentIndex = 0; private Player turnPlayer; + private Player targetPlayer; private Marketplace marketplace; public Game(List players) { @@ -120,6 +122,9 @@ public void takeAllPlayersEffect() { var turnPlayerGreenCards = turnPlayer.getEstablishments(currentDicePoint, IndustryColor.GREEN); turnPlayerGreenCards.forEach(greenEstablishment -> effectHandler.takeEffectGreen(turnPlayer, bank, greenEstablishment)); + var purpleOwnCardPlayers = turnPlayer.getEstablishments(currentDicePoint, IndustryColor.PURPLE); + purpleOwnCardPlayers.forEach(purpleEstablishment -> + effectHandler.takeEffectPurple(turnPlayer, targetPlayer,targetEstablishmentIndex,targetEstablishmentIndex,purpleEstablishment,players)); } public List getPlayersExcludeTurnPlayer() { @@ -140,7 +145,7 @@ public List rollDice(String playerId, boolean isTwoDices) { if (isTwoDices) { currentDicePoint = dices.stream().mapToInt(Dice::throwDice).sum(); - }else { + } else { currentDicePoint = dices.get(0).throwDice(); } diff --git a/src/test/java/domain/GameTest.java b/src/test/java/domain/GameTest.java index 9fae194..8281fdb 100644 --- a/src/test/java/domain/GameTest.java +++ b/src/test/java/domain/GameTest.java @@ -1,13 +1,10 @@ package domain; -import domain.card.establishment.AppleOrchard; -import domain.card.establishment.Bakery; -import domain.card.establishment.Cafe; -import domain.card.establishment.ConvenienceStore; -import domain.card.establishment.Establishment; -import domain.card.establishment.WheatField; +import domain.card.establishment.*; import domain.card.landmark.Landmark; import domain.card.landmark.ShoppingMall; +import domain.card.landmark.TrainStation; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -22,6 +19,20 @@ class GameTest { + private Bank bank; + private Player playerA; + private Player playerB; + private Player playerC; + private Player playerD; + + @BeforeEach + void setUp() { + playerA = Player.builder().id("A01").name("A").build(); + playerB = Player.builder().id("B01").name("B").build(); + playerC = Player.builder().id("C01").name("C").build(); + playerD = Player.builder().id("D01").name("D").build(); + bank = new Bank(); + } @Test @DisplayName(""" @@ -78,13 +89,8 @@ private long getEstablishmentCount(Player player, Establishment establishment) { @Test void test1() { - Bank bank = new Bank(); - var players = List.of(new Player("A"), new Player("B"), new Player("C"), new Player("D")); + var players = List.of(playerA, playerB, playerC, playerD); Game game = new Game(bank, players, new Marketplace()); - var playerA = players.get(0); - var playerB = players.get(1); - var playerC = players.get(2); - var playerD = players.get(3); playerA.gainCoin(30); playerB.gainCoin(30); @@ -132,18 +138,19 @@ void test1() { // given Dice dice = Mockito.mock(Dice.class); - HandCard handCard = new HandCard(); - handCard.addHandCard(new ConvenienceStore()); - handCard.addHandCard(new ConvenienceStore()); - handCard.flipLandMark(ShoppingMall.class); - Player playerA = Player.builder().id("id").name("A").coins(0).handCard(handCard).build(); + Landmark shoppingMall = playerA.getLandMark("購物中心"); + playerA.addCardToHandCard(new ConvenienceStore()); + playerA.addCardToHandCard(new ConvenienceStore()); + //避免玩家沒有足夠的錢建造購物中心建築物 + playerA.gainCoin(10); + playerA.flipLandMark(shoppingMall, bank); Game game = Game.builder() .players(List.of(playerA)) .turnPlayer(playerA) .currentDicePoint(4) .dices(List.of(dice)) - .bank(new Bank()) + .bank(bank) .build(); var originalBankCoins = game.getBank().getTotalCoin(); @@ -151,7 +158,9 @@ void test1() { // when Mockito.when(dice.throwDice()).thenReturn(4); game.rollDice(playerA.getId(), false); - int covenienceSize = handCard.getEstablishments(ConvenienceStore.class).size(); + int covenienceSize = playerA.getHandCard().getEstablishments().stream() + .mapToInt(e -> e instanceof ConvenienceStore ? 1 : 0) + .sum(); // then var effectCoins = (ConvenienceStore.EFFECT_COINS + ShoppingMall.BONUS) * covenienceSize; @@ -159,4 +168,152 @@ void test1() { assertThat(game.getBank().getTotalCoin()).isEqualTo(originalBankCoins - effectCoins); } + + @Test + @DisplayName(""" + 當玩家B有2張麵包店,且輪到B擲骰子 + 當骰子擲出點數為2時 + B可以從銀行得到2元 + """) + void greenCardbackeryCardTest() { + // given + Dice dice = Mockito.mock(Dice.class); + + playerB.addCardToHandCard(new Bakery()); + playerB.addCardToHandCard(new Bakery()); + + Game game = Game.builder() + .players(List.of(playerB)) + .turnPlayer(playerB) + .currentDicePoint(2) + .dices(List.of(dice)) + .bank(bank) + .build(); + + var originalBankCoins = game.getBank().getTotalCoin(); + + // when + Mockito.when(dice.throwDice()).thenReturn(2); + game.rollDice(playerB.getId(), false); + + // then + //TODO 命名為具有領域意義的名稱,會更好理解 + int totalBakeryBonuses = playerB.getHandCard().getEstablishments().stream() + .mapToInt(e -> e instanceof Bakery ? 1 : 0) + .sum(); + assertThat(playerB.getTotalCoins()).isEqualTo(totalBakeryBonuses); + assertThat(game.getBank().getTotalCoin()).isEqualTo(originalBankCoins - totalBakeryBonuses); + } + + @Test + @DisplayName(""" + 當玩家A有2張麵包店,且輪到A擲骰子 + 當玩家B有2張森林 + 當玩家C有1張森林 + 當A骰子擲出點數為5時, + B可以從銀行得到2元,C可以從銀行得到1元 + """) + void buleCardForestTest() { + // given + Dice dice = Mockito.mock(Dice.class); + + playerA.addCardToHandCard(new Bakery()); + playerA.addCardToHandCard(new Bakery()); + playerB.addCardToHandCard(new Forest()); + playerB.addCardToHandCard(new Forest()); + playerC.addCardToHandCard(new Forest()); + + Game game = Game.builder() + .players(List.of(playerA, playerB, playerC)) + .turnPlayer(playerA) + .currentDicePoint(5) + .dices(List.of(dice)) + .bank(bank) + .build(); + + var originalBankCoins = game.getBank().getTotalCoin(); + + // when + Mockito.when(dice.throwDice()).thenReturn(5); + game.rollDice(playerA.getId(), false); + + // then + assertThat(playerA.getTotalCoins()).isEqualTo(0); + assertThat(playerB.getTotalCoins()).isEqualTo(2); + assertThat(playerC.getTotalCoins()).isEqualTo(1); + } + + @Test + @DisplayName(""" + 當玩家A有1張體育館,且輪到A擲骰子 + 當玩家B有10元 + 當玩家C有6元 + 當A骰子擲出點數為6時, + B跟C玩家各自要給A 2元 + """) + void purpleStatdiumTest() { + // given + Dice dice = Mockito.mock(Dice.class); + Stadium stadium = new Stadium(); + + playerA.addCardToHandCard(stadium); + playerB.gainCoin(10); + playerC.gainCoin(6); + + Game game = Game.builder() + .players(List.of(playerA, playerB, playerC)) + .turnPlayer(playerA) + .currentDicePoint(6) + .dices(List.of(dice)) + .bank(bank) + .build(); + + var originalBankCoins = game.getBank().getTotalCoin(); + + // when + Mockito.when(dice.throwDice()).thenReturn(6); + game.rollDice(playerA.getId(), false); + // then + assertThat(playerA.getTotalCoins()).isEqualTo(4); + assertThat(playerB.getTotalCoins()).isEqualTo(8); + assertThat(playerC.getTotalCoins()).isEqualTo(4); + } + + @Test + @DisplayName(""" + 當玩家A有2張麵包店、火車站跟10元,且輪到A擲骰子 + 當玩家B有1張家庭餐廳 + 當A骰子擲出點數為10時, + A要給B 2塊 + """) + void redCardFamilyRestaurantTest() { + // given + Dice dice1 = Mockito.mock(Dice.class); + Dice dice2 = Mockito.mock(Dice.class); + playerA.addCardToHandCard(new Bakery()); + playerA.addCardToHandCard(new Bakery()); + + Landmark trainStation = playerA.getLandMark("火車站"); + //避免玩家沒有足夠的錢建造購物中心建築物 + playerA.gainCoin(10); + playerA.flipLandMark(trainStation, bank); + playerB.addCardToHandCard(new FamilyRestaurant()); + + Game game = Game.builder() + .players(List.of(playerA, playerB)) + .turnPlayer(playerA) + .currentDicePoint(10) + .dices(List.of(dice1, dice2)) + .bank(bank)//這裡不是很確定 + .build(); + + // when + Mockito.when(dice1.throwDice()).thenReturn(5); + Mockito.when(dice2.throwDice()).thenReturn(5); + game.rollDice(playerA.getId(), true); + + //then + assertThat(playerA.getTotalCoins()).isEqualTo(4);//10-4-2 + assertThat(playerB.getTotalCoins()).isEqualTo(2); + } }