Skip to content

Commit

Permalink
add playerBuyCardUseCase & Refactor GameController
Browse files Browse the repository at this point in the history
fix playerTest error
  • Loading branch information
huangken8511429 committed Sep 10, 2023
1 parent 2bfa2f3 commit 54d6f47
Show file tree
Hide file tree
Showing 24 changed files with 507 additions and 164 deletions.
8 changes: 5 additions & 3 deletions src/main/java/app/usecase/BuyCardUseCase.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.usecase;

import app.exception.NotFoundException;
import app.output.GameRepository;
import domain.Game;
import domain.events.DomainEvent;
Expand All @@ -10,21 +11,21 @@

import javax.inject.Named;
import java.util.List;
import java.util.NoSuchElementException;

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

public void execute(Request request, Presenter presenter) {
Game game = findGameById(request.gameId);
List<DomainEvent> events = game.turnPlayerBuyCard(request.getType(), request.getCardName());
List<DomainEvent> events = game.turnPlayerBuyCard(request.getPlayerId(), request.getType(), request.getCardName());
gameRepository.save(game);
presenter.present(events);
}

private Game findGameById(String gameId) {
return gameRepository.findById(gameId).orElseThrow(NoSuchElementException::new);
return gameRepository.findById(gameId).orElseThrow(NotFoundException::new);
}


Expand All @@ -36,6 +37,7 @@ public static class Request {
private String playerId;
private String type;
private String cardName;

}

public interface Presenter {
Expand Down
53 changes: 42 additions & 11 deletions src/main/java/domain/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
import domain.card.establishment.Establishment;
import domain.card.establishment.IndustryColor;
import domain.card.establishment.WheatField;
import domain.card.landmark.Landmark;
import domain.card.landmark.TrainStation;
import domain.events.BuyEstablishmentEvent;
import domain.events.BuyCardEvent;
import domain.events.DomainEvent;
import domain.events.GameOverEvent;
import domain.events.RollDiceEvent;
import domain.exceptions.MachiKoroException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;

@Builder
@Data
Expand Down Expand Up @@ -60,7 +63,6 @@ public Bank getBank() {
}

public void setUp() {

for (Player player : players) {
player.gainCoin(3);
bank.payCoin(3);
Expand All @@ -70,6 +72,10 @@ public void setUp() {
}
}

public Player getPlayer(String playerId) {
return players.stream().filter(player -> playerId.equals(player.getId())).findFirst().orElseThrow();
}

public List<Player> getPlayers() {
return players;
}
Expand Down Expand Up @@ -110,9 +116,7 @@ public List<Player> getPlayersExcludeTurnPlayer() {
}

public List<DomainEvent> rollDice(String playerId, int diceCount) {
if (!playerId.equals(turnPlayer.getId())) {
throw new IllegalArgumentException("Turn player id is incorrect");
}
checkIsTurnPlayer(playerId);

if ((diceCount > 1 && !turnPlayer.hasLandmarkFlipped(TrainStation.class)) || diceCount > 2 || diceCount < 1) {
throw new IllegalArgumentException("Invalid quantity of dice");
Expand All @@ -126,14 +130,41 @@ public List<DomainEvent> rollDice(String playerId, int diceCount) {
return List.of(event);
}

public List<DomainEvent> turnPlayerBuyCard(String type, String cardName) {
public List<DomainEvent> turnPlayerBuyCard(String playerId, String type, String cardName) {
checkIsTurnPlayer(playerId);
if ("Establishment".equals(type)) {
Establishment establishment = marketplace.findEstablishmentByName(cardName);
turnPlayer.addCardToHandCard(establishment);
turnPlayer.buyEstablishment(establishment, bank);
marketplace.removeEstablishment(establishment);
DomainEvent buyEstablishmentEvent = new BuyEstablishmentEvent(String.format("玩家 %s 花費了 %d 元 購買了 %s", turnPlayer.getId(), establishment.getConstructionCost(), establishment.getName()));
DomainEvent buyEstablishmentEvent = new BuyCardEvent(String.format("玩家 %s 花費了 %d 元 建造了 %s", turnPlayer.getId(), establishment.getConstructionCost(), establishment.getName()));
updateTurnPlayer();
return List.of(buyEstablishmentEvent);
} else
return Collections.emptyList();
} else {
Landmark landmark = turnPlayer.getHandCard().getLandmarks().stream().filter(lm -> cardName.equals(lm.getName())).findFirst().orElseThrow(NoSuchElementException::new);
turnPlayer.flipLandMark(landmark, bank);
if (isGameOver(turnPlayer)) {
DomainEvent GameOverEvent = new GameOverEvent(String.format("玩家 %s 勝利", turnPlayer.getId()));
return List.of(GameOverEvent);
} else {
DomainEvent flipLandMarkEvent = new BuyCardEvent(String.format("玩家 %s 花費了 %d 元 建造了 %s", turnPlayer.getId(), landmark.getConstructionCost(), landmark.getName()));
updateTurnPlayer();
return List.of(flipLandMarkEvent);
}
}
}

private boolean isGameOver(Player turnPlayer) {
return turnPlayer.getLandmarks().stream().allMatch(landmark -> landmark.isFlipped());
}

private void checkIsTurnPlayer(String playerId) {
if (!playerId.equals(turnPlayer.getId())) {
throw new MachiKoroException("Turn player id is incorrect");
}
}

private void updateTurnPlayer() {
int index = players.indexOf(turnPlayer);
turnPlayer = players.get((index + 1) % players.size());
}
}
2 changes: 1 addition & 1 deletion src/main/java/domain/HandCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public List<Landmark> getLandmarks() {
public void flipLandMark(Class<? extends Landmark> landmark) {
landmarks
.stream()
.filter(l -> l.getClass() == landmark && !l.isFlipped())
.filter(l -> l.getClass() == landmark && !l.isFlipped())
.findFirst()
.map(targetlandmark -> {
targetlandmark.flipped();
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/domain/Marketplace.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@

@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Marketplace {
private final int IMPORTANT_ESTABLISHMENT_QUANTITY = 4;
private final int ESTABLISHMENT_QUANTITY = 6;
@Builder.Default
private List<Establishment> establishments = new ArrayList<>();

public Marketplace() {
establishments = new ArrayList<>();
initial();
}

public void initial() {
establishments.addAll(generateCards(10, Bakery::new));
establishments.addAll(generateCards(10, WheatField::new));
Expand All @@ -49,7 +53,6 @@ public void initial() {
establishments.addAll(generateCards(6, FurnitureFactory::new));
establishments.addAll(generateCards(6, Mine::new));
establishments.addAll(generateCards(6, Ranch::new));

establishments.addAll(generateCards(4, Stadium::new));
establishments.addAll(generateCards(4, TvStation::new));
establishments.addAll(generateCards(4, BusinessCenter::new));
Expand All @@ -64,10 +67,12 @@ private <T> List<T> generateCards(int amount, Supplier<T> cardSupplier) {
public List<Establishment> getEstablishments() {
return establishments;
}
public Establishment findEstablishmentByName(String cardName){

public Establishment findEstablishmentByName(String cardName) {
Establishment establishment = establishments.stream().filter(card -> cardName.equals(card.getName())).findFirst().orElseThrow(NoSuchElementException::new);
return establishment;
}

public void removeEstablishment(Establishment establishment) {
establishments.remove(establishment);
}
Expand Down
75 changes: 38 additions & 37 deletions src/main/java/domain/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import domain.card.establishment.Establishment;
import domain.card.establishment.IndustryColor;
import domain.card.landmark.Landmark;
import domain.exceptions.MachiKoroException;
import lombok.AllArgsConstructor;
import lombok.Builder;

Expand Down Expand Up @@ -56,17 +57,9 @@ public List<Establishment> getEstablishments(int dicePoint, IndustryColor indust
establishment.getIndustryColor().equals(industryColor)).toList();
}

public List<Establishment> getEstablishments(IndustryColor industryColor) {
return handCard.getEstablishments().stream().filter(establishment -> establishment.getIndustryColor().equals(industryColor)).toList();
}

public List<Establishment> getEstablishments(int dicePoint) {
return handCard.getEstablishments().stream().filter(establishment -> establishment.getDiceRollNeededToActivateEffect().contains(dicePoint)).toList();
}

public List<Establishment> getEstablishments(CardType cardType) {
return handCard.getEstablishments().stream()
.filter(establishment -> establishment.getCardType().equals(CardType.CROP))
.filter(establishment -> establishment.getCardType().equals(cardType))
.collect(Collectors.toList());
}

Expand All @@ -78,28 +71,50 @@ public Landmark getLandmark(int index) {
return handCard.getLandmarks().get(index);
}

public void buyCard(Establishment card) {
int cost = card.getConstructionCost();
if (!isBalanceEnough(cost))
return; // FIXME: 2022/12/8 throw Exception or other way to handle this condition.
public Landmark getLandMark(String landMarkName) {
return handCard.getLandmarks().stream().filter(landmark -> landMarkName.equals(landmark.getName())).findFirst().orElseThrow();
}

if (card.getIndustryColor().equals(IndustryColor.PURPLE)) {
if (hasTheSamePurpleCard(card)) {
//throw new RuntimeException("You already own this card!");
return; // FIXME: 2023/04/27 throw Exception or other way to handle this condition.
}
}
public void buyEstablishment(Establishment card, Bank bank) {
int cost = card.getConstructionCost();
checkBalanceIsEnough(cost);
checkHasTheSamePurpleEstablishment(card);
this.payCoin(cost);
bank.gainCoin(cost);
handCard.addHandCard(card);
}

public void flipLandMark(Landmark card) {
public void flipLandMark(Landmark card, Bank bank) {
int cost = card.getConstructionCost();
checkBalanceIsEnough(cost);
if (card.isFlipped()) {
throw new MachiKoroException("此地標已經翻面,無法再重新翻面");
}
card.flipped();
this.payCoin(cost);
bank.gainCoin(cost);
}

private void checkBalanceIsEnough(int cost) {
if (!isBalanceEnough(cost))
return; // FIXME: 2022/12/8 throw Exception or other way to handle this condition.
throw new MachiKoroException("您沒有足夠的錢建造此建築物");
}

handCard.flipLandMark(card.getClass());
this.payCoin(cost);
private void checkHasTheSamePurpleEstablishment(Establishment card) {
if (hasTheSamePurpleException(card))
throw new MachiKoroException("您已擁有此重要建築,不得重複建造");
}

//購買紫色建築物時,判斷玩家手上是否已有相同建築物
private boolean hasTheSamePurpleException(Establishment toBuyCard) {
return toBuyCard.getIndustryColor() == IndustryColor.PURPLE && handCard.getEstablishments().contains(toBuyCard);
}

public boolean hasLandmarkFlipped(Class<? extends Landmark> landmark) {
return handCard.getLandmarks().stream().anyMatch(lm -> lm.getClass() == landmark && lm.isFlipped());
}

public void removeEstablishment(int index) {

}

Expand All @@ -126,18 +141,4 @@ public String getName() {
public Card getHandCard(int index) {
return handCard.getHandCard(index);
}

//購買紫色建築物時,判斷玩家手上是否已有相同建築物
private boolean hasTheSamePurpleCard(Establishment toBuyCard) {
return handCard.getEstablishments().contains(toBuyCard);
}

public boolean hasLandmarkFlipped(Class<? extends Landmark> landmark) {
return handCard.getLandmarks().stream().anyMatch(lm -> lm.getClass() == landmark && lm.isFlipped());
}

public void removeEstablishment(int index) {

}

}
7 changes: 3 additions & 4 deletions src/main/java/domain/card/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import java.util.Objects;

public abstract class Card {

private final String name;
private final int constructionCost;
private final CardType cardType;
protected final String name;
protected final int constructionCost;
protected final CardType cardType;

public Card(String name, int constructionCost, CardType cardType) {
this.name = name;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/domain/card/landmark/AmusementPark.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ public class AmusementPark extends Landmark {
public AmusementPark() {
super("主題樂園", 16, CardType.MAJOR_ESTABLISHMENT);
}

public AmusementPark(boolean isFlipped) {
super("主題樂園", 16, CardType.MAJOR_ESTABLISHMENT);
this.isFlipped = isFlipped;
}
}
2 changes: 1 addition & 1 deletion src/main/java/domain/card/landmark/Landmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import domain.card.CardType;

public class Landmark extends Card {
private boolean isFlipped = false;
protected boolean isFlipped = false;

public Landmark(String name, int constructionCost, CardType cardType) {
super(name, constructionCost, cardType);
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/domain/card/landmark/RadioTower.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ public class RadioTower extends Landmark {
public RadioTower() {
super("廣播電台", 22, CardType.MAJOR_ESTABLISHMENT);
}

public RadioTower(boolean isFlipped) {
super("廣播電台", 22, CardType.MAJOR_ESTABLISHMENT);
this.isFlipped = isFlipped;
}
}
8 changes: 7 additions & 1 deletion src/main/java/domain/card/landmark/ShoppingMall.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import domain.card.CardType;

public class ShoppingMall extends Landmark{
public class ShoppingMall extends Landmark {
public ShoppingMall() {
super("購物中心", 10, CardType.MAJOR_ESTABLISHMENT);
}

public ShoppingMall(boolean isFlipped) {
super("購物中心", 10, CardType.MAJOR_ESTABLISHMENT);
this.isFlipped = isFlipped;
}

}
7 changes: 6 additions & 1 deletion src/main/java/domain/card/landmark/TrainStation.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

import domain.card.CardType;

public class TrainStation extends Landmark{
public class TrainStation extends Landmark {

public TrainStation() {
super("火車站", 4, CardType.MAJOR_ESTABLISHMENT);
}

public TrainStation(boolean isFlipped) {
super("火車站", 4, CardType.MAJOR_ESTABLISHMENT);
this.isFlipped = isFlipped;
}
}
11 changes: 11 additions & 0 deletions src/main/java/domain/events/BuyCardEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package domain.events;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
public class BuyCardEvent extends DomainEvent {
public String message;

}
8 changes: 0 additions & 8 deletions src/main/java/domain/events/BuyEstablishmentEvent.java

This file was deleted.

Loading

0 comments on commit 54d6f47

Please sign in to comment.