feat: Winnable and some minor changes

This commit is contained in:
jzitnik-dev 2024-12-31 15:36:18 +01:00
parent c47df0d609
commit b6596c7303
Signed by: jzitnik
GPG Key ID: C577A802A6AF4EF3
8 changed files with 67 additions and 5 deletions

View File

@ -81,4 +81,13 @@ public class GameController {
return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.WORKING)); return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.WORKING));
} }
@GetMapping("/winnable")
@CheckUser
public ResponseEntity<UnifiedResponse<Boolean, Error>> winnable(@RequestParam String playerKey) {
var player = playerRepository.findByPlayerKey(playerKey).get();
var game = player.getGame();
return ResponseEntity.ok(UnifiedResponse.success(game.winnable()));
}
} }

View File

@ -44,4 +44,33 @@ public class Game {
public void addPlayer(Player player) { public void addPlayer(Player player) {
this.players.add(player); this.players.add(player);
} }
@JsonIgnore
public boolean winnable() {
var ownedFragments = 0;
for (Player player : players) {
for (Item item : player.getInventory()) {
if (item.getItemType() == ItemType.KEY_FRAGMENT) {
ownedFragments++;
}
}
}
var roomItems = 0;
var characters = new ArrayList<Character>();
for (Room room : rooms) {
characters.addAll(room.getCharacters());
for (Item item : room.getItems()) {
if (item.getItemType() == ItemType.KEY_FRAGMENT) {
roomItems++;
}
}
}
var unplayedCharacters = characters.stream().filter(character -> !character.isInteractedWith()).toList().size();
return roomItems + unplayedCharacters + ownedFragments >= 5;
}
} }

View File

@ -152,7 +152,7 @@ public class Hangman implements InteractionPlayer {
var incorrectGuessesSet = interactionMemory.getIncorrectGuessesSet(); var incorrectGuessesSet = interactionMemory.getIncorrectGuessesSet();
StringBuilder currentProgress = new StringBuilder(interactionMemory.getCurrentProgress()); StringBuilder currentProgress = new StringBuilder(interactionMemory.getCurrentProgress());
if (data == null || data.isEmpty()) { if (data.isEmpty()) {
return new InteractionResponse(false, "invalid_input", new ArrayList<>()); return new InteractionResponse(false, "invalid_input", new ArrayList<>());
} }

View File

@ -7,6 +7,7 @@ import cz.jzitnik.chronos.entities.Player;
import cz.jzitnik.chronos.interactions.InteractionPlayer; import cz.jzitnik.chronos.interactions.InteractionPlayer;
import cz.jzitnik.chronos.payload.responses.InteractionResponse; import cz.jzitnik.chronos.payload.responses.InteractionResponse;
import cz.jzitnik.chronos.repository.CharacterRepository; import cz.jzitnik.chronos.repository.CharacterRepository;
import cz.jzitnik.chronos.repository.ItemRepository;
import cz.jzitnik.chronos.services.ItemService; import cz.jzitnik.chronos.services.ItemService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -19,6 +20,8 @@ public class Mayor implements InteractionPlayer {
private ItemService itemService; private ItemService itemService;
@Autowired @Autowired
private CharacterRepository characterRepository; private CharacterRepository characterRepository;
@Autowired
private ItemRepository itemRepository;
@Override @Override
public InteractionResponse play(Player player, Character character, String data) { public InteractionResponse play(Player player, Character character, String data) {
@ -30,10 +33,12 @@ public class Mayor implements InteractionPlayer {
} }
var golderWatch = golderWatches.getFirst(); var golderWatch = golderWatches.getFirst();
golderWatch.setOwner(null);
itemRepository.save(golderWatch);
playerItems.remove(golderWatch); playerItems.remove(golderWatch);
var item = new Item(ItemType.KEY_FRAGMENT, player); var item = new Item(ItemType.KEY_FRAGMENT, player);
itemService.addItem(player, item); // itemRepository.save is ran by this function so we don't need to save the player when we removed the item from his inv itemService.addItem(player, item);
character.setInteractedWith(true); character.setInteractedWith(true);
characterRepository.save(character); characterRepository.save(character);

View File

@ -22,6 +22,11 @@ public interface ApiService {
@POST("game/new") @POST("game/new")
Call<UnifiedResponse<Game, Error>> newGame(); Call<UnifiedResponse<Game, Error>> newGame();
@GET("game/winnable")
Call<UnifiedResponse<Boolean, Error>> winnable(
@Query("playerKey") String playerKey
);
@POST("game/players/new") @POST("game/players/new")
Call<UnifiedResponse<String, Error>> newPlayer( Call<UnifiedResponse<String, Error>> newPlayer(
@Query("gameKey") String gameKey, @Query("gameKey") String gameKey,

View File

@ -237,9 +237,8 @@ public class Chronos {
var characters = room.getCharacters(); var characters = room.getCharacters();
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...");
} else {
talk(characters);
} }
talk(characters);
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();

View File

@ -19,6 +19,7 @@ public class CommandPalette {
USER_PROFILE, USER_PROFILE,
CHAT_OPEN, CHAT_OPEN,
CHAT_SEND, CHAT_SEND,
CHECK_WINNABLE,
EXIT, EXIT,
} }
@ -62,6 +63,7 @@ public class CommandPalette {
allCommands.add(new Command("Otevřít profil uživatele", CommandType.USER_PROFILE)); allCommands.add(new Command("Otevřít profil uživatele", CommandType.USER_PROFILE));
allCommands.add(new Command("Otevřít chat", CommandType.CHAT_OPEN)); allCommands.add(new Command("Otevřít chat", CommandType.CHAT_OPEN));
allCommands.add(new Command("Odeslat zprávu do chatu", CommandType.CHAT_SEND)); allCommands.add(new Command("Odeslat zprávu do chatu", CommandType.CHAT_SEND));
allCommands.add(new Command("Zkontrolovat vyhratelnost hry", CommandType.CHECK_WINNABLE));
allCommands.add(new Command("Odejít ze hry", CommandType.EXIT)); allCommands.add(new Command("Odejít ze hry", CommandType.EXIT));
var responseInvFull = apiService.inventoryIsFull(playerKey).execute(); var responseInvFull = apiService.inventoryIsFull(playerKey).execute();
@ -115,6 +117,19 @@ public class CommandPalette {
var chat = new Chat(apiService, playerKey); var chat = new Chat(apiService, playerKey);
chat.sendMessage(); chat.sendMessage();
yield displayIndex();
}
case CHECK_WINNABLE -> {
var response = apiService.winnable(playerKey).execute();
var winnable = response.body().getData().get();
System.out.println(Cli.Colors.RED + "Experimentální!!!" + Cli.Colors.RESET + " Toto není 100% jestli je hra vyhratelná.");
if (winnable) {
Cli.info("Hra je dost možná vyhratelná!");
} else {
Cli.info("Hra je dost možná nevyhratelná!");
}
yield displayIndex(); yield displayIndex();
} }
}; };

View File

@ -169,7 +169,7 @@ public class Cli {
if (choice >= 1 && choice <= options.size()) { if (choice >= 1 && choice <= options.size()) {
return choice - 1; return choice - 1;
} else { } else {
System.out.println("Neplatní možnost, vyberte číslo mezi 1 a " + options.size()); System.out.println("Neplatná možnost, vyberte číslo mezi 1 a " + options.size());
} }
} else { } else {
System.out.println("Neplatný vstup, vložte číslo."); System.out.println("Neplatný vstup, vložte číslo.");