diff --git a/pom.xml b/pom.xml
index 945f7dd..80421ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,15 +18,40 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- com.jcabi
- parent
- 0.42
+ oo
+ atom-starter
+ 0.0.11
com.yegor256
hangman
1.0-SNAPSHOT
jar
hangman
+
+
+
+
+ false
+
+ bintray-releases
+ http://dl.bintray.com/skapral/oo-maven
+
+
+
+
+
+ io.vavr
+ vavr
+ 0.9.0
+
+
+ org.assertj
+ assertj-core
+ 3.8.0
+ provided
+
+
+
@@ -37,6 +62,30 @@
1.8
+
+ org.pitest
+ pitest-maven
+ 1.2.0
+
+
+ integration-test
+
+ mutationCoverage
+
+
+ ${skipTests}
+
+ equals
+ hashCode
+ toString
+
+ false
+ false
+ false
+
+
+
+
diff --git a/src/main/java/hangman/Main.java b/src/main/java/hangman/Main.java
index d870fbb..36faf87 100644
--- a/src/main/java/hangman/Main.java
+++ b/src/main/java/hangman/Main.java
@@ -14,85 +14,31 @@
*/
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.GameImplementation;
+import hangman.input.IFromStream;
+import hangman.output.OToStream;
+import hangman.vocabulary.VocStatic;
+import oo.atom.anno.NotAtom;
+@NotAtom
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();
+ 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 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 GameImplementation(
+ new OToStream(System.out),
+ new IFromStream(System.in),
+ new VocStatic(WORDS),
+ 5,
+ System.currentTimeMillis()
+ ).play();
}
-
}
diff --git a/src/main/java/hangman/asserts/AssertScenarioProducesTheOutput.java b/src/main/java/hangman/asserts/AssertScenarioProducesTheOutput.java
new file mode 100644
index 0000000..8429aa0
--- /dev/null
+++ b/src/main/java/hangman/asserts/AssertScenarioProducesTheOutput.java
@@ -0,0 +1,60 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.asserts;
+
+import hangman.input.Input;
+import hangman.output.OToStream;
+import hangman.output.Output;
+import oo.atom.tests.Assertion;
+import org.assertj.core.api.Assertions;
+
+import java.io.ByteArrayOutputStream;
+
+public class AssertScenarioProducesTheOutput implements Assertion {
+ @FunctionalInterface
+ public interface Scenario {
+ void execute(Output output);
+ }
+
+ private final Scenario scenario;
+ private final String expectedOutput;
+
+ public AssertScenarioProducesTheOutput(final Scenario scenario, final String expectedOutput) {
+ this.scenario = scenario;
+ this.expectedOutput = expectedOutput;
+ }
+
+ @Override
+ public final void check() throws Exception {
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ scenario.execute(
+ new OToStream(
+ byteArrayOutputStream
+ )
+ );
+ final String string = byteArrayOutputStream.toString("UTF-8");
+ Assertions.assertThat(string).isEqualTo(expectedOutput);
+ }
+}
diff --git a/src/main/java/hangman/game/AssertGameOutcome.java b/src/main/java/hangman/game/AssertGameOutcome.java
new file mode 100644
index 0000000..aec4ead
--- /dev/null
+++ b/src/main/java/hangman/game/AssertGameOutcome.java
@@ -0,0 +1,54 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.game;
+
+import hangman.input.Input;
+import hangman.output.Output;
+import hangman.output.OutputMock;
+import oo.atom.tests.Assertion;
+
+public class AssertGameOutcome implements Assertion {
+ public interface AssertionSubject {
+ Game game(Input input, Output output);
+ }
+
+ private final AssertionSubject subject;
+ private final Input input;
+ private final String expectedOutput;
+
+ public AssertGameOutcome(final AssertionSubject subject, final Input input, final String expectedOutput) {
+ this.subject = subject;
+ this.input = input;
+ this.expectedOutput = expectedOutput;
+ }
+
+ @Override
+ public final void check() throws Exception {
+ final OutputMock outputMock = new OutputMock(expectedOutput);
+ final Game game = subject.game(input, outputMock);
+ game.play();
+ outputMock.check();
+ }
+}
diff --git a/src/main/java/hangman/game/Game.java b/src/main/java/hangman/game/Game.java
new file mode 100644
index 0000000..0c00542
--- /dev/null
+++ b/src/main/java/hangman/game/Game.java
@@ -0,0 +1,32 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.game;
+
+public interface Game {
+ interface Inference {
+ Game game();
+ }
+ void play();
+}
diff --git a/src/main/java/hangman/game/GameImplementation.java b/src/main/java/hangman/game/GameImplementation.java
new file mode 100644
index 0000000..b7ad59c
--- /dev/null
+++ b/src/main/java/hangman/game/GameImplementation.java
@@ -0,0 +1,138 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.game;
+
+import hangman.gamestatus.GameStatus;
+import hangman.gamestatus.GsImplementation;
+import hangman.guess.GImplementation;
+import hangman.guess.GLimited;
+import hangman.guess.GVerbose;
+import hangman.guess.Guess;
+import hangman.input.IGentle;
+import hangman.input.Input;
+import hangman.memory.BitmaskMemory;
+import hangman.memory.MistakesMemory;
+import hangman.message.*;
+import hangman.mistakes.Mistakes;
+import hangman.mistakes.MstMemoized;
+import hangman.output.Output;
+import hangman.vocabulary.Vocabulary;
+import hangman.word.WPickedRandomlyFromVocabulary;
+import hangman.word.Word;
+import hangman.wordmask.WmMemoized;
+import hangman.wordmask.WordMask;
+
+public class GameImplementation implements Game {
+ private final Guess guesses;
+ private final GameStatus status;
+ private final Message gameStatusMsg;
+
+ private GameImplementation(final Guess guesses, final GameStatus status, final Message gameStatusMsg) {
+ this.guesses = guesses;
+ this.status = status;
+ this.gameStatusMsg = gameStatusMsg;
+ }
+
+ private GameImplementation(Output output, Input input, Word word, Mistakes mistakes, WordMask mask) {
+ this(
+ new GVerbose(
+ new MsgHit(
+ output
+ ),
+ new MsgMissedAttempt(
+ mistakes,
+ output
+ ),
+ new MsgMaskedWord(
+ word,
+ mask,
+ output
+ ),
+ new GLimited(
+ mistakes,
+ new GImplementation(
+ new IGentle(
+ new MsgInputInvitation(
+ output
+ ),
+ input
+ ),
+ word,
+ mask
+ )
+ )
+ ),
+ new GsImplementation(
+ mistakes,
+ mask
+ ),
+ new MsgGameStatus(
+ new GsImplementation(
+ mistakes,
+ mask
+ ),
+ output
+ )
+ );
+ }
+
+ public GameImplementation(Output output, Input input, Word word, int maxMistakes) {
+ this(
+ output,
+ input,
+ word,
+ new MstMemoized(
+ new MistakesMemory(
+ maxMistakes
+ )
+ ),
+ new WmMemoized(
+ new BitmaskMemory(
+ word
+ )
+ )
+ );
+ }
+
+ public GameImplementation(Output output, Input input, Vocabulary vocabulary, int maxMistakes, long seed) {
+ this(
+ output,
+ input,
+ new WPickedRandomlyFromVocabulary(
+ vocabulary,
+ seed
+ ),
+ maxMistakes
+ );
+ }
+
+ @Override
+ public final void play() {
+ while(status.value().equals(GameStatus.Value.IN_PROGRESS)) {
+ guesses.hit();
+ gameStatusMsg.printOut();
+ }
+ }
+}
diff --git a/src/main/java/hangman/gamestatus/AssertGameStatusValue.java b/src/main/java/hangman/gamestatus/AssertGameStatusValue.java
new file mode 100644
index 0000000..0344c36
--- /dev/null
+++ b/src/main/java/hangman/gamestatus/AssertGameStatusValue.java
@@ -0,0 +1,43 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.gamestatus;
+
+import oo.atom.tests.Assertion;
+import org.assertj.core.api.Assertions;
+
+public class AssertGameStatusValue implements Assertion {
+ private final GameStatus status;
+ private final GameStatus.Value expectedValue;
+
+ public AssertGameStatusValue(final GameStatus status, final GameStatus.Value expectedValue) {
+ this.status = status;
+ this.expectedValue = expectedValue;
+ }
+
+ @Override
+ public final void check() throws Exception {
+ Assertions.assertThat(status.value()).isEqualTo(expectedValue);
+ }
+}
diff --git a/src/main/java/hangman/gamestatus/GameStatus.java b/src/main/java/hangman/gamestatus/GameStatus.java
new file mode 100644
index 0000000..9629cc5
--- /dev/null
+++ b/src/main/java/hangman/gamestatus/GameStatus.java
@@ -0,0 +1,35 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.gamestatus;
+
+public interface GameStatus {
+ enum Value {
+ IN_PROGRESS,
+ WORD_GUESSED,
+ MISTAKES_LIMIT_REACHED
+ }
+
+ Value value();
+}
diff --git a/src/main/java/hangman/gamestatus/GsImplementation.java b/src/main/java/hangman/gamestatus/GsImplementation.java
new file mode 100644
index 0000000..592b6b0
--- /dev/null
+++ b/src/main/java/hangman/gamestatus/GsImplementation.java
@@ -0,0 +1,51 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.gamestatus;
+
+import hangman.mistakes.Mistakes;
+import hangman.wordmask.WordMask;
+
+public class GsImplementation implements GameStatus {
+ private final Mistakes mistakes;
+ private final WordMask wordMask;
+
+ public GsImplementation(final Mistakes mistakes, final WordMask wordMask) {
+ this.mistakes = mistakes;
+ this.wordMask = wordMask;
+ }
+
+ @Override
+ public final Value value() {
+ boolean mistakesMax = mistakes.max() <= mistakes.current();
+ boolean wordGuessed = wordMask.mask().filter(t -> !t).size() == 0;
+ if(wordGuessed) {
+ return Value.WORD_GUESSED;
+ } else if(mistakesMax) {
+ return Value.MISTAKES_LIMIT_REACHED;
+ } else {
+ return Value.IN_PROGRESS;
+ }
+ }
+}
diff --git a/src/main/java/hangman/guess/GImplementation.java b/src/main/java/hangman/guess/GImplementation.java
new file mode 100644
index 0000000..f5ab3b7
--- /dev/null
+++ b/src/main/java/hangman/guess/GImplementation.java
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+import com.sun.org.apache.xpath.internal.operations.Bool;
+import hangman.input.Input;
+import hangman.word.Word;
+import hangman.wordmask.WordMask;
+import io.vavr.collection.List;
+
+public class GImplementation implements Guess {
+ private final Input input;
+ private final Word word;
+ private final WordMask wordMask;
+
+ public GImplementation(final Input input, final Word word, final WordMask wordMask) {
+ this.input = input;
+ this.word = word;
+ this.wordMask = wordMask;
+ }
+
+ @Override
+ public final boolean hit() {
+ char chr = input.claimedChar();
+ String word1 = word.string();
+ final List visible = wordMask.mask();
+ boolean hit = false;
+ for (int i = 0; i < word1.length(); ++i) {
+ if (word1.charAt(i) == chr && !visible.get(i)) {
+ wordMask.open(i);
+ hit = true;
+ }
+ }
+ return hit;
+ }
+}
diff --git a/src/main/java/hangman/guess/GLimited.java b/src/main/java/hangman/guess/GLimited.java
new file mode 100644
index 0000000..be4853d
--- /dev/null
+++ b/src/main/java/hangman/guess/GLimited.java
@@ -0,0 +1,50 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+import hangman.mistakes.Mistakes;
+
+public class GLimited implements Guess {
+ private final Mistakes mistakes;
+ private final Guess guesses;
+
+ public GLimited(final Mistakes mistakes, final Guess guesses) {
+ this.mistakes = mistakes;
+ this.guesses = guesses;
+ }
+
+ @Override
+ public final boolean hit() {
+ if(mistakes.current() <= mistakes.max()) {
+ final boolean hit = guesses.hit();
+ if(!hit) {
+ mistakes.countDown();
+ }
+ return hit;
+ } else {
+ throw new IllegalStateException("You are out of guesses");
+ }
+ }
+}
diff --git a/src/main/java/hangman/guess/GLoser.java b/src/main/java/hangman/guess/GLoser.java
new file mode 100644
index 0000000..87c8cb8
--- /dev/null
+++ b/src/main/java/hangman/guess/GLoser.java
@@ -0,0 +1,37 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+/**
+ * A complete loser, who always slips on a straight surface.
+ *
+ * @author Kapralov Sergey
+ */
+public class GLoser implements Guess {
+ @Override
+ public final boolean hit() {
+ return false;
+ }
+}
diff --git a/src/main/java/hangman/guess/GLucky.java b/src/main/java/hangman/guess/GLucky.java
new file mode 100644
index 0000000..d9a4c4a
--- /dev/null
+++ b/src/main/java/hangman/guess/GLucky.java
@@ -0,0 +1,37 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+/**
+ * A guess of a lucky cowboy who always shoots in a bull-eye
+ *
+ * @author Kapralov Sergey
+ */
+public class GLucky implements Guess {
+ @Override
+ public final boolean hit() {
+ return true;
+ }
+}
diff --git a/src/main/java/hangman/guess/GVerbose.java b/src/main/java/hangman/guess/GVerbose.java
new file mode 100644
index 0000000..9cde942
--- /dev/null
+++ b/src/main/java/hangman/guess/GVerbose.java
@@ -0,0 +1,53 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+import hangman.message.Message;
+
+public class GVerbose implements Guess {
+ private final Message successMsg;
+ private final Message failureMessage;
+ private final Message maskedWord;
+ private final Guess guess;
+
+ public GVerbose(final Message successMsg, final Message failureMessage, final Message maskedWord, final Guess guess) {
+ this.successMsg = successMsg;
+ this.failureMessage = failureMessage;
+ this.maskedWord = maskedWord;
+ this.guess = guess;
+ }
+
+ @Override
+ public final boolean hit() {
+ maskedWord.printOut();
+ final boolean hit = guess.hit();
+ if(hit) {
+ successMsg.printOut();
+ } else {
+ failureMessage.printOut();
+ }
+ return hit;
+ }
+}
diff --git a/src/main/java/hangman/guess/Guess.java b/src/main/java/hangman/guess/Guess.java
new file mode 100644
index 0000000..33a05f7
--- /dev/null
+++ b/src/main/java/hangman/guess/Guess.java
@@ -0,0 +1,29 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+public interface Guess {
+ boolean hit();
+}
diff --git a/src/main/java/hangman/input/AssertInput.java b/src/main/java/hangman/input/AssertInput.java
new file mode 100644
index 0000000..024c92f
--- /dev/null
+++ b/src/main/java/hangman/input/AssertInput.java
@@ -0,0 +1,59 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+import io.vavr.collection.List;
+import oo.atom.tests.Assertion;
+import org.assertj.core.api.Assertions;
+
+public class AssertInput implements Assertion {
+ private final Input input;
+ private final List expectedChars;
+
+ public AssertInput(final Input input, final List expectedChars) {
+ this.input = input;
+ this.expectedChars = expectedChars;
+ }
+
+ public AssertInput(final Input input, final Character... expectedChars) {
+ this(
+ input,
+ List.of(expectedChars)
+ );
+ }
+
+ @Override
+ public final void check() throws Exception {
+ expectedChars
+ .zipWithIndex()
+ .forEach(c -> {
+ char cc = input.claimedChar();
+ Assertions
+ .assertThat(cc)
+ .overridingErrorMessage("expecting certain character on position <%s>: <%s> vs <%s>", c._2, cc, c._1)
+ .isEqualTo(c._1);
+ });
+ }
+}
diff --git a/src/main/java/hangman/input/IFromStream.java b/src/main/java/hangman/input/IFromStream.java
new file mode 100644
index 0000000..9faa7b7
--- /dev/null
+++ b/src/main/java/hangman/input/IFromStream.java
@@ -0,0 +1,41 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+import java.io.InputStream;
+import java.util.Scanner;
+
+public class IFromStream implements Input {
+ private final InputStream stream;
+
+ public IFromStream(final InputStream stream) {
+ this.stream = stream;
+ }
+
+ @Override
+ public final char claimedChar() {
+ return new Scanner(stream).next().charAt(0);
+ }
+}
diff --git a/src/main/java/hangman/input/IFromString.java b/src/main/java/hangman/input/IFromString.java
new file mode 100644
index 0000000..c9470a6
--- /dev/null
+++ b/src/main/java/hangman/input/IFromString.java
@@ -0,0 +1,85 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+import oo.atom.anno.NotAtom;
+
+import java.io.ByteArrayInputStream;
+import java.util.Scanner;
+
+@NotAtom
+class CachedScanner {
+ private final String string;
+ private Scanner scanner;
+
+ public CachedScanner(final String string) {
+ this.string = string;
+ }
+
+ public final synchronized Scanner getOrProduceScanner() {
+ if(scanner == null) {
+ scanner = new Scanner(
+ new ByteArrayInputStream(string.getBytes())
+ );
+ }
+ return scanner;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final CachedScanner that = (CachedScanner) o;
+
+ return string != null ? string.equals(that.string) : that.string == null;
+ }
+
+ @Override
+ public int hashCode() {
+ return string != null ? string.hashCode() : 0;
+ }
+}
+
+public class IFromString implements Input {
+ private final CachedScanner scanner;
+
+ IFromString(final CachedScanner scanner) {
+ this.scanner = scanner;
+ }
+
+ public IFromString(final String string) {
+ this(
+ new CachedScanner(
+ string
+ )
+ );
+ }
+
+ @Override
+ public final char claimedChar() {
+ return scanner.getOrProduceScanner().nextLine().charAt(0);
+ }
+}
diff --git a/src/main/java/hangman/input/IGentle.java b/src/main/java/hangman/input/IGentle.java
new file mode 100644
index 0000000..54aea13
--- /dev/null
+++ b/src/main/java/hangman/input/IGentle.java
@@ -0,0 +1,43 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+import hangman.message.Message;
+
+public class IGentle implements Input {
+ private final Message gentleInvitation;
+ private final Input input;
+
+ public IGentle(final Message gentleInvitation, final Input input) {
+ this.gentleInvitation = gentleInvitation;
+ this.input = input;
+ }
+
+ @Override
+ public final char claimedChar() {
+ gentleInvitation.printOut();
+ return input.claimedChar();
+ }
+}
diff --git a/src/main/java/hangman/input/IInferred.java b/src/main/java/hangman/input/IInferred.java
new file mode 100644
index 0000000..51813fb
--- /dev/null
+++ b/src/main/java/hangman/input/IInferred.java
@@ -0,0 +1,38 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+public class IInferred implements Input {
+ private final Inference inference;
+
+ public IInferred(final Inference inference) {
+ this.inference = inference;
+ }
+
+ @Override
+ public final char claimedChar() {
+ return inference.input().claimedChar();
+ }
+}
diff --git a/src/main/java/hangman/input/Input.java b/src/main/java/hangman/input/Input.java
new file mode 100644
index 0000000..2a43c59
--- /dev/null
+++ b/src/main/java/hangman/input/Input.java
@@ -0,0 +1,32 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+public interface Input {
+ interface Inference {
+ Input input();
+ }
+ char claimedChar();
+}
diff --git a/src/main/java/hangman/memory/BitmaskMemory.java b/src/main/java/hangman/memory/BitmaskMemory.java
new file mode 100644
index 0000000..c0bc63f
--- /dev/null
+++ b/src/main/java/hangman/memory/BitmaskMemory.java
@@ -0,0 +1,37 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.memory;
+
+import hangman.word.Word;
+import oo.atom.anno.NotAtom;
+
+@NotAtom
+public class BitmaskMemory {
+ public volatile boolean[] mask;
+
+ public BitmaskMemory(final Word word) {
+ this.mask = new boolean[word.string().length()];
+ }
+}
diff --git a/src/main/java/hangman/memory/MistakesMemory.java b/src/main/java/hangman/memory/MistakesMemory.java
new file mode 100644
index 0000000..00fd473
--- /dev/null
+++ b/src/main/java/hangman/memory/MistakesMemory.java
@@ -0,0 +1,38 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.memory;
+
+import oo.atom.anno.NotAtom;
+
+@NotAtom
+public class MistakesMemory {
+ public volatile int max;
+ public volatile int cur;
+
+ public MistakesMemory(int max) {
+ this.cur = 0;
+ this.max = max;
+ }
+}
diff --git a/src/main/java/hangman/message/Message.java b/src/main/java/hangman/message/Message.java
new file mode 100644
index 0000000..a193a41
--- /dev/null
+++ b/src/main/java/hangman/message/Message.java
@@ -0,0 +1,29 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+public interface Message {
+ void printOut();
+}
diff --git a/src/main/java/hangman/message/MsgExplicit.java b/src/main/java/hangman/message/MsgExplicit.java
new file mode 100644
index 0000000..4775d5d
--- /dev/null
+++ b/src/main/java/hangman/message/MsgExplicit.java
@@ -0,0 +1,42 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.output.Output;
+
+public class MsgExplicit implements Message {
+ private final String text;
+ private final Output output;
+
+ public MsgExplicit(final String text, final Output output) {
+ this.text = text;
+ this.output = output;
+ }
+
+ @Override
+ public final void printOut() {
+ output.printOut(text);
+ }
+}
diff --git a/src/main/java/hangman/message/MsgGameStatus.java b/src/main/java/hangman/message/MsgGameStatus.java
new file mode 100644
index 0000000..f042e93
--- /dev/null
+++ b/src/main/java/hangman/message/MsgGameStatus.java
@@ -0,0 +1,51 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.gamestatus.GameStatus;
+import hangman.output.Output;
+import static hangman.gamestatus.GameStatus.Value.*;
+
+public class MsgGameStatus implements Message {
+ private final GameStatus status;
+ private final Output output;
+
+ public MsgGameStatus(final GameStatus status, final Output output) {
+ this.status = status;
+ this.output = output;
+ }
+
+ @Override
+ public final void printOut() {
+ if(MISTAKES_LIMIT_REACHED.equals(status.value())) {
+ output.printOut("You lost!\n");
+ return;
+ }
+ if(WORD_GUESSED.equals(status.value())) {
+ output.printOut("You win!\n");
+ return;
+ }
+ }
+}
diff --git a/src/main/java/hangman/message/MsgHit.java b/src/main/java/hangman/message/MsgHit.java
new file mode 100644
index 0000000..11d2ed1
--- /dev/null
+++ b/src/main/java/hangman/message/MsgHit.java
@@ -0,0 +1,36 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.output.Output;
+
+public class MsgHit extends MsgExplicit {
+ public MsgHit(final Output output) {
+ super(
+ "Hit!\n",
+ output
+ );
+ }
+}
diff --git a/src/main/java/hangman/message/MsgInputInvitation.java b/src/main/java/hangman/message/MsgInputInvitation.java
new file mode 100644
index 0000000..ca7c91c
--- /dev/null
+++ b/src/main/java/hangman/message/MsgInputInvitation.java
@@ -0,0 +1,40 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.output.Output;
+
+public class MsgInputInvitation implements Message {
+ private final Output output;
+
+ public MsgInputInvitation(final Output output) {
+ this.output = output;
+ }
+
+ @Override
+ public final void printOut() {
+ output.printOut("Guess a letter: ");
+ }
+}
diff --git a/src/main/java/hangman/message/MsgMaskedWord.java b/src/main/java/hangman/message/MsgMaskedWord.java
new file mode 100644
index 0000000..2c83ddb
--- /dev/null
+++ b/src/main/java/hangman/message/MsgMaskedWord.java
@@ -0,0 +1,57 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.output.Output;
+import hangman.word.Word;
+import hangman.wordmask.WordMask;
+import io.vavr.collection.List;
+
+public class MsgMaskedWord implements Message {
+ private final Word word;
+ private final WordMask mask;
+ private final Output output;
+
+ public MsgMaskedWord(final Word word, final WordMask mask, final Output output) {
+ this.word = word;
+ this.mask = mask;
+ this.output = output;
+ }
+
+ @Override
+ public final void printOut() {
+ output.printOut("The word: ");
+ final String wordStr = word.string();
+ final List mask = this.mask.mask();
+ for (int i = 0; i < wordStr.length(); ++i) {
+ if (mask.get(i)) {
+ output.printOut(String.valueOf(wordStr.charAt(i)));
+ } else {
+ output.printOut("?");
+ }
+ }
+ output.printOut("\n\n");
+ }
+}
diff --git a/src/main/java/hangman/message/MsgMissedAttempt.java b/src/main/java/hangman/message/MsgMissedAttempt.java
new file mode 100644
index 0000000..fa2caba
--- /dev/null
+++ b/src/main/java/hangman/message/MsgMissedAttempt.java
@@ -0,0 +1,43 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.message;
+
+import hangman.mistakes.Mistakes;
+import hangman.output.Output;
+
+public class MsgMissedAttempt implements Message {
+ private final Mistakes mistakes;
+ private final Output output;
+
+ public MsgMissedAttempt(final Mistakes mistakes, final Output output) {
+ this.mistakes = mistakes;
+ this.output = output;
+ }
+
+ @Override
+ public final void printOut() {
+ output.printOut("Missed, mistake #" + mistakes.current() + " out of " + mistakes.max() + "\n");
+ }
+}
diff --git a/src/main/java/hangman/mistakes/AssertMistakesCountdown.java b/src/main/java/hangman/mistakes/AssertMistakesCountdown.java
new file mode 100644
index 0000000..82cdfac
--- /dev/null
+++ b/src/main/java/hangman/mistakes/AssertMistakesCountdown.java
@@ -0,0 +1,53 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+import oo.atom.tests.Assertion;
+import org.assertj.core.api.Assertions;
+
+public class AssertMistakesCountdown implements Assertion {
+ private final Mistakes mistakes;
+
+ public AssertMistakesCountdown(final Mistakes mistakes) {
+ this.mistakes = mistakes;
+ }
+
+ @Override
+ public final void check() throws Exception {
+ final int max = mistakes.max();
+ final int countedDown = mistakes.countDown();
+ final int newCurrent = mistakes.current();
+ final int newMax = mistakes.max();
+
+ Assertions
+ .assertThat(countedDown)
+ .withFailMessage("countedDown/new current difference mismatch: <%s> vs <%s>", countedDown, newCurrent)
+ .isEqualTo(newCurrent);
+ Assertions
+ .assertThat(max)
+ .withFailMessage("newMax/max stability mismatch: <%s> vs <%s>", max, newMax)
+ .isEqualTo(newMax);
+ }
+}
diff --git a/src/main/java/hangman/mistakes/Mistakes.java b/src/main/java/hangman/mistakes/Mistakes.java
new file mode 100644
index 0000000..ffdccce
--- /dev/null
+++ b/src/main/java/hangman/mistakes/Mistakes.java
@@ -0,0 +1,31 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+public interface Mistakes {
+ int current();
+ int max();
+ int countDown();
+}
diff --git a/src/main/java/hangman/mistakes/MstInfiniteAttempts.java b/src/main/java/hangman/mistakes/MstInfiniteAttempts.java
new file mode 100644
index 0000000..e518ea8
--- /dev/null
+++ b/src/main/java/hangman/mistakes/MstInfiniteAttempts.java
@@ -0,0 +1,42 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+public class MstInfiniteAttempts implements Mistakes {
+ @Override
+ public final int current() {
+ return 0;
+ }
+
+ @Override
+ public final int max() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public final int countDown() {
+ return 0;
+ }
+}
diff --git a/src/main/java/hangman/mistakes/MstMemoized.java b/src/main/java/hangman/mistakes/MstMemoized.java
new file mode 100644
index 0000000..b6b1e0f
--- /dev/null
+++ b/src/main/java/hangman/mistakes/MstMemoized.java
@@ -0,0 +1,50 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+import hangman.memory.MistakesMemory;
+
+public class MstMemoized implements Mistakes {
+ private final MistakesMemory memory;
+
+ public MstMemoized(final MistakesMemory memory) {
+ this.memory = memory;
+ }
+
+ @Override
+ public final int current() {
+ return memory.cur;
+ }
+
+ @Override
+ public final int max() {
+ return memory.max;
+ }
+
+ @Override
+ public final int countDown() {
+ return ++memory.cur;
+ }
+}
diff --git a/src/main/java/hangman/mistakes/MstOutOfAttempts.java b/src/main/java/hangman/mistakes/MstOutOfAttempts.java
new file mode 100644
index 0000000..8c4d88d
--- /dev/null
+++ b/src/main/java/hangman/mistakes/MstOutOfAttempts.java
@@ -0,0 +1,42 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+public class MstOutOfAttempts implements Mistakes {
+ @Override
+ public final int current() {
+ return 0;
+ }
+
+ @Override
+ public final int max() {
+ return 0;
+ }
+
+ @Override
+ public final int countDown() {
+ return 0;
+ }
+}
diff --git a/src/main/java/hangman/output/OToStream.java b/src/main/java/hangman/output/OToStream.java
new file mode 100644
index 0000000..c0338b0
--- /dev/null
+++ b/src/main/java/hangman/output/OToStream.java
@@ -0,0 +1,49 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.output;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+public class OToStream implements Output {
+ private final PrintStream stream;
+
+ public OToStream(final PrintStream stream) {
+ this.stream = stream;
+ }
+
+ public OToStream(final OutputStream stream) {
+ this(
+ new PrintStream(
+ stream
+ )
+ );
+ }
+
+ @Override
+ public final void printOut(final String msg) {
+ stream.print(msg);
+ }
+}
diff --git a/src/main/java/hangman/output/Output.java b/src/main/java/hangman/output/Output.java
new file mode 100644
index 0000000..c58719e
--- /dev/null
+++ b/src/main/java/hangman/output/Output.java
@@ -0,0 +1,29 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.output;
+
+public interface Output {
+ void printOut(String msg);
+}
diff --git a/src/main/java/hangman/output/OutputMock.java b/src/main/java/hangman/output/OutputMock.java
new file mode 100644
index 0000000..570df6f
--- /dev/null
+++ b/src/main/java/hangman/output/OutputMock.java
@@ -0,0 +1,58 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.output;
+
+import oo.atom.tests.Assertion;
+import org.assertj.core.api.Assertions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+public class OutputMock implements Output, Assertion {
+ private final ByteArrayOutputStream stream;
+ private final String expected;
+
+ private OutputMock(final ByteArrayOutputStream stream, final String expected) {
+ this.stream = stream;
+ this.expected = expected;
+ }
+
+ public OutputMock(final String expected) {
+ this(
+ new ByteArrayOutputStream(),
+ expected
+ );
+ }
+
+ @Override
+ public final void printOut(final String msg) {
+ new PrintStream(stream).print(msg);
+ }
+
+ @Override
+ public final void check() throws Exception {
+ Assertions.assertThat(stream.toString("UTF-8")).isEqualTo(expected);
+ }
+}
diff --git a/src/main/java/hangman/vocabulary/VocStatic.java b/src/main/java/hangman/vocabulary/VocStatic.java
new file mode 100644
index 0000000..f509535
--- /dev/null
+++ b/src/main/java/hangman/vocabulary/VocStatic.java
@@ -0,0 +1,44 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.vocabulary;
+
+import io.vavr.collection.List;
+
+public class VocStatic implements Vocabulary {
+ private final List words;
+
+ public VocStatic(final List words) {
+ this.words = words;
+ }
+
+ public VocStatic(final String... words) {
+ this(List.of(words));
+ }
+
+ @Override
+ public final List contents() {
+ return words;
+ }
+}
diff --git a/src/main/java/hangman/vocabulary/Vocabulary.java b/src/main/java/hangman/vocabulary/Vocabulary.java
new file mode 100644
index 0000000..82654eb
--- /dev/null
+++ b/src/main/java/hangman/vocabulary/Vocabulary.java
@@ -0,0 +1,31 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.vocabulary;
+
+import io.vavr.collection.List;
+
+public interface Vocabulary {
+ List contents();
+}
diff --git a/src/main/java/hangman/word/WExplicit.java b/src/main/java/hangman/word/WExplicit.java
new file mode 100644
index 0000000..4704650
--- /dev/null
+++ b/src/main/java/hangman/word/WExplicit.java
@@ -0,0 +1,38 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.word;
+
+public class WExplicit implements Word {
+ private final String word;
+
+ public WExplicit(final String word) {
+ this.word = word;
+ }
+
+ @Override
+ public final String string() {
+ return word;
+ }
+}
diff --git a/src/main/java/hangman/word/WInferred.java b/src/main/java/hangman/word/WInferred.java
new file mode 100644
index 0000000..8352724
--- /dev/null
+++ b/src/main/java/hangman/word/WInferred.java
@@ -0,0 +1,38 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.word;
+
+public class WInferred implements Word {
+ private final Inference inference;
+
+ public WInferred(final Inference inference) {
+ this.inference = inference;
+ }
+
+ @Override
+ public final String string() {
+ return inference.word().string();
+ }
+}
diff --git a/src/main/java/hangman/word/WPickedRandomlyFromVocabulary.java b/src/main/java/hangman/word/WPickedRandomlyFromVocabulary.java
new file mode 100644
index 0000000..087a7e8
--- /dev/null
+++ b/src/main/java/hangman/word/WPickedRandomlyFromVocabulary.java
@@ -0,0 +1,61 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.word;
+
+import hangman.vocabulary.Vocabulary;
+import io.vavr.collection.List;
+
+import java.util.Random;
+
+class WPickedRandomlyFromVocabularyInference implements Word.Inference {
+ private final Vocabulary vocabulary;
+ private final long seed;
+
+ public WPickedRandomlyFromVocabularyInference(final Vocabulary vocabulary, final long seed) {
+ this.vocabulary = vocabulary;
+ this.seed = seed;
+ }
+
+ @Override
+ public final Word word() {
+ final List contents = vocabulary.contents();
+ Random random = new Random(seed);
+ final int i = random.nextInt(contents.size());
+ return new WExplicit(
+ contents.get(i)
+ );
+ }
+}
+
+public class WPickedRandomlyFromVocabulary extends WInferred implements Word {
+ public WPickedRandomlyFromVocabulary(final Vocabulary vocabulary, final long seed) {
+ super(
+ new WPickedRandomlyFromVocabularyInference(
+ vocabulary,
+ seed
+ )
+ );
+ }
+}
diff --git a/src/main/java/hangman/word/Word.java b/src/main/java/hangman/word/Word.java
new file mode 100644
index 0000000..ff0691f
--- /dev/null
+++ b/src/main/java/hangman/word/Word.java
@@ -0,0 +1,33 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.word;
+
+public interface Word {
+ interface Inference {
+ Word word();
+ }
+
+ String string();
+}
diff --git a/src/main/java/hangman/wordmask/WmMemoized.java b/src/main/java/hangman/wordmask/WmMemoized.java
new file mode 100644
index 0000000..8786731
--- /dev/null
+++ b/src/main/java/hangman/wordmask/WmMemoized.java
@@ -0,0 +1,47 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.wordmask;
+
+import hangman.memory.BitmaskMemory;
+import io.vavr.collection.Array;
+import io.vavr.collection.List;
+
+public class WmMemoized implements WordMask {
+ private final BitmaskMemory memory;
+
+ public WmMemoized(final BitmaskMemory memory) {
+ this.memory = memory;
+ }
+
+ @Override
+ public final List mask() {
+ return Array.ofAll(memory.mask).toList();
+ }
+
+ @Override
+ public final void open(final int position) {
+ memory.mask[position] = true;
+ }
+}
diff --git a/src/main/java/hangman/wordmask/WordMask.java b/src/main/java/hangman/wordmask/WordMask.java
new file mode 100644
index 0000000..036275f
--- /dev/null
+++ b/src/main/java/hangman/wordmask/WordMask.java
@@ -0,0 +1,36 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.wordmask;
+
+import io.vavr.collection.List;
+
+public interface WordMask {
+ interface Inference {
+ WordMask wordMask();
+ }
+
+ List mask();
+ void open(int position);
+}
diff --git a/src/test/java/hangman/MainTest.java b/src/test/java/hangman/MainTest.java
deleted file mode 100644
index d0cc008..0000000
--- a/src/test/java/hangman/MainTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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;
-
-public final class MainTest {
-
- @Test
- public void failsAfterManyWrongAttempts() throws Exception {
- final ByteArrayInputStream input = new ByteArrayInputStream(
- "a\na\na\na\na\n".getBytes()
- );
- final ByteArrayOutputStream output = new ByteArrayOutputStream();
- new Main(input, output, 1).exec();
- assertThat(output.toString(), containsString("You lost"));
- }
-
-}
diff --git a/src/test/java/hangman/asserts/AssertScenarioProducesTheOutputTest.java b/src/test/java/hangman/asserts/AssertScenarioProducesTheOutputTest.java
new file mode 100644
index 0000000..a799666
--- /dev/null
+++ b/src/test/java/hangman/asserts/AssertScenarioProducesTheOutputTest.java
@@ -0,0 +1,57 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.asserts;
+
+import oo.atom.tests.AssertAssertionFails;
+import oo.atom.tests.AssertAssertionPasses;
+import oo.atom.tests.TestCase;
+import oo.atom.tests.TestsSuite;
+
+import static org.junit.Assert.*;
+
+public class AssertScenarioProducesTheOutputTest extends TestsSuite {
+ public AssertScenarioProducesTheOutputTest() {
+ super(
+ new TestCase(
+ "positive",
+ new AssertAssertionPasses(
+ new AssertScenarioProducesTheOutput(
+ out -> out.printOut("test"),
+ "test"
+ )
+ )
+ ),
+ new TestCase(
+ "negative",
+ new AssertAssertionFails(
+ new AssertScenarioProducesTheOutput(
+ out -> out.printOut("test"),
+ "test2"
+ )
+ )
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/hangman/game/GameImplementationTest.java b/src/test/java/hangman/game/GameImplementationTest.java
new file mode 100644
index 0000000..7863426
--- /dev/null
+++ b/src/test/java/hangman/game/GameImplementationTest.java
@@ -0,0 +1,74 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.game;
+
+import hangman.input.IFromString;
+import hangman.input.Input;
+import hangman.output.Output;
+import hangman.word.WExplicit;
+import oo.atom.tests.TestCase;
+import oo.atom.tests.TestsSuite;
+
+import static org.junit.Assert.*;
+
+public class GameImplementationTest extends TestsSuite {
+ public GameImplementationTest() {
+ super(
+ new TestCase(
+ "",
+ new AssertGameOutcome(
+ new AssertGameOutcome.AssertionSubject() {
+ @Override
+ public final Game game(final Input input, final Output output) {
+ return new GameImplementation(
+ output,
+ input,
+ new WExplicit("test"),
+ 5
+ );
+ }
+ },
+ new IFromString("a\na\na\na\na\n"),
+ "The word: ????\n" +
+ "\n" +
+ "Guess a letter: Missed, mistake #1 out of 5\n" +
+ "The word: ????\n" +
+ "\n" +
+ "Guess a letter: Missed, mistake #2 out of 5\n" +
+ "The word: ????\n" +
+ "\n" +
+ "Guess a letter: Missed, mistake #3 out of 5\n" +
+ "The word: ????\n" +
+ "\n" +
+ "Guess a letter: Missed, mistake #4 out of 5\n" +
+ "The word: ????\n" +
+ "\n" +
+ "Guess a letter: Missed, mistake #5 out of 5\n" +
+ "You lost!\n"
+ )
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/hangman/guess/GVerboseTest.java b/src/test/java/hangman/guess/GVerboseTest.java
new file mode 100644
index 0000000..3886ba4
--- /dev/null
+++ b/src/test/java/hangman/guess/GVerboseTest.java
@@ -0,0 +1,65 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.guess;
+
+import hangman.asserts.AssertScenarioProducesTheOutput;
+import hangman.message.MsgExplicit;
+import oo.atom.tests.TestCase;
+import oo.atom.tests.TestsSuite;
+
+public class GVerboseTest extends TestsSuite {
+ public GVerboseTest() {
+ super(
+ new TestCase(
+ "produces expected output on success hit",
+ new AssertScenarioProducesTheOutput(
+ out -> {
+ new GVerbose(
+ new MsgExplicit("[success]\n", out),
+ new MsgExplicit("[failure]\n", out),
+ new MsgExplicit("[masked_word]\n", out),
+ new GLucky()
+ ).hit();
+ },
+ "[masked_word]\n[success]\n"
+ )
+ ),
+ new TestCase(
+ "produces expected output on missed hit",
+ new AssertScenarioProducesTheOutput(
+ out -> {
+ new GVerbose(
+ new MsgExplicit("[success]\n", out),
+ new MsgExplicit("[failure]\n", out),
+ new MsgExplicit("[masked_word]\n", out),
+ new GLoser()
+ ).hit();
+ },
+ "[masked_word]\n[failure]\n"
+ )
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/hangman/input/AssertInputTest.java b/src/test/java/hangman/input/AssertInputTest.java
new file mode 100644
index 0000000..33be0af
--- /dev/null
+++ b/src/test/java/hangman/input/AssertInputTest.java
@@ -0,0 +1,47 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.input;
+
+import oo.atom.tests.TestCase;
+import oo.atom.tests.TestsSuite;
+
+import static org.junit.Assert.*;
+
+public class AssertInputTest extends TestsSuite {
+ public AssertInputTest() {
+ super(
+ new TestCase(
+ "",
+ new AssertInput(
+ new IFromString("a\r\nb\r\nc\r\n"),
+ 'a',
+ 'b',
+ 'c'
+ )
+ )
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/hangman/mistakes/MstMemoizedTest.java b/src/test/java/hangman/mistakes/MstMemoizedTest.java
new file mode 100644
index 0000000..21cd870
--- /dev/null
+++ b/src/test/java/hangman/mistakes/MstMemoizedTest.java
@@ -0,0 +1,46 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2018 Kapralov Sergey.
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package hangman.mistakes;
+
+import hangman.memory.MistakesMemory;
+import oo.atom.tests.TestCase;
+import oo.atom.tests.TestsSuite;
+
+public class MstMemoizedTest extends TestsSuite {
+ public MstMemoizedTest() {
+ super(
+ new TestCase(
+ "assert mistakes countdown is correct",
+ new AssertMistakesCountdown(
+ new MstMemoized(
+ new MistakesMemory(
+ 5
+ )
+ )
+ )
+ )
+ );
+ }
+}
\ No newline at end of file