From 3d7ca5473e086873b8c6f96cb60e62b3b75bb299 Mon Sep 17 00:00:00 2001 From: V0S7ER Date: Sun, 22 Oct 2023 13:52:27 +0300 Subject: [PATCH 1/4] Project 1 done --- src/main/java/edu/project1/ConsoleHangman.java | 2 ++ src/main/java/edu/project1/Dictionary.java | 2 ++ src/main/java/edu/project1/GuessResult.java | 2 ++ .../java/edu/project1/RandomDictionary.java | 17 +++++++++++++++++ src/main/java/edu/project1/Session.java | 2 ++ .../java/edu/project1/SingleWordDictionary.java | 2 ++ 6 files changed, 27 insertions(+) create mode 100644 src/main/java/edu/project1/ConsoleHangman.java create mode 100644 src/main/java/edu/project1/Dictionary.java create mode 100644 src/main/java/edu/project1/GuessResult.java create mode 100644 src/main/java/edu/project1/RandomDictionary.java create mode 100644 src/main/java/edu/project1/Session.java create mode 100644 src/main/java/edu/project1/SingleWordDictionary.java diff --git a/src/main/java/edu/project1/ConsoleHangman.java b/src/main/java/edu/project1/ConsoleHangman.java new file mode 100644 index 0000000..06285b4 --- /dev/null +++ b/src/main/java/edu/project1/ConsoleHangman.java @@ -0,0 +1,2 @@ +package edu.project1;public class ConsoleHangman { +} diff --git a/src/main/java/edu/project1/Dictionary.java b/src/main/java/edu/project1/Dictionary.java new file mode 100644 index 0000000..a38b0f9 --- /dev/null +++ b/src/main/java/edu/project1/Dictionary.java @@ -0,0 +1,2 @@ +package edu.project1;public interface Dictionary { +} diff --git a/src/main/java/edu/project1/GuessResult.java b/src/main/java/edu/project1/GuessResult.java new file mode 100644 index 0000000..c3e726a --- /dev/null +++ b/src/main/java/edu/project1/GuessResult.java @@ -0,0 +1,2 @@ +package edu.project1;public interface GuessResult { +} diff --git a/src/main/java/edu/project1/RandomDictionary.java b/src/main/java/edu/project1/RandomDictionary.java new file mode 100644 index 0000000..b077a27 --- /dev/null +++ b/src/main/java/edu/project1/RandomDictionary.java @@ -0,0 +1,17 @@ +package edu.project1; + +import org.jetbrains.annotations.NotNull; + +public class DefaultDictionary implements Dictionary { + private static final String[] words = {"hello", "easy", "project"}; + private static int counter = 0; + + @Override + public @NotNull String getWord() { + if (counter == words.length) { + counter = 0; + } + + return words[counter++]; + } +} diff --git a/src/main/java/edu/project1/Session.java b/src/main/java/edu/project1/Session.java new file mode 100644 index 0000000..e0b1bf5 --- /dev/null +++ b/src/main/java/edu/project1/Session.java @@ -0,0 +1,2 @@ +package edu.project1;public class Session { +} diff --git a/src/main/java/edu/project1/SingleWordDictionary.java b/src/main/java/edu/project1/SingleWordDictionary.java new file mode 100644 index 0000000..d9fadf4 --- /dev/null +++ b/src/main/java/edu/project1/SingleWordDictionary.java @@ -0,0 +1,2 @@ +package edu.project1;public class SingleWordDictionary { +} From 94050f89cb43e9b13e21df9c4f6c32c46614fa78 Mon Sep 17 00:00:00 2001 From: V0S7ER Date: Sun, 22 Oct 2023 13:53:11 +0300 Subject: [PATCH 2/4] Project1 done --- .../java/edu/project1/ConsoleHangman.java | 40 ++++++++++- src/main/java/edu/project1/Dictionary.java | 7 +- src/main/java/edu/project1/GuessResult.java | 54 ++++++++++++++- src/main/java/edu/project1/Main.java | 18 +---- .../java/edu/project1/RandomDictionary.java | 13 ++-- src/main/java/edu/project1/Session.java | 66 ++++++++++++++++++- .../edu/project1/SingleWordDictionary.java | 17 ++++- 7 files changed, 186 insertions(+), 29 deletions(-) diff --git a/src/main/java/edu/project1/ConsoleHangman.java b/src/main/java/edu/project1/ConsoleHangman.java index 06285b4..2933e90 100644 --- a/src/main/java/edu/project1/ConsoleHangman.java +++ b/src/main/java/edu/project1/ConsoleHangman.java @@ -1,2 +1,40 @@ -package edu.project1;public class ConsoleHangman { +package edu.project1; + +import java.io.PrintWriter; +import java.util.Scanner; + +public class ConsoleHangman { + private static final String EXIT_COMMAND = "exit"; + private static final String GUESS_MESSAGE = "Guess a letter:"; + private static final int MAX_ATTEMPTS = 10; + + private final PrintWriter out = new PrintWriter(System.out); + private final Scanner scanner = new Scanner(System.in); + private final Dictionary dictionary = new RandomDictionary(); + + public void run() { + Session session = new Session(dictionary.getWord(), MAX_ATTEMPTS); + + GuessResult lastResult = null; + while (!(lastResult instanceof GuessResult.Win) && (!(lastResult instanceof GuessResult.Defeat))) { + out.println(GUESS_MESSAGE); + out.flush(); + + lastResult = tryGuess(session, scanner.nextLine()); + printState(lastResult); + } + } + + private GuessResult tryGuess(Session session, String input) { + if (EXIT_COMMAND.equals(input)) { + return session.giveUp(); + } + + return session.guess(input); + } + + private void printState(GuessResult result) { + out.println(result.getMessage()); + out.flush(); + } } diff --git a/src/main/java/edu/project1/Dictionary.java b/src/main/java/edu/project1/Dictionary.java index a38b0f9..5a14019 100644 --- a/src/main/java/edu/project1/Dictionary.java +++ b/src/main/java/edu/project1/Dictionary.java @@ -1,2 +1,7 @@ -package edu.project1;public interface Dictionary { +package edu.project1; + +import org.jetbrains.annotations.NotNull; + +public interface Dictionary { + @NotNull String getWord(); } diff --git a/src/main/java/edu/project1/GuessResult.java b/src/main/java/edu/project1/GuessResult.java index c3e726a..eccb1e0 100644 --- a/src/main/java/edu/project1/GuessResult.java +++ b/src/main/java/edu/project1/GuessResult.java @@ -1,2 +1,54 @@ -package edu.project1;public interface GuessResult { +package edu.project1; + +import org.jetbrains.annotations.NotNull; + +public sealed interface GuessResult { + char[] state(); + + int attempt(); + + int maxAttempts(); + + @NotNull String getMessage(); + + record Defeat(char[] state, int attempt, int maxAttempts) implements GuessResult { + @Override public @NotNull String getMessage() { + return String.format( + "The word: %s\nYou lost! (attempts %d out of %d)\n", + new String(state), + attempt, + maxAttempts + ); + } + } + + record Win(char[] state, int attempt, int maxAttempts) implements GuessResult { + @Override public @NotNull String getMessage() { + return String.format( + "You won! (attempts %d out of %d).\nThe word was: %s", + attempt, + maxAttempts, + new String(state) + ); + } + } + + record SuccessGuess(char[] state, int attempt, int maxAttempts) implements GuessResult { + + @Override public @NotNull String getMessage() { + return String.format("Hit!\nThe word: %s", new String(state)); + } + } + + record FailedGuess(char[] state, int attempt, int maxAttempts) implements GuessResult { + @Override public @NotNull String getMessage() { + return String.format("Missed, mistake %d out of %d\nThe word: %s", attempt, maxAttempts, new String(state)); + } + } + + record IncorrectGuess(char[] state, int attempt, int maxAttempts) implements GuessResult { + @Override public @NotNull String getMessage() { + return "Incorrect input. Try again!"; + } + } } diff --git a/src/main/java/edu/project1/Main.java b/src/main/java/edu/project1/Main.java index cbd494f..0336af3 100644 --- a/src/main/java/edu/project1/Main.java +++ b/src/main/java/edu/project1/Main.java @@ -1,27 +1,13 @@ package edu.project1; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - // Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`, // then press Enter. You can now see whitespace characters in your code. public final class Main { - private final static Logger LOGGER = LogManager.getLogger(); - private Main() { } public static void main(String[] args) { - // Press Alt+Enter with your caret at the highlighted text to see how - // IntelliJ IDEA suggests fixing it. - LOGGER.info("Hello and welcome!"); - - // Press Shift+F10 or click the green arrow button in the gutter to run the code. - for (int i = 0; i <= 2; i++) { - - // Press Shift+F9 to start debugging your code. We have set one breakpoint - // for you, but you can always add more by pressing Ctrl+F8. - LOGGER.info("i = {}", i); - } + ConsoleHangman consoleHangman = new ConsoleHangman(); + consoleHangman.run(); } } diff --git a/src/main/java/edu/project1/RandomDictionary.java b/src/main/java/edu/project1/RandomDictionary.java index b077a27..89a2981 100644 --- a/src/main/java/edu/project1/RandomDictionary.java +++ b/src/main/java/edu/project1/RandomDictionary.java @@ -1,17 +1,14 @@ package edu.project1; +import java.util.Random; import org.jetbrains.annotations.NotNull; -public class DefaultDictionary implements Dictionary { - private static final String[] words = {"hello", "easy", "project"}; - private static int counter = 0; +public class RandomDictionary implements Dictionary { + private static final String[] WORDS = {"hello", "easy", "project"}; + private static final Random RANDOM = new Random(); @Override public @NotNull String getWord() { - if (counter == words.length) { - counter = 0; - } - - return words[counter++]; + return WORDS[RANDOM.nextInt(WORDS.length)]; } } diff --git a/src/main/java/edu/project1/Session.java b/src/main/java/edu/project1/Session.java index e0b1bf5..5ae6872 100644 --- a/src/main/java/edu/project1/Session.java +++ b/src/main/java/edu/project1/Session.java @@ -1,2 +1,66 @@ -package edu.project1;public class Session { +package edu.project1; + +import org.jetbrains.annotations.NotNull; + +public class Session { + private final String answer; + private final char[] userAnswer; + private final int maxAttempts; + private int attempts; + private int guessCount; + + public Session(String answer, int maxAttempts) { + this.answer = answer; + this.userAnswer = "*".repeat(answer.length()).toCharArray(); + this.maxAttempts = maxAttempts; + this.attempts = 0; + this.guessCount = 0; + } + + @NotNull GuessResult guess(String guess) { + if (guess.length() != 1) { + return new GuessResult.IncorrectGuess(userAnswer, attempts, maxAttempts); + } + + char guessLetter = guess.charAt(0); + + boolean wasGuess = false; + + for (int i = 0; i < answer.length(); ++i) { + if (userAnswer[i] == '*' && answer.charAt(i) == guessLetter) { + ++guessCount; + userAnswer[i] = guessLetter; + wasGuess = true; + } + } + + if (!wasGuess) { + attempts++; + } + + if (guessCount == answer.length()) { + return new GuessResult.Win(userAnswer, attempts, maxAttempts); + } + + if (attempts == maxAttempts) { + return new GuessResult.Defeat(userAnswer, attempts, maxAttempts); + } + + return terminalGuess(wasGuess); + } + + /** + * function to fix limit on <= 4 returns in one function in mvn::checkstyle + **/ + private @NotNull GuessResult terminalGuess(boolean wasGuess) { + if (wasGuess) { + return new GuessResult.SuccessGuess(userAnswer, attempts, maxAttempts); + } else { + return new GuessResult.FailedGuess(userAnswer, attempts, maxAttempts); + } + } + + @NotNull GuessResult giveUp() { + return new GuessResult.Defeat(userAnswer, attempts, maxAttempts); + } } diff --git a/src/main/java/edu/project1/SingleWordDictionary.java b/src/main/java/edu/project1/SingleWordDictionary.java index d9fadf4..992fbdd 100644 --- a/src/main/java/edu/project1/SingleWordDictionary.java +++ b/src/main/java/edu/project1/SingleWordDictionary.java @@ -1,2 +1,17 @@ -package edu.project1;public class SingleWordDictionary { +package edu.project1; + +import org.jetbrains.annotations.NotNull; + +public class SingleWordDictionary implements Dictionary { + + private final String word; + + public SingleWordDictionary(String word) { + this.word = word; + } + + @Override + public @NotNull String getWord() { + return word; + } } From c56f2d5dc7d129f125be2954fb03b9274b44e27a Mon Sep 17 00:00:00 2001 From: V0S7ER Date: Sun, 22 Oct 2023 13:57:29 +0300 Subject: [PATCH 3/4] Warning fixes --- src/main/java/edu/project1/GuessResult.java | 4 ++++ src/main/java/edu/project1/SingleWordDictionary.java | 9 ++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/project1/GuessResult.java b/src/main/java/edu/project1/GuessResult.java index eccb1e0..6f29b2b 100644 --- a/src/main/java/edu/project1/GuessResult.java +++ b/src/main/java/edu/project1/GuessResult.java @@ -3,12 +3,16 @@ import org.jetbrains.annotations.NotNull; public sealed interface GuessResult { + @SuppressWarnings("unused") char[] state(); + @SuppressWarnings("unused") int attempt(); + @SuppressWarnings("unused") int maxAttempts(); + @SuppressWarnings("unused") @NotNull String getMessage(); record Defeat(char[] state, int attempt, int maxAttempts) implements GuessResult { diff --git a/src/main/java/edu/project1/SingleWordDictionary.java b/src/main/java/edu/project1/SingleWordDictionary.java index 992fbdd..d1f5c4b 100644 --- a/src/main/java/edu/project1/SingleWordDictionary.java +++ b/src/main/java/edu/project1/SingleWordDictionary.java @@ -2,13 +2,8 @@ import org.jetbrains.annotations.NotNull; -public class SingleWordDictionary implements Dictionary { - - private final String word; - - public SingleWordDictionary(String word) { - this.word = word; - } +@SuppressWarnings("unused") +public record SingleWordDictionary(String word) implements Dictionary { @Override public @NotNull String getWord() { From 93c1ef63fe903ad0265d5e933aa3a0133f4f06c8 Mon Sep 17 00:00:00 2001 From: V0S7ER Date: Sun, 22 Oct 2023 14:02:47 +0300 Subject: [PATCH 4/4] Assert that word is not null --- src/main/java/edu/project1/Session.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/project1/Session.java b/src/main/java/edu/project1/Session.java index 5ae6872..216ae54 100644 --- a/src/main/java/edu/project1/Session.java +++ b/src/main/java/edu/project1/Session.java @@ -10,6 +10,7 @@ public class Session { private int guessCount; public Session(String answer, int maxAttempts) { + assert answer != null && !answer.isEmpty(); this.answer = answer; this.userAnswer = "*".repeat(answer.length()).toCharArray(); this.maxAttempts = maxAttempts;