diff options
Diffstat (limited to 'src/main/java')
95 files changed, 0 insertions, 4562 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/SevenWonders.java b/src/main/java/org/luxons/sevenwonders/SevenWonders.java deleted file mode 100644 index 2c20c5d3..00000000 --- a/src/main/java/org/luxons/sevenwonders/SevenWonders.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.luxons.sevenwonders; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SevenWonders { - - public static void main(String[] args) { - SpringApplication.run(SevenWonders.class, args); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/ChooseNameAction.java b/src/main/java/org/luxons/sevenwonders/actions/ChooseNameAction.java deleted file mode 100644 index 42a26f37..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/ChooseNameAction.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -public class ChooseNameAction { - - @NotNull - @Size(min=2, max=20) - private String playerName; - - public String getPlayerName() { - return playerName; - } - - public void setPlayerName(String playerName) { - this.playerName = playerName; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/CreateGameAction.java b/src/main/java/org/luxons/sevenwonders/actions/CreateGameAction.java deleted file mode 100644 index ce1783c0..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/CreateGameAction.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -public class CreateGameAction { - - @NotNull - @Size(min=2, max=30) - private String gameName; - - public String getGameName() { - return gameName; - } - - public void setGameName(String gameName) { - this.gameName = gameName; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java b/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java deleted file mode 100644 index 82bff168..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import javax.validation.constraints.NotNull; - -public class JoinGameAction { - - @NotNull - private Long gameId; - - public Long getGameId() { - return gameId; - } - - public void setGameId(Long gameId) { - this.gameId = gameId; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/PrepareCardAction.java b/src/main/java/org/luxons/sevenwonders/actions/PrepareCardAction.java deleted file mode 100644 index b333d6c1..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/PrepareCardAction.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import org.luxons.sevenwonders.game.api.PlayerMove; - -public class PrepareCardAction { - - private PlayerMove move; - - public PlayerMove getMove() { - return move; - } - - public void setMove(PlayerMove move) { - this.move = move; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/ReorderPlayersAction.java b/src/main/java/org/luxons/sevenwonders/actions/ReorderPlayersAction.java deleted file mode 100644 index 803a71d8..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/ReorderPlayersAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import java.util.List; -import javax.validation.constraints.NotNull; - -public class ReorderPlayersAction { - - @NotNull - private List<String> orderedPlayers; - - public List<String> getOrderedPlayers() { - return orderedPlayers; - } - - public void setOrderedPlayers(List<String> orderedPlayers) { - this.orderedPlayers = orderedPlayers; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/actions/UpdateSettingsAction.java b/src/main/java/org/luxons/sevenwonders/actions/UpdateSettingsAction.java deleted file mode 100644 index 822a5a1c..00000000 --- a/src/main/java/org/luxons/sevenwonders/actions/UpdateSettingsAction.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.luxons.sevenwonders.actions; - -import javax.validation.constraints.NotNull; - -import org.luxons.sevenwonders.game.api.CustomizableSettings; - -public class UpdateSettingsAction { - - @NotNull - private CustomizableSettings settings; - - public CustomizableSettings getSettings() { - return settings; - } - - public void setSettings(CustomizableSettings settings) { - this.settings = settings; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/config/AnonymousUsersHandshakeHandler.java b/src/main/java/org/luxons/sevenwonders/config/AnonymousUsersHandshakeHandler.java deleted file mode 100644 index bebbd477..00000000 --- a/src/main/java/org/luxons/sevenwonders/config/AnonymousUsersHandshakeHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.config; - -import java.security.Principal; -import java.util.Map; - -import org.springframework.http.server.ServerHttpRequest; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.server.support.DefaultHandshakeHandler; - -class AnonymousUsersHandshakeHandler extends DefaultHandshakeHandler { - - private int playerId = 0; - - @Override - public Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, - Map<String, Object> attributes) { - Principal p = super.determineUser(request, wsHandler, attributes); - if (p == null) { - p = new UsernamePasswordAuthenticationToken("player" + playerId++, null); - } - return p; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/config/TopicSubscriptionInterceptor.java b/src/main/java/org/luxons/sevenwonders/config/TopicSubscriptionInterceptor.java deleted file mode 100644 index f8d92068..00000000 --- a/src/main/java/org/luxons/sevenwonders/config/TopicSubscriptionInterceptor.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.luxons.sevenwonders.config; - -import java.security.Principal; - -import org.luxons.sevenwonders.validation.DestinationAccessValidator; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.simp.stomp.StompCommand; -import org.springframework.messaging.simp.stomp.StompHeaderAccessor; -import org.springframework.messaging.support.ChannelInterceptorAdapter; -import org.springframework.stereotype.Component; - -@Component -public class TopicSubscriptionInterceptor extends ChannelInterceptorAdapter { - - private final DestinationAccessValidator destinationAccessValidator; - - @Autowired - public TopicSubscriptionInterceptor(DestinationAccessValidator destinationAccessValidator) { - this.destinationAccessValidator = destinationAccessValidator; - } - - @Override - public Message<?> preSend(Message<?> message, MessageChannel channel) { - StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message); - if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) { - Principal userPrincipal = headerAccessor.getUser(); - if (!destinationAccessValidator.hasAccess(userPrincipal.getName(), headerAccessor.getDestination())) { - throw new ForbiddenSubscriptionException(); - } - } - return message; - } - - private static class ForbiddenSubscriptionException extends RuntimeException { - } -} diff --git a/src/main/java/org/luxons/sevenwonders/config/WebSocketConfig.java b/src/main/java/org/luxons/sevenwonders/config/WebSocketConfig.java deleted file mode 100644 index d54d8da4..00000000 --- a/src/main/java/org/luxons/sevenwonders/config/WebSocketConfig.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.luxons.sevenwonders.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.simp.config.ChannelRegistration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; -import org.springframework.web.socket.config.annotation.StompEndpointRegistry; -import org.springframework.web.socket.server.support.DefaultHandshakeHandler; - -@Configuration -@EnableWebSocketMessageBroker -public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { - - private final TopicSubscriptionInterceptor topicSubscriptionInterceptor; - - @Autowired - public WebSocketConfig(TopicSubscriptionInterceptor topicSubscriptionInterceptor) { - this.topicSubscriptionInterceptor = topicSubscriptionInterceptor; - } - - @Override - public void configureMessageBroker(MessageBrokerRegistry config) { - // prefixes for all subscriptions - config.enableSimpleBroker("/queue", "/topic"); - config.setUserDestinationPrefix("/user"); - - // /app for normal calls, /topic for subscription events - config.setApplicationDestinationPrefixes("/app", "/topic"); - } - - @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/seven-wonders-websocket") - .setHandshakeHandler(handshakeHandler()) - .setAllowedOrigins("http://localhost:3000") // to allow frontend server proxy requests in dev mode - .withSockJS(); - } - - @Bean - public DefaultHandshakeHandler handshakeHandler() { - return new AnonymousUsersHandshakeHandler(); - } - - @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - registration.setInterceptors(topicSubscriptionInterceptor); - } -}
\ No newline at end of file diff --git a/src/main/java/org/luxons/sevenwonders/controllers/GameController.java b/src/main/java/org/luxons/sevenwonders/controllers/GameController.java deleted file mode 100644 index 0deac4a3..00000000 --- a/src/main/java/org/luxons/sevenwonders/controllers/GameController.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.luxons.sevenwonders.controllers; - -import java.security.Principal; -import java.util.List; - -import org.luxons.sevenwonders.actions.PrepareCardAction; -import org.luxons.sevenwonders.game.Game; -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.api.PlayerTurnInfo; -import org.luxons.sevenwonders.game.api.PreparedCard; -import org.luxons.sevenwonders.repositories.GameRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.handler.annotation.DestinationVariable; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.simp.SimpMessagingTemplate; -import org.springframework.stereotype.Controller; - -@Controller -public class GameController { - - private static final Logger logger = LoggerFactory.getLogger(GameController.class); - - private final SimpMessagingTemplate template; - - private final GameRepository gameRepository; - - @Autowired - public GameController(SimpMessagingTemplate template, GameRepository gameRepository) { - this.template = template; - this.gameRepository = gameRepository; - } - - @MessageMapping("/game/{gameId}/prepare") - public void prepareCard(@DestinationVariable long gameId, PrepareCardAction action, Principal principal) { - Game game = gameRepository.find(gameId); - PreparedCard preparedCard = game.prepareCard(principal.getName(), action.getMove()); - logger.info("Game '{}': player {} prepared move {}", gameId, principal.getName(), action.getMove()); - - if (game.areAllPlayersReady()) { - game.playTurn(); - sendTurnInfo(game); - } else { - sendPreparedCard(preparedCard, game); - } - } - - private void sendPreparedCard(PreparedCard preparedCard, Game game) { - for (Player player : game.getPlayers()) { - String username = player.getUsername(); - template.convertAndSendToUser(username, "/topic/game/" + game.getId() + "/prepared", preparedCard); - } - } - - private void sendTurnInfo(Game game) { - List<PlayerTurnInfo> turnInfos = game.getTurnInfo(); - for (PlayerTurnInfo turnInfo : turnInfos) { - String username = turnInfo.getPlayer().getUsername(); - template.convertAndSendToUser(username, "/topic/game/" + game.getId() + "/turn", turnInfo); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java deleted file mode 100644 index 996ea361..00000000 --- a/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.luxons.sevenwonders.controllers; - -import java.security.Principal; -import java.util.Collection; -import java.util.Collections; - -import org.luxons.sevenwonders.actions.ChooseNameAction; -import org.luxons.sevenwonders.actions.CreateGameAction; -import org.luxons.sevenwonders.actions.JoinGameAction; -import org.luxons.sevenwonders.actions.ReorderPlayersAction; -import org.luxons.sevenwonders.actions.UpdateSettingsAction; -import org.luxons.sevenwonders.errors.ApiMisuseException; -import org.luxons.sevenwonders.game.Game; -import org.luxons.sevenwonders.game.Lobby; -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.repositories.GameRepository; -import org.luxons.sevenwonders.repositories.LobbyRepository; -import org.luxons.sevenwonders.repositories.PlayerRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.SendTo; -import org.springframework.messaging.simp.SimpMessagingTemplate; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.messaging.simp.annotation.SubscribeMapping; -import org.springframework.stereotype.Controller; -import org.springframework.validation.annotation.Validated; - -@Controller -public class LobbyController { - - private static final Logger logger = LoggerFactory.getLogger(LobbyController.class); - - private final LobbyRepository lobbyRepository; - - private final GameRepository gameRepository; - - private final PlayerRepository playerRepository; - - private final SimpMessagingTemplate template; - - @Autowired - public LobbyController(LobbyRepository lobbyRepository, GameRepository gameRepository, - PlayerRepository playerRepository, SimpMessagingTemplate template) { - this.lobbyRepository = lobbyRepository; - this.gameRepository = gameRepository; - this.playerRepository = playerRepository; - this.template = template; - } - - @MessageMapping("/chooseName") - @SendToUser("/queue/nameChoice") - public Player chooseName(@Validated ChooseNameAction action, Principal principal) { - String username = principal.getName(); - Player player = playerRepository.createOrUpdate(username, action.getPlayerName()); - - logger.info("Player '{}' chose the name '{}'", username, player.getDisplayName()); - return player; - } - - @SubscribeMapping("/games") // prefix /topic not shown - public Collection<Lobby> listGames(Principal principal) { - logger.info("Player '{}' subscribed to /topic/games", principal.getName()); - return lobbyRepository.list(); - } - - @MessageMapping("/lobby/create") - @SendTo("/topic/games") - public Collection<Lobby> createGame(@Validated CreateGameAction action, Principal principal) { - checkThatUserIsNotInAGame(principal, "cannot create another game"); - - Player gameOwner = playerRepository.find(principal.getName()); - Lobby lobby = lobbyRepository.create(action.getGameName(), gameOwner); - gameOwner.setLobby(lobby); - - logger.info("Game '{}' ({}) created by {} ({})", lobby.getName(), lobby.getId(), gameOwner.getDisplayName(), - gameOwner.getUsername()); - return Collections.singletonList(lobby); - } - - @MessageMapping("/lobby/join") - @SendToUser("/queue/lobby/joined") - public Lobby joinGame(@Validated JoinGameAction action, Principal principal) { - checkThatUserIsNotInAGame(principal, "cannot join another game"); - - Lobby lobby = lobbyRepository.find(action.getGameId()); - Player newPlayer = playerRepository.find(principal.getName()); - lobby.addPlayer(newPlayer); - newPlayer.setLobby(lobby); - - logger.info("Player '{}' ({}) joined game {}", newPlayer.getDisplayName(), newPlayer.getUsername(), - lobby.getName()); - sendLobbyUpdateToPlayers(lobby); - return lobby; - } - - private void checkThatUserIsNotInAGame(Principal principal, String impossibleActionDescription) { - Lobby lobby = playerRepository.find(principal.getName()).getLobby(); - if (lobby != null) { - throw new UserAlreadyInGameException(lobby.getName(), impossibleActionDescription); - } - } - - @MessageMapping("/lobby/reorderPlayers") - public void reorderPlayers(@Validated ReorderPlayersAction action, Principal principal) { - Lobby lobby = getLobby(principal); - lobby.reorderPlayers(action.getOrderedPlayers()); - - logger.info("Players in game {} reordered to {}", lobby.getName(), action.getOrderedPlayers()); - sendLobbyUpdateToPlayers(lobby); - } - - @MessageMapping("/lobby/updateSettings") - public void updateSettings(@Validated UpdateSettingsAction action, Principal principal) { - Lobby lobby = getLobby(principal); - lobby.setSettings(action.getSettings()); - - logger.info("Updated settings of game {}", lobby.getName()); - sendLobbyUpdateToPlayers(lobby); - } - - private void sendLobbyUpdateToPlayers(Lobby lobby) { - template.convertAndSend("/topic/lobby/" + lobby.getId() + "/updated", lobby); - } - - @MessageMapping("/lobby/start") - public void startGame(Principal principal) { - Lobby lobby = getOwnedLobby(principal); - Game game = lobby.startGame(); - gameRepository.add(game); - - logger.info("Game {} successfully started", game.getId()); - template.convertAndSend("/topic/lobby/" + lobby.getId() + "/started", (Object)null); - } - - private Lobby getOwnedLobby(Principal principal) { - Lobby lobby = getLobby(principal); - if (!lobby.isOwner(principal.getName())) { - throw new UserIsNotOwnerException(principal.getName()); - } - return lobby; - } - - private Lobby getLobby(Principal principal) { - Lobby lobby = playerRepository.find(principal.getName()).getLobby(); - if (lobby == null) { - throw new UserNotInLobbyException(principal.getName()); - } - return lobby; - } - - private static class UserNotInLobbyException extends ApiMisuseException { - UserNotInLobbyException(String username) { - super("User " + username + " is not in a lobby, create or join a game first"); - } - } - - private static class UserIsNotOwnerException extends ApiMisuseException { - UserIsNotOwnerException(String username) { - super("User " + username + " does not own the lobby he's in"); - } - } - - private static class UserAlreadyInGameException extends ApiMisuseException { - UserAlreadyInGameException(String gameName, String impossibleActionDescription) { - super("Client already in game '" + gameName + "', " + impossibleActionDescription); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/ApiMisuseException.java b/src/main/java/org/luxons/sevenwonders/errors/ApiMisuseException.java deleted file mode 100644 index 0d7d1a82..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/ApiMisuseException.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.luxons.sevenwonders.errors; - -public class ApiMisuseException extends RuntimeException { - - public ApiMisuseException(String message) { - super(message); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java b/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java deleted file mode 100644 index 1cd18d09..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/ErrorType.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luxons.sevenwonders.errors; - -enum ErrorType { - USER_INPUT, VALIDATION, CLIENT, SERVER -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/ExceptionHandler.java b/src/main/java/org/luxons/sevenwonders/errors/ExceptionHandler.java deleted file mode 100644 index 628da4f8..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/ExceptionHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.luxons.sevenwonders.errors; - -import java.util.List; -import java.util.Locale; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.messaging.converter.MessageConversionException; -import org.springframework.messaging.handler.annotation.MessageExceptionHandler; -import org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.validation.BindingResult; -import org.springframework.validation.ObjectError; -import org.springframework.web.bind.annotation.ControllerAdvice; - -@ControllerAdvice -public class ExceptionHandler { - - private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class); - - private static final String ERROR_CODE_VALIDATION = "INVALID_DATA"; - - private static final String ERROR_CODE_CONVERSION = "INVALID_MESSAGE_FORMAT"; - - private static final String ERROR_MSG_VALIDATION = "Invalid input data"; - - private static final String ERROR_MSG_CONVERSION = "Invalid input format"; - - private final MessageSource messageSource; - - @Autowired - public ExceptionHandler(MessageSource messageSource) { - this.messageSource = messageSource; - } - - @MessageExceptionHandler - @SendToUser("/queue/errors") - public UIError handleUserInputError(UserInputException exception) { - logger.error("Incorrect user input: " + exception.getMessage()); - String messageKey = exception.getMessageResourceKey(); - String message = messageSource.getMessage(messageKey, exception.getParams(), messageKey, Locale.US); - return new UIError(messageKey, message, ErrorType.USER_INPUT); - } - - @MessageExceptionHandler - @SendToUser("/queue/errors") - public UIError handleValidationError(MethodArgumentNotValidException exception) { - logger.error("Invalid input", exception); - UIError uiError = new UIError(ERROR_CODE_VALIDATION, ERROR_MSG_VALIDATION, ErrorType.VALIDATION); - - BindingResult result = exception.getBindingResult(); - if (result != null) { - List<ObjectError> errors = result.getAllErrors(); - uiError.addDetails(errors); - } - return uiError; - } - - @MessageExceptionHandler - @SendToUser("/queue/errors") - public UIError handleConversionError(MessageConversionException exception) { - logger.error("Error interpreting the message", exception); - return new UIError(ERROR_CODE_CONVERSION, ERROR_MSG_CONVERSION, ErrorType.VALIDATION); - } - - @MessageExceptionHandler - @SendToUser("/queue/errors") - public UIError handleApiError(ApiMisuseException exception) { - logger.error("Invalid API input", exception); - return new UIError(exception.getClass().getSimpleName(), exception.getMessage(), ErrorType.CLIENT); - } - - @MessageExceptionHandler - @SendToUser("/queue/errors") - public UIError handleUnexpectedInternalError(Throwable exception) { - logger.error("Uncaught exception thrown during message handling", exception); - return new UIError(exception.getClass().getSimpleName(), exception.getMessage(), ErrorType.SERVER); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UIError.java b/src/main/java/org/luxons/sevenwonders/errors/UIError.java deleted file mode 100644 index ee5fcbe0..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/UIError.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.luxons.sevenwonders.errors; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; - -public class UIError { - - private final String code; - - private final String message; - - private final ErrorType type; - - private List<UIErrorDetail> details = new ArrayList<>(); - - UIError(String code, String message, ErrorType type) { - this.code = code; - this.message = message; - this.type = type; - } - - public String getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public ErrorType getType() { - return type; - } - - public List<UIErrorDetail> getDetails() { - return details; - } - - void addDetails(List<ObjectError> objectErrors) { - for (ObjectError objectError : objectErrors) { - this.details.add(convertError(objectError)); - } - } - - private UIErrorDetail convertError(ObjectError objectError) { - if (objectError instanceof FieldError) { - return new UIErrorDetail((FieldError)objectError); - } else { - return new UIErrorDetail(objectError); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UIErrorDetail.java b/src/main/java/org/luxons/sevenwonders/errors/UIErrorDetail.java deleted file mode 100644 index dc4250bb..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/UIErrorDetail.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.luxons.sevenwonders.errors; - -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; - -class UIErrorDetail { - - private final Object rejectedValue; - - private final String path; - - private final String message; - - UIErrorDetail(FieldError error) { - rejectedValue = error.getRejectedValue(); - path = error.getObjectName() + '.' + error.getField(); - message = "Invalid value for field '" + error.getField() + "': " + error.getDefaultMessage(); - } - - UIErrorDetail(ObjectError error) { - rejectedValue = null; - path = error.getObjectName(); - message = "Invalid value for object '" + error.getObjectName() + "': " + error.getDefaultMessage(); - } - - public Object getRejectedValue() { - return rejectedValue; - } - - public String getPath() { - return path; - } - - public String getMessage() { - return message; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java b/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java deleted file mode 100644 index 4033a696..00000000 --- a/src/main/java/org/luxons/sevenwonders/errors/UserInputException.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.luxons.sevenwonders.errors; - -public class UserInputException extends RuntimeException { - - private final String messageResourceKey; - - private final Object[] params; - - public UserInputException(String messageResourceKey, Object... params) { - this.messageResourceKey = messageResourceKey; - this.params = params; - } - - String getMessageResourceKey() { - return messageResourceKey; - } - - Object[] getParams() { - return params; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/Game.java b/src/main/java/org/luxons/sevenwonders/game/Game.java deleted file mode 100644 index 8aa7d1b9..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/Game.java +++ /dev/null @@ -1,235 +0,0 @@ -package org.luxons.sevenwonders.game; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.api.Action; -import org.luxons.sevenwonders.game.api.HandCard; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.PlayerTurnInfo; -import org.luxons.sevenwonders.game.api.PreparedCard; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Decks; -import org.luxons.sevenwonders.game.cards.Hands; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.moves.Move; -import org.luxons.sevenwonders.game.scoring.ScoreBoard; - -public class Game { - - private static final int LAST_AGE = 3; - - private final long id; - - private final Settings settings; - - private final List<Player> players; - - private final Table table; - - private final Decks decks; - - private final List<Card> discardedCards; - - private final Map<Integer, Move> preparedMoves; - - private Hands hands; - - public Game(long id, Settings settings, List<Player> players, List<Board> boards, Decks decks) { - this.id = id; - this.settings = settings; - this.players = players; - this.table = new Table(boards); - this.decks = decks; - this.discardedCards = new ArrayList<>(); - this.preparedMoves = new HashMap<>(); - startNewAge(); - } - - public long getId() { - return id; - } - - public boolean containsUser(String username) { - return players.stream().anyMatch(p -> p.getUsername().equals(username)); - } - - public List<Player> getPlayers() { - return players; - } - - private void startNewAge() { - table.increaseCurrentAge(); - hands = decks.deal(table.getCurrentAge(), table.getNbPlayers()); - } - - public List<PlayerTurnInfo> getTurnInfo() { - return players.stream().map(this::createPlayerTurnInfo).collect(Collectors.toList()); - } - - private PlayerTurnInfo createPlayerTurnInfo(Player player) { - PlayerTurnInfo pti = new PlayerTurnInfo(player, table); - List<HandCard> hand = hands.createHand(table, player.getIndex()); - pti.setHand(hand); - Action action = determineAction(hand, table.getBoard(player.getIndex())); - pti.setAction(action); - pti.setMessage(action.getMessage()); - return pti; - } - - private Action determineAction(List<HandCard> hand, Board board) { - if (endOfGameReached() && board.hasSpecial(SpecialAbility.COPY_GUILD)) { - return Action.PICK_NEIGHBOR_GUILD; - } else if (hand.size() == 1 && board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - return Action.PLAY_LAST; - } else if (hand.size() == 2 && board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - return Action.PLAY_2; - } else if (hand.isEmpty()) { - return Action.WAIT; - } else { - return Action.PLAY; - } - } - - public PreparedCard prepareCard(String username, PlayerMove playerMove) throws InvalidMoveException { - Player player = getPlayer(username); - Card card = decks.getCard(playerMove.getCardName()); - Move move = playerMove.getType().resolve(player.getIndex(), card, playerMove); - validate(move); - preparedMoves.put(player.getIndex(), move); - return new PreparedCard(player, card.getBack()); - } - - private Player getPlayer(String username) { - return players.stream() - .filter(p -> p.getUsername().equals(username)) - .findAny() - .orElseThrow(() -> new UnknownPlayerException(username)); - } - - private void validate(Move move) throws InvalidMoveException { - List<Card> hand = hands.get(move.getPlayerIndex()); - if (!move.isValid(table, hand)) { - throw new InvalidMoveException( - "Player " + move.getPlayerIndex() + " cannot play the card " + move.getCard().getName()); - } - } - - public boolean areAllPlayersReady() { - return preparedMoves.size() == players.size(); - } - - public void playTurn() { - makeMoves(); - if (endOfAgeReached()) { - executeEndOfAgeEvents(); - if (!endOfGameReached()) { - startNewAge(); - } - } else if (!hands.maxOneCardRemains()) { - // we don't rotate hands if some player can play his last card (with the special ability) - hands.rotate(table.getHandRotationDirection()); - } - } - - private void makeMoves() { - List<Move> playedMoves = mapToList(preparedMoves); - - // all cards from this turn need to be placed before executing any effect - // because effects depending on played cards need to take the ones from the current turn into account too - placePreparedCards(playedMoves); - - // same goes for the discarded cards during the last turn, which should be available for special actions - if (hands.maxOneCardRemains()) { - discardLastCardsOfHands(); - } - - activatePlayedCards(playedMoves); - - table.setLastPlayedMoves(playedMoves); - preparedMoves.clear(); - } - - private static List<Move> mapToList(Map<Integer, Move> movesPerPlayer) { - List<Move> moves = new ArrayList<>(movesPerPlayer.size()); - for (int p = 0; p < movesPerPlayer.size(); p++) { - Move move = movesPerPlayer.get(p); - if (move == null) { - throw new MissingPreparedMoveException(p); - } - moves.add(move); - } - return moves; - } - - private void placePreparedCards(List<Move> playedMoves) { - playedMoves.forEach(move -> { - move.place(table, discardedCards, settings); - removeFromHand(move.getPlayerIndex(), move.getCard()); - }); - } - - private void discardLastCardsOfHands() { - for (Player p : players) { - Board board = table.getBoard(p.getIndex()); - if (!board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - discardHand(p.getIndex()); - } - } - } - - private void discardHand(int playerIndex) { - List<Card> hand = hands.get(playerIndex); - discardedCards.addAll(hand); - hand.clear(); - } - - private void removeFromHand(int playerIndex, Card card) { - hands.get(playerIndex).remove(card); - } - - private void activatePlayedCards(List<Move> playedMoves) { - playedMoves.forEach(move -> move.activate(table, discardedCards, settings)); - } - - private boolean endOfAgeReached() { - return hands.isEmpty(); - } - - private void executeEndOfAgeEvents() { - table.resolveMilitaryConflicts(); - } - - private boolean endOfGameReached() { - return endOfAgeReached() && table.getCurrentAge() == LAST_AGE; - } - - public ScoreBoard computeScore() { - ScoreBoard scoreBoard = new ScoreBoard(); - table.getBoards().stream().map(b -> b.computePoints(table)).forEach(scoreBoard::add); - return scoreBoard; - } - - private static class MissingPreparedMoveException extends IllegalStateException { - MissingPreparedMoveException(int playerIndex) { - super("Player " + playerIndex + " is not ready to play"); - } - } - - private static class UnknownPlayerException extends IllegalArgumentException { - UnknownPlayerException(String username) { - super(username); - } - } - - private static class InvalidMoveException extends IllegalArgumentException { - InvalidMoveException(String message) { - super(message); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/Lobby.java b/src/main/java/org/luxons/sevenwonders/game/Lobby.java deleted file mode 100644 index 6975349a..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/Lobby.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.luxons.sevenwonders.game; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.api.CustomizableSettings; -import org.luxons.sevenwonders.game.data.GameDefinition; - -public class Lobby { - - private final long id; - - private final String name; - - private final Player owner; - - private final GameDefinition gameDefinition; - - private final List<Player> players; - - private CustomizableSettings settings; - - private State state = State.LOBBY; - - public Lobby(long id, String name, Player owner, GameDefinition gameDefinition) { - this.id = id; - this.name = name; - this.owner = owner; - this.gameDefinition = gameDefinition; - this.players = new ArrayList<>(gameDefinition.getMinPlayers()); - this.settings = new CustomizableSettings(); - players.add(owner); - } - - public long getId() { - return id; - } - - public String getName() { - return name; - } - - public List<Player> getPlayers() { - return players; - } - - public CustomizableSettings getSettings() { - return settings; - } - - public void setSettings(CustomizableSettings settings) { - this.settings = settings; - } - - public synchronized void addPlayer(Player player) throws GameAlreadyStartedException, PlayerOverflowException { - if (hasStarted()) { - throw new GameAlreadyStartedException(); - } - if (maxPlayersReached()) { - throw new PlayerOverflowException(); - } - if (playerNameAlreadyUsed(player.getDisplayName())) { - throw new PlayerNameAlreadyUsedException(player.getDisplayName()); - } - player.setIndex(players.size()); - players.add(player); - } - - private boolean hasStarted() { - return state != State.LOBBY; - } - - private boolean maxPlayersReached() { - return players.size() >= gameDefinition.getMaxPlayers(); - } - - private boolean playerNameAlreadyUsed(String name) { - return players.stream().anyMatch(p -> p.getDisplayName().equals(name)); - } - - public synchronized Game startGame() throws PlayerUnderflowException { - if (!hasEnoughPlayers()) { - throw new PlayerUnderflowException(); - } - state = State.PLAYING; - return gameDefinition.initGame(id, settings, players); - } - - private boolean hasEnoughPlayers() { - return players.size() >= gameDefinition.getMinPlayers(); - } - - public void reorderPlayers(List<String> orderedUsernames) { - List<Player> formerList = new ArrayList<>(players); - players.clear(); - for (int i = 0; i < orderedUsernames.size(); i++) { - Player player = getPlayer(formerList, orderedUsernames.get(i)); - players.add(player); - player.setIndex(i); - } - } - - private static Player getPlayer(List<Player> players, String username) { - return players.stream() - .filter(p -> p.getUsername().equals(username)) - .findAny() - .orElseThrow(() -> new UnknownPlayerException(username)); - } - - public boolean isOwner(String username) { - return owner.getUsername().equals(username); - } - - public boolean containsUser(String username) { - return players.stream().anyMatch(p -> p.getUsername().equals(username)); - } - - static class GameAlreadyStartedException extends IllegalStateException { - } - - static class PlayerOverflowException extends IllegalStateException { - } - - static class PlayerUnderflowException extends IllegalStateException { - } - - static class PlayerNameAlreadyUsedException extends RuntimeException { - PlayerNameAlreadyUsedException(String name) { - super(name); - } - } - - static class UnknownPlayerException extends IllegalArgumentException { - UnknownPlayerException(String username) { - super(username); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/Player.java b/src/main/java/org/luxons/sevenwonders/game/Player.java deleted file mode 100644 index f1095049..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/Player.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.luxons.sevenwonders.game; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -public class Player { - - private final String username; - - private String displayName; - - private int index; - - private transient Lobby lobby; - - private transient Game game; - - public Player(String username, String displayName) { - this.username = username; - this.displayName = displayName; - } - - public String getUsername() { - return username; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - @JsonIgnore - public Lobby getLobby() { - return lobby; - } - - public void setLobby(Lobby lobby) { - this.lobby = lobby; - } - - @JsonIgnore - public Game getGame() { - return game; - } - - public void setGame(Game game) { - this.game = game; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/Settings.java b/src/main/java/org/luxons/sevenwonders/game/Settings.java deleted file mode 100644 index 63ef3522..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/Settings.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luxons.sevenwonders.game; - -import java.util.Map; -import java.util.Random; - -import org.luxons.sevenwonders.game.api.CustomizableSettings; -import org.luxons.sevenwonders.game.data.definitions.WonderSide; -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod; - -public class Settings { - - private final Random random; - - private final int nbPlayers; - - private final int initialGold; - - private final int discardedCardGold; - - private final int defaultTradingCost; - - private final int pointsPer3Gold; - - private final WonderSidePickMethod wonderSidePickMethod; - - private WonderSide lastPickedSide = null; - - private final int lostPointsPerDefeat; - - private final Map<Integer, Integer> wonPointsPerVictoryPerAge; - - public Settings(int nbPlayers) { - this(nbPlayers, new CustomizableSettings()); - } - - public Settings(int nbPlayers, CustomizableSettings customSettings) { - long seed = customSettings.getRandomSeedForTests(); - this.random = seed > 0 ? new Random(seed) : new Random(); - this.nbPlayers = nbPlayers; - this.initialGold = customSettings.getInitialGold(); - this.discardedCardGold = customSettings.getDiscardedCardGold(); - this.defaultTradingCost = customSettings.getDefaultTradingCost(); - this.pointsPer3Gold = customSettings.getPointsPer3Gold(); - this.wonderSidePickMethod = customSettings.getWonderSidePickMethod(); - this.lostPointsPerDefeat = customSettings.getLostPointsPerDefeat(); - this.wonPointsPerVictoryPerAge = customSettings.getWonPointsPerVictoryPerAge(); - } - - public Random getRandom() { - return random; - } - - public int getNbPlayers() { - return nbPlayers; - } - - public int getInitialGold() { - return initialGold; - } - - public int getDiscardedCardGold() { - return discardedCardGold; - } - - public int getDefaultTradingCost() { - return defaultTradingCost; - } - - public int getPointsPer3Gold() { - return pointsPer3Gold; - } - - public WonderSide pickWonderSide() { - return lastPickedSide = wonderSidePickMethod.pickSide(getRandom(), lastPickedSide); - } - - public int getLostPointsPerDefeat() { - return lostPointsPerDefeat; - } - - public Map<Integer, Integer> getWonPointsPerVictoryPerAge() { - return wonPointsPerVictoryPerAge; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/State.java b/src/main/java/org/luxons/sevenwonders/game/State.java deleted file mode 100644 index 0bd71d3a..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/State.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.luxons.sevenwonders.game; - -public enum State { - LOBBY, - PLAYING -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/Action.java b/src/main/java/org/luxons/sevenwonders/game/api/Action.java deleted file mode 100644 index 88e392f9..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/Action.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -public enum Action { - PLAY("Pick the card you want to play or discard."), - PLAY_2("Pick the first card you want to play or discard. Note that you have the ability to play these 2 last cards." - + " You will choose how to play the last one during your next turn."), - PLAY_LAST("You have the special ability to play your last card. Choose how you want to play it."), - PICK_NEIGHBOR_GUILD("Choose a Guild card (purple) that you want to copy from one of your neighbours."), - WAIT("Please wait for other players to perform extra actions."); - - private final String message; - - Action(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java b/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java deleted file mode 100644 index c270a2af..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.HashMap; -import java.util.Map; - -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod; - -public class CustomizableSettings { - - private long randomSeedForTests = -1; - - private WonderSidePickMethod wonderSidePickMethod = WonderSidePickMethod.EACH_RANDOM; - - private int initialGold = 3; - - private int discardedCardGold = 3; - - private int defaultTradingCost = 2; - - private int pointsPer3Gold = 1; - - private int lostPointsPerDefeat = 1; - - private Map<Integer, Integer> wonPointsPerVictoryPerAge = new HashMap<>(); - - public CustomizableSettings() { - wonPointsPerVictoryPerAge.put(1, 1); - wonPointsPerVictoryPerAge.put(2, 3); - wonPointsPerVictoryPerAge.put(3, 5); - } - - public long getRandomSeedForTests() { - return randomSeedForTests; - } - - public void setRandomSeedForTests(long randomSeedForTests) { - this.randomSeedForTests = randomSeedForTests; - } - - public int getInitialGold() { - return initialGold; - } - - public void setInitialGold(int initialGold) { - this.initialGold = initialGold; - } - - public int getDiscardedCardGold() { - return discardedCardGold; - } - - public void setDiscardedCardGold(int discardedCardGold) { - this.discardedCardGold = discardedCardGold; - } - - public int getDefaultTradingCost() { - return defaultTradingCost; - } - - public void setDefaultTradingCost(int defaultTradingCost) { - this.defaultTradingCost = defaultTradingCost; - } - - public int getPointsPer3Gold() { - return pointsPer3Gold; - } - - public void setPointsPer3Gold(int pointsPer3Gold) { - this.pointsPer3Gold = pointsPer3Gold; - } - - public WonderSidePickMethod getWonderSidePickMethod() { - return wonderSidePickMethod; - } - - public void setWonderSidePickMethod(WonderSidePickMethod wonderSidePickMethod) { - this.wonderSidePickMethod = wonderSidePickMethod; - } - - public int getLostPointsPerDefeat() { - return lostPointsPerDefeat; - } - - public void setLostPointsPerDefeat(int lostPointsPerDefeat) { - this.lostPointsPerDefeat = lostPointsPerDefeat; - } - - public Map<Integer, Integer> getWonPointsPerVictoryPerAge() { - return wonPointsPerVictoryPerAge; - } - - public void setWonPointsPerVictoryPerAge(Map<Integer, Integer> wonPointsPerVictoryPerAge) { - this.wonPointsPerVictoryPerAge = wonPointsPerVictoryPerAge; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java b/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java deleted file mode 100644 index 54045607..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -/** - * A card with contextual information relative to the hand it is sitting in. The extra information is especially - * useful because it frees the client from a painful business logic implementation. - */ -public class HandCard { - - private final Card card; - - private final boolean chainable; - - private final boolean free; - - private final boolean playable; - - public HandCard(Card card, Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - this.card = card; - this.chainable = card.isChainableOn(board); - this.free = card.isAffordedBy(board) && card.getRequirements().getGold() == 0; - this.playable = card.isPlayable(table, playerIndex); - } - - public Card getCard() { - return card; - } - - public boolean isChainable() { - return chainable; - } - - public boolean isFree() { - return free; - } - - public boolean isPlayable() { - return playable; - } - -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java b/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java deleted file mode 100644 index 6d2889e0..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.moves.MoveType; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public class PlayerMove { - - private String cardName; - - private MoveType type; - - private List<BoughtResources> boughtResources = new ArrayList<>(); - - public String getCardName() { - return cardName; - } - - public void setCardName(String cardName) { - this.cardName = cardName; - } - - public MoveType getType() { - return type; - } - - public void setType(MoveType type) { - this.type = type; - } - - public List<BoughtResources> getBoughtResources() { - return boughtResources; - } - - public void setBoughtResources(List<BoughtResources> boughtResources) { - this.boughtResources = boughtResources; - } - - @Override - public String toString() { - return type + " '" + cardName + '\''; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java b/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java deleted file mode 100644 index 1ff6f541..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.List; - -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.cards.HandRotationDirection; - -public class PlayerTurnInfo { - - private final Player player; - - private final Table table; - - private int currentAge; - - private HandRotationDirection handRotationDirection; - - private Action action; - - private List<HandCard> hand; - - private String message; - - public PlayerTurnInfo(Player player, Table table) { - this.player = player; - this.table = table; - } - - public Player getPlayer() { - return player; - } - - public Table getTable() { - return table; - } - - public int getCurrentAge() { - return currentAge; - } - - public void setCurrentAge(int currentAge) { - this.currentAge = currentAge; - } - - public HandRotationDirection getHandRotationDirection() { - return handRotationDirection; - } - - public void setHandRotationDirection(HandRotationDirection handRotationDirection) { - this.handRotationDirection = handRotationDirection; - } - - public List<HandCard> getHand() { - return hand; - } - - public void setHand(List<HandCard> hand) { - this.hand = hand; - } - - public Action getAction() { - return action; - } - - public void setAction(Action action) { - this.action = action; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/PreparedCard.java b/src/main/java/org/luxons/sevenwonders/game/api/PreparedCard.java deleted file mode 100644 index 85cac1de..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/PreparedCard.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.cards.CardBack; - -public class PreparedCard { - - private final Player player; - - private final CardBack cardBack; - - public PreparedCard(Player player, CardBack cardBack) { - this.player = player; - this.cardBack = cardBack; - } - - public Player getPlayer() { - return player; - } - - public CardBack getCardBack() { - return cardBack; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/api/Table.java b/src/main/java/org/luxons/sevenwonders/game/api/Table.java deleted file mode 100644 index 8b831527..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/api/Table.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.List; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.HandRotationDirection; -import org.luxons.sevenwonders.game.moves.Move; - -/** - * The table contains what is visible by all the players in the game: the boards and their played cards, and the - * players' information. - */ -public class Table { - - private final int nbPlayers; - - private final List<Board> boards; - - private int currentAge = 0; - - private List<Move> lastPlayedMoves; - - public Table(List<Board> boards) { - this.nbPlayers = boards.size(); - this.boards = boards; - } - - public int getNbPlayers() { - return nbPlayers; - } - - public List<Board> getBoards() { - return boards; - } - - public Board getBoard(int playerIndex) { - return boards.get(playerIndex); - } - - public Board getBoard(int playerIndex, RelativeBoardPosition position) { - return boards.get(position.getIndexFrom(playerIndex, nbPlayers)); - } - - public List<Move> getLastPlayedMoves() { - return lastPlayedMoves; - } - - public void setLastPlayedMoves(List<Move> lastPlayedMoves) { - this.lastPlayedMoves = lastPlayedMoves; - } - - public int getCurrentAge() { - return currentAge; - } - - public void increaseCurrentAge() { - this.currentAge++; - } - - public HandRotationDirection getHandRotationDirection() { - return HandRotationDirection.forAge(currentAge); - } - - public void resolveMilitaryConflicts() { - for (int i = 0; i < nbPlayers; i++) { - Board board1 = getBoard(i); - Board board2 = getBoard((i + 1) % nbPlayers); - resolveConflict(board1, board2, currentAge); - } - } - - private static void resolveConflict(Board board1, Board board2, int age) { - int shields1 = board1.getMilitary().getNbShields(); - int shields2 = board2.getMilitary().getNbShields(); - if (shields1 < shields2) { - board2.getMilitary().victory(age); - board1.getMilitary().defeat(); - } else if (shields1 > shields2) { - board1.getMilitary().victory(age); - board2.getMilitary().defeat(); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/Board.java b/src/main/java/org/luxons/sevenwonders/game/boards/Board.java deleted file mode 100644 index ab557d38..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/Board.java +++ /dev/null @@ -1,173 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.resources.Production; -import org.luxons.sevenwonders.game.resources.TradingRules; -import org.luxons.sevenwonders.game.scoring.PlayerScore; -import org.luxons.sevenwonders.game.scoring.ScoreCategory; -import org.luxons.sevenwonders.game.wonders.Wonder; - -public class Board { - - private final Wonder wonder; - - private final Player player; - - private final List<Card> playedCards = new ArrayList<>(); - - private final Production production = new Production(); - - private final Science science = new Science(); - - private final TradingRules tradingRules; - - private final Military military; - - private final Set<SpecialAbility> specialAbilities = EnumSet.noneOf(SpecialAbility.class); - - private Map<Integer, Boolean> consumedFreeCards = new HashMap<>(); - - private Card copiedGuild; - - private int gold; - - private int pointsPer3Gold; - - public Board(Wonder wonder, Player player, Settings settings) { - this.wonder = wonder; - this.player = player; - this.gold = settings.getInitialGold(); - this.tradingRules = new TradingRules(settings.getDefaultTradingCost()); - this.military = new Military(settings); - this.pointsPer3Gold = settings.getPointsPer3Gold(); - this.production.addFixedResource(wonder.getInitialResource(), 1); - } - - public Wonder getWonder() { - return wonder; - } - - public Player getPlayer() { - return player; - } - - public List<Card> getPlayedCards() { - return playedCards; - } - - public void addCard(Card card) { - playedCards.add(card); - } - - public int getNbCardsOfColor(List<Color> colorFilter) { - return (int) playedCards.stream().filter(c -> colorFilter.contains(c.getColor())).count(); - } - - public boolean isPlayed(String cardName) { - return getPlayedCards().stream().map(Card::getName).filter(name -> name.equals(cardName)).count() > 0; - } - - public Production getProduction() { - return production; - } - - public TradingRules getTradingRules() { - return tradingRules; - } - - public Science getScience() { - return science; - } - - public int getGold() { - return gold; - } - - public void setGold(int amount) { - this.gold = amount; - } - - public void addGold(int amount) { - this.gold += amount; - } - - public void removeGold(int amount) { - if (gold < amount) { - throw new InsufficientFundsException(gold, amount); - } - this.gold -= amount; - } - - public Military getMilitary() { - return military; - } - - public void addSpecial(SpecialAbility specialAbility) { - specialAbilities.add(specialAbility); - } - - public boolean hasSpecial(SpecialAbility specialAbility) { - return specialAbilities.contains(specialAbility); - } - - public boolean canPlayFreeCard(int age) { - return hasSpecial(SpecialAbility.ONE_FREE_PER_AGE) && !consumedFreeCards.getOrDefault(age, false); - } - - public void consumeFreeCard(int age) { - consumedFreeCards.put(age, true); - } - - public void setCopiedGuild(Card copiedGuild) { - if (copiedGuild.getColor() != Color.PURPLE) { - throw new IllegalArgumentException("The given card '" + copiedGuild + "' is not a Guild card"); - } - this.copiedGuild = copiedGuild; - } - - public Card getCopiedGuild() { - return copiedGuild; - } - - public PlayerScore computePoints(Table table) { - PlayerScore score = new PlayerScore(player, gold); - score.put(ScoreCategory.CIVIL, computePointsForCards(table, Color.BLUE)); - score.put(ScoreCategory.MILITARY, military.getTotalPoints()); - score.put(ScoreCategory.SCIENCE, science.computePoints()); - score.put(ScoreCategory.TRADE, computePointsForCards(table, Color.YELLOW)); - score.put(ScoreCategory.GUILD, computePointsForCards(table, Color.PURPLE)); - score.put(ScoreCategory.WONDER, wonder.computePoints(table, player.getIndex())); - score.put(ScoreCategory.GOLD, computeGoldPoints()); - return score; - } - - private int computePointsForCards(Table table, Color color) { - return playedCards.stream() - .filter(c -> c.getColor() == color) - .flatMap(c -> c.getEffects().stream()) - .mapToInt(e -> e.computePoints(table, player.getIndex())) - .sum(); - } - - private int computeGoldPoints() { - return gold / 3 * pointsPer3Gold; - } - - static class InsufficientFundsException extends RuntimeException { - InsufficientFundsException(int current, int required) { - super(String.format("Current balance is %d gold, but %d are required", current, required)); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java b/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java deleted file mode 100644 index e50f4ea0..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.List; - -import org.luxons.sevenwonders.game.cards.Color; - -public enum BoardElementType { - CARD { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getNbCardsOfColor(colors); - } - }, - BUILT_WONDER_STAGES { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getWonder().getNbBuiltStages(); - } - }, - DEFEAT_TOKEN { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getMilitary().getNbDefeatTokens(); - } - }; - - public abstract int getElementCount(Board board, List<Color> colors); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/Military.java b/src/main/java/org/luxons/sevenwonders/game/boards/Military.java deleted file mode 100644 index fb93fa96..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/Military.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import org.luxons.sevenwonders.game.Settings; - -public class Military { - - private final Settings settings; - - private int nbShields = 0; - - private int totalPoints = 0; - - private int nbDefeatTokens = 0; - - Military(Settings settings) { - this.settings = settings; - } - - public int getNbShields() { - return nbShields; - } - - public void addShields(int nbShields) { - this.nbShields += nbShields; - } - - public int getTotalPoints() { - return totalPoints; - } - - public int getNbDefeatTokens() { - return nbDefeatTokens; - } - - public void victory(int age) { - Integer wonPoints = settings.getWonPointsPerVictoryPerAge().get(age); - if (wonPoints == null) { - throw new UnknownAgeException(age); - } - totalPoints += wonPoints; - } - - public void defeat() { - int lostPoints = settings.getLostPointsPerDefeat(); - totalPoints -= lostPoints; - nbDefeatTokens++; - } - - static final class UnknownAgeException extends IllegalArgumentException { - UnknownAgeException(int unknownAge) { - super(String.valueOf(unknownAge)); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java b/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java deleted file mode 100644 index 16b2f3a9..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -public enum RelativeBoardPosition { - LEFT { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return wrapIndex(playerIndex - 1, nbPlayers); - } - }, - SELF { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return playerIndex; - } - }, - RIGHT { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return wrapIndex(playerIndex + 1, nbPlayers); - } - }; - - public abstract int getIndexFrom(int playerIndex, int nbPlayers); - - int wrapIndex(int index, int nbPlayers) { - return Math.floorMod(index, nbPlayers); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/Science.java b/src/main/java/org/luxons/sevenwonders/game/boards/Science.java deleted file mode 100644 index 34928bcc..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/Science.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.Arrays; -import java.util.EnumMap; -import java.util.Map; - -public class Science { - - private Map<ScienceType, Integer> quantities = new EnumMap<>(ScienceType.class); - - private int jokers; - - public void add(ScienceType type, int quantity) { - quantities.merge(type, quantity, (x, y) -> x + y); - } - - public void addJoker(int quantity) { - jokers += quantity; - } - - public int getJokers() { - return jokers; - } - - public void addAll(Science science) { - science.quantities.forEach(this::add); - jokers += science.jokers; - } - - public int getQuantity(ScienceType type) { - return quantities.getOrDefault(type, 0); - } - - public int size() { - return quantities.values().stream().mapToInt(q -> q).sum() + jokers; - } - - public int computePoints() { - ScienceType[] types = ScienceType.values(); - Integer[] values = new Integer[types.length]; - for (int i = 0; i < types.length; i++) { - values[i] = quantities.getOrDefault(types[i], 0); - } - return computePoints(values, jokers); - } - - private static int computePoints(Integer[] values, int jokers) { - if (jokers == 0) { - return computePointsNoJoker(values); - } - int maxPoints = 0; - for (int i = 0; i < values.length; i++) { - values[i]++; - maxPoints = Math.max(maxPoints, computePoints(values, jokers - 1)); - values[i]--; - } - return maxPoints; - } - - private static int computePointsNoJoker(Integer[] values) { - int independentSquaresSum = Arrays.stream(values).mapToInt(i -> i * i).sum(); - int nbGroupsOfAll = Arrays.stream(values).mapToInt(i -> i).min().orElse(0); - return independentSquaresSum + nbGroupsOfAll * 7; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java b/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java deleted file mode 100644 index 06408b9e..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -public enum ScienceType { - COMPASS, WHEEL, TABLET -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Card.java b/src/main/java/org/luxons/sevenwonders/game/cards/Card.java deleted file mode 100644 index de674011..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Card.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.List; -import java.util.Objects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.effects.Effect; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public class Card { - - private final String name; - - private final Color color; - - private final Requirements requirements; - - private final List<Effect> effects; - - private final String chainParent; - - private final List<String> chainChildren; - - private final String image; - - private CardBack back; - - public Card(String name, Color color, Requirements requirements, List<Effect> effects, String chainParent, - List<String> chainChildren, String image) { - this.name = name; - this.color = color; - this.requirements = requirements; - this.chainParent = chainParent; - this.effects = effects; - this.chainChildren = chainChildren; - this.image = image; - } - - public String getName() { - return name; - } - - public Color getColor() { - return color; - } - - public String getChainParent() { - return chainParent; - } - - public Requirements getRequirements() { - return requirements; - } - - public List<Effect> getEffects() { - return effects; - } - - public List<String> getChainChildren() { - return chainChildren; - } - - public String getImage() { - return image; - } - - public CardBack getBack() { - return back; - } - - public void setBack(CardBack back) { - this.back = back; - } - - public boolean isChainableOn(Board board) { - return board.isPlayed(chainParent); - } - - public boolean isAffordedBy(Board board) { - return requirements.isAffordedBy(board); - } - - public boolean isPlayable(Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - if (board.isPlayed(name)) { - return false; // cannot play twice the same card - } - return isChainableOn(board) || requirements.couldBeAffordedBy(table, playerIndex); - } - - public void applyTo(Table table, int playerIndex, List<BoughtResources> boughtResources) { - Board playerBoard = table.getBoard(playerIndex); - if (!isChainableOn(playerBoard)) { - requirements.pay(table, playerIndex, boughtResources); - } - effects.forEach(e -> e.apply(table, playerIndex)); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Card card = (Card)o; - return Objects.equals(name, card.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java b/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java deleted file mode 100644 index f925b6c4..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public class CardBack { - - private final String image; - - public CardBack(String image) { - this.image = image; - } - - public String getImage() { - return image; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Color.java b/src/main/java/org/luxons/sevenwonders/game/cards/Color.java deleted file mode 100644 index 5b4e4473..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Color.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public enum Color { - BROWN, GREY, YELLOW, BLUE, GREEN, RED, PURPLE -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java b/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java deleted file mode 100644 index aa2b00bf..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class Decks { - - private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); - - public Decks(Map<Integer, List<Card>> cardsPerAge) { - this.cardsPerAge = cardsPerAge; - } - - public Card getCard(String cardName) throws CardNotFoundException { - return cardsPerAge.values() - .stream() - .flatMap(List::stream) - .filter(c -> c.getName().equals(cardName)) - .findAny() - .orElseThrow(() -> new CardNotFoundException(cardName)); - } - - public Hands deal(int age, int nbPlayers) { - List<Card> deck = getDeck(age); - validateNbCards(deck, nbPlayers); - return deal(deck, nbPlayers); - } - - private List<Card> getDeck(int age) { - List<Card> deck = cardsPerAge.get(age); - if (deck == null) { - throw new IllegalArgumentException("No deck found for age " + age); - } - return deck; - } - - private void validateNbCards(List<Card> deck, int nbPlayers) { - if (nbPlayers == 0) { - throw new IllegalArgumentException("Cannot deal cards between 0 players"); - } - if (deck.size() % nbPlayers != 0) { - throw new IllegalArgumentException( - String.format("Cannot deal %d cards evenly between %d players", deck.size(), nbPlayers)); - } - } - - private Hands deal(List<Card> deck, int nbPlayers) { - Map<Integer, List<Card>> hands = new HashMap<>(nbPlayers); - for (int i = 0; i < nbPlayers; i++) { - hands.put(i, new ArrayList<>()); - } - for (int i = 0; i < deck.size(); i++) { - hands.get(i % nbPlayers).add(deck.get(i)); - } - return new Hands(hands, nbPlayers); - } - - class CardNotFoundException extends RuntimeException { - CardNotFoundException(String message) { - super(message); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java b/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java deleted file mode 100644 index 9c4f4b02..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public enum HandRotationDirection { - LEFT(-1), RIGHT(1); - - private final int indexOffset; - - HandRotationDirection(int i) { - this.indexOffset = i; - } - - public int getIndexOffset() { - return indexOffset; - } - - public static HandRotationDirection forAge(int age) { - // clockwise (pass to the left) at age 1, and alternating - return age % 2 == 0 ? HandRotationDirection.RIGHT : HandRotationDirection.LEFT; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java b/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java deleted file mode 100644 index 4a8bc143..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.api.HandCard; -import org.luxons.sevenwonders.game.api.Table; - -public class Hands { - - private final int nbPlayers; - - private Map<Integer, List<Card>> hands; - - Hands(Map<Integer, List<Card>> hands, int nbPlayers) { - this.hands = hands; - this.nbPlayers = nbPlayers; - } - - public List<Card> get(int playerIndex) { - if (!hands.containsKey(playerIndex)) { - throw new PlayerIndexOutOfBoundsException(playerIndex); - } - return hands.get(playerIndex); - } - - public List<HandCard> createHand(Table table, int playerIndex) { - return hands.get(playerIndex) - .stream() - .map(c -> new HandCard(c, table, playerIndex)) - .collect(Collectors.toList()); - } - - public Hands rotate(HandRotationDirection direction) { - Map<Integer, List<Card>> newHands = new HashMap<>(hands.size()); - for (int i = 0; i < nbPlayers; i++) { - int newIndex = Math.floorMod(i + direction.getIndexOffset(), nbPlayers); - newHands.put(newIndex, hands.get(i)); - } - return new Hands(newHands, nbPlayers); - } - - public boolean isEmpty() { - return hands.values().stream().allMatch(List::isEmpty); - } - - public boolean maxOneCardRemains() { - return hands.values().stream().mapToInt(List::size).max().orElse(0) <= 1; - } - - public List<Card> gatherAndClear() { - List<Card> remainingCards = hands.values().stream().flatMap(List::stream).collect(Collectors.toList()); - hands.clear(); - return remainingCards; - } - - class PlayerIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException { - PlayerIndexOutOfBoundsException(int index) { - super(index); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java b/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java deleted file mode 100644 index f6d7934c..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.resources.BoughtResources; -import org.luxons.sevenwonders.game.resources.Resources; - -public class Requirements { - - private int gold; - - private Resources resources = new Resources(); - - public int getGold() { - return gold; - } - - public void setGold(int gold) { - this.gold = gold; - } - - public Resources getResources() { - return resources; - } - - public void setResources(Resources resources) { - this.resources = resources; - } - - boolean isAffordedBy(Board board) { - return board.getGold() >= gold && board.getProduction().contains(resources); - } - - public boolean couldBeAffordedBy(Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - if (board.getGold() < gold) { - return false; - } - if (board.getProduction().contains(resources)) { - return true; - } - Resources leftToPay = resources.minus(board.getProduction().getFixedResources()); - // TODO take into account resources buyable from neighbours - return true; - } - - public boolean isAffordedBy(Table table, int playerIndex, List<BoughtResources> boughtResources) { - Board board = table.getBoard(playerIndex); - if (isAffordedBy(board)) { - return true; - } - int totalPrice = board.getTradingRules().computeCost(boughtResources); - if (board.getGold() < totalPrice) { - return false; - } - Resources totalBoughtResources = getTotalResources(boughtResources); - Resources remainingResources = this.resources.minus(totalBoughtResources); - return board.getProduction().contains(remainingResources); - } - - private Resources getTotalResources(List<BoughtResources> boughtResources) { - return boughtResources.stream().map(BoughtResources::getResources).reduce(new Resources(), (r1, r2) -> { - r1.addAll(r2); - return r1; - }); - } - - void pay(Table table, int playerIndex, List<BoughtResources> boughtResources) { - table.getBoard(playerIndex).removeGold(gold); - payBoughtResources(table, playerIndex, boughtResources); - } - - private void payBoughtResources(Table table, int playerIndex, List<BoughtResources> boughtResourcesList) { - boughtResourcesList.forEach(res -> payBoughtResources(table, playerIndex, res)); - } - - private void payBoughtResources(Table table, int playerIndex, BoughtResources boughtResources) { - Board board = table.getBoard(playerIndex); - int price = board.getTradingRules().computeCost(boughtResources); - board.removeGold(price); - RelativeBoardPosition providerPosition = boughtResources.getProvider().getBoardPosition(); - Board providerBoard = table.getBoard(playerIndex, providerPosition); - providerBoard.addGold(price); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java deleted file mode 100644 index 4c63718b..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.luxons.sevenwonders.game.Game; -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.CustomizableSettings; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Decks; -import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; -import org.luxons.sevenwonders.game.data.definitions.WonderDefinition; -import org.luxons.sevenwonders.game.wonders.Wonder; - -public class GameDefinition { - - /** - * This value is heavily dependent on the JSON data. Any change must be carefully thought through. - */ - private static final int MIN_PLAYERS = 3; - - /** - * This value is heavily dependent on the JSON data. Any change must be carefully thought through. - */ - private static final int MAX_PLAYERS = 7; - - private WonderDefinition[] wonders; - - private DecksDefinition decksDefinition; - - GameDefinition(WonderDefinition[] wonders, DecksDefinition decksDefinition) { - this.wonders = wonders; - this.decksDefinition = decksDefinition; - } - - public int getMinPlayers() { - return MIN_PLAYERS; - } - - public int getMaxPlayers() { - return MAX_PLAYERS; - } - - public Game initGame(long id, CustomizableSettings customSettings, List<Player> orderedPlayers) { - Settings settings = new Settings(orderedPlayers.size(), customSettings); - List<Board> boards = assignBoards(settings, orderedPlayers); - Decks decks = decksDefinition.create(settings); - return new Game(id, settings, orderedPlayers, boards, decks); - } - - private List<Board> assignBoards(Settings settings, List<Player> orderedPlayers) { - List<WonderDefinition> randomizedWonders = Arrays.asList(wonders); - Collections.shuffle(randomizedWonders, settings.getRandom()); - - List<Board> boards = new ArrayList<>(orderedPlayers.size()); - for (int i = 0; i < orderedPlayers.size(); i++) { - Player player = orderedPlayers.get(i); - WonderDefinition def = randomizedWonders.get(i); - Wonder w = def.create(settings); - Board b = new Board(w, player, settings); - boards.add(b); - } - return boards; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java b/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java deleted file mode 100644 index 30457d86..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Type; -import java.util.List; - -import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; -import org.luxons.sevenwonders.game.data.definitions.WonderDefinition; -import org.luxons.sevenwonders.game.data.serializers.NumericEffectSerializer; -import org.luxons.sevenwonders.game.data.serializers.ProductionIncreaseSerializer; -import org.luxons.sevenwonders.game.data.serializers.ResourceTypeSerializer; -import org.luxons.sevenwonders.game.data.serializers.ResourceTypesSerializer; -import org.luxons.sevenwonders.game.data.serializers.ResourcesSerializer; -import org.luxons.sevenwonders.game.data.serializers.ScienceProgressSerializer; -import org.luxons.sevenwonders.game.effects.GoldIncrease; -import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; -import org.luxons.sevenwonders.game.effects.ProductionIncrease; -import org.luxons.sevenwonders.game.effects.RawPointsIncrease; -import org.luxons.sevenwonders.game.effects.ScienceProgress; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; -import org.springframework.stereotype.Component; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; - -@Component -public class GameDefinitionLoader { - - private static final String BASE_PACKAGE = GameDefinitionLoader.class.getPackage().getName(); - - private static final String BASE_PACKAGE_PATH = '/' + BASE_PACKAGE.replace('.', '/'); - - private static final String CARDS_FILE = "cards.json"; - - private static final String WONDERS_FILE = "wonders.json"; - - private final GameDefinition gameDefinition; - - public GameDefinitionLoader() { - gameDefinition = load(); - } - - public GameDefinition getGameDefinition() { - return gameDefinition; - } - - private static GameDefinition load() { - return new GameDefinition(loadWonders(), loadDecks()); - } - - private static WonderDefinition[] loadWonders() { - return readJsonFile(WONDERS_FILE, WonderDefinition[].class); - } - - private static DecksDefinition loadDecks() { - return readJsonFile(CARDS_FILE, DecksDefinition.class); - } - - private static <T> T readJsonFile(String filename, Class<T> clazz) { - InputStream in = GameDefinitionLoader.class.getResourceAsStream(BASE_PACKAGE_PATH + '/' + filename); - Reader reader = new BufferedReader(new InputStreamReader(in)); - Gson gson = createGson(); - return gson.fromJson(reader, clazz); - } - - private static Gson createGson() { - Type resourceTypeList = new TypeToken<List<ResourceType>>() {}.getType(); - return new GsonBuilder().disableHtmlEscaping() - .registerTypeAdapter(Resources.class, new ResourcesSerializer()) - .registerTypeAdapter(ResourceType.class, new ResourceTypeSerializer()) - .registerTypeAdapter(resourceTypeList, new ResourceTypesSerializer()) - .registerTypeAdapter(ProductionIncrease.class, new ProductionIncreaseSerializer()) - .registerTypeAdapter(MilitaryReinforcements.class, new NumericEffectSerializer()) - .registerTypeAdapter(RawPointsIncrease.class, new NumericEffectSerializer()) - .registerTypeAdapter(GoldIncrease.class, new NumericEffectSerializer()) - .registerTypeAdapter(ScienceProgress.class, new ScienceProgressSerializer()) - .create(); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java deleted file mode 100644 index 621bed2c..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.List; -import java.util.Map; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.cards.Requirements; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class CardDefinition implements Definition<Card> { - - private String name; - - private Color color; - - private Requirements requirements; - - private EffectsDefinition effect; - - private String chainParent; - - private List<String> chainChildren; - - private Map<Integer, Integer> countPerNbPlayer; - - private String image; - - @Override - public Card create(Settings settings) { - return new Card(name, color, requirements, effect.create(settings), chainParent, chainChildren, image); - } - - Map<Integer, Integer> getCountPerNbPlayer() { - return countPerNbPlayer; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java deleted file mode 100644 index 6f97e55f..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.cards.Decks; - -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") // the fields are injected by Gson -public class DecksDefinition implements Definition<Decks> { - - private List<CardDefinition> age1; - - private List<CardDefinition> age2; - - private List<CardDefinition> age3; - - private String age1Back; - - private String age2Back; - - private String age3Back; - - private List<CardDefinition> guildCards; - - @Override - public Decks create(Settings settings) { - Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); - cardsPerAge.put(1, prepareStandardDeck(age1, settings, age1Back)); - cardsPerAge.put(2, prepareStandardDeck(age2, settings, age2Back)); - cardsPerAge.put(3, prepareAge3Deck(settings)); - return new Decks(cardsPerAge); - } - - private static List<Card> prepareStandardDeck(List<CardDefinition> defs, Settings settings, String backImage) { - CardBack back = new CardBack(backImage); - List<Card> cards = createDeck(defs, settings, back); - Collections.shuffle(cards, settings.getRandom()); - return cards; - } - - private List<Card> prepareAge3Deck(Settings settings) { - CardBack back = new CardBack(age3Back); - List<Card> age3deck = createDeck(age3, settings, back); - age3deck.addAll(createGuildCards(settings, back)); - Collections.shuffle(age3deck, settings.getRandom()); - return age3deck; - } - - private static List<Card> createDeck(List<CardDefinition> defs, Settings settings, CardBack back) { - List<Card> cards = new ArrayList<>(); - for (CardDefinition def : defs) { - for (int i = 0; i < def.getCountPerNbPlayer().get(settings.getNbPlayers()); i++) { - Card card = def.create(settings); - card.setBack(back); - cards.add(card); - } - } - return cards; - } - - private List<Card> createGuildCards(Settings settings, CardBack back) { - List<Card> guild = guildCards.stream() - .map((def) -> def.create(settings)) - .peek(c -> c.setBack(back)) - .collect(Collectors.toList()); - Collections.shuffle(guild, settings.getRandom()); - return guild.subList(0, settings.getNbPlayers() + 2); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java deleted file mode 100644 index 6c6b4b19..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import org.luxons.sevenwonders.game.Settings; - -/** - * Represents a deserialized JSON definition of some data about the game. It is settings-agnostic. An instance of - * in-game data can be generated from this, given specific game settings. - * - * @param <T> - * the type of in-game object that can be generated from this definition - */ -public interface Definition<T> { - - /** - * Creates a T object from the given settings. This method mustn't mutate this Definition as it may be called - * multiple times with different settings. - * - * @param settings - * the game settings to use to generate a game-specific object from this definition - * - * @return the new game-specific object created from this definition - */ - T create(Settings settings); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java deleted file mode 100644 index e35463d4..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.effects.BonusPerBoardElement; -import org.luxons.sevenwonders.game.effects.Discount; -import org.luxons.sevenwonders.game.effects.Effect; -import org.luxons.sevenwonders.game.effects.GoldIncrease; -import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; -import org.luxons.sevenwonders.game.effects.ProductionIncrease; -import org.luxons.sevenwonders.game.effects.RawPointsIncrease; -import org.luxons.sevenwonders.game.effects.ScienceProgress; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.effects.SpecialAbilityActivation; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class EffectsDefinition implements Definition<List<Effect>> { - - private GoldIncrease gold; - - private MilitaryReinforcements military; - - private ScienceProgress science; - - private Discount discount; - - private BonusPerBoardElement perBoardElement; - - private ProductionIncrease production; - - private RawPointsIncrease points; - - private SpecialAbility action; - - @Override - public List<Effect> create(Settings settings) { - List<Effect> effects = new ArrayList<>(); - if (gold != null) { - effects.add(gold); - } - if (military != null) { - effects.add(military); - } - if (science != null) { - effects.add(science); - } - if (discount != null) { - effects.add(discount); - } - if (perBoardElement != null) { - effects.add(perBoardElement); - } - if (production != null) { - effects.add(production); - } - if (points != null) { - effects.add(points); - } - if (action != null) { - effects.add(new SpecialAbilityActivation(action)); - } - return effects; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java deleted file mode 100644 index a972a517..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.Map; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.wonders.Wonder; - -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") // the fields are injected by Gson -public class WonderDefinition implements Definition<Wonder> { - - private String name; - - private Map<WonderSide, WonderSideDefinition> sides; - - @Override - public Wonder create(Settings settings) { - Wonder wonder = new Wonder(); - wonder.setName(name); - - WonderSideDefinition wonderSideDef = sides.get(settings.pickWonderSide()); - wonder.setInitialResource(wonderSideDef.getInitialResource()); - wonder.setStages(wonderSideDef.createStages(settings)); - wonder.setImage(wonderSideDef.getImage()); - return wonder; - } - -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java deleted file mode 100644 index 08c85f57..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -public enum WonderSide { - A, B -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java deleted file mode 100644 index 9b2bc2d5..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.List; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.wonders.WonderStage; - -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") // the fields are injected by Gson -class WonderSideDefinition { - - private ResourceType initialResource; - - private List<WonderStageDefinition> stages; - - private String image; - - ResourceType getInitialResource() { - return initialResource; - } - - List<WonderStage> createStages(Settings settings) { - return stages.stream().map(def -> def.create(settings)).collect(Collectors.toList()); - } - - String getImage() { - return image; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java deleted file mode 100644 index 08aaad14..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.Random; - -public enum WonderSidePickMethod { - ALL_A { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return WonderSide.A; - } - }, - ALL_B { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return WonderSide.B; - } - }, - EACH_RANDOM { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return random.nextBoolean() ? WonderSide.A : WonderSide.B; - } - }, - SAME_RANDOM_FOR_ALL { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - if (lastPickedSide == null) { - return random.nextBoolean() ? WonderSide.A : WonderSide.B; - } else { - return lastPickedSide; - } - } - }; - - public abstract WonderSide pickSide(Random random, WonderSide lastPickedSide); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java deleted file mode 100644 index 887b414a..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Requirements; -import org.luxons.sevenwonders.game.wonders.WonderStage; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class WonderStageDefinition implements Definition<WonderStage> { - - private Requirements requirements; - - private EffectsDefinition effects; - - @Override - public WonderStage create(Settings settings) { - WonderStage stage = new WonderStage(); - stage.setRequirements(requirements); - stage.setEffects(effects.create(settings)); - return stage; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java deleted file mode 100644 index c1a51f24..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import org.luxons.sevenwonders.game.effects.Effect; -import org.luxons.sevenwonders.game.effects.GoldIncrease; -import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; -import org.luxons.sevenwonders.game.effects.RawPointsIncrease; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class NumericEffectSerializer implements JsonSerializer<Effect>, JsonDeserializer<Effect> { - - @Override - public JsonElement serialize(Effect effect, Type typeOfSrc, JsonSerializationContext context) { - int value; - if (MilitaryReinforcements.class.equals(typeOfSrc)) { - value = ((MilitaryReinforcements)effect).getCount(); - } else if (GoldIncrease.class.equals(typeOfSrc)) { - value = ((GoldIncrease)effect).getAmount(); - } else if (RawPointsIncrease.class.equals(typeOfSrc)) { - value = ((RawPointsIncrease)effect).getPoints(); - } else { - throw new IllegalArgumentException("Unknown numeric effect " + typeOfSrc.getTypeName()); - } - return new JsonPrimitive(value); - } - - @Override - public Effect deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - int value = json.getAsInt(); - if (MilitaryReinforcements.class.equals(typeOfT)) { - return new MilitaryReinforcements(value); - } else if (GoldIncrease.class.equals(typeOfT)) { - return new GoldIncrease(value); - } else if (RawPointsIncrease.class.equals(typeOfT)) { - return new RawPointsIncrease(value); - } - throw new IllegalArgumentException("Unknown numeric effet " + typeOfT.getTypeName()); - } -}
\ No newline at end of file diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java deleted file mode 100644 index 6c70a44d..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.effects.ProductionIncrease; -import org.luxons.sevenwonders.game.resources.Production; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class ProductionIncreaseSerializer implements JsonSerializer<ProductionIncrease>, - JsonDeserializer<ProductionIncrease> { - - @Override - public JsonElement serialize(ProductionIncrease productionIncrease, Type typeOfSrc, - JsonSerializationContext context) { - Production production = productionIncrease.getProduction(); - Resources fixedResources = production.getFixedResources(); - List<Set<ResourceType>> choices = production.getAlternativeResources(); - if (fixedResources.isEmpty()) { - return serializeAsChoice(choices, context); - } else if (choices.isEmpty()) { - return serializeAsResources(fixedResources, context); - } else { - throw new IllegalArgumentException("Cannot serialize a production with mixed fixed resources and choices"); - } - } - - private JsonElement serializeAsResources(Resources fixedResources, JsonSerializationContext context) { - return context.serialize(fixedResources); - } - - private JsonElement serializeAsChoice(List<Set<ResourceType>> choices, JsonSerializationContext context) { - if (choices.isEmpty()) { - return JsonNull.INSTANCE; - } - if (choices.size() > 1) { - throw new IllegalArgumentException("Cannot serialize a production with more than one choice"); - } - String str = choices.get(0).stream() - .map(ResourceType::getSymbol) - .map(Object::toString) - .collect(Collectors.joining("/")); - return context.serialize(str); - } - - @Override - public ProductionIncrease deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - String s = json.getAsString(); - ProductionIncrease productionIncrease = new ProductionIncrease(); - Production production = new Production(); - if (s.contains("/")) { - production.addChoice(createChoice(s)); - } else { - Resources fixedResources = context.deserialize(json, Resources.class); - production.addAll(fixedResources); - } - productionIncrease.setProduction(production); - return productionIncrease; - } - - private ResourceType[] createChoice(String choiceStr) { - String[] symbols = choiceStr.split("/"); - ResourceType[] choice = new ResourceType[symbols.length]; - for (int i = 0; i < symbols.length; i++) { - if (symbols[i].length() != 1) { - throw new IllegalArgumentException("Choice elements must be resource types, got " + symbols[i]); - } - choice[i] = ResourceType.fromSymbol(symbols[i].charAt(0)); - } - return choice; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java deleted file mode 100644 index 145063eb..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import org.luxons.sevenwonders.game.resources.ResourceType; - -public class ResourceTypeSerializer implements JsonSerializer<ResourceType>, JsonDeserializer<ResourceType> { - - @Override - public JsonElement serialize(ResourceType type, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(type.getSymbol()); - } - - @Override - public ResourceType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - String str = json.getAsString(); - if (str.isEmpty()) { - throw new IllegalArgumentException("Empty string is not a valid resource type"); - } - return ResourceType.fromSymbol(str.charAt(0)); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java deleted file mode 100644 index 8aca5561..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import org.luxons.sevenwonders.game.resources.ResourceType; - -public class ResourceTypesSerializer implements JsonSerializer<List<ResourceType>>, JsonDeserializer<List<ResourceType>> { - - @Override - public JsonElement serialize(List<ResourceType> resources, Type typeOfSrc, JsonSerializationContext context) { - String s = resources.stream() - .map(ResourceType::getSymbol) - .map(Object::toString) - .collect(Collectors.joining()); - return new JsonPrimitive(s); - } - - @Override - public List<ResourceType> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - String s = json.getAsString(); - List<ResourceType> resources = new ArrayList<>(); - for (char c : s.toCharArray()) { - resources.add(ResourceType.fromSymbol(c)); - } - return resources; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java deleted file mode 100644 index efeafd15..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; - -public class ResourcesSerializer implements JsonSerializer<Resources>, JsonDeserializer<Resources> { - - @Override - public JsonElement serialize(Resources resources, Type typeOfSrc, JsonSerializationContext context) { - String s = resources.getQuantities() - .entrySet() - .stream() - .flatMap(e -> Stream.generate(() -> e.getKey().getSymbol()).limit(e.getValue())) - .map(Object::toString) - .collect(Collectors.joining()); - return s.isEmpty() ? JsonNull.INSTANCE : new JsonPrimitive(s); - } - - @Override - public Resources deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - String s = json.getAsString(); - Resources resources = new Resources(); - for (char c : s.toCharArray()) { - resources.add(ResourceType.fromSymbol(c), 1); - } - return resources; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java deleted file mode 100644 index b6e38540..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import org.luxons.sevenwonders.game.boards.Science; -import org.luxons.sevenwonders.game.boards.ScienceType; -import org.luxons.sevenwonders.game.effects.ScienceProgress; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class ScienceProgressSerializer implements JsonSerializer<ScienceProgress>, JsonDeserializer<ScienceProgress> { - - @Override - public JsonElement serialize(ScienceProgress scienceProgress, Type typeOfSrc, JsonSerializationContext context) { - Science science = scienceProgress.getScience(); - - if (science.size() > 1) { - throw new UnsupportedOperationException("Cannot serialize science containing more than one element"); - } - - for (ScienceType type : ScienceType.values()) { - int quantity = science.getQuantity(type); - if (quantity == 1) { - return context.serialize(type); - } - } - - if (science.getJokers() == 1) { - return new JsonPrimitive("any"); - } - - return JsonNull.INSTANCE; - } - - @Override - public ScienceProgress deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws - JsonParseException { - String s = json.getAsString(); - ScienceProgress scienceProgress = new ScienceProgress(); - Science science = new Science(); - if ("any".equals(s)) { - science.addJoker(1); - } else { - science.add(deserializeScienceType(json, context), 1); - } - scienceProgress.setScience(science); - return scienceProgress; - } - - private ScienceType deserializeScienceType(JsonElement json, JsonDeserializationContext context) { - ScienceType type = context.deserialize(json, ScienceType.class); - if (type == null) { - throw new IllegalArgumentException("Invalid science type " + json.getAsString()); - } - return type; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java b/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java deleted file mode 100644 index e9f9fe5f..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.BoardElementType; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.Color; - -public class BonusPerBoardElement implements Effect { - - private List<RelativeBoardPosition> boards; - - private int gold; - - private int points; - - private BoardElementType type; - - // only relevant if type=CARD - private List<Color> colors; - - public List<RelativeBoardPosition> getBoards() { - return boards; - } - - public void setBoards(List<RelativeBoardPosition> boards) { - this.boards = boards; - } - - public int getGold() { - return gold; - } - - public void setGold(int gold) { - this.gold = gold; - } - - public int getPoints() { - return points; - } - - public void setPoints(int points) { - this.points = points; - } - - public BoardElementType getType() { - return type; - } - - public void setType(BoardElementType type) { - this.type = type; - } - - public List<Color> getColors() { - return colors; - } - - public void setColors(List<Color> colors) { - this.colors = colors; - } - - @Override - public void apply(Table table, int playerIndex) { - int goldGain = gold * computeNbOfMatchingElementsIn(table, playerIndex); - Board board = table.getBoard(playerIndex); - board.addGold(goldGain); - } - - @Override - public int computePoints(Table table, int playerIndex) { - return points * computeNbOfMatchingElementsIn(table, playerIndex); - } - - private int computeNbOfMatchingElementsIn(Table table, int playerIndex) { - return boards.stream() - .map(pos -> table.getBoard(playerIndex, pos)) - .mapToInt(this::computeNbOfMatchingElementsIn) - .sum(); - } - - private int computeNbOfMatchingElementsIn(Board board) { - return type.getElementCount(board, colors); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java b/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java deleted file mode 100644 index 3a44574b..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.resources.Provider; -import org.luxons.sevenwonders.game.resources.TradingRules; -import org.luxons.sevenwonders.game.resources.ResourceType; - -public class Discount extends InstantOwnBoardEffect { - - private final List<ResourceType> resourceTypes = new ArrayList<>(); - - private final List<Provider> providers = new ArrayList<>(); - - private int discountedPrice = 1; - - public List<ResourceType> getResourceTypes() { - return resourceTypes; - } - - public List<Provider> getProviders() { - return providers; - } - - public int getDiscountedPrice() { - return discountedPrice; - } - - public void setDiscountedPrice(int discountedPrice) { - this.discountedPrice = discountedPrice; - } - - @Override - public void apply(Board board) { - TradingRules rules = board.getTradingRules(); - for (ResourceType type : resourceTypes) { - for (Provider provider : providers) { - rules.setCost(type, provider, discountedPrice); - } - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java b/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java deleted file mode 100644 index 692eaea0..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -/** - * Represents an effect than can be applied to a player's board when playing a card or building his wonder. The effect - * may affect (or depend on) the adjacent boards. It can have an instantaneous effect on the board, or be postponed to - * the end of game where point calculations take place. - */ -public interface Effect { - - void apply(Table table, int playerIndex); - - int computePoints(Table table, int playerIndex); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java b/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java deleted file mode 100644 index 1bae16a6..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -public abstract class EndGameEffect implements Effect { - - @Override - public void apply(Table table, int playerIndex) { - // EndGameEffects don't do anything when applied to the board, they simply give more points in the end - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java b/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java deleted file mode 100644 index 79e7bd1a..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; - -public class GoldIncrease extends InstantOwnBoardEffect { - - private final int amount; - - public int getAmount() { - return amount; - } - - public GoldIncrease(int amount) { - this.amount = amount; - } - - @Override - public void apply(Board board) { - board.addGold(amount); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GoldIncrease that = (GoldIncrease)o; - return amount == that.amount; - } - - @Override - public int hashCode() { - return Objects.hash(amount); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java b/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java deleted file mode 100644 index 8f4340cf..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; - -public abstract class InstantOwnBoardEffect implements Effect { - - @Override - public void apply(Table table, int playerIndex) { - apply(table.getBoard(playerIndex)); - } - - protected abstract void apply(Board board); - - @Override - public int computePoints(Table table, int playerIndex) { - // InstantEffects are only important when applied to the board, they don't give extra points in the end - return 0; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java b/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java deleted file mode 100644 index b08e2f59..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; - -public class MilitaryReinforcements extends InstantOwnBoardEffect { - - private final int count; - - public int getCount() { - return count; - } - - public MilitaryReinforcements(int count) { - this.count = count; - } - - @Override - public void apply(Board board) { - board.getMilitary().addShields(count); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - MilitaryReinforcements that = (MilitaryReinforcements)o; - return count == that.count; - } - - @Override - public int hashCode() { - return Objects.hash(count); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java b/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java deleted file mode 100644 index 9724dfcd..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.resources.Production; - -public class ProductionIncrease extends InstantOwnBoardEffect { - - private Production production = new Production(); - - public Production getProduction() { - return production; - } - - public void setProduction(Production production) { - this.production = production; - } - - @Override - public void apply(Board board) { - board.getProduction().addAll(production); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ProductionIncrease that = (ProductionIncrease)o; - return Objects.equals(production, that.production); - } - - @Override - public int hashCode() { - return Objects.hash(production); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java b/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java deleted file mode 100644 index 0d117cec..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.api.Table; - -public class RawPointsIncrease extends EndGameEffect { - - private final int points; - - public int getPoints() { - return points; - } - - public RawPointsIncrease(int points) { - this.points = points; - } - - @Override - public int computePoints(Table table, int playerIndex) { - return points; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RawPointsIncrease that = (RawPointsIncrease)o; - return points == that.points; - } - - @Override - public int hashCode() { - return Objects.hash(points); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java b/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java deleted file mode 100644 index 4e6764ee..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.Science; - -public class ScienceProgress extends InstantOwnBoardEffect { - - private Science science; - - public Science getScience() { - return science; - } - - public void setScience(Science science) { - this.science = science; - } - - @Override - public void apply(Board board) { - board.getScience().addAll(science); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java b/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java deleted file mode 100644 index 5de87784..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public enum SpecialAbility { - /** - * The player can play the last card of each age instead of discarding it. This card can be played by paying its - * cost, discarded to gain 3 coins or used in the construction of his or her Wonder. - */ - PLAY_LAST_CARD, - - /** - * Once per age, a player can construct a building from his or her hand for free. - */ - ONE_FREE_PER_AGE, - - /** - * The player can look at all cards discarded since the beginning of the game, pick one and build it for free. - */ - PLAY_DISCARDED, - - /** - * The player can, at the end of the game, “copy” a Guild of his or her choice (purple card), built by one of his or - * her two neighboring cities. - */ - COPY_GUILD { - @Override - public int computePoints(Table table, int playerIndex) { - Card copiedGuild = table.getBoard(playerIndex).getCopiedGuild(); - if (copiedGuild == null) { - throw new IllegalStateException("The copied Guild has not been chosen, cannot compute points"); - } - return copiedGuild.getEffects().stream().mapToInt(e -> e.computePoints(table, playerIndex)).sum(); - } - }; - - protected void apply(Board board) { - board.addSpecial(this); - } - - public int computePoints(Table table, int playerIndex) { - return 0; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java b/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java deleted file mode 100644 index a5953c2f..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -public class SpecialAbilityActivation implements Effect { - - private final SpecialAbility specialAbility; - - public SpecialAbilityActivation(SpecialAbility specialAbility) { - this.specialAbility = specialAbility; - } - - public SpecialAbility getSpecialAbility() { - return specialAbility; - } - - @Override - public void apply(Table table, int playerIndex) { - specialAbility.apply(table.getBoard(playerIndex)); - } - - @Override - public int computePoints(Table table, int playerIndex) { - return specialAbility.computePoints(table, playerIndex); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java deleted file mode 100644 index bddd6ec6..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class BuildWonderMove extends CardFromHandMove { - - BuildWonderMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public boolean isValid(Table table, List<Card> playerHand) { - if (!super.isValid(table, playerHand)) { - return false; - } - Board board = table.getBoard(getPlayerIndex()); - return board.getWonder().isNextStageBuildable(table, getPlayerIndex(), getBoughtResources()); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.getWonder().buildLevel(getCard().getBack()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - int playerIndex = getPlayerIndex(); - Board board = table.getBoard(playerIndex); - board.getWonder().activateLastBuiltStage(table, playerIndex, getBoughtResources()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java deleted file mode 100644 index 7bbee1e5..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; - -public abstract class CardFromHandMove extends Move { - - CardFromHandMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public boolean isValid(Table table, List<Card> playerHand) { - return playerHand.contains(getCard()); - } - -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java deleted file mode 100644 index 5ebde772..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.effects.SpecialAbility; - -public class CopyGuildMove extends Move { - - CopyGuildMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public boolean isValid(Table table, List<Card> playerHand) { - Board board = table.getBoard(getPlayerIndex()); - if (!board.hasSpecial(SpecialAbility.COPY_GUILD)) { - return false; - } - if (getCard().getColor() != Color.PURPLE) { - return false; - } - boolean leftNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.LEFT); - boolean rightNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.RIGHT); - return leftNeighbourHasIt || rightNeighbourHasIt; - } - - private boolean neighbourHasTheCard(Table table, RelativeBoardPosition position) { - Board neighbourBoard = table.getBoard(getPlayerIndex(), position); - return neighbourBoard.getPlayedCards().contains(getCard()); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - // nothing special to do here - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.setCopiedGuild(getCard()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java deleted file mode 100644 index 076a593c..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class DiscardMove extends CardFromHandMove { - - DiscardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - discardedCards.add(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addGold(settings.getDiscardedCardGold()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/Move.java b/src/main/java/org/luxons/sevenwonders/game/moves/Move.java deleted file mode 100644 index 8b6b60a8..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/Move.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public abstract class Move { - - private int playerIndex; - - private Card card; - - private MoveType type; - - private List<BoughtResources> boughtResources = new ArrayList<>(); - - Move(int playerIndex, Card card, PlayerMove move) { - this.playerIndex = playerIndex; - this.card = card; - this.type = move.getType(); - this.boughtResources = move.getBoughtResources(); - } - - public int getPlayerIndex() { - return playerIndex; - } - - public Card getCard() { - return card; - } - - public MoveType getType() { - return type; - } - - public List<BoughtResources> getBoughtResources() { - return boughtResources; - } - - public abstract boolean isValid(Table table, List<Card> playerHand); - - public abstract void place(Table table, List<Card> discardedCards, Settings settings); - - public abstract void activate(Table table, List<Card> discardedCards, Settings settings); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java b/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java deleted file mode 100644 index bf64344d..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.cards.Card; - -public enum MoveType { - PLAY { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new PlayCardMove(playerIndex, card, move); - } - }, - PLAY_FREE { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new PlayFreeCardMove(playerIndex, card, move); - } - }, - UPGRADE_WONDER { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new BuildWonderMove(playerIndex, card, move); - } - }, - DISCARD { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new DiscardMove(playerIndex, card, move); - } - }, - COPY_GUILD { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new CopyGuildMove(playerIndex, card, move); - } - }; - - public abstract Move resolve(int playerIndex, Card card, PlayerMove move); -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java deleted file mode 100644 index affebc4a..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class PlayCardMove extends CardFromHandMove { - - PlayCardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public boolean isValid(Table table, List<Card> playerHand) { - if (!super.isValid(table, playerHand)) { - return false; - } - return getCard().getRequirements().isAffordedBy(table, getPlayerIndex(), getBoughtResources()); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addCard(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - getCard().applyTo(table, getPlayerIndex(), getBoughtResources()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java b/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java deleted file mode 100644 index fb28b09c..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class PlayFreeCardMove extends CardFromHandMove { - - PlayFreeCardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public boolean isValid(Table table, List<Card> playerHand) { - if (!super.isValid(table, playerHand)) { - return false; - } - Board board = table.getBoard(getPlayerIndex()); - return board.canPlayFreeCard(table.getCurrentAge()); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addCard(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - // only apply effects, without paying the cost - getCard().getEffects().forEach(e -> e.apply(table, getPlayerIndex())); - Board board = table.getBoard(getPlayerIndex()); - board.consumeFreeCard(table.getCurrentAge()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java b/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java deleted file mode 100644 index ec261c8c..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -public class BoughtResources { - - private Provider provider; - - private Resources resources; - - public Provider getProvider() { - return provider; - } - - public void setProvider(Provider provider) { - this.provider = provider; - } - - public Resources getResources() { - return resources; - } - - public void setResources(Resources resources) { - this.resources = resources; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/Production.java b/src/main/java/org/luxons/sevenwonders/game/resources/Production.java deleted file mode 100644 index b7701c27..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/Production.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; - -public class Production { - - private final Resources fixedResources = new Resources(); - - private final List<Set<ResourceType>> alternativeResources = new ArrayList<>(); - - public void addFixedResource(ResourceType type, int quantity) { - fixedResources.add(type, quantity); - } - - public void addChoice(ResourceType... options) { - EnumSet<ResourceType> optionSet = EnumSet.noneOf(ResourceType.class); - optionSet.addAll(Arrays.asList(options)); - alternativeResources.add(optionSet); - } - - public void addAll(Resources resources) { - fixedResources.addAll(resources); - } - - public void addAll(Production production) { - fixedResources.addAll(production.getFixedResources()); - alternativeResources.addAll(production.getAlternativeResources()); - } - - public Resources getFixedResources() { - return fixedResources; - } - - public List<Set<ResourceType>> getAlternativeResources() { - return alternativeResources; - } - - public boolean contains(Resources resources) { - if (fixedResources.contains(resources)) { - return true; - } - Resources remaining = resources.minus(fixedResources); - return containedInAlternatives(remaining); - } - - private boolean containedInAlternatives(Resources resources) { - return containedInAlternatives(resources, alternativeResources); - } - - private static boolean containedInAlternatives(Resources resources, List<Set<ResourceType>> alternatives) { - if (resources.isEmpty()) { - return true; - } - for (Entry<ResourceType, Integer> entry : resources.getQuantities().entrySet()) { - ResourceType type = entry.getKey(); - int count = entry.getValue(); - if (count <= 0) { - continue; - } - Set<ResourceType> candidate = findFirstAlternativeContaining(alternatives, type); - if (candidate == null) { - return false; // no alternative produces the resource of this entry - } - entry.setValue(count - 1); - alternatives.remove(candidate); - boolean remainingAreContainedToo = containedInAlternatives(resources, alternatives); - entry.setValue(count); - alternatives.add(candidate); - if (remainingAreContainedToo) { - return true; - } - } - return false; - } - - private static Set<ResourceType> findFirstAlternativeContaining(List<Set<ResourceType>> alternatives, ResourceType type) { - return alternatives.stream().filter(a -> a.contains(type)).findAny().orElse(null); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Production that = (Production)o; - return Objects.equals(fixedResources, that.fixedResources) && Objects.equals(alternativeResources, - that.alternativeResources); - } - - @Override - public int hashCode() { - return Objects.hash(fixedResources, alternativeResources); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java b/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java deleted file mode 100644 index 9c4aa3f9..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; - -public enum Provider { - LEFT_PLAYER(RelativeBoardPosition.LEFT), - RIGHT_PLAYER(RelativeBoardPosition.RIGHT); - - private final RelativeBoardPosition boardPosition; - - Provider(RelativeBoardPosition boardPosition) { - this.boardPosition = boardPosition; - } - - public RelativeBoardPosition getBoardPosition() { - return boardPosition; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java b/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java deleted file mode 100644 index 46d60123..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.HashMap; -import java.util.Map; - -public enum ResourceType { - WOOD('W'), - STONE('S'), - ORE('O'), - CLAY('C'), - GLASS('G'), - PAPYRUS('P'), - LOOM('L'); - - private static final Map<Character, ResourceType> typesPerSymbol = new HashMap<>(7); - static { - for (ResourceType type : values()) { - typesPerSymbol.put(type.symbol, type); - } - } - - private final Character symbol; - - ResourceType(Character symbol) { - this.symbol = symbol; - } - - public static ResourceType fromSymbol(Character symbol) { - ResourceType type = typesPerSymbol.get(symbol); - if (type == null) { - throw new IllegalArgumentException(String.format("Unknown resource type symbol '%s'", symbol)); - } - return type; - } - - public Character getSymbol() { - return symbol; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java b/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java deleted file mode 100644 index 5bf6f269..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.EnumMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; - -public class Resources { - - private final Map<ResourceType, Integer> quantities = new EnumMap<>(ResourceType.class); - - public void add(ResourceType type, int quantity) { - quantities.merge(type, quantity, (x, y) -> x + y); - } - - public void addAll(Resources resources) { - resources.getQuantities().forEach(this::add); - } - - public int getQuantity(ResourceType type) { - return quantities.getOrDefault(type, 0); - } - - public Map<ResourceType, Integer> getQuantities() { - return quantities; - } - - public boolean contains(Resources resources) { - return resources.quantities.entrySet().stream().allMatch(this::hasAtLeast); - } - - private boolean hasAtLeast(Entry<ResourceType, Integer> quantity) { - return quantity.getValue() <= getQuantity(quantity.getKey()); - } - - public Resources minus(Resources resources) { - Resources diff = new Resources(); - quantities.forEach((type, count) -> { - int remainder = count - resources.getQuantity(type); - diff.quantities.put(type, Math.max(0, remainder)); - }); - return diff; - } - - public boolean isEmpty() { - return quantities.values().stream().reduce(0, Integer::sum) == 0; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Resources resources = (Resources)o; - return Objects.equals(quantities, resources.quantities); - } - - @Override - public int hashCode() { - return Objects.hash(quantities); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java b/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java deleted file mode 100644 index 19409844..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class TradingRules { - - private final Map<ResourceType, Map<Provider, Integer>> costs = new EnumMap<>(ResourceType.class); - - private final int defaultCost; - - public TradingRules(int defaultCost) { - this.defaultCost = defaultCost; - } - - private int getCost(ResourceType type, Provider provider) { - return costs.computeIfAbsent(type, t -> new EnumMap<>(Provider.class)).getOrDefault(provider, defaultCost); - } - - public void setCost(ResourceType type, Provider provider, int cost) { - costs.computeIfAbsent(type, t -> new EnumMap<>(Provider.class)).put(provider, cost); - } - - public int computeCost(List<BoughtResources> boughtResources) { - return boughtResources.stream().mapToInt(this::computeCost).sum(); - } - - public int computeCost(BoughtResources boughtResources) { - Resources resources = boughtResources.getResources(); - int total = 0; - for (Entry<ResourceType, Integer> entry : resources.getQuantities().entrySet()) { - ResourceType type = entry.getKey(); - int count = entry.getValue(); - total += getCost(type, boughtResources.getProvider()) * count; - } - return total; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java b/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java deleted file mode 100644 index 42acec54..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -import java.util.HashMap; - -import org.luxons.sevenwonders.game.Player; - -public class PlayerScore extends HashMap<ScoreCategory, Integer> { - - private final Player player; - - private final int boardGold; - - private int totalPoints = 0; - - public PlayerScore(Player player, int boardGold) { - this.player = player; - this.boardGold = boardGold; - } - - @Override - public Integer put(ScoreCategory category, Integer points) { - totalPoints += points; - return super.put(category, points); - } - - public int getTotalPoints() { - return totalPoints; - } - - public int getBoardGold() { - return boardGold; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java b/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java deleted file mode 100644 index 26b5f8ba..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -import java.util.Comparator; -import java.util.PriorityQueue; - -public class ScoreBoard { - - private static final Comparator<PlayerScore> comparator = Comparator.comparing(PlayerScore::getTotalPoints) - .thenComparing(PlayerScore::getBoardGold); - - private PriorityQueue<PlayerScore> scores; - - public ScoreBoard() { - scores = new PriorityQueue<>(comparator); - } - - public void add(PlayerScore score) { - scores.add(score); - } - - public PriorityQueue<PlayerScore> getScores() { - return scores; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java b/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java deleted file mode 100644 index 54976072..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -public enum ScoreCategory { - CIVIL, SCIENCE, MILITARY, TRADE, GUILD, WONDER, GOLD -} diff --git a/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java b/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java deleted file mode 100644 index 3ddddd30..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.luxons.sevenwonders.game.wonders; - -import java.util.Arrays; -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.resources.BoughtResources; -import org.luxons.sevenwonders.game.resources.ResourceType; - -public class Wonder { - - private String name; - - private ResourceType initialResource; - - private List<WonderStage> stages; - - private String image; - - public Wonder() { - } - - public Wonder(String name, ResourceType initialResource, WonderStage... stages) { - this.name = name; - this.initialResource = initialResource; - this.stages = Arrays.asList(stages); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ResourceType getInitialResource() { - return initialResource; - } - - public void setInitialResource(ResourceType initialResource) { - this.initialResource = initialResource; - } - - public List<WonderStage> getStages() { - return stages; - } - - public void setStages(List<WonderStage> stages) { - this.stages = stages; - } - - public int getNbBuiltStages() { - return (int)stages.stream().filter(WonderStage::isBuilt).count(); - } - - public String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - - public boolean isNextStageBuildable(Table table, int playerIndex, List<BoughtResources> boughtResources) { - int nextLevel = getNbBuiltStages(); - if (nextLevel == stages.size()) { - return false; - } - return getNextStage().isBuildable(table, playerIndex, boughtResources); - } - - public void buildLevel(CardBack cardBack) { - getNextStage().build(cardBack); - } - - private WonderStage getNextStage() { - int nextLevel = getNbBuiltStages(); - if (nextLevel == stages.size()) { - throw new IllegalStateException("This wonder has already reached its maximum level"); - } - return stages.get(nextLevel); - } - - public void activateLastBuiltStage(Table table, int playerIndex, List<BoughtResources> boughtResources) { - getLastBuiltStage().activate(table, playerIndex, boughtResources); - } - - private WonderStage getLastBuiltStage() { - int lastLevel = getNbBuiltStages() - 1; - return stages.get(lastLevel); - } - - public int computePoints(Table table, int playerIndex) { - return stages.stream() - .filter(WonderStage::isBuilt) - .flatMap(c -> c.getEffects().stream()) - .mapToInt(e -> e.computePoints(table, playerIndex)) - .sum(); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java b/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java deleted file mode 100644 index 64d506fc..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.luxons.sevenwonders.game.wonders; - -import java.util.List; - -import org.luxons.sevenwonders.game.resources.BoughtResources; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.cards.Requirements; -import org.luxons.sevenwonders.game.effects.Effect; - -public class WonderStage { - - private Requirements requirements; - - private List<Effect> effects; - - private CardBack cardBack; - - public Requirements getRequirements() { - return requirements; - } - - public void setRequirements(Requirements requirements) { - this.requirements = requirements; - } - - public List<Effect> getEffects() { - return effects; - } - - public void setEffects(List<Effect> effects) { - this.effects = effects; - } - - public boolean isBuilt() { - return cardBack != null; - } - - public boolean isBuildable(Table table, int playerIndex, List<BoughtResources> boughtResources) { - return requirements.isAffordedBy(table, playerIndex, boughtResources); - } - - void build(CardBack cardBack) { - this.cardBack = cardBack; - } - - void activate(Table table, int playerIndex, List<BoughtResources> boughtResources) { - effects.forEach(e -> e.apply(table, playerIndex)); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/repositories/GameRepository.java b/src/main/java/org/luxons/sevenwonders/repositories/GameRepository.java deleted file mode 100644 index efe39b85..00000000 --- a/src/main/java/org/luxons/sevenwonders/repositories/GameRepository.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.luxons.sevenwonders.repositories; - -import java.util.HashMap; -import java.util.Map; - -import org.luxons.sevenwonders.errors.ApiMisuseException; -import org.luxons.sevenwonders.game.Game; -import org.springframework.stereotype.Repository; - -@Repository -public class GameRepository { - - private Map<Long, Game> games = new HashMap<>(); - - public void add(Game game) throws GameAlreadyExistsException { - if (games.containsKey(game.getId())) { - throw new GameAlreadyExistsException(game.getId()); - } - games.put(game.getId(), game); - } - - public Game find(long gameId) throws GameNotFoundException { - Game game = games.get(gameId); - if (game == null) { - throw new GameNotFoundException(gameId); - } - return game; - } - - public Game remove(long gameId) throws GameNotFoundException { - Game game = games.remove(gameId); - if (game == null) { - throw new GameNotFoundException(gameId); - } - return game; - } - - public static class GameNotFoundException extends ApiMisuseException { - GameNotFoundException(long id) { - super("Game " + id + " doesn't exist"); - } - } - - static class GameAlreadyExistsException extends ApiMisuseException { - GameAlreadyExistsException(long id) { - super("Game " + id + " already exists"); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java b/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java deleted file mode 100644 index 8f305791..00000000 --- a/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.luxons.sevenwonders.repositories; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.luxons.sevenwonders.game.Lobby; -import org.luxons.sevenwonders.game.Player; -import org.luxons.sevenwonders.game.data.GameDefinitionLoader; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; - -@Repository -public class LobbyRepository { - - private final GameDefinitionLoader gameDefinitionLoader; - - private Map<Long, Lobby> lobbies = new HashMap<>(); - - private long lastGameId = 0; - - @Autowired - public LobbyRepository(GameDefinitionLoader gameDefinitionLoader) { - this.gameDefinitionLoader = gameDefinitionLoader; - } - - public Collection<Lobby> list() { - return lobbies.values(); - } - - public Lobby create(String gameName, Player owner) { - long id = lastGameId++; - Lobby lobby = new Lobby(id, gameName, owner, gameDefinitionLoader.getGameDefinition()); - lobbies.put(id, lobby); - return lobby; - } - - public Lobby find(long lobbyId) throws LobbyNotFoundException { - Lobby lobby = lobbies.get(lobbyId); - if (lobby == null) { - throw new LobbyNotFoundException(lobbyId); - } - return lobby; - } - - public Lobby remove(long lobbyId) throws LobbyNotFoundException { - Lobby lobby = lobbies.remove(lobbyId); - if (lobby == null) { - throw new LobbyNotFoundException(lobbyId); - } - return lobby; - } - - public static class LobbyNotFoundException extends RuntimeException { - LobbyNotFoundException(long id) { - super("Lobby not found for id '" + id + "'"); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/repositories/PlayerRepository.java b/src/main/java/org/luxons/sevenwonders/repositories/PlayerRepository.java deleted file mode 100644 index 049c5ef9..00000000 --- a/src/main/java/org/luxons/sevenwonders/repositories/PlayerRepository.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.luxons.sevenwonders.repositories; - -import java.util.HashMap; -import java.util.Map; - -import org.luxons.sevenwonders.errors.ApiMisuseException; -import org.luxons.sevenwonders.game.Player; -import org.springframework.stereotype.Repository; - -@Repository -public class PlayerRepository { - - private Map<String, Player> players = new HashMap<>(); - - public boolean contains(String username) { - return players.containsKey(username); - } - - public Player createOrUpdate(String username, String displayName) { - if (players.containsKey(username)) { - return update(username, displayName); - } else { - return create(username, displayName); - } - } - - private Player create(String username, String displayName) { - Player player = new Player(username, displayName); - players.put(username, player); - return player; - } - - private Player update(String username, String displayName) throws PlayerNotFoundException { - Player player = find(username); - player.setDisplayName(displayName); - return player; - } - - public Player find(String username) throws PlayerNotFoundException { - Player player = players.get(username); - if (player == null) { - throw new PlayerNotFoundException(username); - } - return player; - } - - public Player remove(String username) { - Player player = players.remove(username); - if (player == null) { - throw new PlayerNotFoundException(username); - } - return player; - } - - static class PlayerNotFoundException extends ApiMisuseException { - PlayerNotFoundException(String username) { - super("Player '" + username + "' doesn't exist"); - } - } -} diff --git a/src/main/java/org/luxons/sevenwonders/validation/DestinationAccessValidator.java b/src/main/java/org/luxons/sevenwonders/validation/DestinationAccessValidator.java deleted file mode 100644 index 65b3623c..00000000 --- a/src/main/java/org/luxons/sevenwonders/validation/DestinationAccessValidator.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.luxons.sevenwonders.validation; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.luxons.sevenwonders.game.Game; -import org.luxons.sevenwonders.game.Lobby; -import org.luxons.sevenwonders.repositories.GameRepository; -import org.luxons.sevenwonders.repositories.LobbyRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class DestinationAccessValidator { - - private static final Pattern lobbyDestination = Pattern.compile(".*?/lobby/(?<id>\\d+?)(/.*)?"); - - private static final Pattern gameDestination = Pattern.compile(".*?/game/(?<id>\\d+?)(/.*)?"); - - private final LobbyRepository lobbyRepository; - - private final GameRepository gameRepository; - - @Autowired - public DestinationAccessValidator(LobbyRepository lobbyRepository, GameRepository gameRepository) { - this.lobbyRepository = lobbyRepository; - this.gameRepository = gameRepository; - } - - public boolean hasAccess(String username, String destination) { - if (username == null) { - // unnamed user cannot belong to anything - return false; - } - if (hasForbiddenGameReference(username, destination)) { - return false; - } - if (hasForbiddenLobbyReference(username, destination)) { - return false; - } - return true; - } - - private boolean hasForbiddenGameReference(String username, String destination) { - Matcher gameMatcher = gameDestination.matcher(destination); - if (!gameMatcher.matches()) { - return false; // no game reference is always OK - } - int gameId = extractId(gameMatcher); - return !isUserInGame(username, gameId); - } - - private boolean hasForbiddenLobbyReference(String username, String destination) { - Matcher lobbyMatcher = lobbyDestination.matcher(destination); - if (!lobbyMatcher.matches()) { - return false; // no lobby reference is always OK - } - int lobbyId = extractId(lobbyMatcher); - return !isUserInLobby(username, lobbyId); - } - - private boolean isUserInGame(String username, int gameId) { - Game game = gameRepository.find(gameId); - return game.containsUser(username); - } - - private boolean isUserInLobby(String username, int lobbyId) { - Lobby lobby = lobbyRepository.find(lobbyId); - return lobby.containsUser(username); - } - - private static int extractId(Matcher matcher) { - String id = matcher.group("id"); - return Integer.parseInt(id); - } -} |