feat: Wordle interaction

This commit is contained in:
2024-12-30 20:41:48 +01:00
parent 7167b4c34c
commit 171f760d4e
15 changed files with 453 additions and 8 deletions

View File

@ -2,5 +2,6 @@ package cz.jzitnik.api.types;
public enum Interaction {
Farmer,
Cashier
Cashier,
Librarian
}

View File

@ -1,6 +1,5 @@
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;

View File

@ -20,7 +20,6 @@ public class Interactions {
Cli.type(character, interactionData.getStartText());
// "Object _ =" is just for java compiler to ensure that all interactions are covered.
switch (character.getInteraction()) {
case Farmer -> {
var options = new String[]{"Kámen", "Nůžky", "Papír"};
@ -42,6 +41,10 @@ public class Interactions {
Hangman hangman = new Hangman(character, apiService, playerKey);
hangman.play();
}
case Librarian -> {
Wordle wordle = new Wordle(character, apiService, playerKey);
wordle.play();
}
}
}
}

View File

@ -0,0 +1,136 @@
package cz.jzitnik.game.interactions;
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.List;
import java.util.stream.Collectors;
@AllArgsConstructor
public class Wordle {
private Character character;
private ApiService apiService;
private String playerKey;
@Getter
private static class WordleResponse {
public enum Type {
GAME_CREATED,
GAME_WON,
GAME_LOST,
GAME_CONTINUE,
}
private Type type;
private int attemptsRemaining;
private List<GuessFeedback> feedbackHistory;
}
@Getter
private static class GuessFeedback {
private String guess;
private List<CharacterFeedback> feedback;
}
@Getter
private static class CharacterFeedback {
private char character;
private FeedbackType feedbackType;
}
public enum FeedbackType {
NOT_IN_WORD,
WRONG_POSITION,
CORRECT_POSITION
}
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 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 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 wordleData = objectMapper.readValue(data.getResponseText(), WordleResponse.class);
switch (wordleData.getType()) {
case GAME_WON -> {
Cli.type(character, "Vyhrál jsi! Slovo bylo: " + getCurrentWord(wordleData.getFeedbackHistory()));
Cli.gotItems(data.getItems());
}
case GAME_LOST -> Cli.type(character, "Prohrál jsi! Bohužel jste neuhodl slovo. Fragment klíče nedostanete.");
case GAME_CONTINUE, GAME_CREATED -> {
System.out.println("Zbývající pokusy: " + wordleData.getAttemptsRemaining());
displayFeedback(wordleData.getFeedbackHistory());
var guess = askForWord();
var response = apiService.interact(playerKey, new InteractionRequest(guess, character.getId())).execute();
var body = response.body().getData().get();
gameContinue(body);
}
}
}
private String askForWord() {
Console console = System.console();
String word = console.readLine("Zadejte slovo (5 písmen): ");
if (word.length() != 5) {
Cli.error("Neplatný vstup! Slovo musí mít 5 písmen.");
return askForWord();
}
return word.toLowerCase();
}
private void displayFeedback(List<GuessFeedback> feedbackHistory) {
for (var feedback : feedbackHistory) {
System.out.print(feedback.getGuess() + " -> ");
for (var charFeedback : feedback.getFeedback()) {
String color = switch (charFeedback.getFeedbackType()) {
case CORRECT_POSITION -> Cli.Colors.GREEN;
case WRONG_POSITION -> Cli.Colors.YELLOW;
case NOT_IN_WORD -> "";
};
System.out.print(color + charFeedback.getCharacter() + Cli.Colors.RESET);
}
System.out.println();
}
}
private String getCurrentWord(List<GuessFeedback> feedbackHistory) {
for (var feedback : feedbackHistory) {
if (feedback.getFeedback().stream().allMatch(f -> f.getFeedbackType() == FeedbackType.CORRECT_POSITION)) {
return feedback.getGuess();
}
}
return "???";
}
}