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
24 changes: 24 additions & 0 deletions src/main/java/hangman/Attempt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package hangman;

public class Attempt {
private final Secret secret;
private final UserInput guess;

public Attempt(UserInput guess, Secret secret) {
this.guess = guess;
this.secret = secret;
}

boolean check() {
char chr = this.guess.letter();
String word = this.secret.word();

for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == chr && this.secret.isClosed(i)) {
this.secret.open(i);
return true;
}
}
return false;
}
}
34 changes: 34 additions & 0 deletions src/main/java/hangman/Hangman.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package hangman;

class Hangman implements Playable {
private final Attempt attempt;
private final Secret secret;
private final int max;

public Hangman(Attempt attempt, Secret secret, int max) {
this.attempt = attempt;
this.secret = secret;
this.max = max;
}

public Boolean play() {
int mistakes = 0;

while (mistakes < this.max) {
if (this.attempt.check()) {
System.out.println("Hit!");
} else {
mistakes++;
System.out.printf("Missed, mistake #%d out of %d\n", mistakes + 1, this.max);
}

this.secret.state();

if (this.secret.done()) {
return true;
}
}

return false;
}
}
28 changes: 28 additions & 0 deletions src/main/java/hangman/InfinityGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package hangman;

public class InfinityGame {
private final Playable game;
private final UserInput userInput;

public InfinityGame(Playable game, UserInput userInput) {
this.game = game;
this.userInput = userInput;
}

public void play() {
while (true) {
if (this.game.play()) {
System.out.println("You won!\n");
} else {
System.out.println("You lost.\n");
}

System.out.println("Do you want to play one more time (y/n):\n");

char chr = this.userInput.letter();
if (chr == 'n') {
break;
}
}
}
}
104 changes: 13 additions & 91 deletions src/main/java/hangman/Main.java
Original file line number Diff line number Diff line change
@@ -1,98 +1,20 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2017 Yegor Bugayenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*/
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;

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 static void main(final String... args) {
new Main(System.in, System.out, 5).exec();
}
UserInput userInput = new UserInput();
Secret secret = new Secret();

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");
}
}
new InfinityGame(
new Hangman(
new Attempt(
userInput,
secret
),
secret,
5
),
userInput
).play();
}

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

interface Playable {
Boolean play();
}
52 changes: 52 additions & 0 deletions src/main/java/hangman/Secret.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package hangman;

import java.util.Random;

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

private final boolean[] visible;
private final String word;

Secret() {
this.word = WORDS[new Random().nextInt(WORDS.length)];
this.visible = new boolean[word.length()];
}

String word() {
return this.word;
}

boolean done() {
for (int i = 0; i < this.word.length(); ++i) {
if (!this.visible[i]) {
return false;
}
}
return true;
}

void state() {
System.out.append("The word: ");
for (int i = 0; i < this.word().length(); i++) {
if (this.visible[i]) {
System.out.print(this.word().charAt(i));
} else {
System.out.print("?");
}
}
System.out.print("\n");
}

boolean isClosed(int i) {
return !this.visible[i];
}

void open(int i) {
this.visible[i] = true;
}
}
21 changes: 21 additions & 0 deletions src/main/java/hangman/UserInput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package hangman;

import java.io.InputStream;
import java.util.Scanner;

public class UserInput {
private final InputStream stream;

public UserInput(InputStream stream) {
this.stream = stream;
}

public UserInput() {
this.stream = System.in;
}

char letter() {
System.out.print("Print a letter: ");
return new Scanner(this.stream).next().charAt(0);
}
}
42 changes: 18 additions & 24 deletions src/test/java/hangman/MainTest.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2017 Yegor Bugayenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*/
package hangman;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;

import java.io.ByteArrayInputStream;

import static org.junit.Assert.assertFalse;

public final class MainTest {

@Test
public void failsAfterManyWrongAttempts() throws Exception {
public void failsAfterManyWrongAttempts() {
final ByteArrayInputStream input = new ByteArrayInputStream(
"a\na\na\na\na\n".getBytes()
"1\n2\n".getBytes()
);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
new Main(input, output, 1).exec();
assertThat(output.toString(), containsString("You lost"));
}

Secret secret = new Secret();
Boolean gameResult = new Hangman(
new Attempt(
new UserInput(input),
secret
),
secret,
1
).play();

assertFalse(gameResult);
}
}