feat: Hangman interaction
This commit is contained in:
		@ -3,6 +3,7 @@ package cz.jzitnik.chronos.controllers;
 | 
				
			|||||||
import cz.jzitnik.chronos.entities.Interaction;
 | 
					import cz.jzitnik.chronos.entities.Interaction;
 | 
				
			||||||
import cz.jzitnik.chronos.entities.Item;
 | 
					import cz.jzitnik.chronos.entities.Item;
 | 
				
			||||||
import cz.jzitnik.chronos.interactions.InteractionService;
 | 
					import cz.jzitnik.chronos.interactions.InteractionService;
 | 
				
			||||||
 | 
					import cz.jzitnik.chronos.payload.errors.NotFoundError;
 | 
				
			||||||
import cz.jzitnik.chronos.payload.requests.InteractionRequest;
 | 
					import cz.jzitnik.chronos.payload.requests.InteractionRequest;
 | 
				
			||||||
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
 | 
					import cz.jzitnik.chronos.payload.responses.InteractionResponse;
 | 
				
			||||||
import cz.jzitnik.chronos.payload.responses.TakeItemsResponse;
 | 
					import cz.jzitnik.chronos.payload.responses.TakeItemsResponse;
 | 
				
			||||||
@ -53,6 +54,27 @@ public class CharacterController {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @GetMapping("/interacting")
 | 
				
			||||||
 | 
					    @CheckUser
 | 
				
			||||||
 | 
					    public ResponseEntity<UnifiedResponse<Boolean, Error>> isInteracting(@RequestParam String playerKey, @RequestParam Long characterId) {
 | 
				
			||||||
 | 
					        var player = playerRepository.findByPlayerKey(playerKey).get();
 | 
				
			||||||
 | 
					        var characterOptional = characterRepository.findById(characterId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (characterOptional.isEmpty()) {
 | 
				
			||||||
 | 
					            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(new NotFoundError("Character was not found!")));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var character = characterOptional.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var playerInteractingWithCharacter = character.getInteractionData().getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (playerInteractingWithCharacter == null || !playerInteractingWithCharacter.getId().equals(player.getId())) {
 | 
				
			||||||
 | 
					            return ResponseEntity.ok(UnifiedResponse.success(false));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ResponseEntity.ok(UnifiedResponse.success(true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostMapping("/interact")
 | 
					    @PostMapping("/interact")
 | 
				
			||||||
    @CheckUser
 | 
					    @CheckUser
 | 
				
			||||||
    public ResponseEntity<UnifiedResponse<InteractionResponse, Error>> interact(@RequestParam String playerKey, @RequestBody InteractionRequest interactionRequest) {
 | 
					    public ResponseEntity<UnifiedResponse<InteractionResponse, Error>> interact(@RequestParam String playerKey, @RequestBody InteractionRequest interactionRequest) {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,16 +25,16 @@ public class Interaction {
 | 
				
			|||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    private Character character;
 | 
					    private Character character;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Interaction(String startText, String interactedWithText, Character character) {
 | 
					 | 
				
			||||||
        this.startText = startText;
 | 
					 | 
				
			||||||
        this.interactedWithText = interactedWithText;
 | 
					 | 
				
			||||||
        this.character = character;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    private String memory;
 | 
					    private String memory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ManyToOne
 | 
					    @ManyToOne
 | 
				
			||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    private Player player;
 | 
					    private Player player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Interaction(String startText, String interactedWithText, Character character) {
 | 
				
			||||||
 | 
					        this.startText = startText;
 | 
				
			||||||
 | 
					        this.interactedWithText = interactedWithText;
 | 
				
			||||||
 | 
					        this.character = character;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,219 @@
 | 
				
			|||||||
package cz.jzitnik.chronos.interactions.list;
 | 
					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.Character;
 | 
				
			||||||
 | 
					import cz.jzitnik.chronos.entities.Item;
 | 
				
			||||||
 | 
					import cz.jzitnik.chronos.entities.ItemType;
 | 
				
			||||||
import cz.jzitnik.chronos.entities.Player;
 | 
					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.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 org.springframework.stereotype.Service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.HashSet;
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
public class Hangman implements InteractionPlayer {
 | 
					public class Hangman implements InteractionPlayer {
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    private CharacterRepository characterRepository;
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    private ItemService itemService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final int ATTEMPTS = 6; // Arbitrary max incorrect guesses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This can be expanded at any time
 | 
				
			||||||
 | 
					    private final String[] words = {
 | 
				
			||||||
 | 
					        "dům", "pes", "les", "hra", "vlk", "kůň", "vůz", "most", "pán", "noc", "den", "čas", "hora",
 | 
				
			||||||
 | 
					        "sýr", "chleba", "pole", "věk", "slon", "osel", "šnek", "pták", "koza", "míč", "lípa", "knedlík",
 | 
				
			||||||
 | 
					        "čaj", "víno", "hráč", "strom", "nebe", "město", "stůl", "kniha", "kráva", "cesta", "divadlo",
 | 
				
			||||||
 | 
					        "okno", "hory", "slunce", "přítel", "rodina", "jahoda", "židle", "mravenec", "mléko", "sukně",
 | 
				
			||||||
 | 
					        "koberec", "tabule", "škola", "letadlo", "jablko", "písmeno", "košile", "ulice", "dopis",
 | 
				
			||||||
 | 
					        "zpráva", "kolega", "kamarád", "postel", "zmrzlina", "autobus", "tramvaj", "pohádka", "vánočka",
 | 
				
			||||||
 | 
					        "učitelka", "kancelář", "čokoláda", "letadlo", "zahrada", "studentka", "knihtisk", "televizor",
 | 
				
			||||||
 | 
					        "polévka", "zázračný", "papírnictví", "šampaňské", "kinematografie", "obloha", "křišťálový"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Memory
 | 
				
			||||||
 | 
					    @AllArgsConstructor
 | 
				
			||||||
 | 
					    @NoArgsConstructor
 | 
				
			||||||
 | 
					    @Getter
 | 
				
			||||||
 | 
					    @Setter
 | 
				
			||||||
 | 
					    private static class HangmanMemory {
 | 
				
			||||||
 | 
					        private String word;
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> correctGuessesSet;
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> incorrectGuessesSet;
 | 
				
			||||||
 | 
					        private String currentProgress;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private static HangmanMemory readMemory(String memory) {
 | 
				
			||||||
 | 
					        ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return objectMapper.readValue(memory, HangmanMemory.class);
 | 
				
			||||||
 | 
					        } catch (Exception e) {
 | 
				
			||||||
 | 
					            System.out.println(e);
 | 
				
			||||||
 | 
					            throw new RuntimeException("Somebody just fucked up db."); // If this happens idk what is wrong with my life
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private static String writeMemory(HangmanMemory memory) {
 | 
				
			||||||
 | 
					        ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return objectMapper.writeValueAsString(memory);
 | 
				
			||||||
 | 
					        } catch (JsonProcessingException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException(e); // Well hopefully this will never happen
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Response
 | 
				
			||||||
 | 
					    @AllArgsConstructor
 | 
				
			||||||
 | 
					    @Getter
 | 
				
			||||||
 | 
					    @Setter
 | 
				
			||||||
 | 
					    private static class HangmanResponse {
 | 
				
			||||||
 | 
					        public enum Type {
 | 
				
			||||||
 | 
					            GAME_CREATED,
 | 
				
			||||||
 | 
					            GAME_WON,
 | 
				
			||||||
 | 
					            GAME_LOST,
 | 
				
			||||||
 | 
					            GAME_CONTINUE,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Type type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> correctGuessesSet;
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> incorrectGuessesSet;
 | 
				
			||||||
 | 
					        private String currentProgress;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public InteractionResponse play(Player player, Character character, String data) {
 | 
					    public InteractionResponse play(Player player, Character character, String data) {
 | 
				
			||||||
        return null;
 | 
					        if (character.getInteractionData().getPlayer() == null) {
 | 
				
			||||||
 | 
					            // New game
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                return initGame(player, character);
 | 
				
			||||||
 | 
					            } catch (JsonProcessingException e) {
 | 
				
			||||||
 | 
					                throw new RuntimeException(e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Game already exists
 | 
				
			||||||
 | 
					        if (!character.getInteractionData().getPlayer().getId().equals(player.getId())) {
 | 
				
			||||||
 | 
					            // Another player tries to interact with character while somebody else is interacting with him
 | 
				
			||||||
 | 
					            return new InteractionResponse(false, "already_playing", new ArrayList<>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return guessChar(player, character, data);
 | 
				
			||||||
 | 
					        } catch (JsonProcessingException e) {
 | 
				
			||||||
 | 
					            throw new RuntimeException(e); // I hate error handling. This code is just shit but whatever
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private InteractionResponse initGame(Player player, Character character) throws JsonProcessingException {
 | 
				
			||||||
 | 
					        var interactionData = character.getInteractionData();
 | 
				
			||||||
 | 
					        interactionData.setPlayer(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Random random = new Random();
 | 
				
			||||||
 | 
					        int index = random.nextInt(words.length);
 | 
				
			||||||
 | 
					        String randomWord = words[index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String initialProgress = randomWord.replaceAll(".", "_");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        interactionData.setMemory(writeMemory(
 | 
				
			||||||
 | 
					                new HangmanMemory(randomWord, new HashSet<>(), new HashSet<>(), initialProgress)
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        characterRepository.save(character);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var response = new HangmanResponse(HangmanResponse.Type.GAME_CREATED, new HashSet<>(), new HashSet<>(), initialProgress);
 | 
				
			||||||
 | 
					        ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new InteractionResponse(true, objectMapper.writeValueAsString(response), new ArrayList<>());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private InteractionResponse guessChar(Player player, Character character, String data) throws JsonProcessingException {
 | 
				
			||||||
 | 
					        var interactionMemory = readMemory(character.getInteractionData().getMemory());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data.equals("get_data")) {
 | 
				
			||||||
 | 
					            var response = new HangmanResponse(HangmanResponse.Type.GAME_CONTINUE, interactionMemory.getCorrectGuessesSet(), interactionMemory.getIncorrectGuessesSet(), interactionMemory.getCurrentProgress());
 | 
				
			||||||
 | 
					            ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					            var responseText = objectMapper.writeValueAsString(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new InteractionResponse(false, responseText, new ArrayList<>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String word = interactionMemory.getWord();
 | 
				
			||||||
 | 
					        var correctGuessesSet = interactionMemory.getCorrectGuessesSet();
 | 
				
			||||||
 | 
					        var incorrectGuessesSet = interactionMemory.getIncorrectGuessesSet();
 | 
				
			||||||
 | 
					        StringBuilder currentProgress = new StringBuilder(interactionMemory.getCurrentProgress());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data == null || data.isEmpty()) {
 | 
				
			||||||
 | 
					            return new InteractionResponse(false, "invalid_input", new ArrayList<>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        char guessedChar = data.charAt(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (correctGuessesSet.contains(guessedChar) || incorrectGuessesSet.contains(guessedChar)) {
 | 
				
			||||||
 | 
					            return new InteractionResponse(false, "already_guessed", new ArrayList<>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        boolean isCorrect = false;
 | 
				
			||||||
 | 
					        for (int i = 0; i < word.length(); i++) {
 | 
				
			||||||
 | 
					            if (word.charAt(i) == guessedChar) {
 | 
				
			||||||
 | 
					                currentProgress.setCharAt(i, guessedChar);
 | 
				
			||||||
 | 
					                isCorrect = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isCorrect) {
 | 
				
			||||||
 | 
					            correctGuessesSet.add(guessedChar);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            incorrectGuessesSet.add(guessedChar);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        interactionMemory.setCorrectGuessesSet(correctGuessesSet);
 | 
				
			||||||
 | 
					        interactionMemory.setIncorrectGuessesSet(incorrectGuessesSet);
 | 
				
			||||||
 | 
					        interactionMemory.setCurrentProgress(currentProgress.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        character.getInteractionData().setMemory(writeMemory(interactionMemory));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        characterRepository.save(character);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Submit response
 | 
				
			||||||
 | 
					        ObjectMapper objectMapper = new ObjectMapper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (currentProgress.toString().equals(word)) {
 | 
				
			||||||
 | 
					            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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var response = new HangmanResponse(HangmanResponse.Type.GAME_WON, correctGuessesSet, incorrectGuessesSet, currentProgress.toString());
 | 
				
			||||||
 | 
					            var responseText = objectMapper.writeValueAsString(response);
 | 
				
			||||||
 | 
					            return new InteractionResponse(true, responseText, items);
 | 
				
			||||||
 | 
					        } else if (incorrectGuessesSet.size() >= ATTEMPTS) {
 | 
				
			||||||
 | 
					            character.setInteractedWith(true);
 | 
				
			||||||
 | 
					            characterRepository.save(character);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var response = new HangmanResponse(HangmanResponse.Type.GAME_LOST, correctGuessesSet, incorrectGuessesSet, currentProgress.toString());
 | 
				
			||||||
 | 
					            var responseText = objectMapper.writeValueAsString(response);
 | 
				
			||||||
 | 
					            return new InteractionResponse(false, responseText, new ArrayList<>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var response = new HangmanResponse(HangmanResponse.Type.GAME_CONTINUE, correctGuessesSet, incorrectGuessesSet, currentProgress.toString());
 | 
				
			||||||
 | 
					        var responseText = objectMapper.writeValueAsString(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new InteractionResponse(false, responseText, new ArrayList<>());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -43,14 +43,35 @@ public class InitGameService {
 | 
				
			|||||||
        farmar.setInteraction(Interaction.Farmer);
 | 
					        farmar.setInteraction(Interaction.Farmer);
 | 
				
			||||||
        farmar.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
 | 
					        farmar.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
 | 
				
			||||||
                "Tak si zahrajeme kámen nůžky papír",
 | 
					                "Tak si zahrajeme kámen nůžky papír",
 | 
				
			||||||
                "Se mnou jsi již hrál kámen nůžky papír. Znovu už ti fragment klíče nedám",
 | 
					                "Se mnou někdo již hrál kámen nůžky papír. Další fragment klíče nemám.",
 | 
				
			||||||
                farmar
 | 
					                farmar
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
        stodola_characters.add(farmar);
 | 
					        stodola_characters.add(farmar);
 | 
				
			||||||
        stodola.setCharacters(stodola_characters);
 | 
					        stodola.setCharacters(stodola_characters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Shop
 | 
				
			||||||
 | 
					        var shop = new Room(
 | 
				
			||||||
 | 
					                "Obchod",
 | 
				
			||||||
 | 
					                game
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        var shop_characters = new ArrayList<Character>();
 | 
				
			||||||
 | 
					        var cashier = new Character(
 | 
				
			||||||
 | 
					                "Prodavač",
 | 
				
			||||||
 | 
					                shop,
 | 
				
			||||||
 | 
					                "Ahoj já jsem prodavač a budeš se mnou hrát šibenici."
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        cashier.setInteraction(Interaction.Cashier);
 | 
				
			||||||
 | 
					        cashier.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
 | 
				
			||||||
 | 
					                "Tak si zahrajeme šibenici",
 | 
				
			||||||
 | 
					                "Se mnou někdo již hrál šibenici. Další fragment klíče nemám.",
 | 
				
			||||||
 | 
					                cashier
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					        shop_characters.add(cashier);
 | 
				
			||||||
 | 
					        shop.setCharacters(shop_characters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        rooms.add(outside);
 | 
					        rooms.add(outside);
 | 
				
			||||||
        rooms.add(stodola);
 | 
					        rooms.add(stodola);
 | 
				
			||||||
 | 
					        rooms.add(shop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        game.setRooms(rooms);
 | 
					        game.setRooms(rooms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -83,6 +83,12 @@ public interface ApiService {
 | 
				
			|||||||
            @Query("characterId") Long characterId
 | 
					            @Query("characterId") Long characterId
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @GET("game/characters/interacting")
 | 
				
			||||||
 | 
					    Call<UnifiedResponse<Boolean, Error>> isInteracting(
 | 
				
			||||||
 | 
					            @Query("playerKey") String playerKey,
 | 
				
			||||||
 | 
					            @Query("characterId") Long characterId
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @POST("game/characters/interact")
 | 
					    @POST("game/characters/interact")
 | 
				
			||||||
    Call<UnifiedResponse<InteractionResponse, Error>> interact(
 | 
					    Call<UnifiedResponse<InteractionResponse, Error>> interact(
 | 
				
			||||||
            @Query("playerKey") String playerKey,
 | 
					            @Query("playerKey") String playerKey,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
package cz.jzitnik.api.types;
 | 
					package cz.jzitnik.api.types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public enum Interaction {
 | 
					public enum Interaction {
 | 
				
			||||||
    Farmer
 | 
					    Farmer,
 | 
				
			||||||
 | 
					    Cashier
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										104
									
								
								frontend/src/main/java/cz/jzitnik/game/interactions/Hangman.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								frontend/src/main/java/cz/jzitnik/game/interactions/Hangman.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					package cz.jzitnik.game.interactions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.core.JsonProcessingException;
 | 
				
			||||||
 | 
					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.utils.Cli;
 | 
				
			||||||
 | 
					import lombok.AllArgsConstructor;
 | 
				
			||||||
 | 
					import lombok.Getter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.Console;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					import java.util.stream.Stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@AllArgsConstructor
 | 
				
			||||||
 | 
					public class Hangman {
 | 
				
			||||||
 | 
					    private Character character;
 | 
				
			||||||
 | 
					    private ApiService apiService;
 | 
				
			||||||
 | 
					    private String playerKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Getter
 | 
				
			||||||
 | 
					    private static class HangmanResponse {
 | 
				
			||||||
 | 
					        public enum Type {
 | 
				
			||||||
 | 
					            GAME_CREATED,
 | 
				
			||||||
 | 
					            GAME_WON,
 | 
				
			||||||
 | 
					            GAME_LOST,
 | 
				
			||||||
 | 
					            GAME_CONTINUE,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Type type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> correctGuessesSet;
 | 
				
			||||||
 | 
					        private Set<java.lang.Character> incorrectGuessesSet;
 | 
				
			||||||
 | 
					        private String currentProgress;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void play() throws IOException {
 | 
				
			||||||
 | 
					        var response = apiService.isInteracting(playerKey, character.getId()).execute();
 | 
				
			||||||
 | 
					        var interacting = response.body().getData().get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!interacting) {
 | 
				
			||||||
 | 
					            init();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // Get data where we have left of
 | 
				
			||||||
 | 
					            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 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 hangmanData  = objectMapper.readValue(data.getResponseText(), HangmanResponse.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (hangmanData.getType()) {
 | 
				
			||||||
 | 
					            case GAME_WON -> {
 | 
				
			||||||
 | 
					                Cli.type(character, "Vyhrál jsi! Slovo bylo: " + hangmanData.getCurrentProgress());
 | 
				
			||||||
 | 
					                Cli.gotItems(data.getItems());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            case GAME_LOST -> Cli.type(character, "Prohrál jsi! Slovo jsi celé neuhodl. Fragment klíče ti nedám!");
 | 
				
			||||||
 | 
					            case GAME_CONTINUE, GAME_CREATED ->  {
 | 
				
			||||||
 | 
					                System.out.println("Špatně uhodnuté písmena: " + hangmanData.getIncorrectGuessesSet());
 | 
				
			||||||
 | 
					                System.out.println("Slovo: " + hangmanData.getCurrentProgress());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // I hate my life
 | 
				
			||||||
 | 
					                var guessingChar = askForChar(Stream.concat(hangmanData.getCorrectGuessesSet().stream(), hangmanData.getIncorrectGuessesSet().stream()).collect(Collectors.toSet()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var response = apiService.interact(playerKey, new InteractionRequest(guessingChar, character.getId())).execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var body = response.body().getData().get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                gameContinue(body);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private String askForChar(Set<java.lang.Character> guessed) {
 | 
				
			||||||
 | 
					        Console console = System.console();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String data = console.readLine("Zadejte jedno písmeno: ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data.length() != 1) {
 | 
				
			||||||
 | 
					            Cli.error("Neplatný vstup!");
 | 
				
			||||||
 | 
					            return askForChar(guessed);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (guessed.contains(data.charAt(0))) {
 | 
				
			||||||
 | 
					            Cli.error("Toto písmeno jste již se snažil uhodnout!");
 | 
				
			||||||
 | 
					            return askForChar(guessed);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -20,9 +20,10 @@ public class Interactions {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Cli.type(character, interactionData.getStartText());
 | 
					        Cli.type(character, interactionData.getStartText());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // "Object _ =" is just for java compiler to ensure that all interactions are covered.
 | 
				
			||||||
        switch (character.getInteraction()) {
 | 
					        switch (character.getInteraction()) {
 | 
				
			||||||
            case Farmer -> {
 | 
					            case Farmer -> {
 | 
				
			||||||
                var options = new String[] {"Kámen", "Nůžky", "Papír"};
 | 
					                var options = new String[]{"Kámen", "Nůžky", "Papír"};
 | 
				
			||||||
                var selected = Cli.selectOptionIndex(Arrays.stream(options).toList());
 | 
					                var selected = Cli.selectOptionIndex(Arrays.stream(options).toList());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var requestData = new InteractionRequest(String.valueOf(selected), character.getId());
 | 
					                var requestData = new InteractionRequest(String.valueOf(selected), character.getId());
 | 
				
			||||||
@ -35,6 +36,11 @@ public class Interactions {
 | 
				
			|||||||
                if (interactionResponse.isSuccess()) {
 | 
					                if (interactionResponse.isSuccess()) {
 | 
				
			||||||
                    Cli.gotItems(interactionResponse.getItems());
 | 
					                    Cli.gotItems(interactionResponse.getItems());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            case Cashier -> {
 | 
				
			||||||
 | 
					                Hangman hangman = new Hangman(character, apiService, playerKey);
 | 
				
			||||||
 | 
					                hangman.play();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user