Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add 4ColorsCard usecase #99

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/main/java/domain/EffectHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Player> 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 地標]的建築物。
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/domain/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class Game {
@Builder.Default
private List<Dice> 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<Player> players) {
Expand Down Expand Up @@ -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<Player> getPlayersExcludeTurnPlayer() {
Expand All @@ -140,7 +145,7 @@ public List<DomainEvent> rollDice(String playerId, boolean isTwoDices) {

if (isTwoDices) {
currentDicePoint = dices.stream().mapToInt(Dice::throwDice).sum();
}else {
} else {
currentDicePoint = dices.get(0).throwDice();
}

Expand Down
195 changes: 176 additions & 19 deletions src/test/java/domain/GameTest.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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("""
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -132,31 +138,182 @@ 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();

// 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;
assertThat(playerA.getTotalCoins()).isEqualTo(effectCoins);
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

放在 mock 骰子物件下方。
這不是 when 的程式碼,而是 given 模擬的資料。
整個檔案出現類似的程式碼都套用這個規則

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when 要寫的是測試的動作,
Mockito.when(dice.throwDice()).thenReturn(2);
是在 given 的時候建立模擬丟骰子的資料

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);
Copy link
Collaborator

@shmily7829 shmily7829 Oct 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 應該要在 Game new 出來之後火車站才能翻牌,並且需要使用 Game 物件裡面的 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);
}
}