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

public class Condition {

private final String word;
private final int maxMisses;

Condition(String word, int maxMisses) {
this.word = word;
this.maxMisses = maxMisses;
}

String getWord() {
return word;
}

int getMaxMisses() {
return maxMisses;
}

boolean alive(int misses) {
return misses < maxMisses;
}

boolean correctWord(String userWord) {
return word.equals(userWord);
}

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

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Scanner;

public class Game {

private final Condition condition;
private final InputStream in;
private final OutputStream out;
private int misses = 0;
private String word;

public Game(String word, int maxMisses, InputStream in, OutputStream out) {
this.condition = new Condition(word, maxMisses);
this.word = word.replaceAll(".", "?");
this.in = in;
this.out = out;
}

String getWord() {
return word;
}

void setWord(String word) {
this.word = word;
}

String getWinWord() {
return condition.getWord();
}

public void play() {
final PrintStream out = new PrintStream(this.out);
final Iterator<String> scanner = new Scanner(this.in);
while (canContinue()) {
out.print("Guess a letter: ");
char inputLetter = scanner.next().charAt(0);
Round round = new Round(this, inputLetter);
if (round.haveHit()) {
this.word = round.getWordAfterRound();
out.print("Hit!\n");
} else {
this.misses++;
out.printf(
"Missed, mistake #%d out of %d\n",
this.misses, condition.getMaxMisses()
);
}
out.print("The word: " + word + "\n");
}
if (condition.correctWord(word)) {
out.print("You won!\n");
} else {
out.print("You lost.\n");
}
}

private boolean canContinue() {
return (condition.alive(misses) && (!condition.correctWord(word)));
}

}
71 changes: 3 additions & 68 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;

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();
}

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");
}
}
String randomString = WORDS[new Random().nextInt(WORDS.length)];
Game game = new Game(randomString, 5, System.in, System.out);
game.play();
}

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

class Round {

private final Game game;
private final char inputLetter;
private StringBuilder wordAfterRound;

Round(Game game, char inputLetter) {
this.game = game;
this.inputLetter = inputLetter;
}

String getWordAfterRound() {
if (wordAfterRound == null) {
haveHit();
}
return wordAfterRound.toString();
}

boolean haveHit() {
String word = game.getWinWord();
wordAfterRound = new StringBuilder(game.getWord());
boolean hit = false;
for (int index = 0; index < word.length(); index++) {
if ((word.charAt(index) == inputLetter) && ((wordAfterRound.charAt(index) != inputLetter))) {
wordAfterRound.setCharAt(index, inputLetter);
hit = true;
}
}
return hit;
}

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

import org.junit.Test;

public class ConditionTest {

@Test
public void alive() throws Exception {
Condition condition = new Condition("test", 5);
assert(condition.alive(0));
assert(condition.alive(1));
assert(!condition.alive(5));
}

@Test
public void correctWord() throws Exception {
Condition condition = new Condition("test", 5);
assert(condition.correctWord("test"));
assert(!condition.correctWord("bar"));
assert(!condition.correctWord("TEST"));
}

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

import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;

public class GameTest {

@Test
public void play1() throws Exception {
final ByteArrayInputStream input = new ByteArrayInputStream(
"h\ne\nl\no\n".getBytes()
);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
new Game("hello", 1, input, output).play();
assertThat(output.toString(), containsString("You won"));
}

@Test
public void play2() throws Exception {
final ByteArrayInputStream input = new ByteArrayInputStream(
"h\ne\nl\nl\n".getBytes()
);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
new Game("hello", 1, input, output).play();
assertThat(output.toString(), containsString("You lost"));
}

@Test
public void play3() throws Exception {
final ByteArrayInputStream input = new ByteArrayInputStream(
"e\no\na\nb\nl\nh\n".getBytes()
);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
new Game("hello", 3, input, output).play();
assertThat(output.toString(), containsString("Guess a letter: Missed, mistake #1 out of 3"));
assertThat(output.toString(), containsString("Guess a letter: Missed, mistake #2 out of 3"));
assertThat(output.toString(), containsString("You won!"));
}

}
35 changes: 0 additions & 35 deletions src/test/java/hangman/MainTest.java

This file was deleted.

30 changes: 30 additions & 0 deletions src/test/java/hangman/RoundTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package hangman;

import org.junit.Test;

import static org.junit.Assert.*;

public class RoundTest {

@Test
public void getWordAfterRound() throws Exception {
Game game = new Game("test", 5, null, null);
Round round = new Round(game, 't');
assert(round.getWordAfterRound().equals("t??t"));
}

@Test
public void haveHit() throws Exception {
Round round;
Game game = new Game("test", 5, null, null);
round = new Round(game, 't');
assert(round.haveHit());
round = new Round(game, 'e');
assert(round.haveHit());
round = new Round(game, 's');
assert(round.haveHit());
round = new Round(game, 'a');
assert(!round.haveHit());
}

}