refactor: outsource deck related actions to service #236

Merged
ptran merged 1 commit from refactor-blackjack into main 2025-05-28 10:38:15 +00:00
4 changed files with 82 additions and 67 deletions

View file

@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.annotation.JsonManagedReference;
import de.szut.casino.user.UserEntity; import de.szut.casino.user.UserEntity;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View file

@ -11,28 +11,27 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Random;
@Service @Service
public class BlackJackService { public class BlackJackService {
private final BlackJackGameRepository blackJackGameRepository; private final BlackJackGameRepository blackJackGameRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
private final Random random;
private final BalanceService balanceService; private final BalanceService balanceService;
private final UserService userService; private final UserService userService;
private final DeckService deckService;
public BlackJackService( public BlackJackService(
BlackJackGameRepository blackJackGameRepository, BlackJackGameRepository blackJackGameRepository,
UserRepository userRepository, UserRepository userRepository,
Random random,
BalanceService balanceService, BalanceService balanceService,
UserService userService UserService userService,
DeckService deckService
) { ) {
this.blackJackGameRepository = blackJackGameRepository; this.blackJackGameRepository = blackJackGameRepository;
this.userRepository = userRepository; this.userRepository = userRepository;
this.random = random;
this.balanceService = balanceService; this.balanceService = balanceService;
this.userService = userService; this.userService = userService;
this.deckService = deckService;
} }
public BlackJackGameEntity getBlackJackGame(Long id) { public BlackJackGameEntity getBlackJackGame(Long id) {
@ -53,8 +52,8 @@ public class BlackJackService {
game.setUser(user); game.setUser(user);
game.setBet(betDto.getBetAmount()); game.setBet(betDto.getBetAmount());
initializeDeck(game); this.deckService.initializeDeck(game);
dealInitialCards(game); this.deckService.dealInitialCards(game);
game.setState(getState(game)); game.setState(getState(game));
@ -67,7 +66,7 @@ public class BlackJackService {
return game; return game;
} }
dealCardToPlayer(game); this.deckService.dealCardToPlayer(game);
updateGameStateAndBalance(game); updateGameStateAndBalance(game);
return processGameBasedOnState(game); return processGameBasedOnState(game);
@ -91,14 +90,14 @@ public class BlackJackService {
return game; return game;
} }
UserEntity user = getUserWithFreshData(game.getUser()); UserEntity user = game.getUser();
BigDecimal additionalBet = game.getBet(); BigDecimal additionalBet = game.getBet();
this.balanceService.subtractFunds(user, additionalBet); this.balanceService.subtractFunds(user, additionalBet);
game.setBet(game.getBet().add(additionalBet)); game.setBet(game.getBet().add(additionalBet));
dealCardToPlayer(game); this.deckService.dealCardToPlayer(game);
updateGameStateAndBalance(game); updateGameStateAndBalance(game);
if (game.getState() == BlackJackState.IN_PROGRESS) { if (game.getState() == BlackJackState.IN_PROGRESS) {
@ -117,36 +116,6 @@ public class BlackJackService {
return blackJackGameRepository.save(game); return blackJackGameRepository.save(game);
} }
private UserEntity getUserWithFreshData(UserEntity user) {
return userRepository.findById(user.getId()).orElse(user);
}
private void dealInitialCards(BlackJackGameEntity game) {
for (int i = 0; i < 2; i++) {
dealCardToPlayer(game);
}
dealCardToDealer(game);
}
private void dealCardToPlayer(BlackJackGameEntity game) {
CardEntity card = drawCardFromDeck(game);
card.setCardType(CardType.PLAYER);
game.getPlayerCards().add(card);
}
private void dealCardToDealer(BlackJackGameEntity game) {
CardEntity card = drawCardFromDeck(game);
card.setCardType(CardType.DEALER);
game.getDealerCards().add(card);
}
private void dealCardsToDealerUntilMinimumScore(BlackJackGameEntity game) {
while (calculateHandValue(game.getDealerCards()) < 17) {
dealCardToDealer(game);
}
}
private void updateGameStateAndBalance(BlackJackGameEntity game) { private void updateGameStateAndBalance(BlackJackGameEntity game) {
game.setState(getState(game)); game.setState(getState(game));
@ -174,7 +143,7 @@ public class BlackJackService {
} }
protected void updateUserBalance(BlackJackGameEntity game, boolean isWin) { protected void updateUserBalance(BlackJackGameEntity game, boolean isWin) {
UserEntity user = getUserWithFreshData(game.getUser()); UserEntity user = game.getUser();
BigDecimal totalBet = game.getBet(); BigDecimal totalBet = game.getBet();
BigDecimal balance = user.getBalance(); BigDecimal balance = user.getBalance();
@ -188,34 +157,11 @@ public class BlackJackService {
userRepository.save(user); userRepository.save(user);
} }
private void initializeDeck(BlackJackGameEntity game) {
for (Suit suit : Suit.values()) {
for (Rank rank : Rank.values()) {
CardEntity card = new CardEntity();
card.setGame(game);
card.setSuit(suit);
card.setRank(rank);
card.setCardType(CardType.DECK);
game.getDeck().add(card);
}
}
java.util.Collections.shuffle(game.getDeck(), random);
}
private CardEntity drawCardFromDeck(BlackJackGameEntity game) {
if (game.getDeck().isEmpty()) {
throw new IllegalStateException("Deck is empty");
}
return game.getDeck().removeFirst();
}
private BlackJackState getState(BlackJackGameEntity game) { private BlackJackState getState(BlackJackGameEntity game) {
int playerHandValue = calculateHandValue(game.getPlayerCards()); int playerHandValue = calculateHandValue(game.getPlayerCards());
if (playerHandValue == 21) { if (playerHandValue == 21) {
CardEntity hole = drawCardFromDeck(game); CardEntity hole = this.deckService.drawCardFromDeck(game);
hole.setCardType(CardType.DEALER); hole.setCardType(CardType.DEALER);
game.getDealerCards().add(hole); game.getDealerCards().add(hole);
@ -225,7 +171,7 @@ public class BlackJackService {
return BlackJackState.DRAW; return BlackJackState.DRAW;
} else { } else {
BigDecimal blackjackWinnings = game.getBet().multiply(new BigDecimal("1.5")); BigDecimal blackjackWinnings = game.getBet().multiply(new BigDecimal("1.5"));
UserEntity user = getUserWithFreshData(game.getUser()); UserEntity user = game.getUser();
user.setBalance(user.getBalance().add(blackjackWinnings)); user.setBalance(user.getBalance().add(blackjackWinnings));
return BlackJackState.PLAYER_BLACKJACK; return BlackJackState.PLAYER_BLACKJACK;
} }
@ -253,4 +199,12 @@ public class BlackJackService {
return sum; return sum;
} }
private void dealCardsToDealerUntilMinimumScore(BlackJackGameEntity game) {
while (calculateHandValue(game.getDealerCards()) < 17) {
this.deckService.dealCardToDealer(game);
} }
}
}

View file

@ -0,0 +1,57 @@
package de.szut.casino.blackjack;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
public class DeckService {
private final Random random;
public DeckService(Random random) {
this.random = random;
}
public void initializeDeck(BlackJackGameEntity game) {
for (Suit suit : Suit.values()) {
for (Rank rank : Rank.values()) {
CardEntity card = new CardEntity();
card.setGame(game);
card.setSuit(suit);
card.setRank(rank);
card.setCardType(CardType.DECK);
game.getDeck().add(card);
}
}
java.util.Collections.shuffle(game.getDeck(), random);
}
public CardEntity drawCardFromDeck(BlackJackGameEntity game) {
if (game.getDeck().isEmpty()) {
throw new IllegalStateException("Deck is empty");
}
return game.getDeck().removeFirst();
}
public void dealInitialCards(BlackJackGameEntity game) {
for (int i = 0; i < 2; i++) {
dealCardToPlayer(game);
}
dealCardToDealer(game);
}
public void dealCardToPlayer(BlackJackGameEntity game) {
CardEntity card = drawCardFromDeck(game);
card.setCardType(CardType.PLAYER);
game.getPlayerCards().add(card);
}
public void dealCardToDealer(BlackJackGameEntity game) {
CardEntity card = drawCardFromDeck(game);
card.setCardType(CardType.DEALER);
game.getDealerCards().add(card);
}
}

View file

@ -16,6 +16,9 @@ public class UserEntity {
@GeneratedValue @GeneratedValue
private Long id; private Long id;
@Version
private Long version;
@Column(unique = true) @Column(unique = true)
private String email; private String email;
@ -44,7 +47,6 @@ public class UserEntity {
this.password = password; this.password = password;
this.balance = balance; this.balance = balance;
this.verificationToken = verificationToken; this.verificationToken = verificationToken;
this.provider = AuthProvider.LOCAL;
} }
public UserEntity(String email, String username, AuthProvider provider, String providerId, BigDecimal balance) { public UserEntity(String email, String username, AuthProvider provider, String providerId, BigDecimal balance) {