Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/main/java/edu/project1/ConsoleHangman.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я бы просто добавил в GuessResult метод isTerminal - делать проверки через instanceof не самое лучшее решение, особенно с точки зрения дальнейшей поддержки. К примеру, мы захотим добавить терминальный статус — досрочное поражение, и главное будет не забыть его добавить в это условие.

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();
}
}
7 changes: 7 additions & 0 deletions src/main/java/edu/project1/Dictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package edu.project1;

import org.jetbrains.annotations.NotNull;

public interface Dictionary {
@NotNull String getWord();
}
58 changes: 58 additions & 0 deletions src/main/java/edu/project1/GuessResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package edu.project1;

import org.jetbrains.annotations.NotNull;

public sealed interface GuessResult {
@SuppressWarnings("unused")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если не используется, то можно удалить

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 {
@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!";
}
}
}
18 changes: 2 additions & 16 deletions src/main/java/edu/project1/Main.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
14 changes: 14 additions & 0 deletions src/main/java/edu/project1/RandomDictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package edu.project1;

import java.util.Random;
import org.jetbrains.annotations.NotNull;

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() {
return WORDS[RANDOM.nextInt(WORDS.length)];
}
}
67 changes: 67 additions & 0 deletions src/main/java/edu/project1/Session.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
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) {
assert answer != null && !answer.isEmpty();
this.answer = answer;
this.userAnswer = "*".repeat(answer.length()).toCharArray();
this.maxAttempts = maxAttempts;
this.attempts = 0;
this.guessCount = 0;
}

@NotNull GuessResult guess(String guess) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аннотация убежала

if (guess.length() != 1) {
return new GuessResult.IncorrectGuess(userAnswer, attempts, maxAttempts);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут же можно проверить, что guess.charAt(0) от a до z

}

char guessLetter = guess.charAt(0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Пустые строки ни к чему

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);
}
}
12 changes: 12 additions & 0 deletions src/main/java/edu/project1/SingleWordDictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package edu.project1;

import org.jetbrains.annotations.NotNull;

@SuppressWarnings("unused")
public record SingleWordDictionary(String word) implements Dictionary {

@Override
public @NotNull String getWord() {
return word;
}
}