feat: Baker, Blacksmith and winning game
This commit is contained in:
parent
057aaeb858
commit
5dc191c842
@ -1,10 +1,12 @@
|
|||||||
package cz.jzitnik.chronos.controllers;
|
package cz.jzitnik.chronos.controllers;
|
||||||
|
|
||||||
import cz.jzitnik.chronos.entities.Game;
|
import cz.jzitnik.chronos.entities.*;
|
||||||
import cz.jzitnik.chronos.payload.errors.NotFoundError;
|
import cz.jzitnik.chronos.payload.errors.NotFoundError;
|
||||||
|
import cz.jzitnik.chronos.payload.responses.GameWonResponse;
|
||||||
import cz.jzitnik.chronos.payload.responses.TestGameKeyResponse;
|
import cz.jzitnik.chronos.payload.responses.TestGameKeyResponse;
|
||||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||||
import cz.jzitnik.chronos.repository.GameRepository;
|
import cz.jzitnik.chronos.repository.GameRepository;
|
||||||
|
import cz.jzitnik.chronos.repository.ItemRepository;
|
||||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||||
import cz.jzitnik.chronos.services.GameService;
|
import cz.jzitnik.chronos.services.GameService;
|
||||||
import cz.jzitnik.chronos.utils.anotations.CheckUser;
|
import cz.jzitnik.chronos.utils.anotations.CheckUser;
|
||||||
@ -13,6 +15,8 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/game")
|
@RequestMapping("/game")
|
||||||
@ -26,6 +30,9 @@ public class GameController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PlayerRepository playerRepository;
|
private PlayerRepository playerRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ItemRepository itemRepository;
|
||||||
|
|
||||||
@PostMapping("/new")
|
@PostMapping("/new")
|
||||||
public UnifiedResponse<Game, Error> createGame() {
|
public UnifiedResponse<Game, Error> createGame() {
|
||||||
var game = gameService.createGame();
|
var game = gameService.createGame();
|
||||||
@ -90,4 +97,51 @@ public class GameController {
|
|||||||
|
|
||||||
return ResponseEntity.ok(UnifiedResponse.success(game.winnable()));
|
return ResponseEntity.ok(UnifiedResponse.success(game.winnable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/fragments")
|
||||||
|
@CheckUser
|
||||||
|
public ResponseEntity<UnifiedResponse<Object, Error>> putKeyFragments(@RequestParam String playerKey) {
|
||||||
|
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||||
|
var game = player.getGame();
|
||||||
|
|
||||||
|
if (!player.getCurrentRoom().getName().equals("Outside")) {
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(UnifiedResponse.failure(new Error("You are not in the correct room!")));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Item item : player.getInventory()) {
|
||||||
|
if (item.getItemType().equals(ItemType.KEY_FRAGMENT)) {
|
||||||
|
item.setOwner(null);
|
||||||
|
itemRepository.save(item);
|
||||||
|
game.setKeyFragmentsAmount(game.getKeyFragmentsAmount() + 1);
|
||||||
|
|
||||||
|
var message = new Message(player, "", MessageType.KEY_FRAGMENT_HANDED_OVER);
|
||||||
|
|
||||||
|
player.getMessages().add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playerRepository.save(player);
|
||||||
|
|
||||||
|
if (game.getKeyFragmentsAmount() >= 4) {
|
||||||
|
// All key fragments were found
|
||||||
|
game.setWon(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameRepository.save(game);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(UnifiedResponse.success(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/won")
|
||||||
|
@CheckUser
|
||||||
|
public ResponseEntity<UnifiedResponse<GameWonResponse, Error>> gameWon(@RequestParam String playerKey) {
|
||||||
|
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||||
|
var game = player.getGame();
|
||||||
|
|
||||||
|
if (!game.isWon()) {
|
||||||
|
return ResponseEntity.ok(UnifiedResponse.success(new GameWonResponse(false, Optional.empty())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.ok(UnifiedResponse.success(new GameWonResponse(true, Optional.of(game.getWonMessage()))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,15 @@ public class Game {
|
|||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private Player adminPlayer;
|
private Player adminPlayer;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private int keyFragmentsAmount = 0;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private boolean won = false;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private String wonMessage;
|
||||||
|
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
|
|
||||||
public void addPlayer(Player player) {
|
public void addPlayer(Player player) {
|
||||||
@ -71,6 +80,6 @@ public class Game {
|
|||||||
|
|
||||||
var unplayedCharacters = characters.stream().filter(character -> !character.isInteractedWith()).toList().size();
|
var unplayedCharacters = characters.stream().filter(character -> !character.isInteractedWith()).toList().size();
|
||||||
|
|
||||||
return roomItems + unplayedCharacters + ownedFragments >= 5;
|
return (roomItems + unplayedCharacters + ownedFragments) >= (4 - keyFragmentsAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import cz.jzitnik.chronos.payload.errors.ItemNotUsableException;
|
|||||||
public enum ItemType {
|
public enum ItemType {
|
||||||
KEY_FRAGMENT,
|
KEY_FRAGMENT,
|
||||||
LUCK_POTION,
|
LUCK_POTION,
|
||||||
GOLDEN_WATCH;
|
GOLDEN_WATCH,
|
||||||
|
COAL,
|
||||||
|
FLOUR,
|
||||||
|
WATER;
|
||||||
|
|
||||||
public void useItem(Player player) throws ItemNotUsableException {
|
public void useItem(Player player) throws ItemNotUsableException {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
|
@ -6,5 +6,6 @@ public enum MessageType {
|
|||||||
GOT_ITEM,
|
GOT_ITEM,
|
||||||
LOST_ITEM,
|
LOST_ITEM,
|
||||||
ITEM_USED,
|
ITEM_USED,
|
||||||
|
KEY_FRAGMENT_HANDED_OVER,
|
||||||
JOINED,
|
JOINED,
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,7 @@ public enum Interaction {
|
|||||||
Cashier,
|
Cashier,
|
||||||
Librarian,
|
Librarian,
|
||||||
Innkeeper,
|
Innkeeper,
|
||||||
Mayor
|
Mayor,
|
||||||
|
Blacksmith,
|
||||||
|
Baker
|
||||||
}
|
}
|
@ -2,10 +2,7 @@ package cz.jzitnik.chronos.interactions;
|
|||||||
|
|
||||||
import cz.jzitnik.chronos.entities.Player;
|
import cz.jzitnik.chronos.entities.Player;
|
||||||
import cz.jzitnik.chronos.entities.Character;
|
import cz.jzitnik.chronos.entities.Character;
|
||||||
import cz.jzitnik.chronos.interactions.list.Hangman;
|
import cz.jzitnik.chronos.interactions.list.*;
|
||||||
import cz.jzitnik.chronos.interactions.list.Mayor;
|
|
||||||
import cz.jzitnik.chronos.interactions.list.RockPaperScissors;
|
|
||||||
import cz.jzitnik.chronos.interactions.list.TicTacToe;
|
|
||||||
import cz.jzitnik.chronos.interactions.list.wordle.Wordle;
|
import cz.jzitnik.chronos.interactions.list.wordle.Wordle;
|
||||||
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -23,6 +20,10 @@ public class InteractionService {
|
|||||||
private TicTacToe ticTacToe;
|
private TicTacToe ticTacToe;
|
||||||
@Autowired
|
@Autowired
|
||||||
private Mayor mayor;
|
private Mayor mayor;
|
||||||
|
@Autowired
|
||||||
|
private NumberGuessingGame numberGuessingGame;
|
||||||
|
@Autowired
|
||||||
|
private Baker baker;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Function3<T, U, V, W> {
|
public interface Function3<T, U, V, W> {
|
||||||
@ -36,6 +37,8 @@ public class InteractionService {
|
|||||||
case Librarian -> wordle::play;
|
case Librarian -> wordle::play;
|
||||||
case Innkeeper -> ticTacToe::play;
|
case Innkeeper -> ticTacToe::play;
|
||||||
case Mayor -> mayor::play;
|
case Mayor -> mayor::play;
|
||||||
|
case Blacksmith -> numberGuessingGame::play;
|
||||||
|
case Baker -> baker::play;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package cz.jzitnik.chronos.interactions.list;
|
||||||
|
|
||||||
|
import cz.jzitnik.chronos.entities.Character;
|
||||||
|
import cz.jzitnik.chronos.entities.Item;
|
||||||
|
import cz.jzitnik.chronos.entities.ItemType;
|
||||||
|
import cz.jzitnik.chronos.entities.Player;
|
||||||
|
import cz.jzitnik.chronos.interactions.InteractionPlayer;
|
||||||
|
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
||||||
|
import cz.jzitnik.chronos.repository.CharacterRepository;
|
||||||
|
import cz.jzitnik.chronos.repository.ItemRepository;
|
||||||
|
import cz.jzitnik.chronos.services.ItemService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class Baker implements InteractionPlayer {
|
||||||
|
@Autowired
|
||||||
|
private ItemService itemService;
|
||||||
|
@Autowired
|
||||||
|
private CharacterRepository characterRepository;
|
||||||
|
@Autowired
|
||||||
|
private ItemRepository itemRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResponse play(Player player, Character character, String data) {
|
||||||
|
var playerItems = player.getInventory();
|
||||||
|
var flours = playerItems.stream().filter(item -> item.getItemType().equals(ItemType.FLOUR)).toList();
|
||||||
|
var water = playerItems.stream().filter(item -> item.getItemType().equals(ItemType.WATER)).toList();
|
||||||
|
|
||||||
|
if (flours.isEmpty() || water.isEmpty()) {
|
||||||
|
return new InteractionResponse(false, "Nemáš pro mě buď mouku nebo vodu. Dej mi obojí najednou!", new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
var flour = flours.getFirst();
|
||||||
|
flour.setOwner(null);
|
||||||
|
itemRepository.save(flour);
|
||||||
|
playerItems.remove(flour);
|
||||||
|
|
||||||
|
var onewater = water.getFirst();
|
||||||
|
onewater.setOwner(null);
|
||||||
|
itemRepository.save(onewater);
|
||||||
|
playerItems.remove(onewater);
|
||||||
|
|
||||||
|
var item = new Item(ItemType.KEY_FRAGMENT, player);
|
||||||
|
itemService.addItem(player, item);
|
||||||
|
|
||||||
|
character.setInteractedWith(true);
|
||||||
|
characterRepository.save(character);
|
||||||
|
|
||||||
|
var items = new ArrayList<Item>();
|
||||||
|
items.add(item);
|
||||||
|
|
||||||
|
return new InteractionResponse(false, "Díky moc za mouku a vodu. Doplnit dialog!!!", items);
|
||||||
|
}
|
||||||
|
}
|
@ -26,16 +26,16 @@ public class Mayor implements InteractionPlayer {
|
|||||||
@Override
|
@Override
|
||||||
public InteractionResponse play(Player player, Character character, String data) {
|
public InteractionResponse play(Player player, Character character, String data) {
|
||||||
var playerItems = player.getInventory();
|
var playerItems = player.getInventory();
|
||||||
var golderWatches = playerItems.stream().filter(item -> item.getItemType().equals(ItemType.GOLDEN_WATCH)).toList();
|
var goldenWatches = playerItems.stream().filter(item -> item.getItemType().equals(ItemType.GOLDEN_WATCH)).toList();
|
||||||
|
|
||||||
if (golderWatches.isEmpty()) {
|
if (goldenWatches.isEmpty()) {
|
||||||
return new InteractionResponse(false, "Golden watch is not present in your inventory!", new ArrayList<>());
|
return new InteractionResponse(false, "Nemáš zlaté hodinky v inventáři!", new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
var golderWatch = golderWatches.getFirst();
|
var goldenWatch = goldenWatches.getFirst();
|
||||||
golderWatch.setOwner(null);
|
goldenWatch.setOwner(null);
|
||||||
itemRepository.save(golderWatch);
|
itemRepository.save(goldenWatch);
|
||||||
playerItems.remove(golderWatch);
|
playerItems.remove(goldenWatch);
|
||||||
|
|
||||||
var item = new Item(ItemType.KEY_FRAGMENT, player);
|
var item = new Item(ItemType.KEY_FRAGMENT, player);
|
||||||
itemService.addItem(player, item);
|
itemService.addItem(player, item);
|
||||||
|
@ -0,0 +1,210 @@
|
|||||||
|
package cz.jzitnik.chronos.interactions.list;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import cz.jzitnik.chronos.entities.Character;
|
||||||
|
import cz.jzitnik.chronos.entities.Item;
|
||||||
|
import cz.jzitnik.chronos.entities.ItemType;
|
||||||
|
import cz.jzitnik.chronos.entities.Player;
|
||||||
|
import cz.jzitnik.chronos.interactions.InteractionPlayer;
|
||||||
|
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
||||||
|
import cz.jzitnik.chronos.repository.CharacterRepository;
|
||||||
|
import cz.jzitnik.chronos.repository.ItemRepository;
|
||||||
|
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||||
|
import cz.jzitnik.chronos.services.ItemService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NumberGuessingGame implements InteractionPlayer {
|
||||||
|
@Autowired
|
||||||
|
private CharacterRepository characterRepository;
|
||||||
|
@Autowired
|
||||||
|
private ItemService itemService;
|
||||||
|
@Autowired
|
||||||
|
private PlayerRepository playerRepository;
|
||||||
|
@Autowired
|
||||||
|
private ItemRepository itemRepository;
|
||||||
|
|
||||||
|
private static final int RANGE_MIN = 1;
|
||||||
|
private static final int RANGE_MAX = 100;
|
||||||
|
private static final int MAX_ATTEMPTS = 7;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private static class GuessingGameMemory {
|
||||||
|
private int targetNumber;
|
||||||
|
private int attemptsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GuessingGameMemory readMemory(String memory) {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(memory, GuessingGameMemory.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error reading memory from DB.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String writeMemory(GuessingGameMemory memory) {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(memory);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException("Error writing memory to DB.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private static class GuessingGameResponse {
|
||||||
|
public enum Type {
|
||||||
|
GAME_CREATED,
|
||||||
|
GAME_WON,
|
||||||
|
GAME_LOST,
|
||||||
|
GUESS_FEEDBACK
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type type;
|
||||||
|
private String message;
|
||||||
|
private int attemptsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResponse play(Player player, Character character, String data) {
|
||||||
|
if (character.getInteractionData().getPlayer() == null) {
|
||||||
|
// New game initialization
|
||||||
|
try {
|
||||||
|
return initGame(player, character);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ongoing game
|
||||||
|
if (!character.getInteractionData().getPlayer().getId().equals(player.getId())) {
|
||||||
|
return new InteractionResponse(false, "already_playing", new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return processGuess(player, character, data);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InteractionResponse initGame(Player player, Character character) throws JsonProcessingException {
|
||||||
|
var coals = player.getInventory().stream().filter(item -> item.getItemType().equals(ItemType.COAL)).toList();
|
||||||
|
if (coals.isEmpty()) {
|
||||||
|
return new InteractionResponse(false, "Nemáš uhlí pro mě!", new ArrayList<>());
|
||||||
|
}
|
||||||
|
var coal = coals.getFirst();
|
||||||
|
coal.setOwner(null);
|
||||||
|
itemRepository.save(coal);
|
||||||
|
player.getInventory().remove(coal);
|
||||||
|
playerRepository.save(player);
|
||||||
|
|
||||||
|
var interactionData = character.getInteractionData();
|
||||||
|
interactionData.setPlayer(player);
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
int targetNumber = random.nextInt(RANGE_MAX - RANGE_MIN + 1) + RANGE_MIN;
|
||||||
|
|
||||||
|
interactionData.setMemory(writeMemory(
|
||||||
|
new GuessingGameMemory(targetNumber, MAX_ATTEMPTS)
|
||||||
|
));
|
||||||
|
|
||||||
|
characterRepository.save(character);
|
||||||
|
|
||||||
|
var response = new GuessingGameResponse(
|
||||||
|
GuessingGameResponse.Type.GAME_CREATED,
|
||||||
|
String.format("Uhodni číslo mezi %d a %d.", RANGE_MIN, RANGE_MAX),
|
||||||
|
MAX_ATTEMPTS
|
||||||
|
);
|
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
return new InteractionResponse(true, objectMapper.writeValueAsString(response), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private InteractionResponse processGuess(Player player, Character character, String data) throws JsonProcessingException {
|
||||||
|
var memory = readMemory(character.getInteractionData().getMemory());
|
||||||
|
|
||||||
|
int guess;
|
||||||
|
try {
|
||||||
|
guess = Integer.parseInt(data);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return new InteractionResponse(false, "invalid_input", new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guess < RANGE_MIN || guess > RANGE_MAX) {
|
||||||
|
return new InteractionResponse(false, "out_of_range", new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
memory.setAttemptsLeft(memory.getAttemptsLeft() - 1);
|
||||||
|
String feedbackMessage;
|
||||||
|
boolean isGameWon = false;
|
||||||
|
|
||||||
|
if (guess == memory.getTargetNumber()) {
|
||||||
|
feedbackMessage = "Gratuluji! Uhodl jsi číslo. Tady máš fragment klíče.";
|
||||||
|
isGameWon = true;
|
||||||
|
} else if (guess < memory.getTargetNumber()) {
|
||||||
|
feedbackMessage = "Tvoje číslo je moc nízké. Zkus to znovu.";
|
||||||
|
} else {
|
||||||
|
feedbackMessage = "Tvoje číslo je moc vysoké. Zkus to znovu.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGameWon || memory.getAttemptsLeft() <= 0) {
|
||||||
|
character.setInteractedWith(true);
|
||||||
|
characterRepository.save(character);
|
||||||
|
|
||||||
|
if (isGameWon) {
|
||||||
|
var item = new Item(ItemType.KEY_FRAGMENT, player);
|
||||||
|
itemService.addItem(player, item);
|
||||||
|
|
||||||
|
var items = new ArrayList<Item>();
|
||||||
|
items.add(item);
|
||||||
|
|
||||||
|
var response = new GuessingGameResponse(
|
||||||
|
GuessingGameResponse.Type.GAME_WON,
|
||||||
|
feedbackMessage,
|
||||||
|
memory.getAttemptsLeft()
|
||||||
|
);
|
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
return new InteractionResponse(true, objectMapper.writeValueAsString(response), items);
|
||||||
|
} else {
|
||||||
|
var response = new GuessingGameResponse(
|
||||||
|
GuessingGameResponse.Type.GAME_LOST,
|
||||||
|
String.format("Prohrál jsi! Správné číslo bylo %d.", memory.getTargetNumber()),
|
||||||
|
memory.getAttemptsLeft()
|
||||||
|
);
|
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
return new InteractionResponse(false, objectMapper.writeValueAsString(response), new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update memory and save
|
||||||
|
character.getInteractionData().setMemory(writeMemory(memory));
|
||||||
|
characterRepository.save(character);
|
||||||
|
|
||||||
|
var response = new GuessingGameResponse(
|
||||||
|
GuessingGameResponse.Type.GUESS_FEEDBACK,
|
||||||
|
feedbackMessage,
|
||||||
|
memory.getAttemptsLeft()
|
||||||
|
);
|
||||||
|
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
return new InteractionResponse(false, objectMapper.writeValueAsString(response), new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package cz.jzitnik.chronos.payload.responses;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class GameWonResponse {
|
||||||
|
private boolean won;
|
||||||
|
private Optional<String> msg;
|
||||||
|
}
|
@ -137,6 +137,55 @@ public class InitGameService {
|
|||||||
// Zlaté hodinky pro starostu
|
// Zlaté hodinky pro starostu
|
||||||
garden.getItems().add(new Item(ItemType.GOLDEN_WATCH, garden));
|
garden.getItems().add(new Item(ItemType.GOLDEN_WATCH, garden));
|
||||||
|
|
||||||
|
// Kovárna
|
||||||
|
var forge = new Room(
|
||||||
|
"Kovárna",
|
||||||
|
game
|
||||||
|
);
|
||||||
|
var forge_characters = new ArrayList<Character>();
|
||||||
|
var blacksmith = new Character(
|
||||||
|
"Kovář",
|
||||||
|
forge,
|
||||||
|
"Ahoj já jsem kovář. Dones mi uhlí pro moji pec a pak si spolu můžeme zahrát number guessing game"
|
||||||
|
);
|
||||||
|
blacksmith.setInteraction(Interaction.Blacksmith);
|
||||||
|
blacksmith.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
|
||||||
|
"",
|
||||||
|
"Uhlí už mám. Díky moc za uhlí!",
|
||||||
|
mayor
|
||||||
|
));
|
||||||
|
forge_characters.add(blacksmith);
|
||||||
|
forge.setCharacters(forge_characters);
|
||||||
|
|
||||||
|
// Sklad
|
||||||
|
var warehouse = new Room(
|
||||||
|
"Sklad",
|
||||||
|
game
|
||||||
|
);
|
||||||
|
warehouse.getItems().add(new Item(ItemType.COAL, warehouse));
|
||||||
|
warehouse.getItems().add(new Item(ItemType.WATER, warehouse));
|
||||||
|
warehouse.getItems().add(new Item(ItemType.FLOUR, warehouse));
|
||||||
|
|
||||||
|
// Pekárna
|
||||||
|
var bakery = new Room(
|
||||||
|
"Pekárna",
|
||||||
|
game
|
||||||
|
);
|
||||||
|
var bakery_characters = new ArrayList<Character>();
|
||||||
|
var baker = new Character(
|
||||||
|
"Pekař",
|
||||||
|
bakery,
|
||||||
|
"Ahoj já jsem pekař a potřebuji mouku a láhev vody. Prosím dones mi je a dostaneš fragment klíče"
|
||||||
|
);
|
||||||
|
baker.setInteraction(Interaction.Baker);
|
||||||
|
baker.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
|
||||||
|
"",
|
||||||
|
"Mouku a vodu už mám. Díky",
|
||||||
|
baker
|
||||||
|
));
|
||||||
|
bakery_characters.add(baker);
|
||||||
|
bakery.setCharacters(bakery_characters);
|
||||||
|
|
||||||
|
|
||||||
rooms.add(outside);
|
rooms.add(outside);
|
||||||
rooms.add(stodola);
|
rooms.add(stodola);
|
||||||
@ -145,9 +194,14 @@ public class InitGameService {
|
|||||||
rooms.add(inn);
|
rooms.add(inn);
|
||||||
rooms.add(mayor_house);
|
rooms.add(mayor_house);
|
||||||
rooms.add(garden);
|
rooms.add(garden);
|
||||||
|
rooms.add(forge);
|
||||||
|
rooms.add(warehouse);
|
||||||
|
rooms.add(bakery);
|
||||||
|
|
||||||
game.setRooms(rooms);
|
game.setRooms(rooms);
|
||||||
|
|
||||||
|
game.setWonMessage("Gratuluji vyhráli jste!");
|
||||||
|
|
||||||
// Return a room that all players will spawn in
|
// Return a room that all players will spawn in
|
||||||
return outside;
|
return outside;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package cz.jzitnik.api;
|
|||||||
import cz.jzitnik.api.requests.InteractionRequest;
|
import cz.jzitnik.api.requests.InteractionRequest;
|
||||||
import cz.jzitnik.api.requests.MessageRequest;
|
import cz.jzitnik.api.requests.MessageRequest;
|
||||||
import cz.jzitnik.api.requests.PlayerNameRequest;
|
import cz.jzitnik.api.requests.PlayerNameRequest;
|
||||||
|
import cz.jzitnik.api.responses.GameWonResponse;
|
||||||
import cz.jzitnik.api.responses.InteractionResponse;
|
import cz.jzitnik.api.responses.InteractionResponse;
|
||||||
import cz.jzitnik.api.responses.InventoryFullResponse;
|
import cz.jzitnik.api.responses.InventoryFullResponse;
|
||||||
import cz.jzitnik.api.responses.UnifiedResponse;
|
import cz.jzitnik.api.responses.UnifiedResponse;
|
||||||
@ -127,4 +128,14 @@ public interface ApiService {
|
|||||||
@Query("playerKey") String playerKey,
|
@Query("playerKey") String playerKey,
|
||||||
@Query("roomId") Long roomId
|
@Query("roomId") Long roomId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@POST("game/fragments")
|
||||||
|
Call<UnifiedResponse<Object, Error>> putKeyFragments(
|
||||||
|
@Query("playerKey") String playerKey
|
||||||
|
);
|
||||||
|
|
||||||
|
@GET("game/won")
|
||||||
|
Call<UnifiedResponse<GameWonResponse, Error>> gameWon(
|
||||||
|
@Query("playerKey") String playerKey
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package cz.jzitnik.api.responses;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class GameWonResponse {
|
||||||
|
private boolean won;
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
}
|
@ -5,5 +5,7 @@ public enum Interaction {
|
|||||||
Cashier,
|
Cashier,
|
||||||
Librarian,
|
Librarian,
|
||||||
Innkeeper,
|
Innkeeper,
|
||||||
Mayor
|
Mayor,
|
||||||
|
Blacksmith,
|
||||||
|
Baker
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,10 @@ import java.util.Set;
|
|||||||
public enum ItemType {
|
public enum ItemType {
|
||||||
KEY_FRAGMENT,
|
KEY_FRAGMENT,
|
||||||
LUCK_POTION,
|
LUCK_POTION,
|
||||||
GOLDEN_WATCH;
|
GOLDEN_WATCH,
|
||||||
|
COAL,
|
||||||
|
WATER,
|
||||||
|
FLOUR;
|
||||||
|
|
||||||
private static final Set<ItemType> usableItems = new HashSet<>();
|
private static final Set<ItemType> usableItems = new HashSet<>();
|
||||||
|
|
||||||
@ -24,6 +27,9 @@ public enum ItemType {
|
|||||||
case LUCK_POTION -> "Lektvar štěstí";
|
case LUCK_POTION -> "Lektvar štěstí";
|
||||||
case KEY_FRAGMENT -> "Fragment klíče";
|
case KEY_FRAGMENT -> "Fragment klíče";
|
||||||
case GOLDEN_WATCH -> "Zlaté hodinky";
|
case GOLDEN_WATCH -> "Zlaté hodinky";
|
||||||
|
case COAL -> "Uhlí";
|
||||||
|
case WATER -> "Láhev vody";
|
||||||
|
case FLOUR -> "Mouka";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class Message {
|
|||||||
|
|
||||||
yield "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " sice získal " + Cli.Colors.BLUE + item + Cli.Colors.RESET + ", ale měl plný inventář a tím pádem ho " + Cli.Colors.RED + "navždy ztatil" + Cli.Colors.RESET + ".";
|
yield "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " sice získal " + Cli.Colors.BLUE + item + Cli.Colors.RESET + ", ale měl plný inventář a tím pádem ho " + Cli.Colors.RED + "navždy ztatil" + Cli.Colors.RESET + ".";
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
yield "Hráč " + author.getName() + " sice získal item, ale měl plný inventář a tím pádem ho navždy ztratil.";
|
yield "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " sice získal item, ale měl plný inventář a tím pádem ho navždy ztratil.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ITEM_USED -> {
|
case ITEM_USED -> {
|
||||||
@ -85,6 +85,7 @@ public class Message {
|
|||||||
yield "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " využil item unknown.";
|
yield "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " využil item unknown.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case KEY_FRAGMENT_HANDED_OVER -> "Hráč " + Cli.Colors.BLUE + author.getName() + Cli.Colors.RESET + " odevzdal " + Cli.Colors.BLUE + "Fragment klíče" + Cli.Colors.RESET + ".";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,6 @@ public enum MessageType {
|
|||||||
GOT_ITEM,
|
GOT_ITEM,
|
||||||
LOST_ITEM,
|
LOST_ITEM,
|
||||||
ITEM_USED,
|
ITEM_USED,
|
||||||
|
KEY_FRAGMENT_HANDED_OVER,
|
||||||
JOINED,
|
JOINED,
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ public class Chronos {
|
|||||||
if (characters.isEmpty()) {
|
if (characters.isEmpty()) {
|
||||||
Cli.type("V místnosti se nenachází jediná duše...");
|
Cli.type("V místnosti se nenachází jediná duše...");
|
||||||
}
|
}
|
||||||
talk(characters);
|
talk(characters, room.getName().equals("Outside"));
|
||||||
|
|
||||||
var responseRooms = apiService.getAllRooms(localData.getUserSecret()).execute();
|
var responseRooms = apiService.getAllRooms(localData.getUserSecret()).execute();
|
||||||
var rooms = responseRooms.body().getData().get().stream().filter(rm -> !rm.getId().equals(room.getId())).toList();
|
var rooms = responseRooms.body().getData().get().stream().filter(rm -> !rm.getId().equals(room.getId())).toList();
|
||||||
@ -251,12 +251,35 @@ public class Chronos {
|
|||||||
visit(rooms.get(selectedIndex).getId(), true);
|
visit(rooms.get(selectedIndex).getId(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void talk(List<Character> characters) throws IOException {
|
public void talk(List<Character> characters, boolean isOutside) throws IOException {
|
||||||
List<String> commands = new ArrayList<>(characters.stream().map(chachar -> "Promluvit si s " + chachar.getName()).toList());
|
List<String> commands = new ArrayList<>(characters.stream().map(chachar -> "Promluvit si s " + chachar.getName()).toList());
|
||||||
|
if (isOutside) {
|
||||||
|
commands.add(Cli.Colors.GREEN + "Odevzdat fragmenty klíče" + Cli.Colors.RESET);
|
||||||
|
}
|
||||||
commands.add("Přejít do jiné místnosti");
|
commands.add("Přejít do jiné místnosti");
|
||||||
CommandPalette commandPalette = new CommandPalette(commands, apiService, localData.getUserSecret());
|
CommandPalette commandPalette = new CommandPalette(commands, apiService, localData.getUserSecret());
|
||||||
int selectedIndex = commandPalette.displayIndex();
|
int selectedIndex = commandPalette.displayIndex();
|
||||||
|
|
||||||
|
if (isOutside && selectedIndex == commands.size() - 2) {
|
||||||
|
// Odevzdat fragmenty klíče
|
||||||
|
var response = apiService.getMe(localData.getUserSecret()).execute();
|
||||||
|
var me = response.body().getData().get();
|
||||||
|
var keyFragments = me.getInventory().stream().filter(item -> item.getItemType().equals(ItemType.KEY_FRAGMENT)).toList();
|
||||||
|
|
||||||
|
if (keyFragments.isEmpty()) {
|
||||||
|
Cli.error("Nemáte žádné fragmenty klíče v inventáři!");
|
||||||
|
talk(characters, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apiService.putKeyFragments(getLocalData().getUserSecret()).execute();
|
||||||
|
|
||||||
|
Cli.success("Odevzdal jsi " + keyFragments.size() + "x fragment klíče.");
|
||||||
|
|
||||||
|
talk(characters, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedIndex == commands.size() - 1) {
|
if (selectedIndex == commands.size() - 1) {
|
||||||
// Přejít do jiné místnosti
|
// Přejít do jiné místnosti
|
||||||
return;
|
return;
|
||||||
@ -287,6 +310,6 @@ public class Chronos {
|
|||||||
var res = apiService.getCurrentRoom(localData.getUserSecret()).execute();
|
var res = apiService.getCurrentRoom(localData.getUserSecret()).execute();
|
||||||
var room = res.body().getData().get();
|
var room = res.body().getData().get();
|
||||||
|
|
||||||
talk(room.getCharacters());
|
talk(room.getCharacters(), isOutside);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,10 +2,12 @@ package cz.jzitnik.game;
|
|||||||
|
|
||||||
import cz.jzitnik.api.ApiService;
|
import cz.jzitnik.api.ApiService;
|
||||||
import cz.jzitnik.utils.Cli;
|
import cz.jzitnik.utils.Cli;
|
||||||
|
import cz.jzitnik.utils.ConfigPathProvider;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -56,6 +58,22 @@ public class CommandPalette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int displayIndex() throws IOException {
|
public int displayIndex() throws IOException {
|
||||||
|
var res = apiService.gameWon(playerKey).execute();
|
||||||
|
var content = res.body().getData().get();
|
||||||
|
|
||||||
|
if (content.isWon()) {
|
||||||
|
System.out.println("\n\n");
|
||||||
|
Cli.printHeader("Hra byla vyhrána");
|
||||||
|
Cli.typeSkritek(content.getMsg());
|
||||||
|
|
||||||
|
var configPath = ConfigPathProvider.getPath();
|
||||||
|
|
||||||
|
File file = new File(configPath);
|
||||||
|
file.delete();
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
List<Command> allCommands = new ArrayList<>(commands);
|
List<Command> allCommands = new ArrayList<>(commands);
|
||||||
|
|
||||||
// Commands that can be used anywhere
|
// Commands that can be used anywhere
|
||||||
|
@ -12,7 +12,7 @@ public class Interactions {
|
|||||||
var response = apiService.getInteractionData(playerKey, character.getId()).execute();
|
var response = apiService.getInteractionData(playerKey, character.getId()).execute();
|
||||||
var interactionData = response.body().getData().get();
|
var interactionData = response.body().getData().get();
|
||||||
|
|
||||||
if (character.isInteractedWith()) {
|
if (character.isInteractedWith() && !interactionData.getInteractedWithText().isBlank()) {
|
||||||
Cli.type(character, interactionData.getInteractedWithText());
|
Cli.type(character, interactionData.getInteractedWithText());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -42,6 +42,14 @@ public class Interactions {
|
|||||||
Mayor mayor = new Mayor(character, apiService, playerKey);
|
Mayor mayor = new Mayor(character, apiService, playerKey);
|
||||||
mayor.play();
|
mayor.play();
|
||||||
}
|
}
|
||||||
|
case Blacksmith -> {
|
||||||
|
NumberGuessingGame numberGuessingGame = new NumberGuessingGame(character, apiService, playerKey);
|
||||||
|
numberGuessingGame.play();
|
||||||
|
}
|
||||||
|
case Baker -> {
|
||||||
|
Baker baker = new Baker(character, apiService, playerKey);
|
||||||
|
baker.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package cz.jzitnik.game.interactions.list;
|
||||||
|
|
||||||
|
import cz.jzitnik.api.ApiService;
|
||||||
|
import cz.jzitnik.api.requests.InteractionRequest;
|
||||||
|
import cz.jzitnik.api.types.Character;
|
||||||
|
import cz.jzitnik.api.types.ItemType;
|
||||||
|
import cz.jzitnik.utils.Cli;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Baker {
|
||||||
|
private Character character;
|
||||||
|
private ApiService apiService;
|
||||||
|
private String playerKey;
|
||||||
|
|
||||||
|
public void play() throws IOException {
|
||||||
|
var response = apiService.getMe(playerKey).execute();
|
||||||
|
var me = response.body().getData().get();
|
||||||
|
|
||||||
|
var hasWater = me.getInventory().stream().anyMatch(item -> item.getItemType().equals(ItemType.WATER));
|
||||||
|
var hasFlour = me.getInventory().stream().anyMatch(item -> item.getItemType().equals(ItemType.FLOUR));
|
||||||
|
|
||||||
|
if (!hasWater || !hasFlour) {
|
||||||
|
// Player does not have water or flour
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new String[]{"Dát pekařovi vodu a mouku", "Nedat pekařovi vodu a mouku"};
|
||||||
|
var selected = Cli.selectOptionIndex(Arrays.stream(options).toList());
|
||||||
|
|
||||||
|
if (selected == 0) {
|
||||||
|
var res = apiService.interact(playerKey, new InteractionRequest("", character.getId())).execute();
|
||||||
|
var data = res.body().getData().get();
|
||||||
|
|
||||||
|
Cli.type(character, data.getResponseText());
|
||||||
|
Cli.gotItems(data.getItems());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,12 +21,12 @@ public class Mayor {
|
|||||||
var response = apiService.getMe(playerKey).execute();
|
var response = apiService.getMe(playerKey).execute();
|
||||||
var me = response.body().getData().get();
|
var me = response.body().getData().get();
|
||||||
|
|
||||||
if (!me.getInventory().stream().anyMatch(item -> item.getItemType().equals(ItemType.GOLDEN_WATCH))) {
|
if (me.getInventory().stream().noneMatch(item -> item.getItemType().equals(ItemType.GOLDEN_WATCH))) {
|
||||||
// Player does not have golden watch
|
// Player does not have golden watch
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = new String[]{"Dát starostovi zlaté hodinky", "Nedát starostovi zlaté hodinky"};
|
var options = new String[]{"Dát starostovi zlaté hodinky", "Nedat starostovi zlaté hodinky"};
|
||||||
var selected = Cli.selectOptionIndex(Arrays.stream(options).toList());
|
var selected = Cli.selectOptionIndex(Arrays.stream(options).toList());
|
||||||
|
|
||||||
if (selected == 0) {
|
if (selected == 0) {
|
||||||
|
@ -0,0 +1,116 @@
|
|||||||
|
package cz.jzitnik.game.interactions.list;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import cz.jzitnik.api.ApiService;
|
||||||
|
import cz.jzitnik.api.requests.InteractionRequest;
|
||||||
|
import cz.jzitnik.api.responses.InteractionResponse;
|
||||||
|
import cz.jzitnik.api.types.Character;
|
||||||
|
import cz.jzitnik.api.types.ItemType;
|
||||||
|
import cz.jzitnik.utils.Cli;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class NumberGuessingGame {
|
||||||
|
private Character character;
|
||||||
|
private ApiService apiService;
|
||||||
|
private String playerKey;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static class NumberGuessingResponse {
|
||||||
|
public enum Type {
|
||||||
|
GAME_CREATED,
|
||||||
|
GAME_WON,
|
||||||
|
GAME_LOST,
|
||||||
|
GUESS_FEEDBACK
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type type;
|
||||||
|
private String message;
|
||||||
|
private int attemptsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play() throws IOException {
|
||||||
|
var response = apiService.isInteracting(playerKey, character.getId()).execute();
|
||||||
|
var interacting = response.body().getData().get();
|
||||||
|
|
||||||
|
if (!interacting) {
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
// Resume the game where it was left off
|
||||||
|
var body = apiService.interact(playerKey, new InteractionRequest("get_data", character.getId())).execute().body();
|
||||||
|
var data = body.getData().get();
|
||||||
|
gameContinue(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() throws IOException {
|
||||||
|
var response = apiService.getMe(playerKey).execute();
|
||||||
|
var me = response.body().getData().get();
|
||||||
|
|
||||||
|
if (me.getInventory().stream().noneMatch(item -> item.getItemType().equals(ItemType.COAL))) {
|
||||||
|
// Hráč nemá uhlí
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new String[] { "Dát kovářovi uhlí", "Nedat kovářovi uhlí" };
|
||||||
|
var index = Cli.selectOptionIndex(Arrays.asList(options));
|
||||||
|
|
||||||
|
if (index == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var body = apiService.interact(playerKey, new InteractionRequest("", character.getId())).execute().body();
|
||||||
|
var data = body.getData().get();
|
||||||
|
gameContinue(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gameContinue(InteractionResponse data) throws IOException {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
var gameData = objectMapper.readValue(data.getResponseText(), NumberGuessingResponse.class);
|
||||||
|
|
||||||
|
switch (gameData.getType()) {
|
||||||
|
case GAME_WON -> {
|
||||||
|
Cli.type(character, gameData.getMessage());
|
||||||
|
Cli.gotItems(data.getItems());
|
||||||
|
}
|
||||||
|
case GAME_LOST -> Cli.type(character, gameData.getMessage());
|
||||||
|
case GUESS_FEEDBACK, GAME_CREATED -> {
|
||||||
|
Cli.type(character, gameData.getMessage());
|
||||||
|
System.out.println("Počet pokusů: " + gameData.getAttemptsLeft());
|
||||||
|
|
||||||
|
var guess = askForGuess();
|
||||||
|
|
||||||
|
var response = apiService.interact(playerKey, new InteractionRequest(guess, character.getId())).execute();
|
||||||
|
|
||||||
|
var body = response.body().getData().get();
|
||||||
|
|
||||||
|
gameContinue(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String askForGuess() {
|
||||||
|
Console console = System.console();
|
||||||
|
|
||||||
|
String data = console.readLine("Zadejte číslo: ");
|
||||||
|
|
||||||
|
try {
|
||||||
|
int num = Integer.parseInt(data);
|
||||||
|
|
||||||
|
if (num < 1 || num > 100) {
|
||||||
|
Cli.error("Číslo musí být v rozmezí 1-100");
|
||||||
|
return askForGuess();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Cli.error("Neplatný vstup! Zadejte platné číslo.");
|
||||||
|
return askForGuess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -126,24 +126,27 @@ public class Cli {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var itemsMapped = items.stream().map(Item::toString).toList();
|
var itemsMapped = items.stream().map(Item::toString).toList();
|
||||||
Cli.info("Dostal jste: " + String.join(", ", itemsMapped));
|
info("Dostal jste: " + String.join(", ", itemsMapped));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void type(Character character, String text) {
|
public static void type(Character character, String text) {
|
||||||
Cli.type(Cli.Colors.YELLOW + character.getName() + ": " + Cli.Colors.RESET + text);
|
type(Colors.YELLOW + character.getName() + ": " + Colors.RESET + text);
|
||||||
}
|
}
|
||||||
public static void type(String text) {
|
public static void type(String text) {
|
||||||
Cli.typeText(Cli.wrapText(text));
|
typeText(wrapText(text));
|
||||||
|
}
|
||||||
|
public static void typeSkritek(String text) {
|
||||||
|
type(Colors.YELLOW + "Skřítek: " + Colors.RESET + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String text) {
|
public static void info(String text) {
|
||||||
System.out.println(Colors.BLUE + "Info: " + Colors.RESET + Cli.wrapText(text, 6));
|
System.out.println(Colors.BLUE + "Info: " + Colors.RESET + wrapText(text, 6));
|
||||||
}
|
}
|
||||||
public static void success(String text) {
|
public static void success(String text) {
|
||||||
System.out.println(Colors.GREEN + "Úspěch: " + Colors.RESET + Cli.wrapText(text, 8));
|
System.out.println(Colors.GREEN + "Úspěch: " + Colors.RESET + wrapText(text, 8));
|
||||||
}
|
}
|
||||||
public static void error(String text) {
|
public static void error(String text) {
|
||||||
System.out.println(Colors.RED + "Chyba: " + Colors.RESET + Cli.wrapText(text, 7));
|
System.out.println(Colors.RED + "Chyba: " + Colors.RESET + wrapText(text, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user