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
77 changes: 6 additions & 71 deletions src/main/java/hangman/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,20 @@
*/
package hangman;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import hangman.game.Game;
import hangman.game.console.ConsoleGame;

public class Main {

private final InputStream input;
private final OutputStream output;
private final int max;
private static final String[] WORDS = {
"simplicity", "equality", "grandmother",
"neighborhood", "relationship", "mathematics",
"university", "explanation"
};

public Main(final InputStream in, final OutputStream out, final int m) {
this.input = in;
this.output = out;
this.max = m;
public Main() {
}

public static void main(final String... args) {
new Main(System.in, System.out, 5).exec();
new Main().exec();
}

public void exec() {
String word = WORDS[new Random().nextInt(WORDS.length)];
boolean[] visible = new boolean[word.length()];
int mistakes = 0;
try (final PrintStream out = new PrintStream(this.output)) {
final Iterator<String> scanner = new Scanner(this.input);
boolean done = true;
while (mistakes < this.max) {
done = true;
for (int i = 0; i < word.length(); ++i) {
if (!visible[i]) {
done = false;
}
}
if (done) {
break;
}
out.print("Guess a letter: ");
char chr = scanner.next().charAt(0);
boolean hit = false;
for (int i = 0; i < word.length(); ++i) {
if (word.charAt(i) == chr && !visible[i]) {
visible[i] = true;
hit = true;
}
}
if (hit) {
out.print("Hit!\n");
} else {
out.printf(
"Missed, mistake #%d out of %d\n",
mistakes + 1, this.max
);
++mistakes;
}
out.append("The word: ");
for (int i = 0; i < word.length(); ++i) {
if (visible[i]) {
out.print(word.charAt(i));
} else {
out.print("?");
}
}
out.append("\n\n");
}
if (done) {
out.print("You won!\n");
} else {
out.print("You lost.\n");
}
}
Game game = new ConsoleGame();
game.startGame();
}

}
56 changes: 56 additions & 0 deletions src/main/java/hangman/game/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package hangman.game;

public abstract class Game {

private static final int DEFAULT_MAX_GUESS = 5;

private final GameTask task;

public Game() {
this(DEFAULT_MAX_GUESS);
}

public Game(int maxGuess) {
task = new GameTask(maxGuess);
}

protected abstract char getNextChar();

protected abstract void printCurrentHit(boolean success, int mistakes, int maxGuess);

protected abstract void printNextTask(String taskWord);

protected abstract void finishGame();

public void startGame() {
try {
while (task.gameContinued()) {
if (checkWin()) {
break;
}

processNextStep();
}

finishGame();
} finally {
destroyGame();
}
}

private void processNextStep() {
char nextChar = getNextChar();
boolean hit = task.checkHit(nextChar);

printCurrentHit(hit, task.getMistakes(), task.getMaxGuess());
printNextTask(task.getCurrentResult());
}

protected boolean checkWin() {
return task.checkWin();
}

protected void destroyGame() {
// No operations by default
}
}
75 changes: 75 additions & 0 deletions src/main/java/hangman/game/GameTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package hangman.game;

class GameTask {

private static final char SECRET_CHAR = '?';

private final String secretWord;

boolean[] visibleChars;

private final int maxGuess;

private int mistakes = 0;

public GameTask(int maxGuess) {
this.maxGuess = maxGuess;

SecretWordsGenerator generator = new SecretWordsGenerator();
this.secretWord = generator.getSecretWord();
this.visibleChars = new boolean[secretWord.length()];
}

String getCurrentResult() {
StringBuilder builder = new StringBuilder();

for (int i = 0; i < secretWord.length(); ++i) {
if (visibleChars[i]) {
builder.append(secretWord.charAt(i));
} else {
builder.append(SECRET_CHAR);
}
}

return builder.toString();
}

boolean checkHit(char chr) {
boolean hit = false;

for (int i = 0; i < secretWord.length(); ++i) {
if (secretWord.charAt(i) == chr && !visibleChars[i]) {
visibleChars[i] = true;
hit = true;
}
}

if (!hit) {
mistakes += 1;
}

return hit;
}

boolean checkWin() {
for (int i = 0; i < secretWord.length(); ++i) {
if (!visibleChars[i]) {
return false;
}
}

return true;
}

boolean gameContinued() {
return (mistakes < maxGuess);
}

public int getMaxGuess() {
return maxGuess;
}

public int getMistakes() {
return mistakes;
}
}
30 changes: 30 additions & 0 deletions src/main/java/hangman/game/SecretWordsGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package hangman.game;

import java.util.Random;

class SecretWordsGenerator {

private static final String[] SECRET_WORDS = {
"simplicity",
"equality",
"grandmother",
"neighborhood",
"relationship",
"mathematics",
"university",
"explanation"
};

private final Random random;

public SecretWordsGenerator() {
random = new Random();
}

String getSecretWord() {
int wordDbSize = SECRET_WORDS.length;
String word = SECRET_WORDS[random.nextInt(wordDbSize)];

return word;
}
}
64 changes: 64 additions & 0 deletions src/main/java/hangman/game/console/ConsoleGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package hangman.game.console;

import hangman.game.Game;
import hangman.io.InOut;
import hangman.io.console.ConsoleInOut;

public class ConsoleGame extends Game {

private final InOut inOut;

public ConsoleGame() {
inOut = new ConsoleInOut();
}

public ConsoleGame(int maxGuess) {
super(maxGuess);
inOut = new ConsoleInOut();
}

protected char getNextChar() {
inOut.printMessage("Guess a letter: ");
return inOut.readChar();
}

@Override
protected void printCurrentHit(boolean success, int mistakes, int maxGuess) {
if (success) {
inOut.printMessage("Hit!");
} else {
inOut.printMessage("Missed, mistake #%d out of %d", mistakes, maxGuess);
}

inOut.printNewLine();
}

@Override
protected void printNextTask(String taskWord) {
inOut.printMessage("The word: ");
inOut.printMessage(taskWord);

inOut.printNewLine();
inOut.printNewLine();
}

@Override
protected void finishGame() {
if (checkWin()) {
inOut.printMessage("You won!");
} else {
inOut.printMessage("You lost.");
}

inOut.printNewLine();
}

@Override
protected void destroyGame() {
try {
inOut.close();
} catch (Exception e) {
// NOOP
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/hangman/io/InOut.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package hangman.io;

public interface InOut {

char readChar();

void printMessage(char c);

void printMessage(String message);

void printMessage(String message, Object ... args);

void printNewLine();

void close();
}
51 changes: 51 additions & 0 deletions src/main/java/hangman/io/console/ConsoleInOut.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package hangman.io.console;

import java.io.PrintStream;
import java.util.Scanner;

import hangman.io.InOut;

public class ConsoleInOut implements InOut {

private static final String NEW_LINE = "\n";

private final Scanner input;

private final PrintStream output;

public ConsoleInOut() {
input = new Scanner(System.in);
output = new PrintStream(System.out);
}

@Override
public char readChar() {
return input.next().charAt(0);
}

@Override
public void printMessage(char c) {
output.print(c);
}

@Override
public void printMessage(String message) {
output.print(message);
}

@Override
public void printMessage(String message, Object... args) {
output.printf(message, args);
}

@Override
public void printNewLine() {
output.print(NEW_LINE);
}

@Override
public void close() {
input.close();
output.close();
}
}
Loading