From e62f3b337dc297657daecd9938e16f6d380a5c4a Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 8 Jun 2024 11:04:46 +0900 Subject: [PATCH 01/90] =?UTF-8?q?test:=20wordList=EC=97=90=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EB=8B=A8=EC=96=B4=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordList.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/java/wordle/domain/WordList.java diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java new file mode 100644 index 00000000..43721b9c --- /dev/null +++ b/src/test/java/wordle/domain/WordList.java @@ -0,0 +1,21 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WordListTest { + + @Test + public void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { + // given + Word word = new Word("cigar"); + WordList wordList = new WordList(); + + // when + boolean actual = wordList.contains(word); + + // then + assertTrue(actual); + } +} From 2f990b0f98b0f3dfb25dfb904857f7f58eb5e25b Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 8 Jun 2024 11:06:33 +0900 Subject: [PATCH 02/90] =?UTF-8?q?test:=20wordList=EC=97=90=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EB=8B=A8=EC=96=B4=20=EC=97=86=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordList.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 43721b9c..3a46ed71 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class WordListTest { @@ -18,4 +19,17 @@ public class WordListTest { // then assertTrue(actual); } + + @Test + public void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { + // given + Word word = new Word("ooooo"); + WordList wordList = new WordList(); + + // when + boolean actual = wordList.contains(word); + + // then + assertFalse(actual); + } } From ca2a8b3800e5a416ec1e2507f2a06b30e307917d Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 8 Jun 2024 11:18:48 +0900 Subject: [PATCH 03/90] =?UTF-8?q?feat:=20wordList=20=EC=A3=BC=EC=96=B4?= =?UTF-8?q?=EC=A7=84=20=EB=8B=A8=EC=96=B4=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Word.java | 24 ++++++++++++ src/test/java/wordle/domain/WordList.java | 34 ++++------------- src/test/java/wordle/domain/WordListTest.java | 38 +++++++++++++++++++ 3 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 src/test/java/wordle/domain/Word.java create mode 100644 src/test/java/wordle/domain/WordListTest.java diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java new file mode 100644 index 00000000..3368503b --- /dev/null +++ b/src/test/java/wordle/domain/Word.java @@ -0,0 +1,24 @@ +package wordle.domain; + +import java.util.Objects; + +public class Word { + private String word; + + public Word(String word) { + this.word = word; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Word word1 = (Word) o; + return Objects.equals(word, word1.word); + } + + @Override + public int hashCode() { + return Objects.hash(word); + } +} diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 3a46ed71..c36fc910 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -1,35 +1,15 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import java.util.List; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +public class WordList { + private List wordList; -public class WordListTest { - - @Test - public void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { - // given - Word word = new Word("cigar"); - WordList wordList = new WordList(); - - // when - boolean actual = wordList.contains(word); - - // then - assertTrue(actual); + public WordList(List wordList) { + this.wordList = wordList; } - @Test - public void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { - // given - Word word = new Word("ooooo"); - WordList wordList = new WordList(); - - // when - boolean actual = wordList.contains(word); - - // then - assertFalse(actual); + public boolean contains(Word word) { + return wordList.contains(word); } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java new file mode 100644 index 00000000..3c63d812 --- /dev/null +++ b/src/test/java/wordle/domain/WordListTest.java @@ -0,0 +1,38 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class WordListTest { + + @Test + public void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { + // given + Word word = new Word("cigar"); + WordList wordList = new WordList(List.of(new Word("cigar"))); + + // when + boolean actual = wordList.contains(word); + + // then + assertTrue(actual); + } + + @Test + public void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { + // given + Word word = new Word("ooooo"); + WordList wordList = new WordList(new ArrayList<>()); + + // when + boolean actual = wordList.contains(word); + + // then + assertFalse(actual); + } +} From 478f587527d978c84b5ced5c11eeb38cb8c43ddb Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 11:25:28 +0900 Subject: [PATCH 04/90] =?UTF-8?q?test:=20Selector=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=EB=8B=A4=EB=A9=B4=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EB=A5=BC=5F=EC=B6=94=EC=B6=9C=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordListTest.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 3c63d812..a784981a 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -5,13 +5,13 @@ import java.util.ArrayList; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class WordListTest { + @Test - public void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { + void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { // given Word word = new Word("cigar"); WordList wordList = new WordList(List.of(new Word("cigar"))); @@ -24,7 +24,7 @@ public class WordListTest { } @Test - public void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { + void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { // given Word word = new Word("ooooo"); WordList wordList = new WordList(new ArrayList<>()); @@ -35,4 +35,14 @@ public class WordListTest { // then assertFalse(actual); } + + @Test + void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { + Word word = new Word("cigar"); + + WordList wordList = new WordList(List.of(word)); + Word actual = wordList.select(() -> word); + + assertEquals(actual, word); + } } From f7daed8450b6ab3d6405b438fe09d2c6c72b200f Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 11:29:07 +0900 Subject: [PATCH 05/90] =?UTF-8?q?feat:=20Selector=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=EB=8B=A4=EB=A9=B4=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EB=A5=BC=5F=EC=B6=94=EC=B6=9C=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Selector.java | 8 ++++++++ src/test/java/wordle/domain/WordList.java | 4 ++++ src/test/java/wordle/domain/WordListTest.java | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/test/java/wordle/domain/Selector.java diff --git a/src/test/java/wordle/domain/Selector.java b/src/test/java/wordle/domain/Selector.java new file mode 100644 index 00000000..449bd68f --- /dev/null +++ b/src/test/java/wordle/domain/Selector.java @@ -0,0 +1,8 @@ +package wordle.domain; + +import java.util.List; + +@FunctionalInterface +public interface Selector { + Word select(List wordList); +} diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index c36fc910..d98da7c1 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -12,4 +12,8 @@ public WordList(List wordList) { public boolean contains(Word word) { return wordList.contains(word); } + + public Word select(final Selector selector) { + return selector.select(wordList); + } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index a784981a..00fb1592 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -41,7 +41,7 @@ public class WordListTest { Word word = new Word("cigar"); WordList wordList = new WordList(List.of(word)); - Word actual = wordList.select(() -> word); + Word actual = wordList.select(List::getFirst); assertEquals(actual, word); } From cfd46de2100fd9c8e467016f42a255caf31a4597 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 11:31:36 +0900 Subject: [PATCH 06/90] =?UTF-8?q?test:=20Selector=EA=B0=80=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A1=8C=EC=A7=80=EB=A7=8C=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EC=97=90=20=ED=95=B4=EB=8B=B9=ED=95=98=EB=8A=94=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EA=B0=80=20=EC=97=86=EB=8B=A4=EB=A9=B4=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordListTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 00fb1592..912e1a82 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.NoSuchElementException; import static org.junit.jupiter.api.Assertions.*; @@ -45,4 +46,11 @@ public class WordListTest { assertEquals(actual, word); } + + @Test + void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_얘외를_발생한다() { + WordList wordList = new WordList(List.of()); + + assertThrows(NoSuchElementException.class, () -> wordList.select(List::getFirst)); + } } From 280fae8eb9346996f0ad30b2568f57731d04498a Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 8 Jun 2024 11:41:03 +0900 Subject: [PATCH 07/90] =?UTF-8?q?test:=20Guess=EC=97=90=20=EC=86=8C?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=B0=9C=EC=83=9D=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/java/wordle/domain/GuessTest.java diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java new file mode 100644 index 00000000..bf0c62eb --- /dev/null +++ b/src/test/java/wordle/domain/GuessTest.java @@ -0,0 +1,17 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class GuessTest { + + @Test + void 단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { + // given + String word = "Cigar"; + + // when & then + assertThrows(RuntimeException.class, () -> new Guess(word)); + } +} From b9423229d0c98058c8a420d3de7555217c27a7e9 Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 8 Jun 2024 11:52:14 +0900 Subject: [PATCH 08/90] =?UTF-8?q?feat:=20Guess=EC=97=90=20=EC=86=8C?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=B0=9C=EC=83=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Guess.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/java/wordle/domain/Guess.java diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java new file mode 100644 index 00000000..60e3f590 --- /dev/null +++ b/src/test/java/wordle/domain/Guess.java @@ -0,0 +1,19 @@ +package wordle.domain; + +public class Guess extends Word { + + public Guess(String word) { + super(word); + validate(word); + } + + private void validate(String word) { + boolean result = word.chars() + .mapToObj(c -> (char) c) + .allMatch(c -> c >= 'a' && c <= 'z'); + + if (!result) { + throw new RuntimeException(); + } + } +} From 52437cae2685645a40b125f74b216867e4fc3365 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 11:57:14 +0900 Subject: [PATCH 09/90] =?UTF-8?q?test:=20Guess=EC=97=90=20=EC=86=8C?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=20=EB=AC=B8=EC=9E=90=EB=A7=8C=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=98=A4=EB=A9=B4=20=EC=83=9D=EC=84=B1=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index bf0c62eb..ee0d7a57 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -2,10 +2,19 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; public class GuessTest { + @Test + void 단어에_알파벳_소문자_문자가_들어오면_생성할_수_있다() { + // given + String word = "cigar"; + + assertDoesNotThrow(() -> new Guess(word)); + } + @Test void 단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { // given @@ -15,3 +24,4 @@ public class GuessTest { assertThrows(RuntimeException.class, () -> new Guess(word)); } } + From 08b9535306ae20cc247c9a8562eb4c1f17aed83a Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 12:00:10 +0900 Subject: [PATCH 10/90] =?UTF-8?q?test:=20Word=EC=97=90=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EB=8B=A8=EC=96=B4=EA=B0=80=205=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=88=EB=9D=BC=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordListTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 912e1a82..f7d0eb32 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -10,7 +10,6 @@ public class WordListTest { - @Test void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { // given @@ -53,4 +52,10 @@ public class WordListTest { assertThrows(NoSuchElementException.class, () -> wordList.select(List::getFirst)); } + + @Test + void 주어진_단어가_5글자가_아니라면_예외를_발생한다() { + // given when then + assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); + } } From 571b8dd083394b5b13e54dea6f2635304b107a12 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 12:02:01 +0900 Subject: [PATCH 11/90] =?UTF-8?q?feat:=20Word=EC=97=90=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EB=8B=A8=EC=96=B4=EA=B0=80=205=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=88=EB=9D=BC=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Word.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index 3368503b..e46f93a4 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -3,12 +3,21 @@ import java.util.Objects; public class Word { + public static final int WORD_SIZE = 5; + private String word; public Word(String word) { + validate(word); this.word = word; } + private static void validate(final String word) { + if(word.trim().length() != WORD_SIZE) { + throw new RuntimeException(); + } + } + @Override public boolean equals(Object o) { if (this == o) return true; From 83a0887e876f8342b3d3e49eabe8c0f355aea378 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 12:03:37 +0900 Subject: [PATCH 12/90] =?UTF-8?q?refactor:=20WordListTest=20=EC=97=90=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20Word=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20WordTest=20=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordListTest.java | 6 ------ src/test/java/wordle/domain/WordTest.java | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 src/test/java/wordle/domain/WordTest.java diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index f7d0eb32..66e3a056 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -52,10 +52,4 @@ public class WordListTest { assertThrows(NoSuchElementException.class, () -> wordList.select(List::getFirst)); } - - @Test - void 주어진_단어가_5글자가_아니라면_예외를_발생한다() { - // given when then - assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); - } } diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java new file mode 100644 index 00000000..f59c1375 --- /dev/null +++ b/src/test/java/wordle/domain/WordTest.java @@ -0,0 +1,14 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; + +public class WordTest { + + @Test + void 주어진_단어가_5글자가_아니라면_예외를_발생한다() { + // given when then + assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); + } +} From db2dcf4ffda369cfdb5457b35638e2f51da3112c Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 8 Jun 2024 12:06:01 +0900 Subject: [PATCH 13/90] =?UTF-8?q?refactor:=20Guess=20=EC=97=90=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=B1=85=EC=9E=84=20Word=20=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Guess.java | 11 ----------- src/test/java/wordle/domain/GuessTest.java | 21 --------------------- src/test/java/wordle/domain/Word.java | 9 ++++++++- src/test/java/wordle/domain/WordTest.java | 21 +++++++++++++++++++-- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 60e3f590..d3949ca3 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -4,16 +4,5 @@ public class Guess extends Word { public Guess(String word) { super(word); - validate(word); - } - - private void validate(String word) { - boolean result = word.chars() - .mapToObj(c -> (char) c) - .allMatch(c -> c >= 'a' && c <= 'z'); - - if (!result) { - throw new RuntimeException(); - } } } diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index ee0d7a57..53e1fb3e 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -1,27 +1,6 @@ package wordle.domain; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - public class GuessTest { - @Test - void 단어에_알파벳_소문자_문자가_들어오면_생성할_수_있다() { - // given - String word = "cigar"; - - assertDoesNotThrow(() -> new Guess(word)); - } - - @Test - void 단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { - // given - String word = "Cigar"; - - // when & then - assertThrows(RuntimeException.class, () -> new Guess(word)); - } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index e46f93a4..1a480de7 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -13,7 +13,14 @@ public Word(String word) { } private static void validate(final String word) { - if(word.trim().length() != WORD_SIZE) { + if (word.trim().length() != WORD_SIZE) { + throw new RuntimeException(); + } + boolean result = word.chars() + .mapToObj(c -> (char) c) + .allMatch(c -> c >= 'a' && c <= 'z'); + + if (!result) { throw new RuntimeException(); } } diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java index f59c1375..1980c8f9 100644 --- a/src/test/java/wordle/domain/WordTest.java +++ b/src/test/java/wordle/domain/WordTest.java @@ -2,13 +2,30 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.*; public class WordTest { @Test - void 주어진_단어가_5글자가_아니라면_예외를_발생한다() { + void 단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { // given when then assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); } + + @Test + void 단어에_알파벳_소문자_문자가_들어오면_생성할_수_있다() { + // given + String word = "cigar"; + + assertDoesNotThrow(() -> new Word(word)); + } + + @Test + void 단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { + // given + String word = "Cigar"; + + // when & then + assertThrows(RuntimeException.class, () -> new Word(word)); + } } From c9153f3ff4e077ddc985e08db64ba38826efc058 Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 9 Jun 2024 09:19:20 +0900 Subject: [PATCH 14/90] =?UTF-8?q?test:=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EB=8B=A8=EC=96=B4=20=EC=84=A0=ED=83=9D=EA=B8=B0?= =?UTF-8?q?=EB=8A=94=20=EC=A3=BC=EC=96=B4=EC=A7=84=20=EB=82=A0=EC=A7=9C?= =?UTF-8?q?=EB=A5=BC=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EB=A5=BC=20=EC=84=A0=ED=83=9D=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordle/domain/TimeBaseAnswerSelector.java | 24 ++++++++++++++++ .../domain/TimeBaseAnswerSelectorTest.java | 28 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/test/java/wordle/domain/TimeBaseAnswerSelector.java create mode 100644 src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java new file mode 100644 index 00000000..0b87f115 --- /dev/null +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java @@ -0,0 +1,24 @@ +package wordle.domain; + +import java.time.*; +import java.util.List; + +public class TimeBaseAnswerSelector implements Selector { + + private static final ZonedDateTime BASE_ZONED_DATE_TIME = ZonedDateTime.of( + LocalDateTime.of(LocalDate.of(2021, 6, 19), LocalTime.of(0, 0)), + ZoneId.of("Asia/Seoul")); + + private final ZonedDateTime zonedDateTime; + + public TimeBaseAnswerSelector(final ZonedDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public Word select(List wordList) { + + + + return new Word("circle"); + } +} \ No newline at end of file diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java new file mode 100644 index 00000000..e87fa889 --- /dev/null +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java @@ -0,0 +1,28 @@ +package wordle.domain; + + +import org.junit.jupiter.api.Test; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class TimeBaseAnswerSelectorTest { + + @Test + void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { + // given + final TimeBaseAnswerSelector answerSelector = new TimeBaseAnswerSelector(ZonedDateTime.now(ZoneId.of("Asis/Seoul"))); + final List words = List.of("cigar", "circle", "apple", "banana", "orange", "grape", "melon").stream() + .map(Word::new) + .toList(); + + // when + final Word select = answerSelector.select(words); + + // then + assertEquals(select, new Word("circle")); + } +} From f69ee03d4dcbf753f41574ff982cda375a638648 Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 9 Jun 2024 09:32:54 +0900 Subject: [PATCH 15/90] =?UTF-8?q?feat:=20=EB=82=A0=EC=A7=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EB=8B=A8=EC=96=B4=20=EC=84=A0=ED=83=9D=EA=B8=B0?= =?UTF-8?q?=EB=8A=94=20=EC=A3=BC=EC=96=B4=EC=A7=84=20=EB=82=A0=EC=A7=9C?= =?UTF-8?q?=EB=A5=BC=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EB=A5=BC=20=EC=84=A0=ED=83=9D=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordle/domain/TimeBaseAnswerSelector.java | 27 +++++++++++-------- .../domain/TimeBaseAnswerSelectorTest.java | 12 ++++----- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java index 0b87f115..c3faaee4 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java @@ -5,20 +5,25 @@ public class TimeBaseAnswerSelector implements Selector { - private static final ZonedDateTime BASE_ZONED_DATE_TIME = ZonedDateTime.of( - LocalDateTime.of(LocalDate.of(2021, 6, 19), LocalTime.of(0, 0)), - ZoneId.of("Asia/Seoul")); + private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); + private final LocalDate localDate; - private final ZonedDateTime zonedDateTime; - - public TimeBaseAnswerSelector(final ZonedDateTime zonedDateTime) { - this.zonedDateTime = zonedDateTime; + public TimeBaseAnswerSelector(final LocalDate localDate) { + this.localDate = localDate; } public Word select(List wordList) { - - - - return new Word("circle"); + if (wordList.isEmpty()) { + throw new RuntimeException(); + } + final long epochSecond = localDate.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); + final long baseEpochSecond = BASE_LOCAL_DATE.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); + final long timeDifference = Math.subtractExact(epochSecond, baseEpochSecond); + if (timeDifference < 0) { + throw new RuntimeException(); + } + + final int index = (int) timeDifference % wordList.size(); + return wordList.get(index); } } \ No newline at end of file diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java index e87fa889..2913f338 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java @@ -3,8 +3,7 @@ import org.junit.jupiter.api.Test; -import java.time.ZoneId; -import java.time.ZonedDateTime; +import java.time.LocalDate; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,15 +13,16 @@ class TimeBaseAnswerSelectorTest { @Test void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { // given - final TimeBaseAnswerSelector answerSelector = new TimeBaseAnswerSelector(ZonedDateTime.now(ZoneId.of("Asis/Seoul"))); - final List words = List.of("cigar", "circle", "apple", "banana", "orange", "grape", "melon").stream() + final TimeBaseAnswerSelector answerSelector = new TimeBaseAnswerSelector(LocalDate.of(2024, 6, 9)); + final String expectedWord = "cigar"; + final List words = List.of(expectedWord, "apple", "grape", "melon").stream() .map(Word::new) .toList(); // when - final Word select = answerSelector.select(words); + final Word actual = answerSelector.select(words); // then - assertEquals(select, new Word("circle")); + assertEquals(actual, new Word(expectedWord)); } } From acdfe4933f59f56c9ff615495249ddd76be8fd39 Mon Sep 17 00:00:00 2001 From: padoling Date: Sun, 9 Jun 2024 09:52:23 +0900 Subject: [PATCH 16/90] =?UTF-8?q?test:=20=EC=A0=95=EB=8B=B5=EA=B3=BC=20?= =?UTF-8?q?=EB=8F=99=EC=9D=BC=ED=95=9C=20=EB=8B=B5=EC=95=88=EC=9D=B4=20?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20=EB=AA=A8=EB=91=90=20MAT?= =?UTF-8?q?CHED=EC=9D=B8=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/test/java/wordle/domain/AnswerTest.java diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java new file mode 100644 index 00000000..906f4325 --- /dev/null +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -0,0 +1,25 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class AnswerTest { + + @Test + void 정답은_정답과_동일한_답안이_들어오면_모두_MATCHED인_결과를_반환한다() { + // given + Answer answer = new Answer("cigar"); + Guess guess = new Guess("cigar"); + + Result expectedResult = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); + + // when + Result result = answer.examineResult(guess); + + // then + assertEquals(result, expectedResult); + } +} From ee09463ce658ec12cf18335a10f6b976a57ede75 Mon Sep 17 00:00:00 2001 From: padoling Date: Sun, 9 Jun 2024 10:07:38 +0900 Subject: [PATCH 17/90] =?UTF-8?q?feat:=20=EC=A0=95=EB=8B=B5=EA=B3=BC=20?= =?UTF-8?q?=EB=8F=99=EC=9D=BC=ED=95=9C=20=EB=8B=B5=EC=95=88=EC=9D=B4=20?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20=EB=AA=A8=EB=91=90=20MAT?= =?UTF-8?q?CHED=EC=9D=B8=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Answer.java | 38 +++++++++++++++++++++ src/test/java/wordle/domain/Guess.java | 1 - src/test/java/wordle/domain/Result.java | 25 ++++++++++++++ src/test/java/wordle/domain/ResultType.java | 7 ++++ src/test/java/wordle/domain/Word.java | 4 +++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/test/java/wordle/domain/Answer.java create mode 100644 src/test/java/wordle/domain/Result.java create mode 100644 src/test/java/wordle/domain/ResultType.java diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java new file mode 100644 index 00000000..5878b858 --- /dev/null +++ b/src/test/java/wordle/domain/Answer.java @@ -0,0 +1,38 @@ +package wordle.domain; + +import java.util.List; +import java.util.stream.IntStream; + +public class Answer extends Word { + public Answer(String word) { + super(word); + } + + public Result examineResult(Guess guess) { + List resultTypes = IntStream.range(0, guess.getWord().length()) + .mapToObj(i -> examineResultType(guess.getWord(), i)) + .toList(); + + return new Result(resultTypes); + } + + private ResultType examineResultType(String guess, int index) { + char guessChar = guess.charAt(index); + String answer = getWord(); + + if (guessChar == answer.charAt(index)) + return ResultType.MATCHED; + + int answerCount = countChar(answer, guessChar); + int guessCount = countChar(guess.substring(0, index + 1), guessChar); + + if (answerCount >= guessCount) + return ResultType.EXIST; + + return ResultType.MISMATCHED; + } + + private int countChar(String string, char ch) { + return (int) string.chars().filter(c -> c == ch).count(); + } +} diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index d3949ca3..5d8b7652 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -1,7 +1,6 @@ package wordle.domain; public class Guess extends Word { - public Guess(String word) { super(word); } diff --git a/src/test/java/wordle/domain/Result.java b/src/test/java/wordle/domain/Result.java new file mode 100644 index 00000000..2888a24a --- /dev/null +++ b/src/test/java/wordle/domain/Result.java @@ -0,0 +1,25 @@ +package wordle.domain; + +import java.util.List; +import java.util.Objects; + +public class Result { + private List resultTypes; + + public Result(List resultTypes) { + this.resultTypes = resultTypes; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Result result = (Result) o; + return Objects.equals(resultTypes, result.resultTypes); + } + + @Override + public int hashCode() { + return Objects.hash(resultTypes); + } +} diff --git a/src/test/java/wordle/domain/ResultType.java b/src/test/java/wordle/domain/ResultType.java new file mode 100644 index 00000000..da47bde3 --- /dev/null +++ b/src/test/java/wordle/domain/ResultType.java @@ -0,0 +1,7 @@ +package wordle.domain; + +public enum ResultType { + MATCHED, + EXIST, + MISMATCHED +} diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index 1a480de7..b5e2aac0 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -12,6 +12,10 @@ public Word(String word) { this.word = word; } + public String getWord() { + return word; + } + private static void validate(final String word) { if (word.trim().length() != WORD_SIZE) { throw new RuntimeException(); From ebce98e01aa0326e4261054072a7c8abc451e3fa Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 9 Jun 2024 10:41:58 +0900 Subject: [PATCH 18/90] =?UTF-8?q?test:=20=EB=AA=A8=EB=93=A0=20ResultType?= =?UTF-8?q?=EC=9D=B4=20Matched=EB=9D=BC=EB=A9=B4=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20true?= =?UTF-8?q?=EB=A1=9C=5F=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/java/wordle/domain/ResultTest.java diff --git a/src/test/java/wordle/domain/ResultTest.java b/src/test/java/wordle/domain/ResultTest.java new file mode 100644 index 00000000..e9a63014 --- /dev/null +++ b/src/test/java/wordle/domain/ResultTest.java @@ -0,0 +1,17 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ResultTest { + + @Test + void 모든_ResultType이_Matched라면_매칭_성공_여부를_true로_반환한다() { + Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED)); + + assertTrue(result.allMatched()); + } +} From 90055f2e7dd561f5b003f74adbcafc16491051de Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 9 Jun 2024 10:42:03 +0900 Subject: [PATCH 19/90] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20ResultType?= =?UTF-8?q?=EC=9D=B4=20Matched=EB=9D=BC=EB=A9=B4=20=EB=A7=A4=EC=B9=AD=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20true?= =?UTF-8?q?=EB=A1=9C=5F=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Result.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/wordle/domain/Result.java b/src/test/java/wordle/domain/Result.java index 2888a24a..a3ef54bf 100644 --- a/src/test/java/wordle/domain/Result.java +++ b/src/test/java/wordle/domain/Result.java @@ -10,6 +10,10 @@ public Result(List resultTypes) { this.resultTypes = resultTypes; } + public boolean allMatched() { + return resultTypes.stream().allMatch(ResultType.MATCHED::equals); + } + @Override public boolean equals(Object o) { if (this == o) return true; From 2b8a2a43e7fdbfd7caae7b55fce88581bf15a830 Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 9 Jun 2024 10:57:20 +0900 Subject: [PATCH 20/90] =?UTF-8?q?feat:=20View=20=EB=B0=8F=20Controller=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Game.java | 147 ++++++++++++++++++++++++ src/test/java/wordle/domain/Result.java | 7 ++ 2 files changed, 154 insertions(+) create mode 100644 src/test/java/wordle/domain/Game.java diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java new file mode 100644 index 00000000..f0ccbb9f --- /dev/null +++ b/src/test/java/wordle/domain/Game.java @@ -0,0 +1,147 @@ +package wordle.domain; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class Game { + private static final int MAX_ATTEMPT = 6; + + private InputView inputView; + private OutputView outputView; + private AnswerReader answerReader; + + public void start() { + // todo 게임 시작 + final Answer answer = answerReader.read(new TimeBaseAnswerSelector(LocalDate.now())); + outputView.welcome(); + List results = new ArrayList<>(); + for (int i = 0; i < MAX_ATTEMPT; i++) { + final Word word = inputWord(); + final Result result = answer.examineResult(new Guess(word.getWord())); + results.add(result); + final boolean allMatch = results.stream().anyMatch(Result::allMatched); + if (allMatch) { + break; + } + outputView.insertWord(); + } + outputView.showResults(results, MAX_ATTEMPT); + } + + private Word inputWord() { + try { + outputView.insertWord(); + final String wordString = inputView.inputWord(); + final Word word = new Word(wordString); + outputView.insertedWord(wordString); + return word; + } catch (final Exception e) { + outputView.wrongWord(); + return inputWord(); + } + } +} + + +interface InputView { + String inputWord(); +} + +interface OutputView { + void welcome(); + + void insertWord(); + + void wrongWord(); + + void showResults(List results, final int maxAttempt); + + void insertedWord(String wordString); +} + +class ConsoleInputView implements InputView { + private final Scanner scanner; + + public ConsoleInputView() { + this(new Scanner(System.in)); + } + + public ConsoleInputView(final Scanner scanner) { + this.scanner = scanner; + } + + @Override + public String inputWord() { + return scanner.nextLine(); + } +} + +class ConsoleOutputView implements OutputView { + + @Override + public void welcome() { + System.out.println("WORDLE을 6번 만에 맞춰 보세요."); + System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); + } + + @Override + public void insertWord() { + System.out.println("정답을 입력해 주세요."); + } + + @Override + public void wrongWord() { + System.out.println("단어가 올바르지 않습니다."); + System.out.println("5글자의 소문자 알파벳으로 다시 입력해 주세요."); + } + + @Override + public void showResults(final List results, final int maxAttempt) { + System.out.println("%s/%s".formatted(results.size(), maxAttempt)); + final String resultSentence = results.stream() + .map(it -> it.getResult().stream() + .map(ResultType::name) + .collect(Collectors.joining()) + ).collect(Collectors.joining("\n")); + + System.out.println(resultSentence); + } + + @Override + public void insertedWord(final String wordString) { + System.out.println(wordString); + } +} + +interface AnswerReader { + Answer read(final Selector selector); +} + +class AnswerFileReader implements AnswerReader { + private static final String FILE_PATH = "src/main/resources/words.txt"; + private static final WordList wordList = initializeWordList(); + + private static WordList initializeWordList() { + try { + final Path path = Paths.get(FILE_PATH); + return new WordList(Files.readAllLines(path) + .stream() + .map(Word::new) + .toList()); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public Answer read(final Selector selector) { + return new Answer(wordList.select(selector).getWord()); + } +} diff --git a/src/test/java/wordle/domain/Result.java b/src/test/java/wordle/domain/Result.java index a3ef54bf..351f1802 100644 --- a/src/test/java/wordle/domain/Result.java +++ b/src/test/java/wordle/domain/Result.java @@ -1,7 +1,10 @@ package wordle.domain; +import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Stream; public class Result { private List resultTypes; @@ -14,6 +17,10 @@ public boolean allMatched() { return resultTypes.stream().allMatch(ResultType.MATCHED::equals); } + public List getResult() { + return Collections.unmodifiableList(resultTypes); + } + @Override public boolean equals(Object o) { if (this == o) return true; From de9a13a1b6df377558eec9f60ab93d3cf30ccee0 Mon Sep 17 00:00:00 2001 From: padoling Date: Wed, 12 Jun 2024 20:42:10 +0900 Subject: [PATCH 21/90] =?UTF-8?q?feat:=20Results=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A1=9C=20result=20list=20=EB=9E=98=ED=95=91=20?= =?UTF-8?q?=EB=B0=8F=20game=20=20=EC=A2=85=EB=A3=8C=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Application.java | 14 ++++++++ src/test/java/wordle/domain/Game.java | 27 +++++++++------ src/test/java/wordle/domain/Results.java | 36 ++++++++++++++++++++ 3 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/test/java/wordle/domain/Application.java create mode 100644 src/test/java/wordle/domain/Results.java diff --git a/src/test/java/wordle/domain/Application.java b/src/test/java/wordle/domain/Application.java new file mode 100644 index 00000000..ec72b028 --- /dev/null +++ b/src/test/java/wordle/domain/Application.java @@ -0,0 +1,14 @@ +package wordle.domain; + +import wordle.domain.ConsoleInputView; +import wordle.domain.Game; + +public class Application { + public static void main(String[] args) { + ConsoleInputView inputView = new ConsoleInputView(); + ConsoleOutputView outputView = new ConsoleOutputView(); + AnswerFileReader answerFileReader = new AnswerFileReader(); + Game game = new Game(inputView, outputView, answerFileReader); + game.start(); + } +} diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index f0ccbb9f..ae4c804c 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -17,22 +17,26 @@ public class Game { private OutputView outputView; private AnswerReader answerReader; + public Game(InputView inputView, OutputView outputView, AnswerReader answerReader) { + this.inputView = inputView; + this.outputView = outputView; + this.answerReader = answerReader; + } + public void start() { // todo 게임 시작 final Answer answer = answerReader.read(new TimeBaseAnswerSelector(LocalDate.now())); outputView.welcome(); - List results = new ArrayList<>(); + Results results = new Results(new ArrayList<>()); for (int i = 0; i < MAX_ATTEMPT; i++) { final Word word = inputWord(); final Result result = answer.examineResult(new Guess(word.getWord())); results.add(result); - final boolean allMatch = results.stream().anyMatch(Result::allMatched); - if (allMatch) { + outputView.showResults(results, MAX_ATTEMPT); + if (results.isFinished()) { break; } - outputView.insertWord(); } - outputView.showResults(results, MAX_ATTEMPT); } private Word inputWord() { @@ -40,7 +44,7 @@ private Word inputWord() { outputView.insertWord(); final String wordString = inputView.inputWord(); final Word word = new Word(wordString); - outputView.insertedWord(wordString); + outputView.insertedWord(wordString); // 요구사항에는 이 부분은 없는 듯 합니다. return word; } catch (final Exception e) { outputView.wrongWord(); @@ -61,7 +65,7 @@ interface OutputView { void wrongWord(); - void showResults(List results, final int maxAttempt); + void showResults(Results results, final int maxAttempt); void insertedWord(String wordString); } @@ -103,9 +107,12 @@ public void wrongWord() { } @Override - public void showResults(final List results, final int maxAttempt) { - System.out.println("%s/%s".formatted(results.size(), maxAttempt)); - final String resultSentence = results.stream() + public void showResults(final Results results, final int maxAttempt) { + if (results.isFinished()) { + System.out.println("%s/%s".formatted(results.size(), maxAttempt)); + } + + final String resultSentence = results.getResults().stream() .map(it -> it.getResult().stream() .map(ResultType::name) .collect(Collectors.joining()) diff --git a/src/test/java/wordle/domain/Results.java b/src/test/java/wordle/domain/Results.java new file mode 100644 index 00000000..63334629 --- /dev/null +++ b/src/test/java/wordle/domain/Results.java @@ -0,0 +1,36 @@ +package wordle.domain; + +import java.util.Collections; +import java.util.List; + +public class Results { + private List results; + private boolean isFinished = false; + + public Results(List results) { + this.results = results; + } + + private boolean allMatched() { + return results.stream().anyMatch(Result::allMatched); + } + + public void add(Result result) { + results.add(result); + if (allMatched() || results.size() == 6) { + isFinished = true; + } + } + + public boolean isFinished() { + return isFinished; + } + + public int size() { + return results.size(); + } + + public List getResults() { + return Collections.unmodifiableList(results); + } +} From a221c62e4a5706c5754113254df7a524ca595e09 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 20:46:15 +0900 Subject: [PATCH 22/90] =?UTF-8?q?feat:=20Results=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EC=8B=9C=20=EC=8B=A4=EC=A0=9C=20=EC=83=89=EC=83=81=EC=9D=84=20?= =?UTF-8?q?=ED=91=9C=ED=98=84=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Game.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index ae4c804c..256ee443 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; +import java.util.function.Function; import java.util.stream.Collectors; public class Game { @@ -114,13 +115,21 @@ public void showResults(final Results results, final int maxAttempt) { final String resultSentence = results.getResults().stream() .map(it -> it.getResult().stream() - .map(ResultType::name) + .map(ConsoleOutputView::color) .collect(Collectors.joining()) ).collect(Collectors.joining("\n")); System.out.println(resultSentence); } + private static String color(final ResultType resultType) { + return switch (resultType) { + case MATCHED -> "🟩"; + case EXIST -> "🟨"; + case MISMATCHED -> "⬜"; + }; + } + @Override public void insertedWord(final String wordString) { System.out.println(wordString); From b36bf1a557aff8859957c0d437fbbcfde572fdf5 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 20:54:56 +0900 Subject: [PATCH 23/90] =?UTF-8?q?test:=20=EB=8B=A8=EC=96=B4=EC=9E=A5?= =?UTF-8?q?=EC=9D=B4=20=EC=A1=B4=EC=9E=AC=ED=95=9C=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=ED=8A=B9=EC=A0=95=20=EC=A1=B0=EA=B1=B4=EC=9D=84=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=20=EC=A0=95=EB=8B=B5=EC=9D=84=20=EC=B6=94=EC=B6=9C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordle/domain/WordListReaderTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/java/wordle/domain/WordListReaderTest.java diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java new file mode 100644 index 00000000..f8dde0d7 --- /dev/null +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -0,0 +1,27 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WordListReaderTest { + + @Test + void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { + WordListReader wordListReader = new WordListFileReader(); + WordList wordList = wordListReader.read(); + + final Word actual = wordList.select(new TestSelector()); + assertEquals(new Answer("apple"), actual); + } + + class TestSelector implements Selector { + + @Override + public Word select(final List wordList) { + return wordList.getFirst(); + } + } +} From f7d268f07461f9e9341dda1f3167492364c08f18 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 20:57:40 +0900 Subject: [PATCH 24/90] =?UTF-8?q?feat:=20=EB=8B=A8=EC=96=B4=EC=9E=A5?= =?UTF-8?q?=EC=9D=B4=20=EC=A1=B4=EC=9E=AC=ED=95=9C=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=ED=8A=B9=EC=A0=95=20=EC=A1=B0=EA=B1=B4=EC=9D=84=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=20=EC=A0=95=EB=8B=B5=EC=9D=84=20=EC=B6=94=EC=B6=9C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Application.java | 5 +-- src/test/java/wordle/domain/Game.java | 39 ++----------------- .../wordle/domain/WordListFileReader.java | 33 ++++++++++++++++ .../java/wordle/domain/WordListReader.java | 7 ++++ .../wordle/domain/WordListReaderTest.java | 17 +++++++- 5 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 src/test/java/wordle/domain/WordListFileReader.java create mode 100644 src/test/java/wordle/domain/WordListReader.java diff --git a/src/test/java/wordle/domain/Application.java b/src/test/java/wordle/domain/Application.java index ec72b028..7e7bec9e 100644 --- a/src/test/java/wordle/domain/Application.java +++ b/src/test/java/wordle/domain/Application.java @@ -1,13 +1,10 @@ package wordle.domain; -import wordle.domain.ConsoleInputView; -import wordle.domain.Game; - public class Application { public static void main(String[] args) { ConsoleInputView inputView = new ConsoleInputView(); ConsoleOutputView outputView = new ConsoleOutputView(); - AnswerFileReader answerFileReader = new AnswerFileReader(); + WordListFileReader answerFileReader = new WordListFileReader(); Game game = new Game(inputView, outputView, answerFileReader); game.start(); } diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index 256ee443..30bc1a04 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -1,14 +1,8 @@ package wordle.domain; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.time.LocalDate; import java.util.ArrayList; -import java.util.List; import java.util.Scanner; -import java.util.function.Function; import java.util.stream.Collectors; public class Game { @@ -16,17 +10,17 @@ public class Game { private InputView inputView; private OutputView outputView; - private AnswerReader answerReader; + private WordListReader wordListReader; - public Game(InputView inputView, OutputView outputView, AnswerReader answerReader) { + public Game(InputView inputView, OutputView outputView, WordListReader wordListReader) { this.inputView = inputView; this.outputView = outputView; - this.answerReader = answerReader; + this.wordListReader = wordListReader; } public void start() { // todo 게임 시작 - final Answer answer = answerReader.read(new TimeBaseAnswerSelector(LocalDate.now())); + final Answer answer = wordListReader.read(new TimeBaseAnswerSelector(LocalDate.now())); outputView.welcome(); Results results = new Results(new ArrayList<>()); for (int i = 0; i < MAX_ATTEMPT; i++) { @@ -136,28 +130,3 @@ public void insertedWord(final String wordString) { } } -interface AnswerReader { - Answer read(final Selector selector); -} - -class AnswerFileReader implements AnswerReader { - private static final String FILE_PATH = "src/main/resources/words.txt"; - private static final WordList wordList = initializeWordList(); - - private static WordList initializeWordList() { - try { - final Path path = Paths.get(FILE_PATH); - return new WordList(Files.readAllLines(path) - .stream() - .map(Word::new) - .toList()); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public Answer read(final Selector selector) { - return new Answer(wordList.select(selector).getWord()); - } -} diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/test/java/wordle/domain/WordListFileReader.java new file mode 100644 index 00000000..240bd00c --- /dev/null +++ b/src/test/java/wordle/domain/WordListFileReader.java @@ -0,0 +1,33 @@ +package wordle.domain; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +class WordListFileReader implements WordListReader { + private static final String FILE_PATH = "src/main/resources/words.txt"; + private static final WordList wordList = initializeWordList(); + + private static WordList initializeWordList() { + try { + final Path path = Paths.get(FILE_PATH); + return new WordList(Files.readAllLines(path) + .stream() + .map(Word::new) + .toList()); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public Answer read(final Selector selector) { + return new Answer(wordList.select(selector).getWord()); + } + + @Override + public WordList read() { + return null; + } +} diff --git a/src/test/java/wordle/domain/WordListReader.java b/src/test/java/wordle/domain/WordListReader.java new file mode 100644 index 00000000..d8f4590c --- /dev/null +++ b/src/test/java/wordle/domain/WordListReader.java @@ -0,0 +1,7 @@ +package wordle.domain; + +interface WordListReader { + Answer read(final Selector selector); + + WordList read(); +} diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index f8dde0d7..95296638 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -10,11 +10,11 @@ public class WordListReaderTest { @Test void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { - WordListReader wordListReader = new WordListFileReader(); + WordListReader wordListReader = new TestWordListReader(); WordList wordList = wordListReader.read(); final Word actual = wordList.select(new TestSelector()); - assertEquals(new Answer("apple"), actual); + assertEquals(new Word("apple"), actual); } class TestSelector implements Selector { @@ -24,4 +24,17 @@ public Word select(final List wordList) { return wordList.getFirst(); } } + + class TestWordListReader implements WordListReader { + + @Override + public Answer read(final Selector selector) { + throw new RuntimeException(); + } + + @Override + public WordList read() { + return new WordList(List.of(new Word("apple"))); + } + } } From 43f4346924f3e7bb5ca884f87c4a4cf68d8b6c70 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 21:00:53 +0900 Subject: [PATCH 25/90] =?UTF-8?q?refactor:=20Answer=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20WordList=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20Word=20=EC=A1=B0=ED=9A=8C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Answer.java | 5 +++++ src/test/java/wordle/domain/Game.java | 3 ++- src/test/java/wordle/domain/WordListFileReader.java | 7 +------ src/test/java/wordle/domain/WordListReader.java | 2 -- src/test/java/wordle/domain/WordListReaderTest.java | 5 ----- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index 5878b858..72dfcc0b 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -4,6 +4,11 @@ import java.util.stream.IntStream; public class Answer extends Word { + + public Answer(final Word select) { + this(select.getWord()); + } + public Answer(String word) { super(word); } diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index 30bc1a04..f7a774fa 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -20,7 +20,8 @@ public Game(InputView inputView, OutputView outputView, WordListReader wordListR public void start() { // todo 게임 시작 - final Answer answer = wordListReader.read(new TimeBaseAnswerSelector(LocalDate.now())); + final WordList wordList = wordListReader.read(); + final Answer answer = new Answer(wordList.select(new TimeBaseAnswerSelector(LocalDate.now()))); outputView.welcome(); Results results = new Results(new ArrayList<>()); for (int i = 0; i < MAX_ATTEMPT; i++) { diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/test/java/wordle/domain/WordListFileReader.java index 240bd00c..abd59433 100644 --- a/src/test/java/wordle/domain/WordListFileReader.java +++ b/src/test/java/wordle/domain/WordListFileReader.java @@ -16,18 +16,13 @@ private static WordList initializeWordList() { .stream() .map(Word::new) .toList()); - } catch (IOException e) { throw new RuntimeException(e); } } - public Answer read(final Selector selector) { - return new Answer(wordList.select(selector).getWord()); - } - @Override public WordList read() { - return null; + return wordList; } } diff --git a/src/test/java/wordle/domain/WordListReader.java b/src/test/java/wordle/domain/WordListReader.java index d8f4590c..0fc7aa26 100644 --- a/src/test/java/wordle/domain/WordListReader.java +++ b/src/test/java/wordle/domain/WordListReader.java @@ -1,7 +1,5 @@ package wordle.domain; interface WordListReader { - Answer read(final Selector selector); - WordList read(); } diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index 95296638..246c05a2 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -27,11 +27,6 @@ public Word select(final List wordList) { class TestWordListReader implements WordListReader { - @Override - public Answer read(final Selector selector) { - throw new RuntimeException(); - } - @Override public WordList read() { return new WordList(List.of(new Word("apple"))); From 1e6b2122c8102c3d867800054cb01d6f9a59d7e3 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 21:05:21 +0900 Subject: [PATCH 26/90] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=8B=A8=EC=96=B4=EA=B0=80=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EC=9E=A5=EC=97=90=20=EC=97=86=EC=9D=84=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Game.java | 8 ++++---- src/test/java/wordle/domain/Word.java | 4 ++++ src/test/java/wordle/domain/WordList.java | 8 ++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index f7a774fa..93ed0390 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -25,7 +25,7 @@ public void start() { outputView.welcome(); Results results = new Results(new ArrayList<>()); for (int i = 0; i < MAX_ATTEMPT; i++) { - final Word word = inputWord(); + final Word word = inputWord(wordList); final Result result = answer.examineResult(new Guess(word.getWord())); results.add(result); outputView.showResults(results, MAX_ATTEMPT); @@ -35,16 +35,16 @@ public void start() { } } - private Word inputWord() { + private Word inputWord(WordList wordList) { try { outputView.insertWord(); final String wordString = inputView.inputWord(); - final Word word = new Word(wordString); + final Word word = wordList.find(wordString); // 요구사항에는 이 부분은 없는 듯 합니다. outputView.insertedWord(wordString); // 요구사항에는 이 부분은 없는 듯 합니다. return word; } catch (final Exception e) { outputView.wrongWord(); - return inputWord(); + return inputWord(wordList); } } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index b5e2aac0..6cb666db 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -41,4 +41,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(word); } + + public boolean isSameWord(final String word) { + return this.word.equals(word); + } } diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index d98da7c1..0497013b 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -1,6 +1,7 @@ package wordle.domain; import java.util.List; +import java.util.NoSuchElementException; public class WordList { private List wordList; @@ -16,4 +17,11 @@ public boolean contains(Word word) { public Word select(final Selector selector) { return selector.select(wordList); } + + public Word find(final String word) { + return wordList.stream() + .filter(it -> it.isSameWord(word)) + .findFirst() + .orElseThrow(NoSuchElementException::new); + } } From 7890f4686bd3d74abb2c93494aee6e9a0759e2e7 Mon Sep 17 00:00:00 2001 From: padoling Date: Wed, 12 Jun 2024 21:17:07 +0900 Subject: [PATCH 27/90] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=20=EB=AC=B8=EC=9E=90=EC=97=B4=EC=9D=84=20?= =?UTF-8?q?Guess=EB=A1=9C=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Game.java | 12 ++++++------ src/test/java/wordle/domain/Guess.java | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java index 93ed0390..885d5e04 100644 --- a/src/test/java/wordle/domain/Game.java +++ b/src/test/java/wordle/domain/Game.java @@ -25,8 +25,8 @@ public void start() { outputView.welcome(); Results results = new Results(new ArrayList<>()); for (int i = 0; i < MAX_ATTEMPT; i++) { - final Word word = inputWord(wordList); - final Result result = answer.examineResult(new Guess(word.getWord())); + final Guess guess = inputWord(wordList); + final Result result = answer.examineResult(guess); results.add(result); outputView.showResults(results, MAX_ATTEMPT); if (results.isFinished()) { @@ -35,13 +35,13 @@ public void start() { } } - private Word inputWord(WordList wordList) { + private Guess inputWord(WordList wordList) { try { outputView.insertWord(); final String wordString = inputView.inputWord(); - final Word word = wordList.find(wordString); // 요구사항에는 이 부분은 없는 듯 합니다. - outputView.insertedWord(wordString); // 요구사항에는 이 부분은 없는 듯 합니다. - return word; + Guess guess = new Guess(wordList.find(wordString)); + outputView.insertedWord(wordString); + return guess; } catch (final Exception e) { outputView.wrongWord(); return inputWord(wordList); diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 5d8b7652..25451e96 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -4,4 +4,8 @@ public class Guess extends Word { public Guess(String word) { super(word); } + + public Guess(Word word) { + this(word.getWord()); + } } From b634c0b0941fc502942bf48e84a43f745afcff8c Mon Sep 17 00:00:00 2001 From: padoling Date: Wed, 12 Jun 2024 21:26:53 +0900 Subject: [PATCH 28/90] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/wordle/{domain => }/Application.java | 7 +- src/test/java/wordle/Game.java | 57 ++++++++ src/test/java/wordle/domain/Game.java | 133 ------------------ .../wordle/domain/WordListFileReader.java | 2 +- .../java/wordle/domain/WordListReader.java | 2 +- .../java/wordle/view/ConsoleInputView.java | 20 +++ .../java/wordle/view/ConsoleOutputView.java | 54 +++++++ src/test/java/wordle/view/InputView.java | 5 + src/test/java/wordle/view/OutputView.java | 15 ++ 9 files changed, 159 insertions(+), 136 deletions(-) rename src/test/java/wordle/{domain => }/Application.java (70%) create mode 100644 src/test/java/wordle/Game.java delete mode 100644 src/test/java/wordle/domain/Game.java create mode 100644 src/test/java/wordle/view/ConsoleInputView.java create mode 100644 src/test/java/wordle/view/ConsoleOutputView.java create mode 100644 src/test/java/wordle/view/InputView.java create mode 100644 src/test/java/wordle/view/OutputView.java diff --git a/src/test/java/wordle/domain/Application.java b/src/test/java/wordle/Application.java similarity index 70% rename from src/test/java/wordle/domain/Application.java rename to src/test/java/wordle/Application.java index 7e7bec9e..c86caa9c 100644 --- a/src/test/java/wordle/domain/Application.java +++ b/src/test/java/wordle/Application.java @@ -1,4 +1,9 @@ -package wordle.domain; +package wordle; + +import wordle.Game; +import wordle.domain.WordListFileReader; +import wordle.view.ConsoleInputView; +import wordle.view.ConsoleOutputView; public class Application { public static void main(String[] args) { diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java new file mode 100644 index 00000000..44955946 --- /dev/null +++ b/src/test/java/wordle/Game.java @@ -0,0 +1,57 @@ +package wordle; + +import wordle.domain.*; +import wordle.view.InputView; +import wordle.view.OutputView; + +import java.time.LocalDate; +import java.util.ArrayList; + +public class Game { + private static final int MAX_ATTEMPT = 6; + + private InputView inputView; + private OutputView outputView; + private WordListReader wordListReader; + + public Game(InputView inputView, OutputView outputView, WordListReader wordListReader) { + this.inputView = inputView; + this.outputView = outputView; + this.wordListReader = wordListReader; + } + + public void start() { + // todo 게임 시작 + final WordList wordList = wordListReader.read(); + final Answer answer = new Answer(wordList.select(new TimeBaseAnswerSelector(LocalDate.now()))); + outputView.welcome(); + Results results = new Results(new ArrayList<>()); + for (int i = 0; i < MAX_ATTEMPT; i++) { + final Guess guess = inputWord(wordList); + final Result result = answer.examineResult(guess); + results.add(result); + outputView.showResults(results, MAX_ATTEMPT); + if (results.isFinished()) { + break; + } + } + } + + private Guess inputWord(WordList wordList) { + try { + outputView.insertWord(); + final String wordString = inputView.inputWord(); + Guess guess = new Guess(wordList.find(wordString)); + outputView.insertedWord(wordString); + return guess; + } catch (final Exception e) { + outputView.wrongWord(); + return inputWord(wordList); + } + } +} + + + + + diff --git a/src/test/java/wordle/domain/Game.java b/src/test/java/wordle/domain/Game.java deleted file mode 100644 index 885d5e04..00000000 --- a/src/test/java/wordle/domain/Game.java +++ /dev/null @@ -1,133 +0,0 @@ -package wordle.domain; - -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Scanner; -import java.util.stream.Collectors; - -public class Game { - private static final int MAX_ATTEMPT = 6; - - private InputView inputView; - private OutputView outputView; - private WordListReader wordListReader; - - public Game(InputView inputView, OutputView outputView, WordListReader wordListReader) { - this.inputView = inputView; - this.outputView = outputView; - this.wordListReader = wordListReader; - } - - public void start() { - // todo 게임 시작 - final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(new TimeBaseAnswerSelector(LocalDate.now()))); - outputView.welcome(); - Results results = new Results(new ArrayList<>()); - for (int i = 0; i < MAX_ATTEMPT; i++) { - final Guess guess = inputWord(wordList); - final Result result = answer.examineResult(guess); - results.add(result); - outputView.showResults(results, MAX_ATTEMPT); - if (results.isFinished()) { - break; - } - } - } - - private Guess inputWord(WordList wordList) { - try { - outputView.insertWord(); - final String wordString = inputView.inputWord(); - Guess guess = new Guess(wordList.find(wordString)); - outputView.insertedWord(wordString); - return guess; - } catch (final Exception e) { - outputView.wrongWord(); - return inputWord(wordList); - } - } -} - - -interface InputView { - String inputWord(); -} - -interface OutputView { - void welcome(); - - void insertWord(); - - void wrongWord(); - - void showResults(Results results, final int maxAttempt); - - void insertedWord(String wordString); -} - -class ConsoleInputView implements InputView { - private final Scanner scanner; - - public ConsoleInputView() { - this(new Scanner(System.in)); - } - - public ConsoleInputView(final Scanner scanner) { - this.scanner = scanner; - } - - @Override - public String inputWord() { - return scanner.nextLine(); - } -} - -class ConsoleOutputView implements OutputView { - - @Override - public void welcome() { - System.out.println("WORDLE을 6번 만에 맞춰 보세요."); - System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); - } - - @Override - public void insertWord() { - System.out.println("정답을 입력해 주세요."); - } - - @Override - public void wrongWord() { - System.out.println("단어가 올바르지 않습니다."); - System.out.println("5글자의 소문자 알파벳으로 다시 입력해 주세요."); - } - - @Override - public void showResults(final Results results, final int maxAttempt) { - if (results.isFinished()) { - System.out.println("%s/%s".formatted(results.size(), maxAttempt)); - } - - final String resultSentence = results.getResults().stream() - .map(it -> it.getResult().stream() - .map(ConsoleOutputView::color) - .collect(Collectors.joining()) - ).collect(Collectors.joining("\n")); - - System.out.println(resultSentence); - } - - private static String color(final ResultType resultType) { - return switch (resultType) { - case MATCHED -> "🟩"; - case EXIST -> "🟨"; - case MISMATCHED -> "⬜"; - }; - } - - @Override - public void insertedWord(final String wordString) { - System.out.println(wordString); - } -} - diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/test/java/wordle/domain/WordListFileReader.java index abd59433..8ebe2b32 100644 --- a/src/test/java/wordle/domain/WordListFileReader.java +++ b/src/test/java/wordle/domain/WordListFileReader.java @@ -5,7 +5,7 @@ import java.nio.file.Path; import java.nio.file.Paths; -class WordListFileReader implements WordListReader { +public class WordListFileReader implements WordListReader { private static final String FILE_PATH = "src/main/resources/words.txt"; private static final WordList wordList = initializeWordList(); diff --git a/src/test/java/wordle/domain/WordListReader.java b/src/test/java/wordle/domain/WordListReader.java index 0fc7aa26..34dd645c 100644 --- a/src/test/java/wordle/domain/WordListReader.java +++ b/src/test/java/wordle/domain/WordListReader.java @@ -1,5 +1,5 @@ package wordle.domain; -interface WordListReader { +public interface WordListReader { WordList read(); } diff --git a/src/test/java/wordle/view/ConsoleInputView.java b/src/test/java/wordle/view/ConsoleInputView.java new file mode 100644 index 00000000..0ba5e03d --- /dev/null +++ b/src/test/java/wordle/view/ConsoleInputView.java @@ -0,0 +1,20 @@ +package wordle.view; + +import java.util.Scanner; + +public class ConsoleInputView implements InputView { + private final Scanner scanner; + + public ConsoleInputView() { + this(new Scanner(System.in)); + } + + public ConsoleInputView(final Scanner scanner) { + this.scanner = scanner; + } + + @Override + public String inputWord() { + return scanner.nextLine(); + } +} \ No newline at end of file diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java new file mode 100644 index 00000000..f14c0dfa --- /dev/null +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -0,0 +1,54 @@ +package wordle.view; + +import wordle.domain.ResultType; +import wordle.domain.Results; + +import java.util.stream.Collectors; + +public class ConsoleOutputView implements OutputView { + + @Override + public void welcome() { + System.out.println("WORDLE을 6번 만에 맞춰 보세요."); + System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); + } + + @Override + public void insertWord() { + System.out.println("정답을 입력해 주세요."); + } + + @Override + public void wrongWord() { + System.out.println("단어가 올바르지 않습니다."); + System.out.println("5글자의 소문자 알파벳으로 다시 입력해 주세요."); + } + + @Override + public void showResults(final Results results, final int maxAttempt) { + if (results.isFinished()) { + System.out.println("%s/%s".formatted(results.size(), maxAttempt)); + } + + final String resultSentence = results.getResults().stream() + .map(it -> it.getResult().stream() + .map(ConsoleOutputView::color) + .collect(Collectors.joining()) + ).collect(Collectors.joining("\n")); + + System.out.println(resultSentence); + } + + private static String color(final ResultType resultType) { + return switch (resultType) { + case MATCHED -> "🟩"; + case EXIST -> "🟨"; + case MISMATCHED -> "⬜"; + }; + } + + @Override + public void insertedWord(final String wordString) { + System.out.println(wordString); + } +} \ No newline at end of file diff --git a/src/test/java/wordle/view/InputView.java b/src/test/java/wordle/view/InputView.java new file mode 100644 index 00000000..4f637c75 --- /dev/null +++ b/src/test/java/wordle/view/InputView.java @@ -0,0 +1,5 @@ +package wordle.view; + +public interface InputView { + String inputWord(); +} \ No newline at end of file diff --git a/src/test/java/wordle/view/OutputView.java b/src/test/java/wordle/view/OutputView.java new file mode 100644 index 00000000..ee714f8a --- /dev/null +++ b/src/test/java/wordle/view/OutputView.java @@ -0,0 +1,15 @@ +package wordle.view; + +import wordle.domain.Results; + +public interface OutputView { + void welcome(); + + void insertWord(); + + void wrongWord(); + + void showResults(Results results, final int maxAttempt); + + void insertedWord(String wordString); +} \ No newline at end of file From a649fd5fafe781cbe0aabcf99455788a7fe319cd Mon Sep 17 00:00:00 2001 From: padoling Date: Wed, 12 Jun 2024 21:31:55 +0900 Subject: [PATCH 29/90] =?UTF-8?q?refactor:=20=EC=B5=9C=EB=8C=80=20?= =?UTF-8?q?=EC=8B=9C=EB=8F=84=20=ED=9A=9F=EC=88=98=EB=A5=BC=20Game?= =?UTF-8?q?=EC=97=90=EC=84=9C=EB=A7=8C=20=EA=B4=80=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 5 ++--- src/test/java/wordle/domain/Results.java | 7 +++++-- src/test/java/wordle/view/ConsoleOutputView.java | 4 ++-- src/test/java/wordle/view/OutputView.java | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 44955946..96339033 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -21,11 +21,10 @@ public Game(InputView inputView, OutputView outputView, WordListReader wordListR } public void start() { - // todo 게임 시작 final WordList wordList = wordListReader.read(); final Answer answer = new Answer(wordList.select(new TimeBaseAnswerSelector(LocalDate.now()))); - outputView.welcome(); - Results results = new Results(new ArrayList<>()); + outputView.welcome(MAX_ATTEMPT); + Results results = new Results(new ArrayList<>(), MAX_ATTEMPT); for (int i = 0; i < MAX_ATTEMPT; i++) { final Guess guess = inputWord(wordList); final Result result = answer.examineResult(guess); diff --git a/src/test/java/wordle/domain/Results.java b/src/test/java/wordle/domain/Results.java index 63334629..c3a024fd 100644 --- a/src/test/java/wordle/domain/Results.java +++ b/src/test/java/wordle/domain/Results.java @@ -7,8 +7,11 @@ public class Results { private List results; private boolean isFinished = false; - public Results(List results) { + private int maxAttempt; + + public Results(List results, final int maxAttempt) { this.results = results; + this.maxAttempt = maxAttempt; } private boolean allMatched() { @@ -17,7 +20,7 @@ private boolean allMatched() { public void add(Result result) { results.add(result); - if (allMatched() || results.size() == 6) { + if (allMatched() || results.size() == maxAttempt) { isFinished = true; } } diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java index f14c0dfa..f7943eac 100644 --- a/src/test/java/wordle/view/ConsoleOutputView.java +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -8,8 +8,8 @@ public class ConsoleOutputView implements OutputView { @Override - public void welcome() { - System.out.println("WORDLE을 6번 만에 맞춰 보세요."); + public void welcome(final int maxAttempt) { + System.out.println("WORDLE을 %s번 만에 맞춰 보세요.".formatted(maxAttempt)); System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); } diff --git a/src/test/java/wordle/view/OutputView.java b/src/test/java/wordle/view/OutputView.java index ee714f8a..10a244dc 100644 --- a/src/test/java/wordle/view/OutputView.java +++ b/src/test/java/wordle/view/OutputView.java @@ -3,7 +3,7 @@ import wordle.domain.Results; public interface OutputView { - void welcome(); + void welcome(final int maxAttempt); void insertWord(); From 92656af4249f22467e0de75ce8136929591556eb Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 21:34:51 +0900 Subject: [PATCH 30/90] =?UTF-8?q?refactor:=20=EB=8B=A8=EC=96=B4=EC=9E=A5?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A0=95=EB=8B=B5=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=83=81?= =?UTF-8?q?=EC=9C=84=20=ED=98=B8=EC=B6=9C=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Application.java | 5 ++++- src/test/java/wordle/Game.java | 15 ++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/test/java/wordle/Application.java b/src/test/java/wordle/Application.java index c86caa9c..2f2735bf 100644 --- a/src/test/java/wordle/Application.java +++ b/src/test/java/wordle/Application.java @@ -1,16 +1,19 @@ package wordle; import wordle.Game; +import wordle.domain.TimeBaseAnswerSelector; import wordle.domain.WordListFileReader; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; +import java.time.LocalDate; + public class Application { public static void main(String[] args) { ConsoleInputView inputView = new ConsoleInputView(); ConsoleOutputView outputView = new ConsoleOutputView(); WordListFileReader answerFileReader = new WordListFileReader(); Game game = new Game(inputView, outputView, answerFileReader); - game.start(); + game.start(new TimeBaseAnswerSelector(LocalDate.now())); } } diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 96339033..7b8e1917 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -4,25 +4,26 @@ import wordle.view.InputView; import wordle.view.OutputView; -import java.time.LocalDate; import java.util.ArrayList; public class Game { private static final int MAX_ATTEMPT = 6; - private InputView inputView; - private OutputView outputView; - private WordListReader wordListReader; + private final InputView inputView; + private final OutputView outputView; + private final WordListReader wordListReader; - public Game(InputView inputView, OutputView outputView, WordListReader wordListReader) { + public Game(final InputView inputView, + final OutputView outputView, + final WordListReader wordListReader) { this.inputView = inputView; this.outputView = outputView; this.wordListReader = wordListReader; } - public void start() { + public void start(final Selector selector) { final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(new TimeBaseAnswerSelector(LocalDate.now()))); + final Answer answer = new Answer(wordList.select(selector)); outputView.welcome(MAX_ATTEMPT); Results results = new Results(new ArrayList<>(), MAX_ATTEMPT); for (int i = 0; i < MAX_ATTEMPT; i++) { From 3c78afeca9d28c2cc8c46ed260ee2599d81101e0 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 12 Jun 2024 21:49:52 +0900 Subject: [PATCH 31/90] =?UTF-8?q?refactor:=20takeWhile=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 25 ++++++++++++------- src/test/java/wordle/domain/Results.java | 9 ++----- .../java/wordle/view/ConsoleOutputView.java | 4 +-- src/test/java/wordle/view/OutputView.java | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 7b8e1917..83317126 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -5,6 +5,7 @@ import wordle.view.OutputView; import java.util.ArrayList; +import java.util.stream.IntStream; public class Game { private static final int MAX_ATTEMPT = 6; @@ -25,16 +26,22 @@ public void start(final Selector selector) { final WordList wordList = wordListReader.read(); final Answer answer = new Answer(wordList.select(selector)); outputView.welcome(MAX_ATTEMPT); + execute(wordList, answer); + } + + private void execute(final WordList wordList, final Answer answer) { Results results = new Results(new ArrayList<>(), MAX_ATTEMPT); - for (int i = 0; i < MAX_ATTEMPT; i++) { - final Guess guess = inputWord(wordList); - final Result result = answer.examineResult(guess); - results.add(result); - outputView.showResults(results, MAX_ATTEMPT); - if (results.isFinished()) { - break; - } - } + IntStream.range(0, MAX_ATTEMPT) + .mapToObj(i -> i) + .takeWhile(attempt -> !results.isFinished(attempt)) + .forEach(attempt -> examine(wordList, answer, attempt, results)); + } + + private void examine(final WordList wordList, final Answer answer, final Integer attempt, final Results results) { + final Guess guess = inputWord(wordList); + final Result result = answer.examineResult(guess); + results.add(result); + outputView.showResults(results, attempt, MAX_ATTEMPT); } private Guess inputWord(WordList wordList) { diff --git a/src/test/java/wordle/domain/Results.java b/src/test/java/wordle/domain/Results.java index c3a024fd..24b5050e 100644 --- a/src/test/java/wordle/domain/Results.java +++ b/src/test/java/wordle/domain/Results.java @@ -5,8 +5,6 @@ public class Results { private List results; - private boolean isFinished = false; - private int maxAttempt; public Results(List results, final int maxAttempt) { @@ -20,13 +18,10 @@ private boolean allMatched() { public void add(Result result) { results.add(result); - if (allMatched() || results.size() == maxAttempt) { - isFinished = true; - } } - public boolean isFinished() { - return isFinished; + public boolean isFinished(int attempt) { + return (allMatched() || attempt == maxAttempt); } public int size() { diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java index f7943eac..b065722b 100644 --- a/src/test/java/wordle/view/ConsoleOutputView.java +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -25,8 +25,8 @@ public void wrongWord() { } @Override - public void showResults(final Results results, final int maxAttempt) { - if (results.isFinished()) { + public void showResults(final Results results, final int attempt, final int maxAttempt) { + if (results.isFinished(attempt)) { System.out.println("%s/%s".formatted(results.size(), maxAttempt)); } diff --git a/src/test/java/wordle/view/OutputView.java b/src/test/java/wordle/view/OutputView.java index 10a244dc..320714db 100644 --- a/src/test/java/wordle/view/OutputView.java +++ b/src/test/java/wordle/view/OutputView.java @@ -9,7 +9,7 @@ public interface OutputView { void wrongWord(); - void showResults(Results results, final int maxAttempt); + void showResults(final Results results, final int attempt, final int maxAttempt); void insertedWord(String wordString); } \ No newline at end of file From 9f7d1c062136538c3418e88f81fe0deac7d73cf3 Mon Sep 17 00:00:00 2001 From: padoling Date: Thu, 13 Jun 2024 20:39:07 +0900 Subject: [PATCH 32/90] =?UTF-8?q?test=20:=20=EB=AC=B8=EC=9E=90=EA=B0=80=20?= =?UTF-8?q?=EB=AA=A8=EB=91=90=20=EC=9D=BC=EC=B9=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EA=B0=80=20=EC=9E=88=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20true=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultsTest.java | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/wordle/domain/ResultsTest.java diff --git a/src/test/java/wordle/domain/ResultsTest.java b/src/test/java/wordle/domain/ResultsTest.java new file mode 100644 index 00000000..042ad94b --- /dev/null +++ b/src/test/java/wordle/domain/ResultsTest.java @@ -0,0 +1,26 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ResultsTest { + + @Test + void 문자가_모두_일치하는_결과가_있는_경우_true를_반환한다() { + // given + List resultList = List.of( + new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) + ); + Results results = new Results(resultList); + + // when + results.hasAnswer(); + + // then + assertTrue(results.hasAnswer()); + } +} From 924d38ca86e96b947b4820caf21e335256f4ad05 Mon Sep 17 00:00:00 2001 From: padoling Date: Thu, 13 Jun 2024 20:39:27 +0900 Subject: [PATCH 33/90] =?UTF-8?q?test=20:=20=EB=AC=B8=EC=9E=90=EA=B0=80=20?= =?UTF-8?q?=EB=AA=A8=EB=91=90=20=EC=9D=BC=EC=B9=98=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EA=B0=80=20=EC=97=86=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20false=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultsTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/wordle/domain/ResultsTest.java b/src/test/java/wordle/domain/ResultsTest.java index 042ad94b..46397265 100644 --- a/src/test/java/wordle/domain/ResultsTest.java +++ b/src/test/java/wordle/domain/ResultsTest.java @@ -4,6 +4,7 @@ import java.util.List; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class ResultsTest { @@ -23,4 +24,20 @@ public class ResultsTest { // then assertTrue(results.hasAnswer()); } + + @Test + void 문자가_모두_일치하는_결과가_없는_경우_false를_반환한다() { + // given + List resultList = List.of( + new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MATCHED, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) + ); + Results results = new Results(resultList); + + // when + results.hasAnswer(); + + // then + assertFalse(results.hasAnswer()); + } } From b52c6c7865d1b67ab088dafd89474a1d47e7a1ad Mon Sep 17 00:00:00 2001 From: padoling Date: Thu, 13 Jun 2024 20:40:38 +0900 Subject: [PATCH 34/90] =?UTF-8?q?refactor:=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=EC=9D=B4=20=EC=A2=85=EB=A3=8C=EB=90=90=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 6 +++--- src/test/java/wordle/domain/Results.java | 10 ++-------- src/test/java/wordle/view/ConsoleOutputView.java | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 83317126..5fbc9967 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -30,10 +30,10 @@ public void start(final Selector selector) { } private void execute(final WordList wordList, final Answer answer) { - Results results = new Results(new ArrayList<>(), MAX_ATTEMPT); + Results results = new Results(new ArrayList<>()); IntStream.range(0, MAX_ATTEMPT) - .mapToObj(i -> i) - .takeWhile(attempt -> !results.isFinished(attempt)) + .boxed() + .takeWhile(attempt -> results.hasAnswer()) .forEach(attempt -> examine(wordList, answer, attempt, results)); } diff --git a/src/test/java/wordle/domain/Results.java b/src/test/java/wordle/domain/Results.java index 24b5050e..f468840b 100644 --- a/src/test/java/wordle/domain/Results.java +++ b/src/test/java/wordle/domain/Results.java @@ -5,14 +5,12 @@ public class Results { private List results; - private int maxAttempt; - public Results(List results, final int maxAttempt) { + public Results(List results) { this.results = results; - this.maxAttempt = maxAttempt; } - private boolean allMatched() { + public boolean hasAnswer() { return results.stream().anyMatch(Result::allMatched); } @@ -20,10 +18,6 @@ public void add(Result result) { results.add(result); } - public boolean isFinished(int attempt) { - return (allMatched() || attempt == maxAttempt); - } - public int size() { return results.size(); } diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java index b065722b..76c75e6a 100644 --- a/src/test/java/wordle/view/ConsoleOutputView.java +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -26,7 +26,7 @@ public void wrongWord() { @Override public void showResults(final Results results, final int attempt, final int maxAttempt) { - if (results.isFinished(attempt)) { + if (results.hasAnswer() || attempt == maxAttempt) { System.out.println("%s/%s".formatted(results.size(), maxAttempt)); } From 20c1ee4927ae1af091fa8aabe259b51f85c20687 Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 20:48:06 +0900 Subject: [PATCH 35/90] =?UTF-8?q?test:=20=EB=AA=A8=EB=93=A0=20ResultType?= =?UTF-8?q?=EC=9D=B4=20Matched=EA=B0=80=20=EC=95=84=EB=8B=88=EB=9D=BC?= =?UTF-8?q?=EB=A9=B4=20=EB=A7=A4=EC=B9=AD=20=EC=84=B1=EA=B3=B5=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EB=A5=BC=20false=EB=A1=9C=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/wordle/domain/ResultTest.java b/src/test/java/wordle/domain/ResultTest.java index e9a63014..1fc9d9a2 100644 --- a/src/test/java/wordle/domain/ResultTest.java +++ b/src/test/java/wordle/domain/ResultTest.java @@ -4,6 +4,7 @@ import java.util.List; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class ResultTest { @@ -14,4 +15,11 @@ public class ResultTest { assertTrue(result.allMatched()); } + + @Test + void 모든_ResultType이_Matched가_아니라면_매칭_성공_여부를_false로_반환한다() { + Result result = new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED)); + + assertFalse(result.allMatched()); + } } From 4e1ea7169856d7d87773aec3f533bedda121cae9 Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 21:04:42 +0900 Subject: [PATCH 36/90] =?UTF-8?q?refactor:=20WordList=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=EC=97=90=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Selector.java | 4 +-- .../wordle/domain/TimeBaseAnswerSelector.java | 11 ++------ .../domain/TimeBaseAnswerSelectorTest.java | 7 ++--- src/test/java/wordle/domain/WordList.java | 28 ++++++++++++++++++- .../wordle/domain/WordListReaderTest.java | 4 +-- src/test/java/wordle/domain/WordListTest.java | 4 +-- 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/test/java/wordle/domain/Selector.java b/src/test/java/wordle/domain/Selector.java index 449bd68f..19d3436d 100644 --- a/src/test/java/wordle/domain/Selector.java +++ b/src/test/java/wordle/domain/Selector.java @@ -1,8 +1,6 @@ package wordle.domain; -import java.util.List; -@FunctionalInterface public interface Selector { - Word select(List wordList); + Word select(WordList wordList); } diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java index c3faaee4..a09781b0 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelector.java @@ -1,7 +1,6 @@ package wordle.domain; import java.time.*; -import java.util.List; public class TimeBaseAnswerSelector implements Selector { @@ -12,18 +11,14 @@ public TimeBaseAnswerSelector(final LocalDate localDate) { this.localDate = localDate; } - public Word select(List wordList) { - if (wordList.isEmpty()) { - throw new RuntimeException(); - } + @Override + public Word select(final WordList wordList) { final long epochSecond = localDate.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); final long baseEpochSecond = BASE_LOCAL_DATE.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); final long timeDifference = Math.subtractExact(epochSecond, baseEpochSecond); if (timeDifference < 0) { throw new RuntimeException(); } - - final int index = (int) timeDifference % wordList.size(); - return wordList.get(index); + return wordList.get(timeDifference % wordList.size()); } } \ No newline at end of file diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java index 2913f338..2f0581ce 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java +++ b/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import java.time.LocalDate; -import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -15,12 +14,10 @@ class TimeBaseAnswerSelectorTest { // given final TimeBaseAnswerSelector answerSelector = new TimeBaseAnswerSelector(LocalDate.of(2024, 6, 9)); final String expectedWord = "cigar"; - final List words = List.of(expectedWord, "apple", "grape", "melon").stream() - .map(Word::new) - .toList(); + final WordList wordList = new WordList(expectedWord, "apple", "grape", "melon"); // when - final Word actual = answerSelector.select(words); + final Word actual = answerSelector.select(wordList); // then assertEquals(actual, new Word(expectedWord)); diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 0497013b..faf25d37 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -1,5 +1,6 @@ package wordle.domain; +import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; @@ -10,12 +11,18 @@ public WordList(List wordList) { this.wordList = wordList; } + public WordList(final String... words) { + this(Arrays.stream(words) + .map(Word::new) + .toList()); + } + public boolean contains(Word word) { return wordList.contains(word); } public Word select(final Selector selector) { - return selector.select(wordList); + return selector.select(this); } public Word find(final String word) { @@ -24,4 +31,23 @@ public Word find(final String word) { .findFirst() .orElseThrow(NoSuchElementException::new); } + + public boolean isEmpty() { + return wordList.isEmpty(); + } + + public int size() { + return wordList.size(); + } + + public Word get(final long index) { + if (wordList.isEmpty()) { + throw new RuntimeException(); + } + return get((int) index); + } + + public Word get(final int index) { + return wordList.get(index); + } } diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index 246c05a2..2595be6e 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -20,8 +20,8 @@ public class WordListReaderTest { class TestSelector implements Selector { @Override - public Word select(final List wordList) { - return wordList.getFirst(); + public Word select(final WordList wordList) { + return wordList.get(0); } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 66e3a056..7ecd4513 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -41,7 +41,7 @@ public class WordListTest { Word word = new Word("cigar"); WordList wordList = new WordList(List.of(word)); - Word actual = wordList.select(List::getFirst); + Word actual = wordList.select((it) -> it.get(0)); assertEquals(actual, word); } @@ -50,6 +50,6 @@ public class WordListTest { void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_얘외를_발생한다() { WordList wordList = new WordList(List.of()); - assertThrows(NoSuchElementException.class, () -> wordList.select(List::getFirst)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> wordList.select((it) -> it.get(0))); } } From cc09f14bb71c4bb2b70116320c5c269cb8476cb7 Mon Sep 17 00:00:00 2001 From: padoling Date: Thu, 13 Jun 2024 21:44:47 +0900 Subject: [PATCH 37/90] =?UTF-8?q?refactor:=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=EC=83=89=EA=B9=94=20=ED=91=9C=EC=8B=9C=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B0=8F=20=EA=B2=8C=EC=9E=84=20=EC=95=88=EB=82=B4?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=83=81=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/wordle/view/ConsoleOutputView.java | 25 +++++++----------- src/test/java/wordle/view/OutputView.java | 2 +- src/test/java/wordle/view/ResultColor.java | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 src/test/java/wordle/view/ResultColor.java diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java index 76c75e6a..ccd0ab88 100644 --- a/src/test/java/wordle/view/ConsoleOutputView.java +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -1,27 +1,30 @@ package wordle.view; -import wordle.domain.ResultType; import wordle.domain.Results; import java.util.stream.Collectors; public class ConsoleOutputView implements OutputView { + private static final String WELCOME_MESSAGE = "WORDLE을 %s번 만에 맞춰 보세요."; + private static final String RESULT_DESCRIPTION_MESSAGE = "시도의 결과는 타일의 색 변화로 나타납니다."; + public static final String INSERT_ANSWER_MESSAGE = "정답을 입력해 주세요."; + public static final String WRONG_WORD_MESSAGE = "단어가 올바르지 않습니다."; + @Override public void welcome(final int maxAttempt) { - System.out.println("WORDLE을 %s번 만에 맞춰 보세요.".formatted(maxAttempt)); - System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); + System.out.println(WELCOME_MESSAGE.formatted(maxAttempt)); + System.out.println(RESULT_DESCRIPTION_MESSAGE); } @Override public void insertWord() { - System.out.println("정답을 입력해 주세요."); + System.out.println(INSERT_ANSWER_MESSAGE); } @Override public void wrongWord() { - System.out.println("단어가 올바르지 않습니다."); - System.out.println("5글자의 소문자 알파벳으로 다시 입력해 주세요."); + System.out.println(WRONG_WORD_MESSAGE); } @Override @@ -32,21 +35,13 @@ public void showResults(final Results results, final int attempt, final int maxA final String resultSentence = results.getResults().stream() .map(it -> it.getResult().stream() - .map(ConsoleOutputView::color) + .map(ResultColor::color) .collect(Collectors.joining()) ).collect(Collectors.joining("\n")); System.out.println(resultSentence); } - private static String color(final ResultType resultType) { - return switch (resultType) { - case MATCHED -> "🟩"; - case EXIST -> "🟨"; - case MISMATCHED -> "⬜"; - }; - } - @Override public void insertedWord(final String wordString) { System.out.println(wordString); diff --git a/src/test/java/wordle/view/OutputView.java b/src/test/java/wordle/view/OutputView.java index 320714db..d07dd007 100644 --- a/src/test/java/wordle/view/OutputView.java +++ b/src/test/java/wordle/view/OutputView.java @@ -11,5 +11,5 @@ public interface OutputView { void showResults(final Results results, final int attempt, final int maxAttempt); - void insertedWord(String wordString); + void insertedWord(final String wordString); } \ No newline at end of file diff --git a/src/test/java/wordle/view/ResultColor.java b/src/test/java/wordle/view/ResultColor.java new file mode 100644 index 00000000..71f91d00 --- /dev/null +++ b/src/test/java/wordle/view/ResultColor.java @@ -0,0 +1,26 @@ +package wordle.view; + +import wordle.domain.ResultType; + +public enum ResultColor { + GREEN(ResultType.MATCHED, "🟩"), + YELLOW(ResultType.EXIST, "🟨"), + WHITE(ResultType.MISMATCHED, "⬜"); + + private ResultType resultType; + private String color; + + ResultColor(ResultType resultType, String color) { + this.resultType = resultType; + this.color = color; + } + + public static String color(ResultType resultType) { + for (ResultColor resultColor : ResultColor.values()) { + if (resultColor.resultType == resultType) { + return resultColor.color; + } + } + return WHITE.color; + } +} From 1e80356748aaa5e3d6ab1fcb28389476a9f8ba05 Mon Sep 17 00:00:00 2001 From: padoling Date: Thu, 13 Jun 2024 21:46:11 +0900 Subject: [PATCH 38/90] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=98=88=EC=99=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordList.java | 10 +++------- src/test/java/wordle/domain/WordListTest.java | 3 +-- src/test/java/wordle/domain/WordTest.java | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index faf25d37..2fb11b00 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -32,22 +32,18 @@ public Word find(final String word) { .orElseThrow(NoSuchElementException::new); } - public boolean isEmpty() { - return wordList.isEmpty(); - } - public int size() { return wordList.size(); } public Word get(final long index) { - if (wordList.isEmpty()) { - throw new RuntimeException(); - } return get((int) index); } public Word get(final int index) { + if (wordList.isEmpty()) { + throw new RuntimeException(); + } return wordList.get(index); } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 7ecd4513..6b51d3bb 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.NoSuchElementException; import static org.junit.jupiter.api.Assertions.*; @@ -47,7 +46,7 @@ public class WordListTest { } @Test - void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_얘외를_발생한다() { + void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { WordList wordList = new WordList(List.of()); assertThrows(ArrayIndexOutOfBoundsException.class, () -> wordList.select((it) -> it.get(0))); diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java index 1980c8f9..d43a900d 100644 --- a/src/test/java/wordle/domain/WordTest.java +++ b/src/test/java/wordle/domain/WordTest.java @@ -13,7 +13,7 @@ public class WordTest { } @Test - void 단어에_알파벳_소문자_문자가_들어오면_생성할_수_있다() { + void 단어에_5글자_알파벳_소문자_문자가_들어오면_생성할_수_있다() { // given String word = "cigar"; From 7de17cc80374c48cc076c3c4c445f077b169582f Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 21:48:29 +0900 Subject: [PATCH 39/90] =?UTF-8?q?test:=20=EC=86=8C=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EC=98=81=EB=8B=A8=EC=96=B4=EB=A1=9C=20Alphabet=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AlphabetTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/wordle/domain/AlphabetTest.java diff --git a/src/test/java/wordle/domain/AlphabetTest.java b/src/test/java/wordle/domain/AlphabetTest.java new file mode 100644 index 00000000..d1f4040a --- /dev/null +++ b/src/test/java/wordle/domain/AlphabetTest.java @@ -0,0 +1,13 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class AlphabetTest { + + @Test + void 소문자_영단어로_Alphabet을_생성할_수_있다() { + assertDoesNotThrow(() -> Alphabet.of('a')); + } +} From 48ed3b113c34fd59ebbb10e17b557c60890c0026 Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 21:51:30 +0900 Subject: [PATCH 40/90] =?UTF-8?q?feat:=20=EC=86=8C=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EC=98=81=EB=8B=A8=EC=96=B4=EB=A1=9C=20Alphabet=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Alphabet.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/java/wordle/domain/Alphabet.java diff --git a/src/test/java/wordle/domain/Alphabet.java b/src/test/java/wordle/domain/Alphabet.java new file mode 100644 index 00000000..461a68e5 --- /dev/null +++ b/src/test/java/wordle/domain/Alphabet.java @@ -0,0 +1,18 @@ +package wordle.domain; + +import java.util.Arrays; + +public enum Alphabet { + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; + + public static Alphabet of(char alphabet) { + return of(String.valueOf(alphabet)); + } + + public static Alphabet of(String alphabet) { + return Arrays.stream(values()) + .filter(it -> it.name().equals(alphabet)) + .findFirst() + .orElseThrow(IllegalArgumentException::new); + } +} From 9787aef7dcddfa122dcf48a7984dc52bf71c437b Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 21:53:38 +0900 Subject: [PATCH 41/90] =?UTF-8?q?test:=20=EC=86=8C=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=95=84=EB=8B=8C=20=EB=8B=A8=EC=96=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=A4=EC=96=B4=EC=98=A8=EB=8B=A4=EB=A9=B4=20Alphabet?= =?UTF-8?q?=EC=9D=84=20=EC=83=9D=EC=84=B1=ED=95=A0=20=EC=88=98=20=EC=97=86?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AlphabetTest.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/AlphabetTest.java b/src/test/java/wordle/domain/AlphabetTest.java index d1f4040a..eb52481b 100644 --- a/src/test/java/wordle/domain/AlphabetTest.java +++ b/src/test/java/wordle/domain/AlphabetTest.java @@ -2,7 +2,7 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.*; public class AlphabetTest { @@ -10,4 +10,13 @@ public class AlphabetTest { void 소문자_영단어로_Alphabet을_생성할_수_있다() { assertDoesNotThrow(() -> Alphabet.of('a')); } + + @Test + void 소문자가_아닌_단어가_들어온다면_Alphabet을_생성할_수_없다() { + assertAll( + () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('A')), + () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('1')), + () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('ㄱ')) + ); + } } From ea46eb5ccc8c64c81ad8ac3b20d455b127b83e5f Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 21:59:41 +0900 Subject: [PATCH 42/90] =?UTF-8?q?refactor:=20Word=20=EB=82=B4=EB=B6=80=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=EC=9D=84=20Alphabet=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Word.java | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index 6cb666db..8ce33f1f 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -1,48 +1,48 @@ package wordle.domain; +import java.util.List; import java.util.Objects; public class Word { public static final int WORD_SIZE = 5; - private String word; + private List alphabets; public Word(String word) { validate(word); - this.word = word; + this.alphabets = word.chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList(); } public String getWord() { - return word; + return alphabets.stream() + .map(Alphabet::name) + .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString(); } private static void validate(final String word) { if (word.trim().length() != WORD_SIZE) { throw new RuntimeException(); } - boolean result = word.chars() - .mapToObj(c -> (char) c) - .allMatch(c -> c >= 'a' && c <= 'z'); - - if (!result) { - throw new RuntimeException(); - } } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Word word1 = (Word) o; - return Objects.equals(word, word1.word); + final Word word = (Word) o; + return Objects.equals(alphabets, word.alphabets); } @Override public int hashCode() { - return Objects.hash(word); + return Objects.hashCode(alphabets); } public boolean isSameWord(final String word) { - return this.word.equals(word); + return this.equals(new Word(word)); } } From fbe7a1e2823dfa60d5ac79e3dbc920692cae212c Mon Sep 17 00:00:00 2001 From: woozi Date: Thu, 13 Jun 2024 22:00:14 +0900 Subject: [PATCH 43/90] =?UTF-8?q?fix:=20WordList=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20Exception=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordListTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 6b51d3bb..1398dd83 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -49,6 +49,6 @@ public class WordListTest { void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { WordList wordList = new WordList(List.of()); - assertThrows(ArrayIndexOutOfBoundsException.class, () -> wordList.select((it) -> it.get(0))); + assertThrows(RuntimeException.class, () -> wordList.select((it) -> it.get(0))); } } From 7a2caa85468af44fa4d870bc526e4f4f909b3e31 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 14:20:16 +0900 Subject: [PATCH 44/90] =?UTF-8?q?fix:=20=EB=8B=A4=EC=9D=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EC=9E=85=EB=A0=A5=20=EC=A1=B0=EA=B1=B4=EC=8B=9D=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 5fbc9967..6b06f16c 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -33,7 +33,7 @@ private void execute(final WordList wordList, final Answer answer) { Results results = new Results(new ArrayList<>()); IntStream.range(0, MAX_ATTEMPT) .boxed() - .takeWhile(attempt -> results.hasAnswer()) + .takeWhile(attempt -> !results.hasAnswer()) .forEach(attempt -> examine(wordList, answer, attempt, results)); } From afbfdd5f03cbf1994463a257f92e748c6b3c0a30 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 14:25:51 +0900 Subject: [PATCH 45/90] =?UTF-8?q?refactor:=20=EB=8B=A8=EC=88=9C=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=B0=98=ED=99=98=EC=9D=84=20?= =?UTF-8?q?=EC=95=8C=ED=8C=8C=EB=B2=B3=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Answer.java | 2 +- src/test/java/wordle/domain/Guess.java | 3 ++- src/test/java/wordle/domain/Word.java | 19 ++++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index 72dfcc0b..f183f71e 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -6,7 +6,7 @@ public class Answer extends Word { public Answer(final Word select) { - this(select.getWord()); + super(select.alphabets()); } public Answer(String word) { diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 25451e96..29f789a8 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -1,11 +1,12 @@ package wordle.domain; public class Guess extends Word { + public Guess(String word) { super(word); } public Guess(Word word) { - this(word.getWord()); + super(word.alphabets()); } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index 8ce33f1f..5a6858ba 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -1,5 +1,6 @@ package wordle.domain; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -8,12 +9,20 @@ public class Word { private List alphabets; + public Word(final List alphabets) { + validate(alphabets); + this.alphabets = alphabets; + } + public Word(String word) { - validate(word); - this.alphabets = word.chars() + this(word.chars() .mapToObj(it -> (char) it) .map(Alphabet::of) - .toList(); + .toList()); + } + + public List alphabets() { + return Collections.unmodifiableList(alphabets); } public String getWord() { @@ -23,8 +32,8 @@ public String getWord() { .toString(); } - private static void validate(final String word) { - if (word.trim().length() != WORD_SIZE) { + private static void validate(final List alphabets) { + if (alphabets.size() != WORD_SIZE) { throw new RuntimeException(); } } From 57f7b06fb40f0d342828974a72a1b4d9491891b4 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 14:37:36 +0900 Subject: [PATCH 46/90] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=20=EB=B0=98=ED=99=98=EC=9D=84=20=EC=95=8C=ED=8C=8C=EB=B2=B3=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A1=9C=EC=A7=81=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Answer.java | 31 ++++++++++++------------- src/test/java/wordle/domain/Guess.java | 6 +++++ src/test/java/wordle/domain/Word.java | 19 +++++++-------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index f183f71e..3f8c0ef9 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -13,31 +13,30 @@ public Answer(String word) { super(word); } - public Result examineResult(Guess guess) { - List resultTypes = IntStream.range(0, guess.getWord().length()) - .mapToObj(i -> examineResultType(guess.getWord(), i)) + public Result examineResult(final Guess guess) { + final List resultTypes = IntStream.range(0, guess.alphabets().size()) + .mapToObj(i -> examineResultType(guess, i)) .toList(); return new Result(resultTypes); } - private ResultType examineResultType(String guess, int index) { - char guessChar = guess.charAt(index); - String answer = getWord(); - - if (guessChar == answer.charAt(index)) + private ResultType examineResultType(Guess guess, int index) { + final Alphabet alphabet = guess.find(index); + if (alphabet == this.find(index)) { return ResultType.MATCHED; - - int answerCount = countChar(answer, guessChar); - int guessCount = countChar(guess.substring(0, index + 1), guessChar); - - if (answerCount >= guessCount) + } + long answerCount = countChar(this, alphabet); + long guessCount = countChar(new Word(guess.subAlphabets(0, index + 1)), alphabet); + if (answerCount >= guessCount) { return ResultType.EXIST; - + } return ResultType.MISMATCHED; } - private int countChar(String string, char ch) { - return (int) string.chars().filter(c -> c == ch).count(); + private long countChar(Word word, Alphabet alphabet) { + return word.alphabets().stream() + .filter(alphabet::equals) + .count(); } } diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 29f789a8..f1dc25b6 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -1,5 +1,7 @@ package wordle.domain; +import java.util.List; + public class Guess extends Word { public Guess(String word) { @@ -9,4 +11,8 @@ public Guess(String word) { public Guess(Word word) { super(word.alphabets()); } + + public List subAlphabets(final int startIndex, final int endIndex) { + return alphabets().subList(startIndex, endIndex); + } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index 5a6858ba..f7f2df87 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -25,19 +25,20 @@ public List alphabets() { return Collections.unmodifiableList(alphabets); } - public String getWord() { - return alphabets.stream() - .map(Alphabet::name) - .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) - .toString(); - } - private static void validate(final List alphabets) { if (alphabets.size() != WORD_SIZE) { throw new RuntimeException(); } } + public boolean isSameWord(final String word) { + return this.equals(new Word(word)); + } + + public Alphabet find(final int index) { + return alphabets.get(index); + } + @Override public boolean equals(final Object o) { if (this == o) return true; @@ -50,8 +51,4 @@ public boolean equals(final Object o) { public int hashCode() { return Objects.hashCode(alphabets); } - - public boolean isSameWord(final String word) { - return this.equals(new Word(word)); - } } From 4a9c8f515ca448215bcbc7df72aad5e662b8d9c8 Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 15 Jun 2024 14:52:58 +0900 Subject: [PATCH 47/90] =?UTF-8?q?fix:=20=EC=8B=9C=EA=B0=84=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EB=8B=B5=EC=95=88=20=EC=84=A0=ED=83=9D=EA=B8=B0=20?= =?UTF-8?q?=EB=8B=B5=EC=95=88=20=EC=84=A0=ED=83=9D=20=EA=B7=9C=EC=B9=99=20?= =?UTF-8?q?=EC=B4=88=EC=97=90=EC=84=9C=20=EC=9D=BC=20=EB=8B=A8=EC=9C=84?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Application.java | 5 ++--- ...erSelector.java => EpochDayBaseAnswerSelector.java} | 10 +++++----- ...orTest.java => EpochDayBaseAnswerSelectorTest.java} | 8 ++++---- 3 files changed, 11 insertions(+), 12 deletions(-) rename src/test/java/wordle/domain/{TimeBaseAnswerSelector.java => EpochDayBaseAnswerSelector.java} (51%) rename src/test/java/wordle/domain/{TimeBaseAnswerSelectorTest.java => EpochDayBaseAnswerSelectorTest.java} (60%) diff --git a/src/test/java/wordle/Application.java b/src/test/java/wordle/Application.java index 2f2735bf..8021daed 100644 --- a/src/test/java/wordle/Application.java +++ b/src/test/java/wordle/Application.java @@ -1,7 +1,6 @@ package wordle; -import wordle.Game; -import wordle.domain.TimeBaseAnswerSelector; +import wordle.domain.EpochDayBaseAnswerSelector; import wordle.domain.WordListFileReader; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; @@ -14,6 +13,6 @@ public static void main(String[] args) { ConsoleOutputView outputView = new ConsoleOutputView(); WordListFileReader answerFileReader = new WordListFileReader(); Game game = new Game(inputView, outputView, answerFileReader); - game.start(new TimeBaseAnswerSelector(LocalDate.now())); + game.start(new EpochDayBaseAnswerSelector(LocalDate.now())); } } diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java similarity index 51% rename from src/test/java/wordle/domain/TimeBaseAnswerSelector.java rename to src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java index a09781b0..85e5129f 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelector.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -2,20 +2,20 @@ import java.time.*; -public class TimeBaseAnswerSelector implements Selector { +public class EpochDayBaseAnswerSelector implements Selector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); private final LocalDate localDate; - public TimeBaseAnswerSelector(final LocalDate localDate) { + public EpochDayBaseAnswerSelector(final LocalDate localDate) { this.localDate = localDate; } @Override public Word select(final WordList wordList) { - final long epochSecond = localDate.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); - final long baseEpochSecond = BASE_LOCAL_DATE.toEpochSecond(LocalTime.of(0, 0), ZoneOffset.UTC); - final long timeDifference = Math.subtractExact(epochSecond, baseEpochSecond); + final long epochDay = localDate.toEpochDay(); + final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); + final long timeDifference = Math.subtractExact(epochDay, baseEpochDay); if (timeDifference < 0) { throw new RuntimeException(); } diff --git a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java b/src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java similarity index 60% rename from src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java rename to src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java index 2f0581ce..a62bd9af 100644 --- a/src/test/java/wordle/domain/TimeBaseAnswerSelectorTest.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java @@ -7,14 +7,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class TimeBaseAnswerSelectorTest { +class EpochDayBaseAnswerSelectorTest { @Test void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { // given - final TimeBaseAnswerSelector answerSelector = new TimeBaseAnswerSelector(LocalDate.of(2024, 6, 9)); - final String expectedWord = "cigar"; - final WordList wordList = new WordList(expectedWord, "apple", "grape", "melon"); + final EpochDayBaseAnswerSelector answerSelector = new EpochDayBaseAnswerSelector(LocalDate.of(2024, 6, 9)); + final String expectedWord = "grape"; + final WordList wordList = new WordList("cigar", "apple", expectedWord, "melon"); // when final Word actual = answerSelector.select(wordList); From 2dcb810d9bf758c177ebf10fce13653aca4f64e5 Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 15 Jun 2024 15:31:34 +0900 Subject: [PATCH 48/90] =?UTF-8?q?wip:=20=EB=8B=A8=EC=96=B4=EC=99=80=20?= =?UTF-8?q?=EC=B6=94=EC=B8=A1=20=EB=B0=8F=20=EB=8B=B5=EC=95=88=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=ED=99=94=20=EB=B6=84=EB=A6=AC=20=EC=A7=84=ED=96=89=20?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/Answer.java | 29 +++++++--- .../java/wordle/domain/DictionaryWord.java | 13 +++++ src/test/java/wordle/domain/GameWord.java | 56 +++++++++++++++++++ src/test/java/wordle/domain/Guess.java | 27 +++++++-- src/test/java/wordle/domain/Word.java | 52 +---------------- src/test/java/wordle/domain/WordList.java | 2 +- 6 files changed, 114 insertions(+), 65 deletions(-) create mode 100644 src/test/java/wordle/domain/DictionaryWord.java create mode 100644 src/test/java/wordle/domain/GameWord.java diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index 3f8c0ef9..2a867549 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -3,18 +3,23 @@ import java.util.List; import java.util.stream.IntStream; -public class Answer extends Word { +public class Answer { + private GameWord compositeWord; - public Answer(final Word select) { - super(select.alphabets()); + public Answer(GameWord word) { + this.compositeWord = word; } public Answer(String word) { - super(word); + this(new GameWord(word)); + } + + public Alphabet find(final int index) { + return compositeWord.find(index); } public Result examineResult(final Guess guess) { - final List resultTypes = IntStream.range(0, guess.alphabets().size()) + final List resultTypes = IntStream.range(0, guess.size()) .mapToObj(i -> examineResultType(guess, i)) .toList(); @@ -26,17 +31,25 @@ private ResultType examineResultType(Guess guess, int index) { if (alphabet == this.find(index)) { return ResultType.MATCHED; } - long answerCount = countChar(this, alphabet); - long guessCount = countChar(new Word(guess.subAlphabets(0, index + 1)), alphabet); + long answerCount = countAlphabets(alphabet, size()); + long guessCount = guess.countAlphabets(alphabet, index + 1); if (answerCount >= guessCount) { return ResultType.EXIST; } return ResultType.MISMATCHED; } - private long countChar(Word word, Alphabet alphabet) { + private long countChar(GameWord word, Alphabet alphabet) { return word.alphabets().stream() .filter(alphabet::equals) .count(); } + + public long countAlphabets(final Alphabet alphabet, final int endIndex) { + return compositeWord.countAlphabets(alphabet, endIndex); + } + + public int size() { + return compositeWord.alphabets().size(); + } } diff --git a/src/test/java/wordle/domain/DictionaryWord.java b/src/test/java/wordle/domain/DictionaryWord.java new file mode 100644 index 00000000..caa6f048 --- /dev/null +++ b/src/test/java/wordle/domain/DictionaryWord.java @@ -0,0 +1,13 @@ +package wordle.domain; + +import java.util.List; + +public class DictionaryWord implements Word { + private String alphabets; + + public DictionaryWord(String alphabets) { + this.alphabets = alphabets; + } + + +} diff --git a/src/test/java/wordle/domain/GameWord.java b/src/test/java/wordle/domain/GameWord.java new file mode 100644 index 00000000..391f6f19 --- /dev/null +++ b/src/test/java/wordle/domain/GameWord.java @@ -0,0 +1,56 @@ +package wordle.domain; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class GameWord implements Word { + public static final int WORD_SIZE = 5; + private List alphabets; + + public GameWord(final List alphabets) { + validate(alphabets); + this.alphabets = alphabets; + } + + public GameWord(String word) { + this(word.chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList()); + } + + private static void validate(final List alphabets) { + if (alphabets.size() != WORD_SIZE) { + throw new RuntimeException(); + } + } + + public Alphabet find(final int index) { + return alphabets.get(index); + } + + public List alphabets() { + return Collections.unmodifiableList(alphabets); + } + + public long countAlphabets(final Alphabet alphabet, final int endIndex) { + return alphabets.subList(0, endIndex) + .stream() + .filter(it -> it.equals(alphabet)) + .count(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GameWord gameWord = (GameWord) o; + return Objects.equals(alphabets, gameWord.alphabets); + } + + @Override + public int hashCode() { + return Objects.hash(alphabets); + } +} diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index f1dc25b6..0524acd1 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -2,17 +2,34 @@ import java.util.List; -public class Guess extends Word { +public class Guess { + private final GameWord compositeWord; + + public Guess(GameWord word) { + this.compositeWord = word; + } + + public Guess(List alphabets) { + this(new GameWord(alphabets)); + } public Guess(String word) { - super(word); + this(new GameWord(word)); } - public Guess(Word word) { - super(word.alphabets()); + public int size() { + return compositeWord.alphabets().size(); } public List subAlphabets(final int startIndex, final int endIndex) { - return alphabets().subList(startIndex, endIndex); + return compositeWord.alphabets().subList(startIndex, endIndex); + } + + public Alphabet find(final int index) { + return compositeWord.find(index); + } + + public long countAlphabets(final Alphabet alphabet, final int endIndex) { + return compositeWord.countAlphabets(alphabet, endIndex); } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index f7f2df87..b243246a 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -1,54 +1,4 @@ package wordle.domain; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class Word { - public static final int WORD_SIZE = 5; - - private List alphabets; - - public Word(final List alphabets) { - validate(alphabets); - this.alphabets = alphabets; - } - - public Word(String word) { - this(word.chars() - .mapToObj(it -> (char) it) - .map(Alphabet::of) - .toList()); - } - - public List alphabets() { - return Collections.unmodifiableList(alphabets); - } - - private static void validate(final List alphabets) { - if (alphabets.size() != WORD_SIZE) { - throw new RuntimeException(); - } - } - - public boolean isSameWord(final String word) { - return this.equals(new Word(word)); - } - - public Alphabet find(final int index) { - return alphabets.get(index); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final Word word = (Word) o; - return Objects.equals(alphabets, word.alphabets); - } - - @Override - public int hashCode() { - return Objects.hashCode(alphabets); - } +public interface Word { } diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 2fb11b00..0774027a 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -27,7 +27,7 @@ public Word select(final Selector selector) { public Word find(final String word) { return wordList.stream() - .filter(it -> it.isSameWord(word)) + .filter(it -> it.equals(word)) .findFirst() .orElseThrow(NoSuchElementException::new); } From 9aa9f6fbf2f6b3012a175d5714646b1d2fc35ac2 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 16:07:52 +0900 Subject: [PATCH 49/90] =?UTF-8?q?wip:=20Word=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 4 +-- src/test/java/wordle/domain/Answer.java | 9 +----- .../java/wordle/domain/DictionaryWord.java | 24 ++++++++++++-- ...ochDayBaseAnswerGameWordSelectorTest.java} | 4 +-- .../domain/EpochDayBaseAnswerSelector.java | 6 ++-- src/test/java/wordle/domain/GameWord.java | 4 +++ .../java/wordle/domain/GameWordSelector.java | 6 ++++ src/test/java/wordle/domain/GameWordTest.java | 31 +++++++++++++++++++ src/test/java/wordle/domain/Guess.java | 6 ++-- src/test/java/wordle/domain/Selector.java | 6 ---- src/test/java/wordle/domain/Word.java | 1 + src/test/java/wordle/domain/WordList.java | 14 +++------ .../wordle/domain/WordListFileReader.java | 2 +- .../wordle/domain/WordListReaderTest.java | 10 +++--- src/test/java/wordle/domain/WordListTest.java | 31 ++----------------- src/test/java/wordle/domain/WordTest.java | 31 ------------------- 16 files changed, 89 insertions(+), 100 deletions(-) rename src/test/java/wordle/domain/{EpochDayBaseAnswerSelectorTest.java => EpochDayBaseAnswerGameWordSelectorTest.java} (85%) create mode 100644 src/test/java/wordle/domain/GameWordSelector.java create mode 100644 src/test/java/wordle/domain/GameWordTest.java delete mode 100644 src/test/java/wordle/domain/Selector.java delete mode 100644 src/test/java/wordle/domain/WordTest.java diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 6b06f16c..9c7ceb17 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -22,9 +22,9 @@ public Game(final InputView inputView, this.wordListReader = wordListReader; } - public void start(final Selector selector) { + public void start(final GameWordSelector gameWordSelector) { final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(selector)); + final Answer answer = new Answer(wordList.select(gameWordSelector)); outputView.welcome(MAX_ATTEMPT); execute(wordList, answer); } diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index 2a867549..8016caaf 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -22,11 +22,10 @@ public Result examineResult(final Guess guess) { final List resultTypes = IntStream.range(0, guess.size()) .mapToObj(i -> examineResultType(guess, i)) .toList(); - return new Result(resultTypes); } - private ResultType examineResultType(Guess guess, int index) { + private ResultType examineResultType(final Guess guess, int index) { final Alphabet alphabet = guess.find(index); if (alphabet == this.find(index)) { return ResultType.MATCHED; @@ -39,12 +38,6 @@ private ResultType examineResultType(Guess guess, int index) { return ResultType.MISMATCHED; } - private long countChar(GameWord word, Alphabet alphabet) { - return word.alphabets().stream() - .filter(alphabet::equals) - .count(); - } - public long countAlphabets(final Alphabet alphabet, final int endIndex) { return compositeWord.countAlphabets(alphabet, endIndex); } diff --git a/src/test/java/wordle/domain/DictionaryWord.java b/src/test/java/wordle/domain/DictionaryWord.java index caa6f048..1a721d01 100644 --- a/src/test/java/wordle/domain/DictionaryWord.java +++ b/src/test/java/wordle/domain/DictionaryWord.java @@ -1,13 +1,33 @@ package wordle.domain; import java.util.List; +import java.util.Objects; public class DictionaryWord implements Word { - private String alphabets; + private final List alphabets; - public DictionaryWord(String alphabets) { + public DictionaryWord(final String alphabets) { + this(alphabets.chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList() + ); + } + + public DictionaryWord(final List alphabets) { this.alphabets = alphabets; } + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final DictionaryWord that = (DictionaryWord) o; + return Objects.equals(alphabets, that.alphabets); + } + @Override + public int hashCode() { + return Objects.hashCode(alphabets); + } } diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java b/src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java similarity index 85% rename from src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java rename to src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java index a62bd9af..e79007f6 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerSelectorTest.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class EpochDayBaseAnswerSelectorTest { +class EpochDayBaseAnswerGameWordSelectorTest { @Test void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { @@ -20,6 +20,6 @@ class EpochDayBaseAnswerSelectorTest { final Word actual = answerSelector.select(wordList); // then - assertEquals(actual, new Word(expectedWord)); + assertEquals(actual, new GameWord(expectedWord)); } } diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java index 85e5129f..ea567aa6 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -2,7 +2,7 @@ import java.time.*; -public class EpochDayBaseAnswerSelector implements Selector { +public class EpochDayBaseAnswerSelector implements GameWordSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); private final LocalDate localDate; @@ -12,13 +12,13 @@ public EpochDayBaseAnswerSelector(final LocalDate localDate) { } @Override - public Word select(final WordList wordList) { + public GameWord select(final WordList wordList) { final long epochDay = localDate.toEpochDay(); final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); final long timeDifference = Math.subtractExact(epochDay, baseEpochDay); if (timeDifference < 0) { throw new RuntimeException(); } - return wordList.get(timeDifference % wordList.size()); + return new GameWord(wordList.get(timeDifference % wordList.size())); } } \ No newline at end of file diff --git a/src/test/java/wordle/domain/GameWord.java b/src/test/java/wordle/domain/GameWord.java index 391f6f19..dc5bba79 100644 --- a/src/test/java/wordle/domain/GameWord.java +++ b/src/test/java/wordle/domain/GameWord.java @@ -20,6 +20,10 @@ public GameWord(String word) { .toList()); } + public GameWord(Word word) { + this(word.toString()); + } + private static void validate(final List alphabets) { if (alphabets.size() != WORD_SIZE) { throw new RuntimeException(); diff --git a/src/test/java/wordle/domain/GameWordSelector.java b/src/test/java/wordle/domain/GameWordSelector.java new file mode 100644 index 00000000..3deaf5bb --- /dev/null +++ b/src/test/java/wordle/domain/GameWordSelector.java @@ -0,0 +1,6 @@ +package wordle.domain; + + +public interface GameWordSelector { + GameWord select(WordList wordList); +} diff --git a/src/test/java/wordle/domain/GameWordTest.java b/src/test/java/wordle/domain/GameWordTest.java new file mode 100644 index 00000000..cc2bfc53 --- /dev/null +++ b/src/test/java/wordle/domain/GameWordTest.java @@ -0,0 +1,31 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class GameWordTest { + + @Test + void 게임_단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { + // given when then + assertThrowsExactly(RuntimeException.class, () -> new GameWord("abcdef")); + } + + @Test + void 게임_단어에_5글자_알파벳_소문자_문자가_들어오면_생성할_수_있다() { + // given + String word = "cigar"; + + assertDoesNotThrow(() -> new GameWord(word)); + } + + @Test + void 게임_단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { + // given + String word = "Cigar"; + + // when & then + assertThrows(RuntimeException.class, () -> new GameWord(word)); + } +} diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 0524acd1..2fce2dc9 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -9,11 +9,11 @@ public Guess(GameWord word) { this.compositeWord = word; } - public Guess(List alphabets) { - this(new GameWord(alphabets)); + public Guess(String word) { + this(new GameWord(word)); } - public Guess(String word) { + public Guess(Word word) { this(new GameWord(word)); } diff --git a/src/test/java/wordle/domain/Selector.java b/src/test/java/wordle/domain/Selector.java deleted file mode 100644 index 19d3436d..00000000 --- a/src/test/java/wordle/domain/Selector.java +++ /dev/null @@ -1,6 +0,0 @@ -package wordle.domain; - - -public interface Selector { - Word select(WordList wordList); -} diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index b243246a..d9550376 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -1,4 +1,5 @@ package wordle.domain; public interface Word { + } diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 0774027a..62e51aab 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -5,24 +5,20 @@ import java.util.NoSuchElementException; public class WordList { - private List wordList; + private List wordList; - public WordList(List wordList) { + public WordList(List wordList) { this.wordList = wordList; } public WordList(final String... words) { this(Arrays.stream(words) - .map(Word::new) + .map(DictionaryWord::new) .toList()); } - public boolean contains(Word word) { - return wordList.contains(word); - } - - public Word select(final Selector selector) { - return selector.select(this); + public GameWord select(final GameWordSelector gameWordSelector) { + return gameWordSelector.select(this); } public Word find(final String word) { diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/test/java/wordle/domain/WordListFileReader.java index 8ebe2b32..83cafa33 100644 --- a/src/test/java/wordle/domain/WordListFileReader.java +++ b/src/test/java/wordle/domain/WordListFileReader.java @@ -14,7 +14,7 @@ private static WordList initializeWordList() { final Path path = Paths.get(FILE_PATH); return new WordList(Files.readAllLines(path) .stream() - .map(Word::new) + .map(DictionaryWord::new) .toList()); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index 2595be6e..21fcdcc4 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -14,14 +14,14 @@ public class WordListReaderTest { WordList wordList = wordListReader.read(); final Word actual = wordList.select(new TestSelector()); - assertEquals(new Word("apple"), actual); + assertEquals(new GameWord("apple"), actual); } - class TestSelector implements Selector { + class TestSelector implements GameWordSelector { @Override - public Word select(final WordList wordList) { - return wordList.get(0); + public GameWord select(final WordList wordList) { + return new GameWord(wordList.get(0)); } } @@ -29,7 +29,7 @@ class TestWordListReader implements WordListReader { @Override public WordList read() { - return new WordList(List.of(new Word("apple"))); + return new WordList(List.of(new DictionaryWord("apple"))); } } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 1398dd83..33d652dd 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -9,38 +9,13 @@ public class WordListTest { - @Test - void 주어진_단어가_wordList_안에_있으면_true를_반환한다() { - // given - Word word = new Word("cigar"); - WordList wordList = new WordList(List.of(new Word("cigar"))); - - // when - boolean actual = wordList.contains(word); - - // then - assertTrue(actual); - } - - @Test - void 주어진_단어가_wordList_안에_없으면_false를_반환한다() { - // given - Word word = new Word("ooooo"); - WordList wordList = new WordList(new ArrayList<>()); - - // when - boolean actual = wordList.contains(word); - - // then - assertFalse(actual); - } @Test void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { - Word word = new Word("cigar"); + DictionaryWord word = new DictionaryWord("cigar"); WordList wordList = new WordList(List.of(word)); - Word actual = wordList.select((it) -> it.get(0)); + GameWord actual = wordList.select((it) -> new GameWord(it.get(0))); assertEquals(actual, word); } @@ -49,6 +24,6 @@ public class WordListTest { void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { WordList wordList = new WordList(List.of()); - assertThrows(RuntimeException.class, () -> wordList.select((it) -> it.get(0))); + assertThrows(RuntimeException.class, () -> wordList.select((it) -> new GameWord(it.get(0)))); } } diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java deleted file mode 100644 index d43a900d..00000000 --- a/src/test/java/wordle/domain/WordTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package wordle.domain; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class WordTest { - - @Test - void 단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { - // given when then - assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); - } - - @Test - void 단어에_5글자_알파벳_소문자_문자가_들어오면_생성할_수_있다() { - // given - String word = "cigar"; - - assertDoesNotThrow(() -> new Word(word)); - } - - @Test - void 단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { - // given - String word = "Cigar"; - - // when & then - assertThrows(RuntimeException.class, () -> new Word(word)); - } -} From fe243e02f1ae8bde5ff9b478064a315614f97a58 Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 15 Jun 2024 16:38:01 +0900 Subject: [PATCH 50/90] =?UTF-8?q?refactor:=20guess=20=EB=B0=8F=20answer=20?= =?UTF-8?q?word=20=ED=95=A9=EC=84=B1=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 4 +- src/test/java/wordle/domain/Answer.java | 14 ++--- .../java/wordle/domain/DictionaryWord.java | 33 ---------- .../domain/EpochDayBaseAnswerSelector.java | 7 ++- ...> EpochDayBaseAnswerWordSelectorTest.java} | 10 +++- src/test/java/wordle/domain/GameWord.java | 60 ------------------- .../java/wordle/domain/GameWordSelector.java | 6 -- src/test/java/wordle/domain/Guess.java | 24 +++----- src/test/java/wordle/domain/Word.java | 52 +++++++++++++++- src/test/java/wordle/domain/WordList.java | 10 ++-- .../wordle/domain/WordListFileReader.java | 2 +- .../wordle/domain/WordListReaderTest.java | 10 ++-- src/test/java/wordle/domain/WordListTest.java | 6 +- src/test/java/wordle/domain/WordSelector.java | 8 +++ .../{GameWordTest.java => WordTest.java} | 8 +-- 15 files changed, 104 insertions(+), 150 deletions(-) delete mode 100644 src/test/java/wordle/domain/DictionaryWord.java rename src/test/java/wordle/domain/{EpochDayBaseAnswerGameWordSelectorTest.java => EpochDayBaseAnswerWordSelectorTest.java} (65%) delete mode 100644 src/test/java/wordle/domain/GameWord.java delete mode 100644 src/test/java/wordle/domain/GameWordSelector.java create mode 100644 src/test/java/wordle/domain/WordSelector.java rename src/test/java/wordle/domain/{GameWordTest.java => WordTest.java} (72%) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 9c7ceb17..9f2d1da2 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -22,9 +22,9 @@ public Game(final InputView inputView, this.wordListReader = wordListReader; } - public void start(final GameWordSelector gameWordSelector) { + public void start(final WordSelector wordSelector) { final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(gameWordSelector)); + final Answer answer = new Answer(wordList.select(wordSelector)); outputView.welcome(MAX_ATTEMPT); execute(wordList, answer); } diff --git a/src/test/java/wordle/domain/Answer.java b/src/test/java/wordle/domain/Answer.java index 8016caaf..79c1215d 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/test/java/wordle/domain/Answer.java @@ -4,18 +4,18 @@ import java.util.stream.IntStream; public class Answer { - private GameWord compositeWord; + private Word word; - public Answer(GameWord word) { - this.compositeWord = word; + public Answer(Word word) { + this.word = word; } public Answer(String word) { - this(new GameWord(word)); + this(new Word(word)); } public Alphabet find(final int index) { - return compositeWord.find(index); + return word.find(index); } public Result examineResult(final Guess guess) { @@ -39,10 +39,10 @@ private ResultType examineResultType(final Guess guess, int index) { } public long countAlphabets(final Alphabet alphabet, final int endIndex) { - return compositeWord.countAlphabets(alphabet, endIndex); + return word.countAlphabets(alphabet, endIndex); } public int size() { - return compositeWord.alphabets().size(); + return word.size(); } } diff --git a/src/test/java/wordle/domain/DictionaryWord.java b/src/test/java/wordle/domain/DictionaryWord.java deleted file mode 100644 index 1a721d01..00000000 --- a/src/test/java/wordle/domain/DictionaryWord.java +++ /dev/null @@ -1,33 +0,0 @@ -package wordle.domain; - -import java.util.List; -import java.util.Objects; - -public class DictionaryWord implements Word { - private final List alphabets; - - public DictionaryWord(final String alphabets) { - this(alphabets.chars() - .mapToObj(it -> (char) it) - .map(Alphabet::of) - .toList() - ); - } - - public DictionaryWord(final List alphabets) { - this.alphabets = alphabets; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final DictionaryWord that = (DictionaryWord) o; - return Objects.equals(alphabets, that.alphabets); - } - - @Override - public int hashCode() { - return Objects.hashCode(alphabets); - } -} diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java index ea567aa6..3cdb624d 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -1,8 +1,9 @@ package wordle.domain; import java.time.*; +import java.util.List; -public class EpochDayBaseAnswerSelector implements GameWordSelector { +public class EpochDayBaseAnswerSelector implements WordSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); private final LocalDate localDate; @@ -12,13 +13,13 @@ public EpochDayBaseAnswerSelector(final LocalDate localDate) { } @Override - public GameWord select(final WordList wordList) { + public Word select(final List wordList) { final long epochDay = localDate.toEpochDay(); final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); final long timeDifference = Math.subtractExact(epochDay, baseEpochDay); if (timeDifference < 0) { throw new RuntimeException(); } - return new GameWord(wordList.get(timeDifference % wordList.size())); + return wordList.get((int) timeDifference % wordList.size()); } } \ No newline at end of file diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java b/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java similarity index 65% rename from src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java rename to src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java index e79007f6..d8c83885 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerGameWordSelectorTest.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java @@ -4,22 +4,26 @@ import org.junit.jupiter.api.Test; import java.time.LocalDate; +import java.util.List; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; -class EpochDayBaseAnswerGameWordSelectorTest { +class EpochDayBaseAnswerWordSelectorTest { @Test void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { // given final EpochDayBaseAnswerSelector answerSelector = new EpochDayBaseAnswerSelector(LocalDate.of(2024, 6, 9)); final String expectedWord = "grape"; - final WordList wordList = new WordList("cigar", "apple", expectedWord, "melon"); + final List wordList = Stream.of("cigar", "apple", expectedWord, "melon") + .map(Word::new) + .toList(); // when final Word actual = answerSelector.select(wordList); // then - assertEquals(actual, new GameWord(expectedWord)); + assertEquals(actual, new Word(expectedWord)); } } diff --git a/src/test/java/wordle/domain/GameWord.java b/src/test/java/wordle/domain/GameWord.java deleted file mode 100644 index dc5bba79..00000000 --- a/src/test/java/wordle/domain/GameWord.java +++ /dev/null @@ -1,60 +0,0 @@ -package wordle.domain; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class GameWord implements Word { - public static final int WORD_SIZE = 5; - private List alphabets; - - public GameWord(final List alphabets) { - validate(alphabets); - this.alphabets = alphabets; - } - - public GameWord(String word) { - this(word.chars() - .mapToObj(it -> (char) it) - .map(Alphabet::of) - .toList()); - } - - public GameWord(Word word) { - this(word.toString()); - } - - private static void validate(final List alphabets) { - if (alphabets.size() != WORD_SIZE) { - throw new RuntimeException(); - } - } - - public Alphabet find(final int index) { - return alphabets.get(index); - } - - public List alphabets() { - return Collections.unmodifiableList(alphabets); - } - - public long countAlphabets(final Alphabet alphabet, final int endIndex) { - return alphabets.subList(0, endIndex) - .stream() - .filter(it -> it.equals(alphabet)) - .count(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GameWord gameWord = (GameWord) o; - return Objects.equals(alphabets, gameWord.alphabets); - } - - @Override - public int hashCode() { - return Objects.hash(alphabets); - } -} diff --git a/src/test/java/wordle/domain/GameWordSelector.java b/src/test/java/wordle/domain/GameWordSelector.java deleted file mode 100644 index 3deaf5bb..00000000 --- a/src/test/java/wordle/domain/GameWordSelector.java +++ /dev/null @@ -1,6 +0,0 @@ -package wordle.domain; - - -public interface GameWordSelector { - GameWord select(WordList wordList); -} diff --git a/src/test/java/wordle/domain/Guess.java b/src/test/java/wordle/domain/Guess.java index 2fce2dc9..93bce471 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/test/java/wordle/domain/Guess.java @@ -1,35 +1,25 @@ package wordle.domain; -import java.util.List; - public class Guess { - private final GameWord compositeWord; + private final Word word; - public Guess(GameWord word) { - this.compositeWord = word; + public Guess(Word word) { + this.word = word; } public Guess(String word) { - this(new GameWord(word)); - } - - public Guess(Word word) { - this(new GameWord(word)); + this(new Word(word)); } public int size() { - return compositeWord.alphabets().size(); - } - - public List subAlphabets(final int startIndex, final int endIndex) { - return compositeWord.alphabets().subList(startIndex, endIndex); + return word.size(); } public Alphabet find(final int index) { - return compositeWord.find(index); + return word.find(index); } public long countAlphabets(final Alphabet alphabet, final int endIndex) { - return compositeWord.countAlphabets(alphabet, endIndex); + return word.countAlphabets(alphabet, endIndex); } } diff --git a/src/test/java/wordle/domain/Word.java b/src/test/java/wordle/domain/Word.java index d9550376..fcd0f521 100644 --- a/src/test/java/wordle/domain/Word.java +++ b/src/test/java/wordle/domain/Word.java @@ -1,5 +1,55 @@ package wordle.domain; -public interface Word { +import java.util.List; +import java.util.Objects; +public class Word { + public static final int WORD_SIZE = 5; + private List alphabets; + + public Word(List alphabets) { + validate(alphabets); + this.alphabets = alphabets; + } + + public Word(String word) { + this(word.chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList()); + } + + private static void validate(final List alphabets) { + if (alphabets.size() != WORD_SIZE) { + throw new RuntimeException(); + } + } + + public int size() { + return alphabets.size(); + } + + public Alphabet find(final int index) { + return alphabets.get(index); + } + + public long countAlphabets(final Alphabet alphabet, final int endIndex) { + return alphabets.subList(0, endIndex) + .stream() + .filter(it -> it.equals(alphabet)) + .count(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Word word = (Word) o; + return Objects.equals(alphabets, word.alphabets); + } + + @Override + public int hashCode() { + return Objects.hash(alphabets); + } } diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index 62e51aab..a385b190 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -5,20 +5,20 @@ import java.util.NoSuchElementException; public class WordList { - private List wordList; + private List wordList; - public WordList(List wordList) { + public WordList(List wordList) { this.wordList = wordList; } public WordList(final String... words) { this(Arrays.stream(words) - .map(DictionaryWord::new) + .map(Word::new) .toList()); } - public GameWord select(final GameWordSelector gameWordSelector) { - return gameWordSelector.select(this); + public Word select(final WordSelector wordSelector) { + return wordSelector.select(wordList); } public Word find(final String word) { diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/test/java/wordle/domain/WordListFileReader.java index 83cafa33..8ebe2b32 100644 --- a/src/test/java/wordle/domain/WordListFileReader.java +++ b/src/test/java/wordle/domain/WordListFileReader.java @@ -14,7 +14,7 @@ private static WordList initializeWordList() { final Path path = Paths.get(FILE_PATH); return new WordList(Files.readAllLines(path) .stream() - .map(DictionaryWord::new) + .map(Word::new) .toList()); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index 21fcdcc4..3375758c 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -14,14 +14,14 @@ public class WordListReaderTest { WordList wordList = wordListReader.read(); final Word actual = wordList.select(new TestSelector()); - assertEquals(new GameWord("apple"), actual); + assertEquals(new Word("apple"), actual); } - class TestSelector implements GameWordSelector { + class TestSelector implements WordSelector { @Override - public GameWord select(final WordList wordList) { - return new GameWord(wordList.get(0)); + public Word select(final List wordList) { + return wordList.get(0); } } @@ -29,7 +29,7 @@ class TestWordListReader implements WordListReader { @Override public WordList read() { - return new WordList(List.of(new DictionaryWord("apple"))); + return new WordList(List.of(new Word("apple"))); } } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 33d652dd..c1ab97a3 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -12,10 +12,10 @@ public class WordListTest { @Test void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { - DictionaryWord word = new DictionaryWord("cigar"); + Word word = new Word("cigar"); WordList wordList = new WordList(List.of(word)); - GameWord actual = wordList.select((it) -> new GameWord(it.get(0))); + Word actual = wordList.select((it) -> it.get(0)); assertEquals(actual, word); } @@ -24,6 +24,6 @@ public class WordListTest { void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { WordList wordList = new WordList(List.of()); - assertThrows(RuntimeException.class, () -> wordList.select((it) -> new GameWord(it.get(0)))); + assertThrows(RuntimeException.class, () -> wordList.select((it) -> it.get(0))); } } diff --git a/src/test/java/wordle/domain/WordSelector.java b/src/test/java/wordle/domain/WordSelector.java new file mode 100644 index 00000000..cad4065a --- /dev/null +++ b/src/test/java/wordle/domain/WordSelector.java @@ -0,0 +1,8 @@ +package wordle.domain; + + +import java.util.List; + +public interface WordSelector { + Word select(List wordList); +} diff --git a/src/test/java/wordle/domain/GameWordTest.java b/src/test/java/wordle/domain/WordTest.java similarity index 72% rename from src/test/java/wordle/domain/GameWordTest.java rename to src/test/java/wordle/domain/WordTest.java index cc2bfc53..9f05df43 100644 --- a/src/test/java/wordle/domain/GameWordTest.java +++ b/src/test/java/wordle/domain/WordTest.java @@ -4,12 +4,12 @@ import static org.junit.jupiter.api.Assertions.*; -public class GameWordTest { +public class WordTest { @Test void 게임_단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { // given when then - assertThrowsExactly(RuntimeException.class, () -> new GameWord("abcdef")); + assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); } @Test @@ -17,7 +17,7 @@ public class GameWordTest { // given String word = "cigar"; - assertDoesNotThrow(() -> new GameWord(word)); + assertDoesNotThrow(() -> new Word(word)); } @Test @@ -26,6 +26,6 @@ public class GameWordTest { String word = "Cigar"; // when & then - assertThrows(RuntimeException.class, () -> new GameWord(word)); + assertThrows(RuntimeException.class, () -> new Word(word)); } } From de3dcd92c971d814e2150b20027f08dcddaa5df0 Mon Sep 17 00:00:00 2001 From: padoling Date: Sat, 15 Jun 2024 16:45:20 +0900 Subject: [PATCH 51/90] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EC=9D=80=20=EB=8B=B5=EC=95=88=EC=9D=B4=20wordList=EC=97=90=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EB=8A=94=EC=A7=80=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=ED=94=BD=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/Game.java | 6 ++---- src/test/java/wordle/domain/WordList.java | 2 +- src/test/java/wordle/view/ConsoleInputView.java | 6 ++++-- src/test/java/wordle/view/ConsoleOutputView.java | 5 ----- src/test/java/wordle/view/InputView.java | 4 +++- src/test/java/wordle/view/OutputView.java | 2 -- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/test/java/wordle/Game.java b/src/test/java/wordle/Game.java index 9f2d1da2..d5eeaede 100644 --- a/src/test/java/wordle/Game.java +++ b/src/test/java/wordle/Game.java @@ -47,10 +47,8 @@ private void examine(final WordList wordList, final Answer answer, final Integer private Guess inputWord(WordList wordList) { try { outputView.insertWord(); - final String wordString = inputView.inputWord(); - Guess guess = new Guess(wordList.find(wordString)); - outputView.insertedWord(wordString); - return guess; + final Word word = inputView.inputWord(); + return new Guess(wordList.find(word)); } catch (final Exception e) { outputView.wrongWord(); return inputWord(wordList); diff --git a/src/test/java/wordle/domain/WordList.java b/src/test/java/wordle/domain/WordList.java index a385b190..8beef281 100644 --- a/src/test/java/wordle/domain/WordList.java +++ b/src/test/java/wordle/domain/WordList.java @@ -21,7 +21,7 @@ public Word select(final WordSelector wordSelector) { return wordSelector.select(wordList); } - public Word find(final String word) { + public Word find(final Word word) { return wordList.stream() .filter(it -> it.equals(word)) .findFirst() diff --git a/src/test/java/wordle/view/ConsoleInputView.java b/src/test/java/wordle/view/ConsoleInputView.java index 0ba5e03d..f78f74c7 100644 --- a/src/test/java/wordle/view/ConsoleInputView.java +++ b/src/test/java/wordle/view/ConsoleInputView.java @@ -1,5 +1,7 @@ package wordle.view; +import wordle.domain.Word; + import java.util.Scanner; public class ConsoleInputView implements InputView { @@ -14,7 +16,7 @@ public ConsoleInputView(final Scanner scanner) { } @Override - public String inputWord() { - return scanner.nextLine(); + public Word inputWord() { + return new Word(scanner.nextLine()); } } \ No newline at end of file diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/test/java/wordle/view/ConsoleOutputView.java index ccd0ab88..550ae92b 100644 --- a/src/test/java/wordle/view/ConsoleOutputView.java +++ b/src/test/java/wordle/view/ConsoleOutputView.java @@ -41,9 +41,4 @@ public void showResults(final Results results, final int attempt, final int maxA System.out.println(resultSentence); } - - @Override - public void insertedWord(final String wordString) { - System.out.println(wordString); - } } \ No newline at end of file diff --git a/src/test/java/wordle/view/InputView.java b/src/test/java/wordle/view/InputView.java index 4f637c75..e1d2c299 100644 --- a/src/test/java/wordle/view/InputView.java +++ b/src/test/java/wordle/view/InputView.java @@ -1,5 +1,7 @@ package wordle.view; +import wordle.domain.Word; + public interface InputView { - String inputWord(); + Word inputWord(); } \ No newline at end of file diff --git a/src/test/java/wordle/view/OutputView.java b/src/test/java/wordle/view/OutputView.java index d07dd007..ce585416 100644 --- a/src/test/java/wordle/view/OutputView.java +++ b/src/test/java/wordle/view/OutputView.java @@ -10,6 +10,4 @@ public interface OutputView { void wrongWord(); void showResults(final Results results, final int attempt, final int maxAttempt); - - void insertedWord(final String wordString); } \ No newline at end of file From ef9b33609021b2e9ebe82d3195b53d5d7871be00 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 16:55:45 +0900 Subject: [PATCH 52/90] =?UTF-8?q?refactor:=20test=20=EC=BD=94=EB=93=9C=20p?= =?UTF-8?q?roduction=20=EC=BD=94=EB=93=9C=EB=A1=9C=20=EC=9D=B4=EA=B4=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/.gitkeep | 0 src/{test => main}/java/wordle/Application.java | 0 src/{test => main}/java/wordle/Game.java | 0 .../java/wordle/domain/Alphabet.java | 0 src/{test => main}/java/wordle/domain/Answer.java | 15 +++++++++------ .../wordle/domain/EpochDayBaseAnswerSelector.java | 2 +- src/{test => main}/java/wordle/domain/Guess.java | 4 ++-- src/{test => main}/java/wordle/domain/Result.java | 6 ++---- .../java/wordle/domain/ResultType.java | 0 .../java/wordle/domain/Results.java | 6 +++--- src/{test => main}/java/wordle/domain/Word.java | 0 .../java/wordle/domain/WordList.java | 0 .../java/wordle/domain/WordListFileReader.java | 0 .../java/wordle/domain/WordListReader.java | 0 .../java/wordle/domain/WordSelector.java | 0 .../java/wordle/view/ConsoleInputView.java | 0 .../java/wordle/view/ConsoleOutputView.java | 0 .../java/wordle/view/InputView.java | 0 .../java/wordle/view/OutputView.java | 0 .../java/wordle/view/ResultColor.java | 0 src/test/java/.gitkeep | 0 .../EpochDayBaseAnswerWordSelectorTest.java | 5 ++--- src/test/java/wordle/domain/WordListTest.java | 4 ++-- 24 files changed, 22 insertions(+), 22 deletions(-) delete mode 100644 src/main/java/.gitkeep rename src/{test => main}/java/wordle/Application.java (100%) rename src/{test => main}/java/wordle/Game.java (100%) rename src/{test => main}/java/wordle/domain/Alphabet.java (100%) rename src/{test => main}/java/wordle/domain/Answer.java (73%) rename src/{test => main}/java/wordle/domain/EpochDayBaseAnswerSelector.java (96%) rename src/{test => main}/java/wordle/domain/Guess.java (85%) rename src/{test => main}/java/wordle/domain/Result.java (82%) rename src/{test => main}/java/wordle/domain/ResultType.java (100%) rename src/{test => main}/java/wordle/domain/Results.java (77%) rename src/{test => main}/java/wordle/domain/Word.java (100%) rename src/{test => main}/java/wordle/domain/WordList.java (100%) rename src/{test => main}/java/wordle/domain/WordListFileReader.java (100%) rename src/{test => main}/java/wordle/domain/WordListReader.java (100%) rename src/{test => main}/java/wordle/domain/WordSelector.java (100%) rename src/{test => main}/java/wordle/view/ConsoleInputView.java (100%) rename src/{test => main}/java/wordle/view/ConsoleOutputView.java (100%) rename src/{test => main}/java/wordle/view/InputView.java (100%) rename src/{test => main}/java/wordle/view/OutputView.java (100%) rename src/{test => main}/java/wordle/view/ResultColor.java (100%) delete mode 100644 src/test/java/.gitkeep diff --git a/README.md b/README.md index d3179421..f5049a57 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ spill ## 🎯 프로그래밍 요구 사항 - JDK 21 버전에서 실행 가능해야 한다. -- 프로그램 실행의 시작점은 `Application`의 `main()`이다. +- 프로그램 실행의 시작점은 `wordle.Application`의 `main()`이다. - `build.gradle` 파일은 변경할 수 없으며, **제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.** - 프로그램 종료 시 `System.exit()`를 호출하지 않는다. - 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/java/wordle/Application.java b/src/main/java/wordle/Application.java similarity index 100% rename from src/test/java/wordle/Application.java rename to src/main/java/wordle/Application.java diff --git a/src/test/java/wordle/Game.java b/src/main/java/wordle/Game.java similarity index 100% rename from src/test/java/wordle/Game.java rename to src/main/java/wordle/Game.java diff --git a/src/test/java/wordle/domain/Alphabet.java b/src/main/java/wordle/domain/Alphabet.java similarity index 100% rename from src/test/java/wordle/domain/Alphabet.java rename to src/main/java/wordle/domain/Alphabet.java diff --git a/src/test/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java similarity index 73% rename from src/test/java/wordle/domain/Answer.java rename to src/main/java/wordle/domain/Answer.java index 79c1215d..d889e305 100644 --- a/src/test/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -4,13 +4,16 @@ import java.util.stream.IntStream; public class Answer { - private Word word; + private static final int START_INDEX = 0; + private static final int EXCLUDE_UNIT = 1; - public Answer(Word word) { + private final Word word; + + public Answer(final Word word) { this.word = word; } - public Answer(String word) { + public Answer(final String word) { this(new Word(word)); } @@ -19,19 +22,19 @@ public Alphabet find(final int index) { } public Result examineResult(final Guess guess) { - final List resultTypes = IntStream.range(0, guess.size()) + final List resultTypes = IntStream.range(START_INDEX, guess.size()) .mapToObj(i -> examineResultType(guess, i)) .toList(); return new Result(resultTypes); } - private ResultType examineResultType(final Guess guess, int index) { + private ResultType examineResultType(final Guess guess, final int index) { final Alphabet alphabet = guess.find(index); if (alphabet == this.find(index)) { return ResultType.MATCHED; } long answerCount = countAlphabets(alphabet, size()); - long guessCount = guess.countAlphabets(alphabet, index + 1); + long guessCount = guess.countAlphabets(alphabet, index + EXCLUDE_UNIT); if (answerCount >= guessCount) { return ResultType.EXIST; } diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java similarity index 96% rename from src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java rename to src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java index 3cdb624d..00498c9f 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -1,6 +1,6 @@ package wordle.domain; -import java.time.*; +import java.time.LocalDate; import java.util.List; public class EpochDayBaseAnswerSelector implements WordSelector { diff --git a/src/test/java/wordle/domain/Guess.java b/src/main/java/wordle/domain/Guess.java similarity index 85% rename from src/test/java/wordle/domain/Guess.java rename to src/main/java/wordle/domain/Guess.java index 93bce471..981a02d3 100644 --- a/src/test/java/wordle/domain/Guess.java +++ b/src/main/java/wordle/domain/Guess.java @@ -3,11 +3,11 @@ public class Guess { private final Word word; - public Guess(Word word) { + public Guess(final Word word) { this.word = word; } - public Guess(String word) { + public Guess(final String word) { this(new Word(word)); } diff --git a/src/test/java/wordle/domain/Result.java b/src/main/java/wordle/domain/Result.java similarity index 82% rename from src/test/java/wordle/domain/Result.java rename to src/main/java/wordle/domain/Result.java index 351f1802..983ef55b 100644 --- a/src/test/java/wordle/domain/Result.java +++ b/src/main/java/wordle/domain/Result.java @@ -3,13 +3,11 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Stream; public class Result { - private List resultTypes; + private final List resultTypes; - public Result(List resultTypes) { + public Result(final List resultTypes) { this.resultTypes = resultTypes; } diff --git a/src/test/java/wordle/domain/ResultType.java b/src/main/java/wordle/domain/ResultType.java similarity index 100% rename from src/test/java/wordle/domain/ResultType.java rename to src/main/java/wordle/domain/ResultType.java diff --git a/src/test/java/wordle/domain/Results.java b/src/main/java/wordle/domain/Results.java similarity index 77% rename from src/test/java/wordle/domain/Results.java rename to src/main/java/wordle/domain/Results.java index f468840b..0fdadf0b 100644 --- a/src/test/java/wordle/domain/Results.java +++ b/src/main/java/wordle/domain/Results.java @@ -4,9 +4,9 @@ import java.util.List; public class Results { - private List results; + private final List results; - public Results(List results) { + public Results(final List results) { this.results = results; } @@ -14,7 +14,7 @@ public boolean hasAnswer() { return results.stream().anyMatch(Result::allMatched); } - public void add(Result result) { + public void add(final Result result) { results.add(result); } diff --git a/src/test/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java similarity index 100% rename from src/test/java/wordle/domain/Word.java rename to src/main/java/wordle/domain/Word.java diff --git a/src/test/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java similarity index 100% rename from src/test/java/wordle/domain/WordList.java rename to src/main/java/wordle/domain/WordList.java diff --git a/src/test/java/wordle/domain/WordListFileReader.java b/src/main/java/wordle/domain/WordListFileReader.java similarity index 100% rename from src/test/java/wordle/domain/WordListFileReader.java rename to src/main/java/wordle/domain/WordListFileReader.java diff --git a/src/test/java/wordle/domain/WordListReader.java b/src/main/java/wordle/domain/WordListReader.java similarity index 100% rename from src/test/java/wordle/domain/WordListReader.java rename to src/main/java/wordle/domain/WordListReader.java diff --git a/src/test/java/wordle/domain/WordSelector.java b/src/main/java/wordle/domain/WordSelector.java similarity index 100% rename from src/test/java/wordle/domain/WordSelector.java rename to src/main/java/wordle/domain/WordSelector.java diff --git a/src/test/java/wordle/view/ConsoleInputView.java b/src/main/java/wordle/view/ConsoleInputView.java similarity index 100% rename from src/test/java/wordle/view/ConsoleInputView.java rename to src/main/java/wordle/view/ConsoleInputView.java diff --git a/src/test/java/wordle/view/ConsoleOutputView.java b/src/main/java/wordle/view/ConsoleOutputView.java similarity index 100% rename from src/test/java/wordle/view/ConsoleOutputView.java rename to src/main/java/wordle/view/ConsoleOutputView.java diff --git a/src/test/java/wordle/view/InputView.java b/src/main/java/wordle/view/InputView.java similarity index 100% rename from src/test/java/wordle/view/InputView.java rename to src/main/java/wordle/view/InputView.java diff --git a/src/test/java/wordle/view/OutputView.java b/src/main/java/wordle/view/OutputView.java similarity index 100% rename from src/test/java/wordle/view/OutputView.java rename to src/main/java/wordle/view/OutputView.java diff --git a/src/test/java/wordle/view/ResultColor.java b/src/main/java/wordle/view/ResultColor.java similarity index 100% rename from src/test/java/wordle/view/ResultColor.java rename to src/main/java/wordle/view/ResultColor.java diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java b/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java index d8c83885..506df648 100644 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java +++ b/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java @@ -1,14 +1,13 @@ package wordle.domain; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.time.LocalDate; import java.util.List; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; - class EpochDayBaseAnswerWordSelectorTest { @Test @@ -24,6 +23,6 @@ class EpochDayBaseAnswerWordSelectorTest { final Word actual = answerSelector.select(wordList); // then - assertEquals(actual, new Word(expectedWord)); + Assertions.assertEquals(actual, new Word(expectedWord)); } } diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index c1ab97a3..354d5aef 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -2,10 +2,10 @@ import org.junit.jupiter.api.Test; -import java.util.ArrayList; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class WordListTest { From 60a0d8ffb0a9a75879eb82a421847fc451e92614 Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 15 Jun 2024 17:06:52 +0900 Subject: [PATCH 53/90] =?UTF-8?q?refactor:=20final=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=A7=80=EC=A0=95=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 8 +++--- src/main/java/wordle/Game.java | 19 +++++++------ src/main/java/wordle/domain/Alphabet.java | 4 +-- .../domain/EpochDayBaseAnswerSelector.java | 12 ++++---- src/main/java/wordle/domain/Results.java | 19 +++++++++++++ src/main/java/wordle/domain/Word.java | 6 ++-- src/main/java/wordle/domain/WordList.java | 28 ++++++++----------- .../java/wordle/domain/WordListReader.java | 1 + src/main/java/wordle/domain/WordSelector.java | 3 +- 9 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index 8021daed..284b9354 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -9,10 +9,10 @@ public class Application { public static void main(String[] args) { - ConsoleInputView inputView = new ConsoleInputView(); - ConsoleOutputView outputView = new ConsoleOutputView(); - WordListFileReader answerFileReader = new WordListFileReader(); - Game game = new Game(inputView, outputView, answerFileReader); + final ConsoleInputView inputView = new ConsoleInputView(); + final ConsoleOutputView outputView = new ConsoleOutputView(); + final WordListFileReader answerFileReader = new WordListFileReader(); + final Game game = new Game(inputView, outputView, answerFileReader); game.start(new EpochDayBaseAnswerSelector(LocalDate.now())); } } diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index d5eeaede..75d22fb0 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -4,10 +4,10 @@ import wordle.view.InputView; import wordle.view.OutputView; -import java.util.ArrayList; import java.util.stream.IntStream; public class Game { + private static final int START_ATTEMPT = 0; private static final int MAX_ATTEMPT = 6; private final InputView inputView; @@ -30,21 +30,22 @@ public void start(final WordSelector wordSelector) { } private void execute(final WordList wordList, final Answer answer) { - Results results = new Results(new ArrayList<>()); - IntStream.range(0, MAX_ATTEMPT) + final Results results = new Results(); + IntStream.range(START_ATTEMPT, MAX_ATTEMPT) .boxed() .takeWhile(attempt -> !results.hasAnswer()) - .forEach(attempt -> examine(wordList, answer, attempt, results)); + .forEach(attempt -> { + results.add(examine(wordList, answer)); + outputView.showResults(results, attempt, MAX_ATTEMPT); + }); } - private void examine(final WordList wordList, final Answer answer, final Integer attempt, final Results results) { + private Result examine(final WordList wordList, final Answer answer) { final Guess guess = inputWord(wordList); - final Result result = answer.examineResult(guess); - results.add(result); - outputView.showResults(results, attempt, MAX_ATTEMPT); + return answer.examineResult(guess); } - private Guess inputWord(WordList wordList) { + private Guess inputWord(final WordList wordList) { try { outputView.insertWord(); final Word word = inputView.inputWord(); diff --git a/src/main/java/wordle/domain/Alphabet.java b/src/main/java/wordle/domain/Alphabet.java index 461a68e5..2750c9bb 100644 --- a/src/main/java/wordle/domain/Alphabet.java +++ b/src/main/java/wordle/domain/Alphabet.java @@ -5,11 +5,11 @@ public enum Alphabet { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; - public static Alphabet of(char alphabet) { + public static Alphabet of(final char alphabet) { return of(String.valueOf(alphabet)); } - public static Alphabet of(String alphabet) { + public static Alphabet of(final String alphabet) { return Arrays.stream(values()) .filter(it -> it.name().equals(alphabet)) .findFirst() diff --git a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java index 00498c9f..7907c89a 100644 --- a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -4,17 +4,19 @@ import java.util.List; public class EpochDayBaseAnswerSelector implements WordSelector { - private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); - private final LocalDate localDate; + private final long epochDay; + + public EpochDayBaseAnswerSelector(final long epochDay) { + this.epochDay = epochDay; + } public EpochDayBaseAnswerSelector(final LocalDate localDate) { - this.localDate = localDate; + this(localDate.toEpochDay()); } @Override public Word select(final List wordList) { - final long epochDay = localDate.toEpochDay(); final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); final long timeDifference = Math.subtractExact(epochDay, baseEpochDay); if (timeDifference < 0) { @@ -22,4 +24,4 @@ public Word select(final List wordList) { } return wordList.get((int) timeDifference % wordList.size()); } -} \ No newline at end of file +} diff --git a/src/main/java/wordle/domain/Results.java b/src/main/java/wordle/domain/Results.java index 0fdadf0b..9cb320cd 100644 --- a/src/main/java/wordle/domain/Results.java +++ b/src/main/java/wordle/domain/Results.java @@ -1,11 +1,17 @@ package wordle.domain; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; public class Results { private final List results; + public Results() { + this(new ArrayList<>()); + } + public Results(final List results) { this.results = results; } @@ -25,4 +31,17 @@ public int size() { public List getResults() { return Collections.unmodifiableList(results); } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Results results1 = (Results) o; + return Objects.equals(getResults(), results1.getResults()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getResults()); + } } diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index fcd0f521..4e354646 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -5,14 +5,14 @@ public class Word { public static final int WORD_SIZE = 5; - private List alphabets; + private final List alphabets; - public Word(List alphabets) { + public Word(final List alphabets) { validate(alphabets); this.alphabets = alphabets; } - public Word(String word) { + public Word(final String word) { this(word.chars() .mapToObj(it -> (char) it) .map(Alphabet::of) diff --git a/src/main/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java index 8beef281..715d73ae 100644 --- a/src/main/java/wordle/domain/WordList.java +++ b/src/main/java/wordle/domain/WordList.java @@ -1,22 +1,16 @@ package wordle.domain; -import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; +import java.util.Objects; public class WordList { - private List wordList; + private final List wordList; - public WordList(List wordList) { + public WordList(final List wordList) { this.wordList = wordList; } - public WordList(final String... words) { - this(Arrays.stream(words) - .map(Word::new) - .toList()); - } - public Word select(final WordSelector wordSelector) { return wordSelector.select(wordList); } @@ -32,14 +26,16 @@ public int size() { return wordList.size(); } - public Word get(final long index) { - return get((int) index); + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final WordList wordList1 = (WordList) o; + return Objects.equals(wordList, wordList1.wordList); } - public Word get(final int index) { - if (wordList.isEmpty()) { - throw new RuntimeException(); - } - return wordList.get(index); + @Override + public int hashCode() { + return Objects.hashCode(wordList); } } diff --git a/src/main/java/wordle/domain/WordListReader.java b/src/main/java/wordle/domain/WordListReader.java index 34dd645c..f92d2f0b 100644 --- a/src/main/java/wordle/domain/WordListReader.java +++ b/src/main/java/wordle/domain/WordListReader.java @@ -1,5 +1,6 @@ package wordle.domain; +@FunctionalInterface public interface WordListReader { WordList read(); } diff --git a/src/main/java/wordle/domain/WordSelector.java b/src/main/java/wordle/domain/WordSelector.java index cad4065a..594086c7 100644 --- a/src/main/java/wordle/domain/WordSelector.java +++ b/src/main/java/wordle/domain/WordSelector.java @@ -3,6 +3,7 @@ import java.util.List; +@FunctionalInterface public interface WordSelector { - Word select(List wordList); + Word select(final List wordList); } From 9d0061575fb9e90654ae75752d0589e7c934733a Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:17:46 +0900 Subject: [PATCH 54/90] =?UTF-8?q?test:=20=EB=8B=B5=EC=95=88=EC=9D=80=205?= =?UTF-8?q?=EA=B8=80=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=88=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index 53e1fb3e..52a2c976 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -1,6 +1,14 @@ package wordle.domain; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + public class GuessTest { + @Test + void 답안은_5글자가_아니면_예외를_발생한다() { + assertThrows(RuntimeException.class, () -> new Guess("abcdef")); + } } From a759ed7d89ede5c9be8c8207cba19ece280a9878 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:19:08 +0900 Subject: [PATCH 55/90] =?UTF-8?q?feat:=20=EB=8B=B5=EC=95=88=EC=9D=80=205?= =?UTF-8?q?=EA=B8=80=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=88=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Word.java | 2 +- src/test/java/wordle/domain/GuessTest.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index 4e354646..01d9ccd3 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -21,7 +21,7 @@ public Word(final String word) { private static void validate(final List alphabets) { if (alphabets.size() != WORD_SIZE) { - throw new RuntimeException(); + throw new IllegalArgumentException("단어는 5글자의 소문자 알파벳으로 이루어져야 합니다"); } } diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index 52a2c976..f16730ad 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -2,13 +2,12 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; public class GuessTest { @Test void 답안은_5글자가_아니면_예외를_발생한다() { - assertThrows(RuntimeException.class, () -> new Guess("abcdef")); + assertThrowsExactly(IllegalArgumentException.class, () -> new Guess("abcdef")); } } - From 3ec118d426034a7b9700b9134d4c9bf0f67a457b Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:21:59 +0900 Subject: [PATCH 56/90] =?UTF-8?q?test:=20=EC=95=8C=ED=8C=8C=EB=B2=B3?= =?UTF-8?q?=EA=B3=BC=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=EA=B0=80=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=98=A4=EB=A9=B4=20=ED=95=B4=EB=8B=B9=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=20=EC=9D=B4=EC=A0=84=EC=9D=98=20=EC=95=8C?= =?UTF-8?q?=ED=8C=8C=EB=B2=B3=20=EA=B0=9C=EC=88=98=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index f16730ad..96178056 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrowsExactly; public class GuessTest { @@ -10,4 +11,12 @@ public class GuessTest { void 답안은_5글자가_아니면_예외를_발생한다() { assertThrowsExactly(IllegalArgumentException.class, () -> new Guess("abcdef")); } + + @Test + void 알파벳과_인덱스가_들어오면_해당_인덱스_이전의_알파벳_개수를_반환한다() { + final Guess guess = new Guess("tasty"); + final long count = guess.countAlphabets(Alphabet.t, 4); + + assertEquals(2, count); + } } From 6c1f76e95053be5f69646bc921e5a4a16b633edc Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:24:32 +0900 Subject: [PATCH 57/90] =?UTF-8?q?feat:=20=EC=95=8C=ED=8C=8C=EB=B2=B3?= =?UTF-8?q?=EA=B3=BC=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=EA=B0=80=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=98=A4=EB=A9=B4=20=ED=95=B4=EB=8B=B9=20=EC=9D=B8?= =?UTF-8?q?=EB=8D=B1=EC=8A=A4=20=EC=9D=B4=EC=A0=84=EC=9D=98=20=EC=95=8C?= =?UTF-8?q?=ED=8C=8C=EB=B2=B3=20=EA=B0=9C=EC=88=98=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Word.java | 3 +++ src/test/java/wordle/domain/GuessTest.java | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index 01d9ccd3..96ae473c 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -34,6 +34,9 @@ public Alphabet find(final int index) { } public long countAlphabets(final Alphabet alphabet, final int endIndex) { + if (endIndex > alphabets.size()) { + throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); + } return alphabets.subList(0, endIndex) .stream() .filter(it -> it.equals(alphabet)) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index 96178056..f6bd8231 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -19,4 +19,11 @@ public class GuessTest { assertEquals(2, count); } + + @Test + void 답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { + final Guess guess = new Guess("tasty"); + + assertThrowsExactly(IllegalArgumentException.class, () -> guess.countAlphabets(Alphabet.t, 6)); + } } From 63e9340ee9485f9206aa628d058af911801736e8 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:25:41 +0900 Subject: [PATCH 58/90] =?UTF-8?q?refactor:=20=EC=9D=B8=EB=8D=B1=EC=8A=A4?= =?UTF-8?q?=20=EA=B8=B8=EC=9D=B4=20=EC=83=81=EC=88=98=ED=99=94=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Word.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index 96ae473c..c20fc576 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -4,7 +4,8 @@ import java.util.Objects; public class Word { - public static final int WORD_SIZE = 5; + private static final int FROM_INDEX = 0; + private static final int WORD_SIZE = 5; private final List alphabets; public Word(final List alphabets) { @@ -33,11 +34,11 @@ public Alphabet find(final int index) { return alphabets.get(index); } - public long countAlphabets(final Alphabet alphabet, final int endIndex) { - if (endIndex > alphabets.size()) { + public long countAlphabets(final Alphabet alphabet, final int toIndex) { + if (toIndex > alphabets.size()) { throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); } - return alphabets.subList(0, endIndex) + return alphabets.subList(FROM_INDEX, toIndex) .stream() .filter(it -> it.equals(alphabet)) .count(); From 58f7569b6ec592536d56dd936e173530ee18162f Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:26:44 +0900 Subject: [PATCH 59/90] =?UTF-8?q?test:=20=EC=9D=B8=EB=8D=B1=EC=8A=A4?= =?UTF-8?q?=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=EC=9D=98=20=EC=95=8C?= =?UTF-8?q?=ED=8C=8C=EB=B2=B3=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index f6bd8231..c14f7fc0 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -26,4 +26,13 @@ public class GuessTest { assertThrowsExactly(IllegalArgumentException.class, () -> guess.countAlphabets(Alphabet.t, 6)); } + + @Test + void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { + final Guess guess = new Guess("tasty"); + + final Alphabet alphabet = guess.find(0); + + assertEquals(alphabet, Alphabet.t); + } } From 50d084fdae8a7a911de3a7477ee62707dc749b37 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:29:14 +0900 Subject: [PATCH 60/90] =?UTF-8?q?test:=20=EC=95=8C=ED=8C=8C=EB=B2=B3=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=8B=B5=EC=95=88=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=EB=B3=B4=EB=8B=A4=20=EA=B8=B4=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Word.java | 7 +++++-- src/test/java/wordle/domain/GuessTest.java | 10 ++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index c20fc576..d816ad14 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -4,7 +4,7 @@ import java.util.Objects; public class Word { - private static final int FROM_INDEX = 0; + private static final int MINIMUM_INDEX = 0; private static final int WORD_SIZE = 5; private final List alphabets; @@ -31,6 +31,9 @@ public int size() { } public Alphabet find(final int index) { + if(index < MINIMUM_INDEX || index >= alphabets.size()) { + throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); + } return alphabets.get(index); } @@ -38,7 +41,7 @@ public long countAlphabets(final Alphabet alphabet, final int toIndex) { if (toIndex > alphabets.size()) { throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); } - return alphabets.subList(FROM_INDEX, toIndex) + return alphabets.subList(MINIMUM_INDEX, toIndex) .stream() .filter(it -> it.equals(alphabet)) .count(); diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index c14f7fc0..a63cdfca 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -2,8 +2,7 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.*; public class GuessTest { @@ -35,4 +34,11 @@ public class GuessTest { assertEquals(alphabet, Alphabet.t); } + + @Test + void 알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { + final Guess guess = new Guess("tasty"); + + assertThrows(IllegalArgumentException.class, () -> guess.find(5)); + } } From d7ac95ef8361aafb2c6b1f29b4c0fe9e1923b3cb Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:50:48 +0900 Subject: [PATCH 61/90] =?UTF-8?q?refactor:=20Java=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=BB=A8=EB=B2=A4=EC=85=98=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?=EC=9D=BC=EB=B6=80=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 2 +- src/main/java/wordle/Game.java | 7 +---- src/main/java/wordle/domain/Answer.java | 4 +-- .../domain/EpochDayBaseAnswerSelector.java | 15 +++------- src/main/java/wordle/domain/Results.java | 3 +- src/main/java/wordle/domain/Word.java | 2 +- src/main/java/wordle/domain/WordList.java | 4 +-- .../wordle/domain/WordListFileReader.java | 6 ++-- .../java/wordle/view/ConsoleInputView.java | 2 +- .../java/wordle/view/ConsoleOutputView.java | 25 ++++++++++------- src/main/java/wordle/view/InputView.java | 2 +- src/main/java/wordle/view/OutputView.java | 2 +- src/main/java/wordle/view/ResultColor.java | 21 +++++++------- .../EpochDayBaseAnswerWordSelectorTest.java | 28 ------------------- 14 files changed, 45 insertions(+), 78 deletions(-) delete mode 100644 src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index 284b9354..6f1114ae 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -13,6 +13,6 @@ public static void main(String[] args) { final ConsoleOutputView outputView = new ConsoleOutputView(); final WordListFileReader answerFileReader = new WordListFileReader(); final Game game = new Game(inputView, outputView, answerFileReader); - game.start(new EpochDayBaseAnswerSelector(LocalDate.now())); + game.start(new EpochDayBaseAnswerSelector()); } } diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 75d22fb0..17116fa3 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -49,15 +49,10 @@ private Guess inputWord(final WordList wordList) { try { outputView.insertWord(); final Word word = inputView.inputWord(); - return new Guess(wordList.find(word)); + return new Guess(wordList.getWordIfExists(word)); } catch (final Exception e) { outputView.wrongWord(); return inputWord(wordList); } } } - - - - - diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index d889e305..d05ff341 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -33,8 +33,8 @@ private ResultType examineResultType(final Guess guess, final int index) { if (alphabet == this.find(index)) { return ResultType.MATCHED; } - long answerCount = countAlphabets(alphabet, size()); - long guessCount = guess.countAlphabets(alphabet, index + EXCLUDE_UNIT); + final long answerCount = countAlphabets(alphabet, size()); + final long guessCount = guess.countAlphabets(alphabet, Math.addExact(index, EXCLUDE_UNIT)); if (answerCount >= guessCount) { return ResultType.EXIST; } diff --git a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java index 7907c89a..b202f367 100644 --- a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -5,22 +5,15 @@ public class EpochDayBaseAnswerSelector implements WordSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); - private final long epochDay; - - public EpochDayBaseAnswerSelector(final long epochDay) { - this.epochDay = epochDay; - } - - public EpochDayBaseAnswerSelector(final LocalDate localDate) { - this(localDate.toEpochDay()); - } @Override public Word select(final List wordList) { + final LocalDate now = LocalDate.now(); + final long nowEpochDay = now.toEpochDay(); final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); - final long timeDifference = Math.subtractExact(epochDay, baseEpochDay); + final long timeDifference = Math.subtractExact(nowEpochDay, baseEpochDay); if (timeDifference < 0) { - throw new RuntimeException(); + throw new RuntimeException("시간 차이가 음수로 나와서 단어를 선택할 수 없습니다"); } return wordList.get((int) timeDifference % wordList.size()); } diff --git a/src/main/java/wordle/domain/Results.java b/src/main/java/wordle/domain/Results.java index 9cb320cd..7174c388 100644 --- a/src/main/java/wordle/domain/Results.java +++ b/src/main/java/wordle/domain/Results.java @@ -17,7 +17,8 @@ public Results(final List results) { } public boolean hasAnswer() { - return results.stream().anyMatch(Result::allMatched); + return results.stream() + .anyMatch(Result::allMatched); } public void add(final Result result) { diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index d816ad14..92e0ce3c 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -31,7 +31,7 @@ public int size() { } public Alphabet find(final int index) { - if(index < MINIMUM_INDEX || index >= alphabets.size()) { + if (index < MINIMUM_INDEX || index >= alphabets.size()) { throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); } return alphabets.get(index); diff --git a/src/main/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java index 715d73ae..bf0ab154 100644 --- a/src/main/java/wordle/domain/WordList.java +++ b/src/main/java/wordle/domain/WordList.java @@ -15,9 +15,9 @@ public Word select(final WordSelector wordSelector) { return wordSelector.select(wordList); } - public Word find(final Word word) { + public Word getWordIfExists(final Word word) { return wordList.stream() - .filter(it -> it.equals(word)) + .filter(word::equals) .findFirst() .orElseThrow(NoSuchElementException::new); } diff --git a/src/main/java/wordle/domain/WordListFileReader.java b/src/main/java/wordle/domain/WordListFileReader.java index 8ebe2b32..22088ddc 100644 --- a/src/main/java/wordle/domain/WordListFileReader.java +++ b/src/main/java/wordle/domain/WordListFileReader.java @@ -7,12 +7,12 @@ public class WordListFileReader implements WordListReader { private static final String FILE_PATH = "src/main/resources/words.txt"; - private static final WordList wordList = initializeWordList(); + private static final WordList wordList; - private static WordList initializeWordList() { + static { try { final Path path = Paths.get(FILE_PATH); - return new WordList(Files.readAllLines(path) + wordList = new WordList(Files.readAllLines(path) .stream() .map(Word::new) .toList()); diff --git a/src/main/java/wordle/view/ConsoleInputView.java b/src/main/java/wordle/view/ConsoleInputView.java index f78f74c7..7220e330 100644 --- a/src/main/java/wordle/view/ConsoleInputView.java +++ b/src/main/java/wordle/view/ConsoleInputView.java @@ -19,4 +19,4 @@ public ConsoleInputView(final Scanner scanner) { public Word inputWord() { return new Word(scanner.nextLine()); } -} \ No newline at end of file +} diff --git a/src/main/java/wordle/view/ConsoleOutputView.java b/src/main/java/wordle/view/ConsoleOutputView.java index 550ae92b..05988029 100644 --- a/src/main/java/wordle/view/ConsoleOutputView.java +++ b/src/main/java/wordle/view/ConsoleOutputView.java @@ -1,5 +1,6 @@ package wordle.view; +import wordle.domain.Result; import wordle.domain.Results; import java.util.stream.Collectors; @@ -8,8 +9,10 @@ public class ConsoleOutputView implements OutputView { private static final String WELCOME_MESSAGE = "WORDLE을 %s번 만에 맞춰 보세요."; private static final String RESULT_DESCRIPTION_MESSAGE = "시도의 결과는 타일의 색 변화로 나타납니다."; - public static final String INSERT_ANSWER_MESSAGE = "정답을 입력해 주세요."; - public static final String WRONG_WORD_MESSAGE = "단어가 올바르지 않습니다."; + private static final String INSERT_ANSWER_MESSAGE = "정답을 입력해 주세요."; + private static final String WRONG_WORD_MESSAGE = "단어가 올바르지 않습니다."; + private static final String NEW_LINE = "\n"; + private static final String ATTEMPT_RESULT = "%s/%s"; @Override public void welcome(final int maxAttempt) { @@ -30,15 +33,17 @@ public void wrongWord() { @Override public void showResults(final Results results, final int attempt, final int maxAttempt) { if (results.hasAnswer() || attempt == maxAttempt) { - System.out.println("%s/%s".formatted(results.size(), maxAttempt)); + System.out.println(ATTEMPT_RESULT.formatted(results.size(), maxAttempt)); } - final String resultSentence = results.getResults().stream() - .map(it -> it.getResult().stream() - .map(ResultColor::color) - .collect(Collectors.joining()) - ).collect(Collectors.joining("\n")); - + .map(this::color) + .collect(Collectors.joining(NEW_LINE)); System.out.println(resultSentence); } -} \ No newline at end of file + + private String color(final Result result) { + return result.getResult().stream() + .map(ResultColor::color) + .collect(Collectors.joining()); + } +} diff --git a/src/main/java/wordle/view/InputView.java b/src/main/java/wordle/view/InputView.java index e1d2c299..6cd571f7 100644 --- a/src/main/java/wordle/view/InputView.java +++ b/src/main/java/wordle/view/InputView.java @@ -4,4 +4,4 @@ public interface InputView { Word inputWord(); -} \ No newline at end of file +} diff --git a/src/main/java/wordle/view/OutputView.java b/src/main/java/wordle/view/OutputView.java index ce585416..f091793d 100644 --- a/src/main/java/wordle/view/OutputView.java +++ b/src/main/java/wordle/view/OutputView.java @@ -10,4 +10,4 @@ public interface OutputView { void wrongWord(); void showResults(final Results results, final int attempt, final int maxAttempt); -} \ No newline at end of file +} diff --git a/src/main/java/wordle/view/ResultColor.java b/src/main/java/wordle/view/ResultColor.java index 71f91d00..fe6f1b5c 100644 --- a/src/main/java/wordle/view/ResultColor.java +++ b/src/main/java/wordle/view/ResultColor.java @@ -2,25 +2,26 @@ import wordle.domain.ResultType; +import java.util.Arrays; + public enum ResultColor { GREEN(ResultType.MATCHED, "🟩"), YELLOW(ResultType.EXIST, "🟨"), WHITE(ResultType.MISMATCHED, "⬜"); - private ResultType resultType; - private String color; + private final ResultType resultType; + private final String color; - ResultColor(ResultType resultType, String color) { + ResultColor(final ResultType resultType, final String color) { this.resultType = resultType; this.color = color; } - public static String color(ResultType resultType) { - for (ResultColor resultColor : ResultColor.values()) { - if (resultColor.resultType == resultType) { - return resultColor.color; - } - } - return WHITE.color; + public static String color(final ResultType resultType) { + return Arrays.stream(ResultColor.values()) + .filter(it -> it.resultType == resultType) + .map(it -> it.color) + .findFirst() + .orElseGet(() -> WHITE.color); } } diff --git a/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java b/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java deleted file mode 100644 index 506df648..00000000 --- a/src/test/java/wordle/domain/EpochDayBaseAnswerWordSelectorTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package wordle.domain; - - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.time.LocalDate; -import java.util.List; -import java.util.stream.Stream; - -class EpochDayBaseAnswerWordSelectorTest { - - @Test - void 날짜_기반_단어_선택기는_주어진_날짜를_기준으로_단어를_선택할_수_있다() { - // given - final EpochDayBaseAnswerSelector answerSelector = new EpochDayBaseAnswerSelector(LocalDate.of(2024, 6, 9)); - final String expectedWord = "grape"; - final List wordList = Stream.of("cigar", "apple", expectedWord, "melon") - .map(Word::new) - .toList(); - - // when - final Word actual = answerSelector.select(wordList); - - // then - Assertions.assertEquals(actual, new Word(expectedWord)); - } -} From d32d773cb97bf8c896e3b193d2f7a33a466ee5fc Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:53:44 +0900 Subject: [PATCH 62/90] =?UTF-8?q?test:=20=EA=B2=B0=EA=B3=BC=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=9E=88=EB=8B=A4?= =?UTF-8?q?=EB=A9=B4=20=EA=B0=9C=EC=88=98=EB=A5=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultsTest.java | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/test/java/wordle/domain/ResultsTest.java b/src/test/java/wordle/domain/ResultsTest.java index 46397265..4b4b55ae 100644 --- a/src/test/java/wordle/domain/ResultsTest.java +++ b/src/test/java/wordle/domain/ResultsTest.java @@ -4,11 +4,29 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class ResultsTest { + @Test + void 결과들을_가지고_있다면_개수를_반환할_수_있다() { + // given + List resultList = List.of( + new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)) + ); + Results results = new Results(resultList); + + // when + final int actual = results.size(); + + // then + assertEquals(actual, 4); + } + + @Test void 문자가_모두_일치하는_결과가_있는_경우_true를_반환한다() { // given From 3178ff52ec2415815f16fc3a6c8c41ed9871bd2b Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:56:01 +0900 Subject: [PATCH 63/90] =?UTF-8?q?test:=20=EC=A0=95=EB=8B=B5=EC=9D=80=205?= =?UTF-8?q?=EA=B8=80=EC=9E=90=EA=B0=80=20=EC=95=84=EB=8B=88=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index 906f4325..de811848 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -4,7 +4,7 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; public class AnswerTest { @@ -22,4 +22,9 @@ public class AnswerTest { // then assertEquals(result, expectedResult); } + + @Test + void 정답은_5글자가_아니면_예외를_발생한다() { + assertThrowsExactly(IllegalArgumentException.class, () -> new Answer("abcdef")); + } } From a955693465b1a08bbefc773991e82f4cdb06df05 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:56:23 +0900 Subject: [PATCH 64/90] =?UTF-8?q?test:=20=EC=A0=95=EB=8B=B5=EC=9D=80=20?= =?UTF-8?q?=EC=95=8C=ED=8C=8C=EB=B2=B3=EA=B3=BC=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=ED=95=B4=EB=8B=B9=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=EC=9D=98=20=EC=95=8C=ED=8C=8C=EB=B2=B3=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index de811848..a2bf3d72 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -27,4 +27,13 @@ public class AnswerTest { void 정답은_5글자가_아니면_예외를_발생한다() { assertThrowsExactly(IllegalArgumentException.class, () -> new Answer("abcdef")); } + + + @Test + void 알파벳과_인덱스가_들어오면_해당_인덱스_이전의_알파벳_개수를_반환한다() { + final Answer answer = new Answer("tasty"); + final long count = answer.countAlphabets(Alphabet.t, 4); + + assertEquals(2, count); + } } From 05ba0a5161220a8d78e0a0faa36100f454baccb9 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:56:52 +0900 Subject: [PATCH 65/90] =?UTF-8?q?test:=20=EB=8B=B5=EC=95=88=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=EB=B3=B4=EB=8B=A4=20=EA=B8=B4=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index a2bf3d72..449b0126 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -36,4 +36,13 @@ public class AnswerTest { assertEquals(2, count); } + + + @Test + void 답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { + final Answer answer = new Answer("tasty"); + + assertThrowsExactly(IllegalArgumentException.class, () -> answer.countAlphabets(Alphabet.t, 6)); + } + } From fbda6b0ce711be7c804186750374da74d15dab12 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:57:19 +0900 Subject: [PATCH 66/90] =?UTF-8?q?test:=20=EC=9D=B8=EB=8D=B1=EC=8A=A4?= =?UTF-8?q?=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=EC=9D=98=20=EC=95=8C?= =?UTF-8?q?=ED=8C=8C=EB=B2=B3=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index 449b0126..e4634d47 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -45,4 +45,13 @@ public class AnswerTest { assertThrowsExactly(IllegalArgumentException.class, () -> answer.countAlphabets(Alphabet.t, 6)); } + + @Test + void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { + final Answer answer = new Answer("tasty"); + + final Alphabet alphabet = answer.find(0); + + assertEquals(alphabet, Alphabet.t); + } } From 440362873109b4c3fedb1975bd531b3c2f939c02 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 20:57:36 +0900 Subject: [PATCH 67/90] =?UTF-8?q?test:=20=EC=95=8C=ED=8C=8C=EB=B2=B3=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=8B=B5=EC=95=88=20=EA=B8=B8?= =?UTF-8?q?=EC=9D=B4=EB=B3=B4=EB=8B=A4=20=EA=B8=B4=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EA=B0=80=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EB=A5=BC=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index e4634d47..767f99ed 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -54,4 +54,11 @@ public class AnswerTest { assertEquals(alphabet, Alphabet.t); } + + @Test + void 알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { + final Answer answer = new Answer("tasty"); + + assertThrows(IllegalArgumentException.class, () -> answer.find(5)); + } } From f6fc5146d7592c344791da47b9ea38e034478d1b Mon Sep 17 00:00:00 2001 From: padoling Date: Mon, 17 Jun 2024 20:58:07 +0900 Subject: [PATCH 68/90] =?UTF-8?q?docs:=20README=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 241 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 161 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index f5049a57..7f938f82 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,170 @@ # 미션 - 워들 -## 🔍 진행 방식 - -- 미션은 **과제 진행 요구 사항**, **기능 요구 사항**, **프로그래밍 요구 사항** 세 가지로 구성되어 있다. -- 세 개의 요구 사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다. -- **기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다.** - ---- - -## 🚀 기능 요구 사항 - -선풍적인 인기를 끌었던 영어 단어 맞추기 게임이다. - -- 6x5 격자를 통해서 5글자 단어를 6번 만에 추측한다. -- 플레이어가 답안을 제출하면 프로그램이 정답과 제출된 단어의 각 알파벳 종류와 위치를 비교해 판별한다. -- 판별 결과는 흰색의 타일이 세 가지 색(초록색/노란색/회색) 중 하나로 바뀌면서 표현된다. - - 맞는 글자는 초록색, 위치가 틀리면 노란색, 없으면 회색 - - 두 개의 동일한 문자를 입력하고 그중 하나가 회색으로 표시되면 해당 문자 중 하나만 최종 단어에 나타난다. -- 정답과 답안은 `words.txt`에 존재하는 단어여야 한다. -- 정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다. - -### 입출력 요구 사항 - -#### 실행 결과 예시 - +## 시퀀스 다이어그램 +```mermaid +sequenceDiagram +actor User +participant OutputView +participant InputView +participant Game +Note right of Game: 게임 시작 + +Game ->> OutputView: User 에게 환영 문구를 보여줘라 +OutputView ->> User: WORDLE을 6번 만에 맞춰 보세요.
시도의 결과는 타일의 색 변화로 나타납니다. +Game ->> WordListReader: 사전 요청 +WordListReader ->> Game: 사전 응답 +Game ->> WordList: 정답 요청 +WordList ->> Game: 정답 응답 +loop 게임시작 6라운드 +loop 단어 검증 +Game ->> OutputView: 정답 입력 문구를 보여줘라 +OutputView ->> User: 정답을 입력해 주세요. +User ->> InputView: 예상 단어 입력 +InputView->>Game: 예상 단어 입력 +activate Game +Game->>WordList: 단어 확인 +WordList->>Game: 단어 확인 결과 +alt is 잘못된 단어 +Game ->> OutputView: 잘못된 단어라고 알려줘라 +OutputView ->> User: 잘못된 단어를 입력하셨습니다. +else is 올바른 단어 +end +end +Game ->> Word: 정답인지 확인해라 +Word ->> Answer: 체점해줘 +Answer ->> Word: 체점완료 +Word ->> Game: 정답 결과 반환 +Game ->> Results: 정답인가? +Results ->> Game: 정답여부 반환 + + break when Results 가 정답일 경우 + Game ->> OutputView: 결과를 화면에 나타내라 + OutputView ->> User: 4/6
[1][1][1][1][1][1] + Note right of Game: 게임 종료 +end +Game ->> Results: 기회를 다 사용했는가? +Results ->> Game: 기회 사용 여부 반환 +break when 기회를 다 사용했다면 +Game ->> OutputView: 결과를 화면에 나타내라 +OutputView ->> User: 6/6
[1][1][1][1][1][0] +Note right of Game: 게임 종료 +end +deactivate Game +end ``` -WORDLE을 6번 만에 맞춰 보세요. -시도의 결과는 타일의 색 변화로 나타납니다. -정답을 입력해 주세요. -hello -⬜⬜🟨🟩⬜ - -정답을 입력해 주세요. -label - -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 - -정답을 입력해 주세요. -spell - -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 -🟩🟩⬜🟩🟩 - -정답을 입력해 주세요. -spill - -4/6 +## 클래스 설계 + +### view + +```mermaid +classDiagram + class Game { + start() + } + class InputView { + Scanner scanner + Word inputWord() + } + class OutputView { + void welcome() + void insertWord() + void wrongWord() + void showResults(Results results) + } + class enum ResultColor { + String color // 🟩, 🟨, ⬜ + ResultType type + + String color(ResultType type) + } +``` -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 -🟩🟩⬜🟩🟩 -🟩🟩🟩🟩🟩 +### Word + +```mermaid +classDiagram + Answer -- WordSelector + class Word { + List alphabets + } + Word -- Alphabet + class Alphabet { + + } + Word <|-- Answer + class Answer { + Word word + Result examineResult(Guess guess) + } + class EpochDayBaseAnswerSelector { + Word select() + } + class WordSelector { + Word select() + } + WordSelector <|-- EpochDayBaseAnswerSelector + + Word <|-- Guess + class Guess { + Word word + } + + class WordList { + Word find(Word word) + Word select(Selector selector) + } + + class WordListReader { + WordList read() + } + class WordListFileReader { + WordList read() + } + WordListReader <|-- WordListFileReader + WordList -- WordListReader ``` +### Result + +```mermaid +classDiagram + class Result { + List resultTypes + boolean allMatched() + } + + class Results { + List resultList + boolean hasAnswer() + } + + class enum ResultType { + char type // MATCHED, EXIST, MISMATCHED + } +``` --- -## 🎯 프로그래밍 요구 사항 - -- JDK 21 버전에서 실행 가능해야 한다. -- 프로그램 실행의 시작점은 `wordle.Application`의 `main()`이다. -- `build.gradle` 파일은 변경할 수 없으며, **제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.** -- 프로그램 종료 시 `System.exit()`를 호출하지 않는다. -- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. -- 자바 코드 컨벤션을 지키면서 프로그래밍한다. - - 기본적으로 [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)를 원칙으로 한다. - - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. -- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다. - - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. - - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. -- 3항 연산자를 쓰지 않는다. -- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. -- JUnit 5와 AssertJ를 이용하여 정리한 기능 목록이 정상적으로 작동하는지 테스트 코드로 확인한다. - - 테스트 도구 사용법이 익숙하지 않다면 아래 문서를 참고하여 학습한 후 테스트를 구현한다. - - [JUnit 5 User Guide](https://junit.org/junit5/docs/current/user-guide) - - [AssertJ User Guide](https://assertj.github.io/doc) - - [AssertJ Exception Assertions](https://www.baeldung.com/assertj-exception-assertion) - - [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) -- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다. - - 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다. -- else 예약어를 쓰지 않는다. - - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. - - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. -- 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. - - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. - - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다. +## 테스트케이스 + +- Game + - [x] 게임은 지정된 횟수만큼 입력받고 종료된다. +- Word + - [x] 단어에 알파벳 소문자가 아닌 문자가 들어오면 예외를 반환한다. + - [x] 단어는 5글자이다. + - [x] 단어가 5글자가 아니면 예외를 반환한다. +- Answer + - [x] 정답은 답안을 기반으로 결과를 반환할 수 있다. +- AnswerSelector + - [x] 정답은 매일 바뀌며 `((현재 날짜 - 2021년 6월 19일) % 배열의 크기)` 번째의 단어이다. +- WordList + - [x] 주어진 단어가 WordList 안에 있으면 true를 반환한다. + - [x] 주어진 단어가 WordList 안에 없으면 false를 반환한다. + - [x] 주어진 Selector의 조건에 해당하는 단어를 추출한다. +- Result + - [x] 판별 결과는 세 가지 색(초록색/노란색/회색) 중 하나로 표현되어야 한다. +- Results + - [x] 정답을 포함하고 있는 경우 true를 반환한다. + - [x] 정답을 포함하고 있지 않은 경우 false를 반환한다. + +--- \ No newline at end of file From db80ad720b4a0082eb23d1cb5c9d8ae9f3dcd2d4 Mon Sep 17 00:00:00 2001 From: padoling Date: Mon, 17 Jun 2024 21:01:06 +0900 Subject: [PATCH 69/90] =?UTF-8?q?docs:=20README=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f938f82..6eb4a1c8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # 미션 - 워들 +- 참여자 : 우지, 구월 ## 시퀀스 다이어그램 ```mermaid @@ -53,6 +54,8 @@ deactivate Game end ``` +--- + ## 클래스 설계 ### view @@ -166,5 +169,3 @@ classDiagram - Results - [x] 정답을 포함하고 있는 경우 true를 반환한다. - [x] 정답을 포함하고 있지 않은 경우 false를 반환한다. - ---- \ No newline at end of file From d0ac6e80395316230ab16549766caa1193b923bf Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 21:01:08 +0900 Subject: [PATCH 70/90] =?UTF-8?q?refactor:=20=EC=9E=90=EB=B0=94=20?= =?UTF-8?q?=EC=BD=94=EB=94=A9=20=EC=BB=A8=EB=B2=A4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 8 ++++---- src/test/java/wordle/domain/ResultTest.java | 4 ++-- src/test/java/wordle/domain/ResultsTest.java | 12 ++++++------ src/test/java/wordle/domain/WordListReaderTest.java | 13 +++---------- src/test/java/wordle/domain/WordListTest.java | 8 ++++---- src/test/java/wordle/domain/WordTest.java | 4 ++-- 6 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index 767f99ed..3f68c0fa 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -11,13 +11,13 @@ public class AnswerTest { @Test void 정답은_정답과_동일한_답안이_들어오면_모두_MATCHED인_결과를_반환한다() { // given - Answer answer = new Answer("cigar"); - Guess guess = new Guess("cigar"); + final Answer answer = new Answer("cigar"); + final Guess guess = new Guess("cigar"); - Result expectedResult = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); + final Result expectedResult = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); // when - Result result = answer.examineResult(guess); + final Result result = answer.examineResult(guess); // then assertEquals(result, expectedResult); diff --git a/src/test/java/wordle/domain/ResultTest.java b/src/test/java/wordle/domain/ResultTest.java index 1fc9d9a2..608b69e2 100644 --- a/src/test/java/wordle/domain/ResultTest.java +++ b/src/test/java/wordle/domain/ResultTest.java @@ -11,14 +11,14 @@ public class ResultTest { @Test void 모든_ResultType이_Matched라면_매칭_성공_여부를_true로_반환한다() { - Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED)); + final Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED)); assertTrue(result.allMatched()); } @Test void 모든_ResultType이_Matched가_아니라면_매칭_성공_여부를_false로_반환한다() { - Result result = new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED)); + final Result result = new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED)); assertFalse(result.allMatched()); } diff --git a/src/test/java/wordle/domain/ResultsTest.java b/src/test/java/wordle/domain/ResultsTest.java index 4b4b55ae..8d213105 100644 --- a/src/test/java/wordle/domain/ResultsTest.java +++ b/src/test/java/wordle/domain/ResultsTest.java @@ -11,13 +11,13 @@ public class ResultsTest { @Test void 결과들을_가지고_있다면_개수를_반환할_수_있다() { // given - List resultList = List.of( + final List resultList = List.of( new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)) ); - Results results = new Results(resultList); + final Results results = new Results(resultList); // when final int actual = results.size(); @@ -30,11 +30,11 @@ public class ResultsTest { @Test void 문자가_모두_일치하는_결과가_있는_경우_true를_반환한다() { // given - List resultList = List.of( + final List resultList = List.of( new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) ); - Results results = new Results(resultList); + final Results results = new Results(resultList); // when results.hasAnswer(); @@ -46,11 +46,11 @@ public class ResultsTest { @Test void 문자가_모두_일치하는_결과가_없는_경우_false를_반환한다() { // given - List resultList = List.of( + final List resultList = List.of( new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.MATCHED, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) ); - Results results = new Results(resultList); + final Results results = new Results(resultList); // when results.hasAnswer(); diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java index 3375758c..ddcd63c9 100644 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ b/src/test/java/wordle/domain/WordListReaderTest.java @@ -10,20 +10,13 @@ public class WordListReaderTest { @Test void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { - WordListReader wordListReader = new TestWordListReader(); - WordList wordList = wordListReader.read(); + final WordListReader wordListReader = new TestWordListReader(); + final WordList wordList = wordListReader.read(); - final Word actual = wordList.select(new TestSelector()); + final Word actual = wordList.select((it) -> it.get(0)); assertEquals(new Word("apple"), actual); } - class TestSelector implements WordSelector { - - @Override - public Word select(final List wordList) { - return wordList.get(0); - } - } class TestWordListReader implements WordListReader { diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java index 354d5aef..1a9f970e 100644 --- a/src/test/java/wordle/domain/WordListTest.java +++ b/src/test/java/wordle/domain/WordListTest.java @@ -12,17 +12,17 @@ public class WordListTest { @Test void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { - Word word = new Word("cigar"); + final Word word = new Word("cigar"); - WordList wordList = new WordList(List.of(word)); - Word actual = wordList.select((it) -> it.get(0)); + final WordList wordList = new WordList(List.of(word)); + final Word actual = wordList.select((it) -> it.get(0)); assertEquals(actual, word); } @Test void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { - WordList wordList = new WordList(List.of()); + final WordList wordList = new WordList(List.of()); assertThrows(RuntimeException.class, () -> wordList.select((it) -> it.get(0))); } diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java index 9f05df43..b0027573 100644 --- a/src/test/java/wordle/domain/WordTest.java +++ b/src/test/java/wordle/domain/WordTest.java @@ -15,7 +15,7 @@ public class WordTest { @Test void 게임_단어에_5글자_알파벳_소문자_문자가_들어오면_생성할_수_있다() { // given - String word = "cigar"; + final String word = "cigar"; assertDoesNotThrow(() -> new Word(word)); } @@ -23,7 +23,7 @@ public class WordTest { @Test void 게임_단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { // given - String word = "Cigar"; + final String word = "Cigar"; // when & then assertThrows(RuntimeException.class, () -> new Word(word)); From 8cdbedb426cbba87e982fb4d6a4cacb851c2977e Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 21:01:57 +0900 Subject: [PATCH 71/90] =?UTF-8?q?fix:=20=EA=B2=8C=EC=9E=84=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EC=97=90=205=EA=B8=80=EC=9E=90=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=8C=20=EB=AC=B8=EC=9E=90=EC=97=B4=EC=9D=B4=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EC=98=A4=EB=A9=B4=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=97=90=EB=9F=AC=20=ED=83=80=EC=9E=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/WordTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/WordTest.java index b0027573..c4fc3891 100644 --- a/src/test/java/wordle/domain/WordTest.java +++ b/src/test/java/wordle/domain/WordTest.java @@ -9,7 +9,7 @@ public class WordTest { @Test void 게임_단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { // given when then - assertThrowsExactly(RuntimeException.class, () -> new Word("abcdef")); + assertThrowsExactly(IllegalArgumentException.class, () -> new Word("abcdef")); } @Test From acc82c58a13d9c65a7fa8f81440e2b9cb93d80cc Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 17 Jun 2024 21:12:27 +0900 Subject: [PATCH 72/90] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Game.java | 6 +++--- src/main/java/wordle/domain/Answer.java | 2 +- src/main/java/wordle/domain/WordList.java | 4 ---- src/test/java/wordle/domain/AnswerTest.java | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 17116fa3..d30a5b04 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -26,10 +26,10 @@ public void start(final WordSelector wordSelector) { final WordList wordList = wordListReader.read(); final Answer answer = new Answer(wordList.select(wordSelector)); outputView.welcome(MAX_ATTEMPT); - execute(wordList, answer); + play(wordList, answer); } - private void execute(final WordList wordList, final Answer answer) { + private void play(final WordList wordList, final Answer answer) { final Results results = new Results(); IntStream.range(START_ATTEMPT, MAX_ATTEMPT) .boxed() @@ -42,7 +42,7 @@ private void execute(final WordList wordList, final Answer answer) { private Result examine(final WordList wordList, final Answer answer) { final Guess guess = inputWord(wordList); - return answer.examineResult(guess); + return answer.examine(guess); } private Guess inputWord(final WordList wordList) { diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index d05ff341..b70297d4 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -21,7 +21,7 @@ public Alphabet find(final int index) { return word.find(index); } - public Result examineResult(final Guess guess) { + public Result examine(final Guess guess) { final List resultTypes = IntStream.range(START_INDEX, guess.size()) .mapToObj(i -> examineResultType(guess, i)) .toList(); diff --git a/src/main/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java index bf0ab154..eba412cf 100644 --- a/src/main/java/wordle/domain/WordList.java +++ b/src/main/java/wordle/domain/WordList.java @@ -22,10 +22,6 @@ public Word getWordIfExists(final Word word) { .orElseThrow(NoSuchElementException::new); } - public int size() { - return wordList.size(); - } - @Override public boolean equals(final Object o) { if (this == o) return true; diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index 3f68c0fa..90d79add 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -17,7 +17,7 @@ public class AnswerTest { final Result expectedResult = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); // when - final Result result = answer.examineResult(guess); + final Result result = answer.examine(guess); // then assertEquals(result, expectedResult); From 79edbf76eca53aca80d66f5a9be79915fb3f699d Mon Sep 17 00:00:00 2001 From: woozi Date: Sun, 23 Jun 2024 18:13:52 +0900 Subject: [PATCH 73/90] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=82=B4=EC=9A=A9=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 11 +++--- src/main/java/wordle/Game.java | 33 +++++++++--------- ...{WordSelector.java => AnswerSelector.java} | 2 +- src/main/java/wordle/domain/Attempt.java | 34 +++++++++++++++++++ .../domain/EpochDayBaseAnswerSelector.java | 2 +- src/main/java/wordle/domain/Results.java | 10 ++++-- src/main/java/wordle/domain/Word.java | 23 ++++++++----- src/main/java/wordle/domain/WordList.java | 8 ++--- .../java/wordle/view/ConsoleInputView.java | 6 ++-- .../java/wordle/view/ConsoleOutputView.java | 7 ++-- src/main/java/wordle/view/InputView.java | 4 +-- src/main/java/wordle/view/OutputView.java | 3 +- src/main/java/wordle/view/ResultColor.java | 4 +-- 13 files changed, 94 insertions(+), 53 deletions(-) rename src/main/java/wordle/domain/{WordSelector.java => AnswerSelector.java} (77%) create mode 100644 src/main/java/wordle/domain/Attempt.java diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index 6f1114ae..8a154619 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -2,17 +2,18 @@ import wordle.domain.EpochDayBaseAnswerSelector; import wordle.domain.WordListFileReader; +import wordle.domain.WordListReader; +import wordle.domain.AnswerSelector; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; -import java.time.LocalDate; - public class Application { public static void main(String[] args) { final ConsoleInputView inputView = new ConsoleInputView(); final ConsoleOutputView outputView = new ConsoleOutputView(); - final WordListFileReader answerFileReader = new WordListFileReader(); - final Game game = new Game(inputView, outputView, answerFileReader); - game.start(new EpochDayBaseAnswerSelector()); + final WordListReader wordListReader = new WordListFileReader(); + final AnswerSelector answerSelector = new EpochDayBaseAnswerSelector(); + final Game game = new Game(inputView, outputView, wordListReader, answerSelector); + game.start(); } } diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index d30a5b04..3cd719d5 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -4,40 +4,39 @@ import wordle.view.InputView; import wordle.view.OutputView; -import java.util.stream.IntStream; - public class Game { - private static final int START_ATTEMPT = 0; private static final int MAX_ATTEMPT = 6; private final InputView inputView; private final OutputView outputView; private final WordListReader wordListReader; + private final AnswerSelector answerSelector; public Game(final InputView inputView, final OutputView outputView, - final WordListReader wordListReader) { + final WordListReader wordListReader, + final AnswerSelector answerSelector) { this.inputView = inputView; this.outputView = outputView; this.wordListReader = wordListReader; + this.answerSelector = answerSelector; } - public void start(final WordSelector wordSelector) { + public void start() { final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(wordSelector)); - outputView.welcome(MAX_ATTEMPT); + final Answer answer = new Answer(wordList.select(answerSelector)); play(wordList, answer); } private void play(final WordList wordList, final Answer answer) { - final Results results = new Results(); - IntStream.range(START_ATTEMPT, MAX_ATTEMPT) - .boxed() - .takeWhile(attempt -> !results.hasAnswer()) - .forEach(attempt -> { - results.add(examine(wordList, answer)); - outputView.showResults(results, attempt, MAX_ATTEMPT); - }); + Attempt attempt = new Attempt(MAX_ATTEMPT); + Results results = new Results(); + outputView.welcome(attempt.last()); + do { + attempt = attempt.next(); + results = results.add(examine(wordList, answer)); + outputView.showResults(results, attempt); + } while (attempt.isRunning() && results.hasNotAnswer()); } private Result examine(final WordList wordList, final Answer answer) { @@ -48,8 +47,8 @@ private Result examine(final WordList wordList, final Answer answer) { private Guess inputWord(final WordList wordList) { try { outputView.insertWord(); - final Word word = inputView.inputWord(); - return new Guess(wordList.getWordIfExists(word)); + final String guess = inputView.inputWord(); + return new Guess(wordList.getWord(guess)); } catch (final Exception e) { outputView.wrongWord(); return inputWord(wordList); diff --git a/src/main/java/wordle/domain/WordSelector.java b/src/main/java/wordle/domain/AnswerSelector.java similarity index 77% rename from src/main/java/wordle/domain/WordSelector.java rename to src/main/java/wordle/domain/AnswerSelector.java index 594086c7..f6f01615 100644 --- a/src/main/java/wordle/domain/WordSelector.java +++ b/src/main/java/wordle/domain/AnswerSelector.java @@ -4,6 +4,6 @@ import java.util.List; @FunctionalInterface -public interface WordSelector { +public interface AnswerSelector { Word select(final List wordList); } diff --git a/src/main/java/wordle/domain/Attempt.java b/src/main/java/wordle/domain/Attempt.java new file mode 100644 index 00000000..c0493990 --- /dev/null +++ b/src/main/java/wordle/domain/Attempt.java @@ -0,0 +1,34 @@ +package wordle.domain; + +public class Attempt { + private static final int START_INDEX = 0; + private static final int INCREASE_UNIT = 1; + + private final int current; + private final int last; + + public Attempt(final int maxAttempt) { + this(START_INDEX, maxAttempt); + } + + public Attempt(final int current, final int maxAttempt) { + this.current = current; + this.last = maxAttempt; + } + + public int current() { + return current; + } + + public int last() { + return last; + } + + public boolean isRunning() { + return current < last; + } + + public Attempt next() { + return new Attempt(Math.addExact(current, INCREASE_UNIT), last); + } +} diff --git a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java index b202f367..5f6f0450 100644 --- a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -3,7 +3,7 @@ import java.time.LocalDate; import java.util.List; -public class EpochDayBaseAnswerSelector implements WordSelector { +public class EpochDayBaseAnswerSelector implements AnswerSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); @Override diff --git a/src/main/java/wordle/domain/Results.java b/src/main/java/wordle/domain/Results.java index 7174c388..c7a9f33d 100644 --- a/src/main/java/wordle/domain/Results.java +++ b/src/main/java/wordle/domain/Results.java @@ -16,13 +16,17 @@ public Results(final List results) { this.results = results; } + public boolean hasNotAnswer() { + return !(hasAnswer()); + } + public boolean hasAnswer() { - return results.stream() - .anyMatch(Result::allMatched); + return results.stream().anyMatch(Result::allMatched); } - public void add(final Result result) { + public Results add(final Result result) { results.add(result); + return new Results(results); } public int size() { diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index 92e0ce3c..a198359a 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -8,22 +8,23 @@ public class Word { private static final int WORD_SIZE = 5; private final List alphabets; - public Word(final List alphabets) { - validate(alphabets); - this.alphabets = alphabets; + private static List alphabets(final String word) { + return word.toLowerCase().chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList(); } + public Word(final String word) { - this(word.chars() - .mapToObj(it -> (char) it) - .map(Alphabet::of) - .toList()); + this(alphabets(word)); } - private static void validate(final List alphabets) { + public Word(final List alphabets) { if (alphabets.size() != WORD_SIZE) { throw new IllegalArgumentException("단어는 5글자의 소문자 알파벳으로 이루어져야 합니다"); } + this.alphabets = alphabets; } public int size() { @@ -43,10 +44,14 @@ public long countAlphabets(final Alphabet alphabet, final int toIndex) { } return alphabets.subList(MINIMUM_INDEX, toIndex) .stream() - .filter(it -> it.equals(alphabet)) + .filter(it -> it == alphabet) .count(); } + public boolean isSameAs(final String word) { + return alphabets.equals(alphabets(word)); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java index eba412cf..845a7d05 100644 --- a/src/main/java/wordle/domain/WordList.java +++ b/src/main/java/wordle/domain/WordList.java @@ -11,13 +11,13 @@ public WordList(final List wordList) { this.wordList = wordList; } - public Word select(final WordSelector wordSelector) { - return wordSelector.select(wordList); + public Word select(final AnswerSelector answerSelector) { + return answerSelector.select(wordList); } - public Word getWordIfExists(final Word word) { + public Word getWord(final String word) { return wordList.stream() - .filter(word::equals) + .filter(it -> it.isSameAs(word)) .findFirst() .orElseThrow(NoSuchElementException::new); } diff --git a/src/main/java/wordle/view/ConsoleInputView.java b/src/main/java/wordle/view/ConsoleInputView.java index 7220e330..db7304cb 100644 --- a/src/main/java/wordle/view/ConsoleInputView.java +++ b/src/main/java/wordle/view/ConsoleInputView.java @@ -1,7 +1,5 @@ package wordle.view; -import wordle.domain.Word; - import java.util.Scanner; public class ConsoleInputView implements InputView { @@ -16,7 +14,7 @@ public ConsoleInputView(final Scanner scanner) { } @Override - public Word inputWord() { - return new Word(scanner.nextLine()); + public String inputWord() { + return scanner.nextLine(); } } diff --git a/src/main/java/wordle/view/ConsoleOutputView.java b/src/main/java/wordle/view/ConsoleOutputView.java index 05988029..e7a92c0e 100644 --- a/src/main/java/wordle/view/ConsoleOutputView.java +++ b/src/main/java/wordle/view/ConsoleOutputView.java @@ -1,5 +1,6 @@ package wordle.view; +import wordle.domain.Attempt; import wordle.domain.Result; import wordle.domain.Results; @@ -31,9 +32,9 @@ public void wrongWord() { } @Override - public void showResults(final Results results, final int attempt, final int maxAttempt) { - if (results.hasAnswer() || attempt == maxAttempt) { - System.out.println(ATTEMPT_RESULT.formatted(results.size(), maxAttempt)); + public void showResults(final Results results, final Attempt attempt) { + if (results.hasAnswer()) { + System.out.println(ATTEMPT_RESULT.formatted(attempt.current(), attempt.last())); } final String resultSentence = results.getResults().stream() .map(this::color) diff --git a/src/main/java/wordle/view/InputView.java b/src/main/java/wordle/view/InputView.java index 6cd571f7..da52a397 100644 --- a/src/main/java/wordle/view/InputView.java +++ b/src/main/java/wordle/view/InputView.java @@ -1,7 +1,5 @@ package wordle.view; -import wordle.domain.Word; - public interface InputView { - Word inputWord(); + String inputWord(); } diff --git a/src/main/java/wordle/view/OutputView.java b/src/main/java/wordle/view/OutputView.java index f091793d..d6302a06 100644 --- a/src/main/java/wordle/view/OutputView.java +++ b/src/main/java/wordle/view/OutputView.java @@ -1,5 +1,6 @@ package wordle.view; +import wordle.domain.Attempt; import wordle.domain.Results; public interface OutputView { @@ -9,5 +10,5 @@ public interface OutputView { void wrongWord(); - void showResults(final Results results, final int attempt, final int maxAttempt); + void showResults(final Results results, final Attempt attempt); } diff --git a/src/main/java/wordle/view/ResultColor.java b/src/main/java/wordle/view/ResultColor.java index fe6f1b5c..845e1df1 100644 --- a/src/main/java/wordle/view/ResultColor.java +++ b/src/main/java/wordle/view/ResultColor.java @@ -19,9 +19,9 @@ public enum ResultColor { public static String color(final ResultType resultType) { return Arrays.stream(ResultColor.values()) - .filter(it -> it.resultType == resultType) + .filter(it -> resultType == it.resultType) .map(it -> it.color) .findFirst() - .orElseGet(() -> WHITE.color); + .orElse(WHITE.color); } } From f89b99c185268395ba7485648c056ff9202a9cea Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 24 Jun 2024 23:02:05 +0900 Subject: [PATCH 74/90] =?UTF-8?q?refactor:=20Word=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20DictionaryWord=20=EC=99=80=20GameWord?= =?UTF-8?q?=20=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 8 +- src/main/java/wordle/Game.java | 28 +++---- src/main/java/wordle/domain/Answer.java | 6 +- .../java/wordle/domain/AnswerSelector.java | 2 +- src/main/java/wordle/domain/Dictionary.java | 40 ++++++++++ ...eReader.java => DictionaryFileReader.java} | 12 +-- .../java/wordle/domain/DictionaryReader.java | 6 ++ .../java/wordle/domain/DictionaryWord.java | 9 +++ .../domain/EpochDayBaseAnswerSelector.java | 2 +- src/main/java/wordle/domain/GameWord.java | 75 +++++++++++++++++++ src/main/java/wordle/domain/Guess.java | 6 +- src/main/java/wordle/domain/Word.java | 66 +--------------- src/main/java/wordle/domain/WordList.java | 37 --------- .../java/wordle/domain/WordListReader.java | 6 -- .../wordle/domain/DictionaryReaderTest.java | 27 +++++++ .../java/wordle/domain/DictionaryTest.java | 28 +++++++ .../{WordTest.java => GameWordTest.java} | 10 +-- .../wordle/domain/WordListReaderTest.java | 28 ------- src/test/java/wordle/domain/WordListTest.java | 29 ------- 19 files changed, 225 insertions(+), 200 deletions(-) create mode 100644 src/main/java/wordle/domain/Dictionary.java rename src/main/java/wordle/domain/{WordListFileReader.java => DictionaryFileReader.java} (62%) create mode 100644 src/main/java/wordle/domain/DictionaryReader.java create mode 100644 src/main/java/wordle/domain/DictionaryWord.java create mode 100644 src/main/java/wordle/domain/GameWord.java delete mode 100644 src/main/java/wordle/domain/WordList.java delete mode 100644 src/main/java/wordle/domain/WordListReader.java create mode 100644 src/test/java/wordle/domain/DictionaryReaderTest.java create mode 100644 src/test/java/wordle/domain/DictionaryTest.java rename src/test/java/wordle/domain/{WordTest.java => GameWordTest.java} (75%) delete mode 100644 src/test/java/wordle/domain/WordListReaderTest.java delete mode 100644 src/test/java/wordle/domain/WordListTest.java diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index 8a154619..e1719abd 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -1,8 +1,8 @@ package wordle; import wordle.domain.EpochDayBaseAnswerSelector; -import wordle.domain.WordListFileReader; -import wordle.domain.WordListReader; +import wordle.domain.DictionaryFileReader; +import wordle.domain.DictionaryReader; import wordle.domain.AnswerSelector; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; @@ -11,9 +11,9 @@ public class Application { public static void main(String[] args) { final ConsoleInputView inputView = new ConsoleInputView(); final ConsoleOutputView outputView = new ConsoleOutputView(); - final WordListReader wordListReader = new WordListFileReader(); + final DictionaryReader dictionaryReader = new DictionaryFileReader(); final AnswerSelector answerSelector = new EpochDayBaseAnswerSelector(); - final Game game = new Game(inputView, outputView, wordListReader, answerSelector); + final Game game = new Game(inputView, outputView, dictionaryReader, answerSelector); game.start(); } } diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 3cd719d5..d59c0c5b 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -9,49 +9,49 @@ public class Game { private final InputView inputView; private final OutputView outputView; - private final WordListReader wordListReader; + private final DictionaryReader dictionaryReader; private final AnswerSelector answerSelector; public Game(final InputView inputView, final OutputView outputView, - final WordListReader wordListReader, + final DictionaryReader dictionaryReader, final AnswerSelector answerSelector) { this.inputView = inputView; this.outputView = outputView; - this.wordListReader = wordListReader; + this.dictionaryReader = dictionaryReader; this.answerSelector = answerSelector; } public void start() { - final WordList wordList = wordListReader.read(); - final Answer answer = new Answer(wordList.select(answerSelector)); - play(wordList, answer); + final Dictionary dictionary = dictionaryReader.read(); + final Answer answer = dictionary.answer(answerSelector); + play(dictionary, answer); } - private void play(final WordList wordList, final Answer answer) { + private void play(final Dictionary dictionary, final Answer answer) { Attempt attempt = new Attempt(MAX_ATTEMPT); Results results = new Results(); outputView.welcome(attempt.last()); do { attempt = attempt.next(); - results = results.add(examine(wordList, answer)); + results = results.add(examine(dictionary, answer)); outputView.showResults(results, attempt); } while (attempt.isRunning() && results.hasNotAnswer()); } - private Result examine(final WordList wordList, final Answer answer) { - final Guess guess = inputWord(wordList); + private Result examine(final Dictionary dictionary, final Answer answer) { + final Guess guess = guess(dictionary); return answer.examine(guess); } - private Guess inputWord(final WordList wordList) { + private Guess guess(final Dictionary dictionary) { try { outputView.insertWord(); - final String guess = inputView.inputWord(); - return new Guess(wordList.getWord(guess)); + final String word = inputView.inputWord(); + return dictionary.guess(word); } catch (final Exception e) { outputView.wrongWord(); - return inputWord(wordList); + return guess(dictionary); } } } diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index b70297d4..e256e98b 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -7,14 +7,14 @@ public class Answer { private static final int START_INDEX = 0; private static final int EXCLUDE_UNIT = 1; - private final Word word; + private final GameWord word; - public Answer(final Word word) { + public Answer(final GameWord word) { this.word = word; } public Answer(final String word) { - this(new Word(word)); + this(new GameWord(word)); } public Alphabet find(final int index) { diff --git a/src/main/java/wordle/domain/AnswerSelector.java b/src/main/java/wordle/domain/AnswerSelector.java index f6f01615..358a4bcc 100644 --- a/src/main/java/wordle/domain/AnswerSelector.java +++ b/src/main/java/wordle/domain/AnswerSelector.java @@ -5,5 +5,5 @@ @FunctionalInterface public interface AnswerSelector { - Word select(final List wordList); + Word select(final List wordList); } diff --git a/src/main/java/wordle/domain/Dictionary.java b/src/main/java/wordle/domain/Dictionary.java new file mode 100644 index 00000000..c87df238 --- /dev/null +++ b/src/main/java/wordle/domain/Dictionary.java @@ -0,0 +1,40 @@ +package wordle.domain; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + +public class Dictionary { + private final List words; + + public Dictionary(final List words) { + this.words = words; + } + + public Answer answer(final AnswerSelector answerSelector) { + final Word word = answerSelector.select(words); + return new Answer(word.word()); + } + + public Guess guess(final String word) { + return words.stream() + .filter(it -> it.isSameAs(word)) + .findFirst() + .map(Word::word) + .map(Guess::new) + .orElseThrow(NoSuchElementException::new); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Dictionary dictionary1 = (Dictionary) o; + return Objects.equals(words, dictionary1.words); + } + + @Override + public int hashCode() { + return Objects.hashCode(words); + } +} diff --git a/src/main/java/wordle/domain/WordListFileReader.java b/src/main/java/wordle/domain/DictionaryFileReader.java similarity index 62% rename from src/main/java/wordle/domain/WordListFileReader.java rename to src/main/java/wordle/domain/DictionaryFileReader.java index 22088ddc..f77ab161 100644 --- a/src/main/java/wordle/domain/WordListFileReader.java +++ b/src/main/java/wordle/domain/DictionaryFileReader.java @@ -5,16 +5,16 @@ import java.nio.file.Path; import java.nio.file.Paths; -public class WordListFileReader implements WordListReader { +public class DictionaryFileReader implements DictionaryReader { private static final String FILE_PATH = "src/main/resources/words.txt"; - private static final WordList wordList; + private static final Dictionary DICTIONARY; static { try { final Path path = Paths.get(FILE_PATH); - wordList = new WordList(Files.readAllLines(path) + DICTIONARY = new Dictionary(Files.readAllLines(path) .stream() - .map(Word::new) + .map(DictionaryWord::new) .toList()); } catch (IOException e) { throw new RuntimeException(e); @@ -22,7 +22,7 @@ public class WordListFileReader implements WordListReader { } @Override - public WordList read() { - return wordList; + public Dictionary read() { + return DICTIONARY; } } diff --git a/src/main/java/wordle/domain/DictionaryReader.java b/src/main/java/wordle/domain/DictionaryReader.java new file mode 100644 index 00000000..d3bace28 --- /dev/null +++ b/src/main/java/wordle/domain/DictionaryReader.java @@ -0,0 +1,6 @@ +package wordle.domain; + +@FunctionalInterface +public interface DictionaryReader { + Dictionary read(); +} diff --git a/src/main/java/wordle/domain/DictionaryWord.java b/src/main/java/wordle/domain/DictionaryWord.java new file mode 100644 index 00000000..2924047e --- /dev/null +++ b/src/main/java/wordle/domain/DictionaryWord.java @@ -0,0 +1,9 @@ +package wordle.domain; + +public record DictionaryWord(String word) implements Word { + + @Override + public boolean isSameAs(final String other) { + return word.equals(other); + } +} diff --git a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java index 5f6f0450..8d3669c7 100644 --- a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java @@ -7,7 +7,7 @@ public class EpochDayBaseAnswerSelector implements AnswerSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); @Override - public Word select(final List wordList) { + public Word select(final List wordList) { final LocalDate now = LocalDate.now(); final long nowEpochDay = now.toEpochDay(); final long baseEpochDay = BASE_LOCAL_DATE.toEpochDay(); diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java new file mode 100644 index 00000000..74c35a1e --- /dev/null +++ b/src/main/java/wordle/domain/GameWord.java @@ -0,0 +1,75 @@ +package wordle.domain; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class GameWord implements Word { + private static final int MINIMUM_INDEX = 0; + private static final int WORD_SIZE = 5; + + private final List alphabets; + + private static List alphabets(final String word) { + return word.toLowerCase().chars() + .mapToObj(it -> (char) it) + .map(Alphabet::of) + .toList(); + } + + public GameWord(final String word) { + this(alphabets(word)); + } + + public GameWord(final List alphabets) { + if (alphabets.size() != WORD_SIZE) { + throw new IllegalArgumentException("단어는 5글자의 소문자 알파벳으로 이루어져야 합니다"); + } + this.alphabets = alphabets; + } + + public int size() { + return alphabets.size(); + } + + public Alphabet find(final int index) { + if (index < MINIMUM_INDEX || index >= alphabets.size()) { + throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); + } + return alphabets.get(index); + } + + public long countAlphabets(final Alphabet alphabet, final int toIndex) { + if (toIndex > alphabets.size()) { + throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); + } + return alphabets.subList(MINIMUM_INDEX, toIndex) + .stream() + .filter(it -> it == alphabet) + .count(); + } + + public boolean isSameAs(final String word) { + return word().equals(word); + } + + @Override + public String word() { + return alphabets.stream() + .map(Enum::name) + .collect(Collectors.joining()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final GameWord gameWord = (GameWord) o; + return Objects.equals(alphabets, gameWord.alphabets); + } + + @Override + public int hashCode() { + return Objects.hashCode(alphabets); + } +} \ No newline at end of file diff --git a/src/main/java/wordle/domain/Guess.java b/src/main/java/wordle/domain/Guess.java index 981a02d3..576d25e5 100644 --- a/src/main/java/wordle/domain/Guess.java +++ b/src/main/java/wordle/domain/Guess.java @@ -1,14 +1,14 @@ package wordle.domain; public class Guess { - private final Word word; + private final GameWord word; - public Guess(final Word word) { + public Guess(final GameWord word) { this.word = word; } public Guess(final String word) { - this(new Word(word)); + this(new GameWord(word)); } public int size() { diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index a198359a..c2621478 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -1,67 +1,7 @@ package wordle.domain; -import java.util.List; -import java.util.Objects; +public interface Word { + boolean isSameAs(String word); -public class Word { - private static final int MINIMUM_INDEX = 0; - private static final int WORD_SIZE = 5; - private final List alphabets; - - private static List alphabets(final String word) { - return word.toLowerCase().chars() - .mapToObj(it -> (char) it) - .map(Alphabet::of) - .toList(); - } - - - public Word(final String word) { - this(alphabets(word)); - } - - public Word(final List alphabets) { - if (alphabets.size() != WORD_SIZE) { - throw new IllegalArgumentException("단어는 5글자의 소문자 알파벳으로 이루어져야 합니다"); - } - this.alphabets = alphabets; - } - - public int size() { - return alphabets.size(); - } - - public Alphabet find(final int index) { - if (index < MINIMUM_INDEX || index >= alphabets.size()) { - throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); - } - return alphabets.get(index); - } - - public long countAlphabets(final Alphabet alphabet, final int toIndex) { - if (toIndex > alphabets.size()) { - throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); - } - return alphabets.subList(MINIMUM_INDEX, toIndex) - .stream() - .filter(it -> it == alphabet) - .count(); - } - - public boolean isSameAs(final String word) { - return alphabets.equals(alphabets(word)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Word word = (Word) o; - return Objects.equals(alphabets, word.alphabets); - } - - @Override - public int hashCode() { - return Objects.hash(alphabets); - } + String word(); } diff --git a/src/main/java/wordle/domain/WordList.java b/src/main/java/wordle/domain/WordList.java deleted file mode 100644 index 845a7d05..00000000 --- a/src/main/java/wordle/domain/WordList.java +++ /dev/null @@ -1,37 +0,0 @@ -package wordle.domain; - -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Objects; - -public class WordList { - private final List wordList; - - public WordList(final List wordList) { - this.wordList = wordList; - } - - public Word select(final AnswerSelector answerSelector) { - return answerSelector.select(wordList); - } - - public Word getWord(final String word) { - return wordList.stream() - .filter(it -> it.isSameAs(word)) - .findFirst() - .orElseThrow(NoSuchElementException::new); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final WordList wordList1 = (WordList) o; - return Objects.equals(wordList, wordList1.wordList); - } - - @Override - public int hashCode() { - return Objects.hashCode(wordList); - } -} diff --git a/src/main/java/wordle/domain/WordListReader.java b/src/main/java/wordle/domain/WordListReader.java deleted file mode 100644 index f92d2f0b..00000000 --- a/src/main/java/wordle/domain/WordListReader.java +++ /dev/null @@ -1,6 +0,0 @@ -package wordle.domain; - -@FunctionalInterface -public interface WordListReader { - WordList read(); -} diff --git a/src/test/java/wordle/domain/DictionaryReaderTest.java b/src/test/java/wordle/domain/DictionaryReaderTest.java new file mode 100644 index 00000000..5c1285de --- /dev/null +++ b/src/test/java/wordle/domain/DictionaryReaderTest.java @@ -0,0 +1,27 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class DictionaryReaderTest { + + @Test + void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { + final DictionaryReader dictionaryReader = new TestDictionaryReader(); + final Dictionary dictionary = dictionaryReader.read(); + + assertNotNull(dictionary); + } + + + class TestDictionaryReader implements DictionaryReader { + + @Override + public Dictionary read() { + return new Dictionary(List.of(new DictionaryWord("apple"))); + } + } +} diff --git a/src/test/java/wordle/domain/DictionaryTest.java b/src/test/java/wordle/domain/DictionaryTest.java new file mode 100644 index 00000000..21b3b62d --- /dev/null +++ b/src/test/java/wordle/domain/DictionaryTest.java @@ -0,0 +1,28 @@ +package wordle.domain; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class DictionaryTest { + + + @Test + void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { + final DictionaryWord word = new DictionaryWord("cigar"); + + final Dictionary dictionary = new Dictionary(List.of(word)); + final Answer answer = dictionary.answer((it) -> it.get(0)); + + assertNotNull(answer); + } + + @Test + void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { + final Dictionary dictionary = new Dictionary(List.of()); + + assertThrows(RuntimeException.class, () -> dictionary.answer((it) -> it.get(0))); + } +} diff --git a/src/test/java/wordle/domain/WordTest.java b/src/test/java/wordle/domain/GameWordTest.java similarity index 75% rename from src/test/java/wordle/domain/WordTest.java rename to src/test/java/wordle/domain/GameWordTest.java index c4fc3891..2339fab3 100644 --- a/src/test/java/wordle/domain/WordTest.java +++ b/src/test/java/wordle/domain/GameWordTest.java @@ -4,12 +4,12 @@ import static org.junit.jupiter.api.Assertions.*; -public class WordTest { +public class GameWordTest { @Test void 게임_단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { // given when then - assertThrowsExactly(IllegalArgumentException.class, () -> new Word("abcdef")); + assertThrowsExactly(IllegalArgumentException.class, () -> new GameWord("abcdef")); } @Test @@ -17,15 +17,15 @@ public class WordTest { // given final String word = "cigar"; - assertDoesNotThrow(() -> new Word(word)); + assertDoesNotThrow(() -> new GameWord(word)); } @Test - void 게임_단어에_알파벳_소문자가_아닌_문자가_들어오면_예외를_반환한다() { + void 게임_단어에_알파벳_소문자가_아닌_문자가_들어오더도_성생할_수_있다() { // given final String word = "Cigar"; // when & then - assertThrows(RuntimeException.class, () -> new Word(word)); + assertDoesNotThrow(() -> new GameWord(word)); } } diff --git a/src/test/java/wordle/domain/WordListReaderTest.java b/src/test/java/wordle/domain/WordListReaderTest.java deleted file mode 100644 index ddcd63c9..00000000 --- a/src/test/java/wordle/domain/WordListReaderTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package wordle.domain; - -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class WordListReaderTest { - - @Test - void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { - final WordListReader wordListReader = new TestWordListReader(); - final WordList wordList = wordListReader.read(); - - final Word actual = wordList.select((it) -> it.get(0)); - assertEquals(new Word("apple"), actual); - } - - - class TestWordListReader implements WordListReader { - - @Override - public WordList read() { - return new WordList(List.of(new Word("apple"))); - } - } -} diff --git a/src/test/java/wordle/domain/WordListTest.java b/src/test/java/wordle/domain/WordListTest.java deleted file mode 100644 index 1a9f970e..00000000 --- a/src/test/java/wordle/domain/WordListTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package wordle.domain; - -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class WordListTest { - - - @Test - void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { - final Word word = new Word("cigar"); - - final WordList wordList = new WordList(List.of(word)); - final Word actual = wordList.select((it) -> it.get(0)); - - assertEquals(actual, word); - } - - @Test - void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { - final WordList wordList = new WordList(List.of()); - - assertThrows(RuntimeException.class, () -> wordList.select((it) -> it.get(0))); - } -} From 38dec0dab15b9047e80c34a6c1f954adea6c47a9 Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 24 Jun 2024 23:09:32 +0900 Subject: [PATCH 75/90] =?UTF-8?q?refactor:=20Attempt=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EB=8F=84=20=EC=B5=9C=EC=86=8C=ED=99=94=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Game.java | 13 ++++--------- src/main/java/wordle/domain/Attempt.java | 11 ++++++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index d59c0c5b..47a0d951 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -5,8 +5,6 @@ import wordle.view.OutputView; public class Game { - private static final int MAX_ATTEMPT = 6; - private final InputView inputView; private final OutputView outputView; private final DictionaryReader dictionaryReader; @@ -29,21 +27,18 @@ public void start() { } private void play(final Dictionary dictionary, final Answer answer) { - Attempt attempt = new Attempt(MAX_ATTEMPT); + Attempt attempt = new Attempt(); Results results = new Results(); outputView.welcome(attempt.last()); do { + final Guess guess = guess(dictionary); + final Result result = answer.examine(guess); + results = results.add(result); attempt = attempt.next(); - results = results.add(examine(dictionary, answer)); outputView.showResults(results, attempt); } while (attempt.isRunning() && results.hasNotAnswer()); } - private Result examine(final Dictionary dictionary, final Answer answer) { - final Guess guess = guess(dictionary); - return answer.examine(guess); - } - private Guess guess(final Dictionary dictionary) { try { outputView.insertWord(); diff --git a/src/main/java/wordle/domain/Attempt.java b/src/main/java/wordle/domain/Attempt.java index c0493990..5aa37df5 100644 --- a/src/main/java/wordle/domain/Attempt.java +++ b/src/main/java/wordle/domain/Attempt.java @@ -1,14 +1,15 @@ package wordle.domain; public class Attempt { - private static final int START_INDEX = 0; - private static final int INCREASE_UNIT = 1; + private static final int MINIMUM = 0; + private static final int MAXIMUM = 6; + private static final int NEXT_UNIT = 1; private final int current; private final int last; - public Attempt(final int maxAttempt) { - this(START_INDEX, maxAttempt); + public Attempt() { + this(MINIMUM, MAXIMUM); } public Attempt(final int current, final int maxAttempt) { @@ -29,6 +30,6 @@ public boolean isRunning() { } public Attempt next() { - return new Attempt(Math.addExact(current, INCREASE_UNIT), last); + return new Attempt(Math.addExact(current, NEXT_UNIT), last); } } From 82a762d915823855f4d68d17e98451d49fbe758d Mon Sep 17 00:00:00 2001 From: woozi Date: Mon, 24 Jun 2024 23:16:30 +0900 Subject: [PATCH 76/90] =?UTF-8?q?refactor:=20WordSelector=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 8 ++++---- src/main/java/wordle/Game.java | 8 ++++---- src/main/java/wordle/domain/Dictionary.java | 6 +++--- src/main/java/wordle/domain/DictionaryWord.java | 15 +++++++++++++++ ...elector.java => EpochDayBaseWordSelector.java} | 2 +- .../{AnswerSelector.java => WordSelector.java} | 2 +- 6 files changed, 28 insertions(+), 13 deletions(-) rename src/main/java/wordle/domain/{EpochDayBaseAnswerSelector.java => EpochDayBaseWordSelector.java} (91%) rename src/main/java/wordle/domain/{AnswerSelector.java => WordSelector.java} (78%) diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index e1719abd..b0db0764 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -1,9 +1,9 @@ package wordle; -import wordle.domain.EpochDayBaseAnswerSelector; +import wordle.domain.EpochDayBaseWordSelector; import wordle.domain.DictionaryFileReader; import wordle.domain.DictionaryReader; -import wordle.domain.AnswerSelector; +import wordle.domain.WordSelector; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; @@ -12,8 +12,8 @@ public static void main(String[] args) { final ConsoleInputView inputView = new ConsoleInputView(); final ConsoleOutputView outputView = new ConsoleOutputView(); final DictionaryReader dictionaryReader = new DictionaryFileReader(); - final AnswerSelector answerSelector = new EpochDayBaseAnswerSelector(); - final Game game = new Game(inputView, outputView, dictionaryReader, answerSelector); + final WordSelector wordSelector = new EpochDayBaseWordSelector(); + final Game game = new Game(inputView, outputView, dictionaryReader, wordSelector); game.start(); } } diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 47a0d951..3655dbb4 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -8,21 +8,21 @@ public class Game { private final InputView inputView; private final OutputView outputView; private final DictionaryReader dictionaryReader; - private final AnswerSelector answerSelector; + private final WordSelector wordSelector; public Game(final InputView inputView, final OutputView outputView, final DictionaryReader dictionaryReader, - final AnswerSelector answerSelector) { + final WordSelector wordSelector) { this.inputView = inputView; this.outputView = outputView; this.dictionaryReader = dictionaryReader; - this.answerSelector = answerSelector; + this.wordSelector = wordSelector; } public void start() { final Dictionary dictionary = dictionaryReader.read(); - final Answer answer = dictionary.answer(answerSelector); + final Answer answer = dictionary.answer(wordSelector); play(dictionary, answer); } diff --git a/src/main/java/wordle/domain/Dictionary.java b/src/main/java/wordle/domain/Dictionary.java index c87df238..0388ab34 100644 --- a/src/main/java/wordle/domain/Dictionary.java +++ b/src/main/java/wordle/domain/Dictionary.java @@ -11,17 +11,17 @@ public Dictionary(final List words) { this.words = words; } - public Answer answer(final AnswerSelector answerSelector) { - final Word word = answerSelector.select(words); + public Answer answer(final WordSelector wordSelector) { + final Word word = wordSelector.select(words); return new Answer(word.word()); } public Guess guess(final String word) { return words.stream() .filter(it -> it.isSameAs(word)) - .findFirst() .map(Word::word) .map(Guess::new) + .findFirst() .orElseThrow(NoSuchElementException::new); } diff --git a/src/main/java/wordle/domain/DictionaryWord.java b/src/main/java/wordle/domain/DictionaryWord.java index 2924047e..a05c7095 100644 --- a/src/main/java/wordle/domain/DictionaryWord.java +++ b/src/main/java/wordle/domain/DictionaryWord.java @@ -1,9 +1,24 @@ package wordle.domain; +import java.util.Objects; + public record DictionaryWord(String word) implements Word { @Override public boolean isSameAs(final String other) { return word.equals(other); } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final DictionaryWord that = (DictionaryWord) o; + return Objects.equals(word, that.word); + } + + @Override + public int hashCode() { + return Objects.hashCode(word); + } } diff --git a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java b/src/main/java/wordle/domain/EpochDayBaseWordSelector.java similarity index 91% rename from src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java rename to src/main/java/wordle/domain/EpochDayBaseWordSelector.java index 8d3669c7..620249f9 100644 --- a/src/main/java/wordle/domain/EpochDayBaseAnswerSelector.java +++ b/src/main/java/wordle/domain/EpochDayBaseWordSelector.java @@ -3,7 +3,7 @@ import java.time.LocalDate; import java.util.List; -public class EpochDayBaseAnswerSelector implements AnswerSelector { +public class EpochDayBaseWordSelector implements WordSelector { private static final LocalDate BASE_LOCAL_DATE = LocalDate.of(2021, 6, 19); @Override diff --git a/src/main/java/wordle/domain/AnswerSelector.java b/src/main/java/wordle/domain/WordSelector.java similarity index 78% rename from src/main/java/wordle/domain/AnswerSelector.java rename to src/main/java/wordle/domain/WordSelector.java index 358a4bcc..c9d7f846 100644 --- a/src/main/java/wordle/domain/AnswerSelector.java +++ b/src/main/java/wordle/domain/WordSelector.java @@ -4,6 +4,6 @@ import java.util.List; @FunctionalInterface -public interface AnswerSelector { +public interface WordSelector { Word select(final List wordList); } From bf21adec2b920bd0d362883051c0d70976fcea0b Mon Sep 17 00:00:00 2001 From: woozi Date: Tue, 25 Jun 2024 23:15:14 +0900 Subject: [PATCH 77/90] =?UTF-8?q?refactor:=20enum=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B9=84=EA=B5=90=EB=AC=B8=20equals=20=EB=A1=9C=20=ED=86=B5?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Alphabet.java | 8 ++++++-- src/main/java/wordle/domain/Answer.java | 2 +- src/main/java/wordle/domain/GameWord.java | 6 +++--- src/main/java/wordle/view/ResultColor.java | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/wordle/domain/Alphabet.java b/src/main/java/wordle/domain/Alphabet.java index 2750c9bb..f580752e 100644 --- a/src/main/java/wordle/domain/Alphabet.java +++ b/src/main/java/wordle/domain/Alphabet.java @@ -5,8 +5,12 @@ public enum Alphabet { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; - public static Alphabet of(final char alphabet) { - return of(String.valueOf(alphabet)); + public static Alphabet of(final int codePoint) { + return of(Character.toChars(codePoint)); + } + + public static Alphabet of(final char[] chars) { + return of(String.valueOf(chars)); } public static Alphabet of(final String alphabet) { diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index e256e98b..7c0bf146 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -30,7 +30,7 @@ public Result examine(final Guess guess) { private ResultType examineResultType(final Guess guess, final int index) { final Alphabet alphabet = guess.find(index); - if (alphabet == this.find(index)) { + if (alphabet.equals(find(index))) { return ResultType.MATCHED; } final long answerCount = countAlphabets(alphabet, size()); diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java index 74c35a1e..5ae43a5a 100644 --- a/src/main/java/wordle/domain/GameWord.java +++ b/src/main/java/wordle/domain/GameWord.java @@ -11,8 +11,8 @@ public class GameWord implements Word { private final List alphabets; private static List alphabets(final String word) { - return word.toLowerCase().chars() - .mapToObj(it -> (char) it) + return word.toLowerCase().codePoints() + .boxed() .map(Alphabet::of) .toList(); } @@ -45,7 +45,7 @@ public long countAlphabets(final Alphabet alphabet, final int toIndex) { } return alphabets.subList(MINIMUM_INDEX, toIndex) .stream() - .filter(it -> it == alphabet) + .filter(alphabet::equals) .count(); } diff --git a/src/main/java/wordle/view/ResultColor.java b/src/main/java/wordle/view/ResultColor.java index 845e1df1..72e7e6ff 100644 --- a/src/main/java/wordle/view/ResultColor.java +++ b/src/main/java/wordle/view/ResultColor.java @@ -19,7 +19,7 @@ public enum ResultColor { public static String color(final ResultType resultType) { return Arrays.stream(ResultColor.values()) - .filter(it -> resultType == it.resultType) + .filter(it -> resultType.equals(it.resultType)) .map(it -> it.color) .findFirst() .orElse(WHITE.color); From 03fc9c1c0a0aefec92fc5bd31680853157eb2400 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 00:58:08 +0900 Subject: [PATCH 78/90] =?UTF-8?q?fix:=20=EB=A7=A4=EC=B9=AD=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=8B=A8=EC=96=B4=EC=99=80=20=EB=8F=99=EC=9D=BC?= =?UTF-8?q?=ED=95=9C=20=EB=8B=A8=EC=96=B4=EA=B0=80=20=EC=95=9E=EC=97=90=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=A0=20=EA=B2=BD=EC=9A=B0=20=EB=AF=B8?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=20=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=5F?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Answer.java | 53 +++++++++++++-------- src/main/java/wordle/domain/GameWord.java | 7 +++ src/main/java/wordle/domain/Guess.java | 6 ++- src/main/java/wordle/domain/Result.java | 10 ++-- src/main/java/wordle/domain/ResultType.java | 7 ++- src/test/java/wordle/domain/AnswerTest.java | 28 +++++------ src/test/java/wordle/domain/GuessTest.java | 4 +- 7 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index 7c0bf146..76fd9ac4 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -1,11 +1,16 @@ package wordle.domain; + import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.IntStream; public class Answer { private static final int START_INDEX = 0; - private static final int EXCLUDE_UNIT = 1; + public static final long DEFAULT_COUNT = 0L; + public static final long DECREASE_COUNT_UNIT = 1L; private final GameWord word; @@ -22,27 +27,37 @@ public Alphabet find(final int index) { } public Result examine(final Guess guess) { - final List resultTypes = IntStream.range(START_INDEX, guess.size()) - .mapToObj(i -> examineResultType(guess, i)) + final List matchedResults = IntStream.range(START_INDEX, word.size()) + .mapToObj(index -> { + final Alphabet answerAlphabet = find(index); + final Alphabet guessAlphabet = guess.find(index); + if (answerAlphabet.equals(guessAlphabet)) { + return ResultType.MATCHED; + } + return ResultType.NONE; + }) .toList(); - return new Result(resultTypes); - } - private ResultType examineResultType(final Guess guess, final int index) { - final Alphabet alphabet = guess.find(index); - if (alphabet.equals(find(index))) { - return ResultType.MATCHED; - } - final long answerCount = countAlphabets(alphabet, size()); - final long guessCount = guess.countAlphabets(alphabet, Math.addExact(index, EXCLUDE_UNIT)); - if (answerCount >= guessCount) { - return ResultType.EXIST; - } - return ResultType.MISMATCHED; - } + final Map unmatchedAnswerCounts = IntStream.range(START_INDEX, word.size()) + .filter(index -> ResultType.NONE.equals(matchedResults.get(index))) + .mapToObj(this::find) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - public long countAlphabets(final Alphabet alphabet, final int endIndex) { - return word.countAlphabets(alphabet, endIndex); + final List resultTypes = IntStream.range(START_INDEX, guess.size()) + .mapToObj(index -> { + if (ResultType.MATCHED.equals(matchedResults.get(index))) { + return ResultType.MATCHED; + } + final Alphabet alphabet = guess.find(index); + final long count = unmatchedAnswerCounts.getOrDefault(alphabet, DEFAULT_COUNT); + if (count > 0) { + unmatchedAnswerCounts.put(alphabet, Math.subtractExact(count, DECREASE_COUNT_UNIT)); + return ResultType.EXIST; + } + return ResultType.MISMATCHED; + }) + .toList(); + return new Result(resultTypes); } public int size() { diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java index 5ae43a5a..94d110bd 100644 --- a/src/main/java/wordle/domain/GameWord.java +++ b/src/main/java/wordle/domain/GameWord.java @@ -49,6 +49,12 @@ public long countAlphabets(final Alphabet alphabet, final int toIndex) { .count(); } + public long count(final Alphabet alphabet) { + return alphabets.stream() + .filter(alphabet::equals) + .count(); + } + public boolean isSameAs(final String word) { return word().equals(word); } @@ -72,4 +78,5 @@ public boolean equals(final Object o) { public int hashCode() { return Objects.hashCode(alphabets); } + } \ No newline at end of file diff --git a/src/main/java/wordle/domain/Guess.java b/src/main/java/wordle/domain/Guess.java index 576d25e5..563d154f 100644 --- a/src/main/java/wordle/domain/Guess.java +++ b/src/main/java/wordle/domain/Guess.java @@ -19,7 +19,11 @@ public Alphabet find(final int index) { return word.find(index); } - public long countAlphabets(final Alphabet alphabet, final int endIndex) { + public long count(final Alphabet alphabet, final int endIndex) { return word.countAlphabets(alphabet, endIndex); } + + public long count(final Alphabet alphabet) { + return word.count(alphabet); + } } diff --git a/src/main/java/wordle/domain/Result.java b/src/main/java/wordle/domain/Result.java index 983ef55b..8e6f9cc8 100644 --- a/src/main/java/wordle/domain/Result.java +++ b/src/main/java/wordle/domain/Result.java @@ -20,15 +20,19 @@ public List getResult() { } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Result result = (Result) o; + final Result result = (Result) o; return Objects.equals(resultTypes, result.resultTypes); } @Override public int hashCode() { - return Objects.hash(resultTypes); + return Objects.hashCode(resultTypes); + } + + public ResultType get(final int index) { + return resultTypes.get(index); } } diff --git a/src/main/java/wordle/domain/ResultType.java b/src/main/java/wordle/domain/ResultType.java index da47bde3..47961842 100644 --- a/src/main/java/wordle/domain/ResultType.java +++ b/src/main/java/wordle/domain/ResultType.java @@ -1,7 +1,12 @@ package wordle.domain; public enum ResultType { + NONE, MATCHED, EXIST, - MISMATCHED + MISMATCHED; + + public boolean isNotEquals(final ResultType resultType) { + return this.equals(resultType); + } } diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index 90d79add..c4e419e1 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -5,6 +5,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; +import static wordle.domain.ResultType.*; public class AnswerTest { @@ -29,23 +30,6 @@ public class AnswerTest { } - @Test - void 알파벳과_인덱스가_들어오면_해당_인덱스_이전의_알파벳_개수를_반환한다() { - final Answer answer = new Answer("tasty"); - final long count = answer.countAlphabets(Alphabet.t, 4); - - assertEquals(2, count); - } - - - @Test - void 답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { - final Answer answer = new Answer("tasty"); - - assertThrowsExactly(IllegalArgumentException.class, () -> answer.countAlphabets(Alphabet.t, 6)); - } - - @Test void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { final Answer answer = new Answer("tasty"); @@ -61,4 +45,14 @@ public class AnswerTest { assertThrows(IllegalArgumentException.class, () -> answer.find(5)); } + + @Test + void 매칭_타입_단어와_동일한_단어가_앞에_존재할_경우_미존재_타입으로_처리한다() { + final Answer answer = new Answer("apple"); + final Guess guess = new Guess("hello"); + final Result expected = new Result(List.of(MISMATCHED, EXIST, MISMATCHED, MATCHED, MISMATCHED)); + + final Result actual = answer.examine(guess); + assertEquals(expected, actual); + } } diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index a63cdfca..b5c3da61 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -14,7 +14,7 @@ public class GuessTest { @Test void 알파벳과_인덱스가_들어오면_해당_인덱스_이전의_알파벳_개수를_반환한다() { final Guess guess = new Guess("tasty"); - final long count = guess.countAlphabets(Alphabet.t, 4); + final long count = guess.count(Alphabet.t, 4); assertEquals(2, count); } @@ -23,7 +23,7 @@ public class GuessTest { void 답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { final Guess guess = new Guess("tasty"); - assertThrowsExactly(IllegalArgumentException.class, () -> guess.countAlphabets(Alphabet.t, 6)); + assertThrowsExactly(IllegalArgumentException.class, () -> guess.count(Alphabet.t, 6)); } @Test From fbb1f8c005674d98ff6b5b2df07ff08d9d9e2f0c Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 01:07:50 +0900 Subject: [PATCH 79/90] =?UTF-8?q?test:=20Alphabet=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Alphabet.java | 2 +- src/test/java/wordle/domain/AlphabetTest.java | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/wordle/domain/Alphabet.java b/src/main/java/wordle/domain/Alphabet.java index f580752e..72ac7931 100644 --- a/src/main/java/wordle/domain/Alphabet.java +++ b/src/main/java/wordle/domain/Alphabet.java @@ -15,7 +15,7 @@ public static Alphabet of(final char[] chars) { public static Alphabet of(final String alphabet) { return Arrays.stream(values()) - .filter(it -> it.name().equals(alphabet)) + .filter(it -> it.name().equals(alphabet.toLowerCase())) .findFirst() .orElseThrow(IllegalArgumentException::new); } diff --git a/src/test/java/wordle/domain/AlphabetTest.java b/src/test/java/wordle/domain/AlphabetTest.java index eb52481b..e679305b 100644 --- a/src/test/java/wordle/domain/AlphabetTest.java +++ b/src/test/java/wordle/domain/AlphabetTest.java @@ -1,22 +1,29 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; public class AlphabetTest { - @Test - void 소문자_영단어로_Alphabet을_생성할_수_있다() { - assertDoesNotThrow(() -> Alphabet.of('a')); + @ValueSource(chars = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' + }) + @ParameterizedTest(name = "영단어 {0} 로 Alphabet 객체를 생성할 수 있다") + void 영단어로_Alphabet_객체를_생성할_수_있다(char alphabet) { + assertDoesNotThrow(() -> Alphabet.of(alphabet)); } - @Test - void 소문자가_아닌_단어가_들어온다면_Alphabet을_생성할_수_없다() { - assertAll( - () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('A')), - () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('1')), - () -> assertThrows(IllegalArgumentException.class, () -> Alphabet.of('ㄱ')) - ); + @ValueSource(chars = { + 'ㄱ', 'ㄴ', 'ㄷ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅅ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')' + }) + @ParameterizedTest(name = "영단어가 아닌 {0} 로 Alphabet 객체를 생성할 수 없다") + void 영단어가_아닌_단어가_들어온다면_Alphabet을_생성할_수_없다(char alphabet) { + assertThrowsExactly(IllegalArgumentException.class, () -> Alphabet.of(alphabet)); } } From a8d8bd24b39d0a746d1ed339c36d6e876c0342f3 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 01:23:51 +0900 Subject: [PATCH 80/90] =?UTF-8?q?test:=20Result=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Result.java | 8 ++--- src/test/java/wordle/domain/ResultTest.java | 40 ++++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/main/java/wordle/domain/Result.java b/src/main/java/wordle/domain/Result.java index 8e6f9cc8..9cbef8c5 100644 --- a/src/main/java/wordle/domain/Result.java +++ b/src/main/java/wordle/domain/Result.java @@ -15,6 +15,10 @@ public boolean allMatched() { return resultTypes.stream().allMatch(ResultType.MATCHED::equals); } + public ResultType get(final int index) { + return resultTypes.get(index); + } + public List getResult() { return Collections.unmodifiableList(resultTypes); } @@ -31,8 +35,4 @@ public boolean equals(final Object o) { public int hashCode() { return Objects.hashCode(resultTypes); } - - public ResultType get(final int index) { - return resultTypes.get(index); - } } diff --git a/src/test/java/wordle/domain/ResultTest.java b/src/test/java/wordle/domain/ResultTest.java index 608b69e2..451c168f 100644 --- a/src/test/java/wordle/domain/ResultTest.java +++ b/src/test/java/wordle/domain/ResultTest.java @@ -1,25 +1,47 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EnumSource; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class ResultTest { - @Test - void 모든_ResultType이_Matched라면_매칭_성공_여부를_true로_반환한다() { - final Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED)); + @EnumSource(value = ResultType.class, names = {"MATCHED"}) + @ParameterizedTest(name = "모든 ResultType이 {0}일 때 성공되었다고 판단한다") + void 모든_ResultType이_Matched라면_매칭_성공_여부를_true로_반환한다(final ResultType resultType) { + final Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, resultType)); assertTrue(result.allMatched()); } - @Test - void 모든_ResultType이_Matched가_아니라면_매칭_성공_여부를_false로_반환한다() { - final Result result = new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED)); + @EnumSource(value = ResultType.class, names = {"NONE", "MISMATCHED", "EXIST"}) + @ParameterizedTest(name = "ResultType 중 하나라도 {0}일 때 성공되지 않았다고 판단한다") + void 모든_ResultType이_Matched가_아니라면_매칭_성공_여부를_false로_반환한다(final ResultType resultType) { + final Result result = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, resultType)); assertFalse(result.allMatched()); } + + @CsvSource(value = {"0, MATCHED", "1, MISMATCHED", "2, EXIST"}) + @ParameterizedTest(name = "Result 가 생성될 때 {0} 순번의 ResultType {1} 를 반환할 수 있다") + void Result_가_생성될_때_N번의_ResultType_를_반환할_수_있다(final int index, final ResultType expected) { + final List matched = List.of(ResultType.MATCHED, ResultType.MISMATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED); + final Result result = new Result(matched); + + assertEquals(expected, result.get(index)); + } + + @EnumSource(value = ResultType.class, names = {"MATCHED", "NONE", "MISMATCHED", "EXIST"}) + @ParameterizedTest(name = "Result 가 생성될 때 {0} 가 포함된 ResultType 리스트를 반환할 수 있다") + void Result_가_생성될_때의_ResultType_리스트를_반환할_수_있다(final ResultType resultType) { + final List expected = List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, resultType); + final Result result = new Result(expected); + final List actual = result.getResult(); + + assertEquals(expected, actual); + } } From d853bad6240562056d1645d8570aa6299f2163a8 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 01:43:26 +0900 Subject: [PATCH 81/90] =?UTF-8?q?test:=20GameWord=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Alphabet.java | 5 +- src/main/java/wordle/domain/Answer.java | 6 +- src/main/java/wordle/domain/GameWord.java | 18 +----- src/main/java/wordle/domain/Guess.java | 12 ---- src/test/java/wordle/domain/GameWordTest.java | 60 +++++++++++++++---- src/test/java/wordle/domain/GuessTest.java | 14 ----- 6 files changed, 52 insertions(+), 63 deletions(-) diff --git a/src/main/java/wordle/domain/Alphabet.java b/src/main/java/wordle/domain/Alphabet.java index 72ac7931..912fc5ab 100644 --- a/src/main/java/wordle/domain/Alphabet.java +++ b/src/main/java/wordle/domain/Alphabet.java @@ -3,7 +3,8 @@ import java.util.Arrays; public enum Alphabet { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z; public static Alphabet of(final int codePoint) { return of(Character.toChars(codePoint)); @@ -15,7 +16,7 @@ public static Alphabet of(final char[] chars) { public static Alphabet of(final String alphabet) { return Arrays.stream(values()) - .filter(it -> it.name().equals(alphabet.toLowerCase())) + .filter(it -> it.name().equals(alphabet)) .findFirst() .orElseThrow(IllegalArgumentException::new); } diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index 76fd9ac4..de030bb5 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -43,7 +43,7 @@ public Result examine(final Guess guess) { .mapToObj(this::find) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - final List resultTypes = IntStream.range(START_INDEX, guess.size()) + final List resultTypes = IntStream.range(START_INDEX, matchedResults.size()) .mapToObj(index -> { if (ResultType.MATCHED.equals(matchedResults.get(index))) { return ResultType.MATCHED; @@ -59,8 +59,4 @@ public Result examine(final Guess guess) { .toList(); return new Result(resultTypes); } - - public int size() { - return word.size(); - } } diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java index 94d110bd..324b9fea 100644 --- a/src/main/java/wordle/domain/GameWord.java +++ b/src/main/java/wordle/domain/GameWord.java @@ -11,7 +11,7 @@ public class GameWord implements Word { private final List alphabets; private static List alphabets(final String word) { - return word.toLowerCase().codePoints() + return word.codePoints() .boxed() .map(Alphabet::of) .toList(); @@ -39,22 +39,6 @@ public Alphabet find(final int index) { return alphabets.get(index); } - public long countAlphabets(final Alphabet alphabet, final int toIndex) { - if (toIndex > alphabets.size()) { - throw new IllegalArgumentException("단어의 길이보다 작거나 같은 인덱스만 들어올 수 있습니다"); - } - return alphabets.subList(MINIMUM_INDEX, toIndex) - .stream() - .filter(alphabet::equals) - .count(); - } - - public long count(final Alphabet alphabet) { - return alphabets.stream() - .filter(alphabet::equals) - .count(); - } - public boolean isSameAs(final String word) { return word().equals(word); } diff --git a/src/main/java/wordle/domain/Guess.java b/src/main/java/wordle/domain/Guess.java index 563d154f..07c34929 100644 --- a/src/main/java/wordle/domain/Guess.java +++ b/src/main/java/wordle/domain/Guess.java @@ -11,19 +11,7 @@ public Guess(final String word) { this(new GameWord(word)); } - public int size() { - return word.size(); - } - public Alphabet find(final int index) { return word.find(index); } - - public long count(final Alphabet alphabet, final int endIndex) { - return word.countAlphabets(alphabet, endIndex); - } - - public long count(final Alphabet alphabet) { - return word.count(alphabet); - } } diff --git a/src/test/java/wordle/domain/GameWordTest.java b/src/test/java/wordle/domain/GameWordTest.java index 2339fab3..98742abc 100644 --- a/src/test/java/wordle/domain/GameWordTest.java +++ b/src/test/java/wordle/domain/GameWordTest.java @@ -1,31 +1,65 @@ package wordle.domain; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.*; public class GameWordTest { - @Test - void 게임_단어에_5글자가_아닌_문자열이_들어오면_예외를_발생한다() { - // given when then - assertThrowsExactly(IllegalArgumentException.class, () -> new GameWord("abcdef")); + @ValueSource(strings = {"", "a", "ab", "abc", "abcd", "abcdef"}) + @ParameterizedTest(name = "게임 단어는 생성할 때 5글자가 아닌 알파벳 문자열 {0} 이 들어오면 예외를 발생한다") + void 게임_단어는_생성할_때_5글자가_아닌_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new GameWord(word)); } - @Test - void 게임_단어에_5글자_알파벳_소문자_문자가_들어오면_생성할_수_있다() { - // given - final String word = "cigar"; + @ValueSource(strings = {"ㄱabcde", "!@$fz", "24315", "a1b2c", "a1b2c$"}) + @ParameterizedTest(name = "게임 단어는 생성할 때 5글자이지만 알파벳이 아닌 문자도 섞인 문자열 {0} 이 들어오면 예외를 발생한다") + void 게임_단어는_생성할_때_5글자이지만_알파벳이_아닌_문자도_섞인_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new GameWord(word)); + } + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "게임 단어는 5글자 알파벳 문자열 {0}이 들어오면 생성할 수 있다") + void 게임_단어는_5글자_알파벳_문자가_들어오면_생성할_수_있다(final String word) { assertDoesNotThrow(() -> new GameWord(word)); } + @DisplayName("게임 단어는 단어의 길이를 반환할 수 있다") @Test - void 게임_단어에_알파벳_소문자가_아닌_문자가_들어오더도_성생할_수_있다() { - // given - final String word = "Cigar"; + void 게임_단어는_단어의_길이를_반환할_수_있다() { + final String word = "abcde"; + final GameWord gameWord = new GameWord(word); - // when & then - assertDoesNotThrow(() -> new GameWord(word)); + assertEquals(word.length(), gameWord.size()); + } + + @CsvSource(value = {"0, a", "1, b", "2, c", "3, d", "4, e"}) + @ParameterizedTest(name = "게임 단어는 {0} 순번의 알파벳 {1} 을 반환할 수 있다") + void 게임_단어는_N번의_알파벳을_반환할_수_있다(final int index, final char alphabet) { + final Alphabet expected = Alphabet.of(alphabet); + final String word = "abcde"; + final GameWord gameWord = new GameWord(word); + + assertEquals(expected, gameWord.find(index)); + } + + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "게임 단어는 {0} 와 같은 단어인지 확인할 수 있다") + void 게임_단어는_주어진_문자열과_같은_단어인지_확인할_수_있다(final String word) { + final GameWord gameWord = new GameWord(word); + + assertTrue(gameWord.isSameAs(word)); + } + + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "게임 단어는 가지고 있는 단어를 문자열 {0}로 반환할 수 있다") + void 게임_단어는_가지고_있는_단어를_문자열로_반환할_수_있다(final String expected) { + final GameWord gameWord = new GameWord(expected); + + assertEquals(expected, gameWord.word()); } } diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index b5c3da61..b7b5b424 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -11,20 +11,6 @@ public class GuessTest { assertThrowsExactly(IllegalArgumentException.class, () -> new Guess("abcdef")); } - @Test - void 알파벳과_인덱스가_들어오면_해당_인덱스_이전의_알파벳_개수를_반환한다() { - final Guess guess = new Guess("tasty"); - final long count = guess.count(Alphabet.t, 4); - - assertEquals(2, count); - } - - @Test - void 답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { - final Guess guess = new Guess("tasty"); - - assertThrowsExactly(IllegalArgumentException.class, () -> guess.count(Alphabet.t, 6)); - } @Test void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { From d09129904e3dd955ac5374d1b93db3759bdbdcd8 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 01:49:00 +0900 Subject: [PATCH 82/90] =?UTF-8?q?test:=20DictionaryReader=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordle/domain/DictionaryReaderTest.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/test/java/wordle/domain/DictionaryReaderTest.java b/src/test/java/wordle/domain/DictionaryReaderTest.java index 5c1285de..6f81da5b 100644 --- a/src/test/java/wordle/domain/DictionaryReaderTest.java +++ b/src/test/java/wordle/domain/DictionaryReaderTest.java @@ -1,27 +1,35 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; public class DictionaryReaderTest { - @Test - void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다() { - final DictionaryReader dictionaryReader = new TestDictionaryReader(); - final Dictionary dictionary = dictionaryReader.read(); + @ValueSource(strings = {"apple", "banana", "cherry"}) + @ParameterizedTest(name = "단어장을 만들 때 사용한 문자열 {0} 을 읽을 수 있다") + void 단어장이_존재한다면_특정_조건을_통해_정답을_추출할_수_있다(final String word) { + final List dictionaryWords = List.of(new DictionaryWord(word)); + final Dictionary expected = new Dictionary(dictionaryWords); - assertNotNull(dictionary); + final DictionaryReader dictionaryReader = new TestDictionaryReader(dictionaryWords); + assertEquals(expected, dictionaryReader.read()); } class TestDictionaryReader implements DictionaryReader { + private final List words; + + public TestDictionaryReader(final List words) { + this.words = words; + } @Override public Dictionary read() { - return new Dictionary(List.of(new DictionaryWord("apple"))); + return new Dictionary(words); } } } From a91a56146efbb2059bcd16b52c9805e95814745a Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 02:13:16 +0900 Subject: [PATCH 83/90] =?UTF-8?q?test:=20DictionaryWord=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Game.java | 8 +++-- src/main/java/wordle/domain/Dictionary.java | 19 ++++------- .../wordle/domain/DictionaryFileReader.java | 1 + .../java/wordle/domain/DictionaryWord.java | 5 --- src/main/java/wordle/domain/Word.java | 2 -- src/main/java/wordle/domain/WordSelector.java | 1 - .../wordle/domain/DictionaryReaderTest.java | 1 + .../java/wordle/domain/DictionaryTest.java | 27 ++++++---------- .../wordle/domain/DictionaryWordTest.java | 32 +++++++++++++++++++ src/test/java/wordle/domain/GameWordTest.java | 8 ----- 10 files changed, 56 insertions(+), 48 deletions(-) create mode 100644 src/test/java/wordle/domain/DictionaryWordTest.java diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 3655dbb4..b6d5a776 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -22,7 +22,8 @@ public Game(final InputView inputView, public void start() { final Dictionary dictionary = dictionaryReader.read(); - final Answer answer = dictionary.answer(wordSelector); + final Word word = dictionary.select(wordSelector); + final Answer answer = new Answer(word.word()); play(dictionary, answer); } @@ -43,7 +44,10 @@ private Guess guess(final Dictionary dictionary) { try { outputView.insertWord(); final String word = inputView.inputWord(); - return dictionary.guess(word); + if(dictionary.isExist(word)) { + return new Guess(word); + } + return guess(dictionary); } catch (final Exception e) { outputView.wrongWord(); return guess(dictionary); diff --git a/src/main/java/wordle/domain/Dictionary.java b/src/main/java/wordle/domain/Dictionary.java index 0388ab34..d880ef72 100644 --- a/src/main/java/wordle/domain/Dictionary.java +++ b/src/main/java/wordle/domain/Dictionary.java @@ -1,28 +1,21 @@ package wordle.domain; import java.util.List; -import java.util.NoSuchElementException; import java.util.Objects; public class Dictionary { - private final List words; + private final List words; - public Dictionary(final List words) { + public Dictionary(final List words) { this.words = words; } - public Answer answer(final WordSelector wordSelector) { - final Word word = wordSelector.select(words); - return new Answer(word.word()); + public Word select(final WordSelector wordSelector) { + return wordSelector.select(words); } - public Guess guess(final String word) { - return words.stream() - .filter(it -> it.isSameAs(word)) - .map(Word::word) - .map(Guess::new) - .findFirst() - .orElseThrow(NoSuchElementException::new); + public boolean isExist(final String word) { + return words.stream().anyMatch(word::equals); } @Override diff --git a/src/main/java/wordle/domain/DictionaryFileReader.java b/src/main/java/wordle/domain/DictionaryFileReader.java index f77ab161..476565de 100644 --- a/src/main/java/wordle/domain/DictionaryFileReader.java +++ b/src/main/java/wordle/domain/DictionaryFileReader.java @@ -4,6 +4,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.stream.Collectors; public class DictionaryFileReader implements DictionaryReader { private static final String FILE_PATH = "src/main/resources/words.txt"; diff --git a/src/main/java/wordle/domain/DictionaryWord.java b/src/main/java/wordle/domain/DictionaryWord.java index a05c7095..524f1c6e 100644 --- a/src/main/java/wordle/domain/DictionaryWord.java +++ b/src/main/java/wordle/domain/DictionaryWord.java @@ -4,11 +4,6 @@ public record DictionaryWord(String word) implements Word { - @Override - public boolean isSameAs(final String other) { - return word.equals(other); - } - @Override public boolean equals(final Object o) { if (this == o) return true; diff --git a/src/main/java/wordle/domain/Word.java b/src/main/java/wordle/domain/Word.java index c2621478..3aca604a 100644 --- a/src/main/java/wordle/domain/Word.java +++ b/src/main/java/wordle/domain/Word.java @@ -1,7 +1,5 @@ package wordle.domain; public interface Word { - boolean isSameAs(String word); - String word(); } diff --git a/src/main/java/wordle/domain/WordSelector.java b/src/main/java/wordle/domain/WordSelector.java index c9d7f846..c9d0b844 100644 --- a/src/main/java/wordle/domain/WordSelector.java +++ b/src/main/java/wordle/domain/WordSelector.java @@ -1,6 +1,5 @@ package wordle.domain; - import java.util.List; @FunctionalInterface diff --git a/src/test/java/wordle/domain/DictionaryReaderTest.java b/src/test/java/wordle/domain/DictionaryReaderTest.java index 6f81da5b..7c7f0788 100644 --- a/src/test/java/wordle/domain/DictionaryReaderTest.java +++ b/src/test/java/wordle/domain/DictionaryReaderTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.params.provider.ValueSource; import java.util.List; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/wordle/domain/DictionaryTest.java b/src/test/java/wordle/domain/DictionaryTest.java index 21b3b62d..2b4cb3fc 100644 --- a/src/test/java/wordle/domain/DictionaryTest.java +++ b/src/test/java/wordle/domain/DictionaryTest.java @@ -1,28 +1,21 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; public class DictionaryTest { + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "단어장을 만들 때 사용한 문자열 {0} 을 읽을 수 있다") + void 단어장에_존재하는_단어는_추춣할_수_있다(final String word) { + final DictionaryWord dictionaryWord = new DictionaryWord(word); + final Dictionary dictionary = new Dictionary(List.of(dictionaryWord)); + final Word actual = dictionary.select((it) -> dictionaryWord); - @Test - void Selector가_주어진다면_조건에_해당하는_단어를_추출할_수_있다() { - final DictionaryWord word = new DictionaryWord("cigar"); - - final Dictionary dictionary = new Dictionary(List.of(word)); - final Answer answer = dictionary.answer((it) -> it.get(0)); - - assertNotNull(answer); - } - - @Test - void Selector가_주어졌지만_조건에_해당하는_단어가_없다면_예외를_발생한다() { - final Dictionary dictionary = new Dictionary(List.of()); - - assertThrows(RuntimeException.class, () -> dictionary.answer((it) -> it.get(0))); + assertNotNull(actual); } } diff --git a/src/test/java/wordle/domain/DictionaryWordTest.java b/src/test/java/wordle/domain/DictionaryWordTest.java new file mode 100644 index 00000000..3b0c09c5 --- /dev/null +++ b/src/test/java/wordle/domain/DictionaryWordTest.java @@ -0,0 +1,32 @@ +package wordle.domain; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DictionaryWordTest { + + @ValueSource(strings = { + "", "a", "ab", "abc", "abcd", "abcdef", + "ㄱabcde", "!@$fz", "24315", "a1b2c", "a1b2c$", + "abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE", + }) + @ParameterizedTest(name = "단어장 단어는 모든 문자열 중 하나인 {0} 에 대해서 생성 할 수 있다") + void 단어장_단어는_모든_문자열에_대해서_생성_할_수_있다(final String word) { + assertDoesNotThrow(() -> new DictionaryWord((word))); + } + + @ValueSource(strings = { + "", "a", "ab", "abc", "abcd", "abcdef", + "ㄱabcde", "!@$fz", "24315", "a1b2c", "a1b2c$", + "abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE", + }) + @ParameterizedTest(name = "단어장 단어는 생성될 때 사용한 문자열 {0} 에 대해서 반환 할 수 있다") + void 단어장_단어는_생성될_때_사용한_문자열을_반환_할_수_있다(final String expected) { + final DictionaryWord dictionaryWord = new DictionaryWord((expected)); + + assertEquals(expected, dictionaryWord.word()); + } +} diff --git a/src/test/java/wordle/domain/GameWordTest.java b/src/test/java/wordle/domain/GameWordTest.java index 98742abc..d1b3ecd5 100644 --- a/src/test/java/wordle/domain/GameWordTest.java +++ b/src/test/java/wordle/domain/GameWordTest.java @@ -47,14 +47,6 @@ public class GameWordTest { assertEquals(expected, gameWord.find(index)); } - @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) - @ParameterizedTest(name = "게임 단어는 {0} 와 같은 단어인지 확인할 수 있다") - void 게임_단어는_주어진_문자열과_같은_단어인지_확인할_수_있다(final String word) { - final GameWord gameWord = new GameWord(word); - - assertTrue(gameWord.isSameAs(word)); - } - @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) @ParameterizedTest(name = "게임 단어는 가지고 있는 단어를 문자열 {0}로 반환할 수 있다") void 게임_단어는_가지고_있는_단어를_문자열로_반환할_수_있다(final String expected) { From ece84a3177a7fe8b2cab135d6e0bbdc987560dea Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 02:20:15 +0900 Subject: [PATCH 84/90] =?UTF-8?q?test:=20Guess=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/GuessTest.java | 41 +++++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/test/java/wordle/domain/GuessTest.java b/src/test/java/wordle/domain/GuessTest.java index b7b5b424..649bb3a6 100644 --- a/src/test/java/wordle/domain/GuessTest.java +++ b/src/test/java/wordle/domain/GuessTest.java @@ -1,30 +1,45 @@ package wordle.domain; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.*; public class GuessTest { - @Test - void 답안은_5글자가_아니면_예외를_발생한다() { - assertThrowsExactly(IllegalArgumentException.class, () -> new Guess("abcdef")); + @ValueSource(strings = {"", "a", "ab", "abc", "abcd", "abcdef"}) + @ParameterizedTest(name = "답안은 생성할 때 5글자가 아닌 알파벳 문자열 {0} 이 들어오면 예외를 발생한다") + void 답안은_생성할_때_5글자가_아닌_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new Guess(word)); } + @ValueSource(strings = {"ㄱabcde", "!@$fz", "24315", "a1b2c", "a1b2c$"}) + @ParameterizedTest(name = "답안은 생성할 때 5글자이지만 알파벳이 아닌 문자도 섞인 문자열 {0} 이 들어오면 예외를 발생한다") + void 답안은_생성할_때_5글자이지만_알파벳이_아닌_문자도_섞인_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new Guess(word)); + } - @Test - void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { - final Guess guess = new Guess("tasty"); + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "답안은 5글자 알파벳 문자열 {0}이 들어오면 생성할 수 있다") + void 답안은_5글자_알파벳_문자가_들어오면_생성할_수_있다(final String word) { + assertDoesNotThrow(() -> new Guess(word)); + } - final Alphabet alphabet = guess.find(0); + @CsvSource(value = {"0, t", "1, a", "2, s", "3, t", "4, y"}) + @ParameterizedTest(name = "답안은 {0} 순번의 알파벳 {1} 을 반환할 수 있다") + void 답안은_인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다(final int index, final char alphabet) { + final Alphabet expected = Alphabet.of(alphabet); + final Guess guess = new Guess("tasty"); - assertEquals(alphabet, Alphabet.t); + assertEquals(expected, guess.find(index)); } - @Test - void 알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { - final Guess guess = new Guess("tasty"); + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "답안은 가지고 있는 단어보다 긴 인덱스가 들어오면 예외를 발생한다") + void 답안은_알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다(final String word) { + final Guess guess = new Guess(word); - assertThrows(IllegalArgumentException.class, () -> guess.find(5)); + assertThrows(IllegalArgumentException.class, () -> guess.find(word.length())); } } From 6fa1d40168ba38c7359a1fc05f130958735e4106 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 02:39:54 +0900 Subject: [PATCH 85/90] =?UTF-8?q?test:=20Answer=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/AnswerTest.java | 100 +++++++++++++++----- 1 file changed, 78 insertions(+), 22 deletions(-) diff --git a/src/test/java/wordle/domain/AnswerTest.java b/src/test/java/wordle/domain/AnswerTest.java index c4e419e1..d0c9bd91 100644 --- a/src/test/java/wordle/domain/AnswerTest.java +++ b/src/test/java/wordle/domain/AnswerTest.java @@ -1,6 +1,10 @@ package wordle.domain; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; import java.util.List; @@ -9,45 +13,86 @@ public class AnswerTest { - @Test - void 정답은_정답과_동일한_답안이_들어오면_모두_MATCHED인_결과를_반환한다() { - // given - final Answer answer = new Answer("cigar"); - final Guess guess = new Guess("cigar"); + @ValueSource(strings = {"", "a", "ab", "abc", "abcd", "abcdef"}) + @ParameterizedTest(name = "정답은 생성할 때 5글자가 아닌 알파벳 문자열 {0} 이 들어오면 예외를 발생한다") + void 정답은_생성할_때_5글자가_아닌_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new Answer(word)); + } + + @ValueSource(strings = {"ㄱabcde", "!@$fz", "24315", "a1b2c", "a1b2c$"}) + @ParameterizedTest(name = "정답은 생성할 때 5글자이지만 알파벳이 아닌 문자도 섞인 문자열 {0} 이 들어오면 예외를 발생한다") + void 정답은_생성할_때_5글자이지만_알파벳이_아닌_문자도_섞인_문자열이_들어오면_예외를_발생한다(final String word) { + assertThrowsExactly(IllegalArgumentException.class, () -> new Answer(word)); + } - final Result expectedResult = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "정답은 5글자 알파벳 문자열 {0}이 들어오면 생성할 수 있다") + void 정답은_5글자_알파벳_문자가_들어오면_생성할_수_있다(final String word) { + assertDoesNotThrow(() -> new Answer(word)); + } - // when - final Result result = answer.examine(guess); + @CsvSource(value = {"0, t", "1, a", "2, s", "3, t", "4, y"}) + @ParameterizedTest(name = "정답 {0}은 순번의 알파벳 {1} 을 반환할 수 있다") + void 정답은_인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다(final int index, final char alphabet) { + final Alphabet expected = Alphabet.of(alphabet); + final Answer answer = new Answer("tasty"); - // then - assertEquals(result, expectedResult); + assertEquals(expected, answer.find(index)); } - @Test - void 정답은_5글자가_아니면_예외를_발생한다() { - assertThrowsExactly(IllegalArgumentException.class, () -> new Answer("abcdef")); + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "정답 {0}은 가지고 있는 단어보다 긴 인덱스가 들어오면 예외를 발생한다") + void 정답은_알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다(final String word) { + final Answer answer = new Answer(word); + + assertThrows(IllegalArgumentException.class, () -> answer.find(word.length())); } + @ValueSource(strings = {"abcde", "fghij", "klmno", "pqrst", "uvwxy", "zxcvb", "ABCDE", "AbcdE"}) + @ParameterizedTest(name = "정답 {0}은 가지고 있는 단어와 동일한 답안{0}이 들어오면 모두 MATCHED인 결과를 반환한다") + void 정답은_정답과_동일한_답안이_들어오면_모두_MATCHED인_결과를_반환한다(final String word) { + final Answer answer = new Answer(word); + final Guess guess = new Guess(word); - @Test - void 인덱스가_들어오면_해당_인덱스의_알파벳을_반환한다() { - final Answer answer = new Answer("tasty"); + final Result expected = new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)); + + assertEquals(expected, answer.examine(guess)); + } - final Alphabet alphabet = answer.find(0); + @CsvSource(value = {"abcde, fghij", "abcde, ABCDE", "klmno, pqrst", "uewfk, zxcvb"}) + @ParameterizedTest(name = "정답 {0}은 가지고 있는 단어와 문자가 하나도 같지 않은 답안 {1}이 들어오면 모두 MISMATCHED인 결과를 반환한다") + void 정답은_문자가_하나도_같지_않은_답안이_들어오면_모두_MISMATCHED인_결과를_반환한다(final String answerWord, final String guessWord) { + final Answer answer = new Answer(answerWord); + final Guess guess = new Guess(guessWord); + final Result expected = new Result(List.of(MISMATCHED, MISMATCHED, MISMATCHED, MISMATCHED, MISMATCHED)); - assertEquals(alphabet, Alphabet.t); + assertEquals(expected, answer.examine(guess)); } + @CsvSource(value = {"abcde, bcdea", "abcde, cdeab", "plmno, lmnop", "uewfk, ewfku"}) + @ParameterizedTest(name = "정답 {0}은 가지고 있는 단어와 문자가 일부만 일치하는 답안 {1}이 들어오면 일치하는 문자만 EXIST 로 처리한다") + void 정답은_가지고_있는_단어와_문자가_일부만_일치하는_답안이_들어오면_일치하는_문자만_EXIST로_처리한다(final String answerWord, final String guessWord) { + final Answer answer = new Answer(answerWord); + final Guess guess = new Guess(guessWord); + final Result expected = new Result(List.of(EXIST, EXIST, EXIST, EXIST, EXIST)); + + assertEquals(expected, answer.examine(guess)); + } + + @DisplayName("정답은 가지고 있는 단어와 문자가 일치, 존재, 미존재 하는 답안이 들어오면 매칭 결과를 반환한다") @Test - void 알파벳_조회시_답안_길이보다_긴_인덱스가_들어오면_예외를_발생한다() { - final Answer answer = new Answer("tasty"); + void 정답은_가지고_있는_단어와_문자가_일치_존재_미존재_하는_답안이_들어오면_매칭_결과를_반환한다() { + final Answer answer = new Answer("hello"); + final Guess guess = new Guess("apple"); + final Result expected = new Result(List.of(MISMATCHED, MISMATCHED, MISMATCHED, MATCHED, EXIST)); - assertThrows(IllegalArgumentException.class, () -> answer.find(5)); + final Result actual = answer.examine(guess); + assertEquals(expected, actual); } + @DisplayName("정답은 가지고 있는 단어와 문자가 일부만 일치하는 답안이 들어오면 일치하는 문자만 MATCHED로 처리한다") @Test - void 매칭_타입_단어와_동일한_단어가_앞에_존재할_경우_미존재_타입으로_처리한다() { + void 정답은_가지고_있는_단어와_문자가_일부만_일치하는_답안이_앞에_들어오면_일치하는_문자만_MATCHED로_처리한다() { final Answer answer = new Answer("apple"); final Guess guess = new Guess("hello"); final Result expected = new Result(List.of(MISMATCHED, EXIST, MISMATCHED, MATCHED, MISMATCHED)); @@ -55,4 +100,15 @@ public class AnswerTest { final Result actual = answer.examine(guess); assertEquals(expected, actual); } + + @DisplayName("정답은 가지고 있는 단어와 문자가 일부만 일치하는 답안이 뒤에 들어오면 일치하는 문자만 MATCHED로 처리한다") + @Test + void 정답은_가지고_있는_단어와_문자가_일부만_일치하는_답안이_뒤에_들어오면_일치하는_문자만_MATCHED로_처리한다() { + final Answer answer = new Answer("hello"); + final Guess guess = new Guess("olleh"); + final Result expected = new Result(List.of(EXIST, EXIST, MATCHED, EXIST, EXIST)); + + final Result actual = answer.examine(guess); + assertEquals(expected, actual); + } } From 1efe596e051b7fee399c45db197f7c84edf35b99 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 02:44:15 +0900 Subject: [PATCH 86/90] =?UTF-8?q?test:=20Results=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/wordle/domain/ResultsTest.java | 47 +++++++++----------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/test/java/wordle/domain/ResultsTest.java b/src/test/java/wordle/domain/ResultsTest.java index 8d213105..8d568747 100644 --- a/src/test/java/wordle/domain/ResultsTest.java +++ b/src/test/java/wordle/domain/ResultsTest.java @@ -1,5 +1,6 @@ package wordle.domain; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -8,54 +9,48 @@ public class ResultsTest { + @DisplayName("결과 목록은 가지고 있는 결과의 개수를 반환할 수 있다") @Test - void 결과들을_가지고_있다면_개수를_반환할_수_있다() { - // given + void 결과_목록은_가지고_있는_결과의_개수를_반환할_수_있다() { final List resultList = List.of( - new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), - new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)), - new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED)), - new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)) + new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) ); final Results results = new Results(resultList); - // when - final int actual = results.size(); - - // then - assertEquals(actual, 4); + assertEquals(resultList.size(), results.size()); } + @DisplayName("결과 목록은 모든 결과가 매칭된 결과가 있는 경우 true를 반환한다") @Test - void 문자가_모두_일치하는_결과가_있는_경우_true를_반환한다() { - // given + void 결과_목록은_모든_결과가_매칭된_결과가_있는_경우_true를_반환한다() { final List resultList = List.of( - new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)), new Result(List.of(ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) ); final Results results = new Results(resultList); - // when - results.hasAnswer(); - - // then assertTrue(results.hasAnswer()); } + @DisplayName("결과 목록은 모든 결과가 매칭된 결과가 없는 경우 false를 반환한다") @Test - void 문자가_모두_일치하는_결과가_없는_경우_false를_반환한다() { - // given + void 결과_목록은_모든_결과가_매칭된_결과가_없는_경우_false를_반환한다() { final List resultList = List.of( - new Result(List.of(ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), - new Result(List.of(ResultType.MATCHED, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)) + new Result(List.of(ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST, ResultType.EXIST)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED, ResultType.MISMATCHED)), + new Result(List.of(ResultType.EXIST, ResultType.MISMATCHED, ResultType.MATCHED, ResultType.MATCHED, ResultType.MATCHED)), + new Result(List.of(ResultType.MISMATCHED, ResultType.MATCHED, ResultType.EXIST, ResultType.MATCHED, ResultType.MATCHED)) ); final Results results = new Results(resultList); - // when - results.hasAnswer(); - - // then assertFalse(results.hasAnswer()); } } From 102dd6e2886b6ce454d6c0fc0801f6182d86b631 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 02:45:58 +0900 Subject: [PATCH 87/90] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=BB=A8=EB=B2=A4=EC=85=98=20=EB=B0=8F=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Application.java | 2 +- src/main/java/wordle/Game.java | 2 +- src/main/java/wordle/domain/Answer.java | 2 +- src/main/java/wordle/domain/DictionaryFileReader.java | 1 - src/main/java/wordle/domain/GameWord.java | 4 ---- src/main/java/wordle/domain/ResultType.java | 6 +----- src/test/java/wordle/domain/DictionaryReaderTest.java | 1 - 7 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/main/java/wordle/Application.java b/src/main/java/wordle/Application.java index b0db0764..36b59cb2 100644 --- a/src/main/java/wordle/Application.java +++ b/src/main/java/wordle/Application.java @@ -1,8 +1,8 @@ package wordle; -import wordle.domain.EpochDayBaseWordSelector; import wordle.domain.DictionaryFileReader; import wordle.domain.DictionaryReader; +import wordle.domain.EpochDayBaseWordSelector; import wordle.domain.WordSelector; import wordle.view.ConsoleInputView; import wordle.view.ConsoleOutputView; diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index b6d5a776..135a00f9 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -44,7 +44,7 @@ private Guess guess(final Dictionary dictionary) { try { outputView.insertWord(); final String word = inputView.inputWord(); - if(dictionary.isExist(word)) { + if (dictionary.isExist(word)) { return new Guess(word); } return guess(dictionary); diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index de030bb5..0648e2b7 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -50,7 +50,7 @@ public Result examine(final Guess guess) { } final Alphabet alphabet = guess.find(index); final long count = unmatchedAnswerCounts.getOrDefault(alphabet, DEFAULT_COUNT); - if (count > 0) { + if (count > DEFAULT_COUNT) { unmatchedAnswerCounts.put(alphabet, Math.subtractExact(count, DECREASE_COUNT_UNIT)); return ResultType.EXIST; } diff --git a/src/main/java/wordle/domain/DictionaryFileReader.java b/src/main/java/wordle/domain/DictionaryFileReader.java index 476565de..f77ab161 100644 --- a/src/main/java/wordle/domain/DictionaryFileReader.java +++ b/src/main/java/wordle/domain/DictionaryFileReader.java @@ -4,7 +4,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.stream.Collectors; public class DictionaryFileReader implements DictionaryReader { private static final String FILE_PATH = "src/main/resources/words.txt"; diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java index 324b9fea..5623abe3 100644 --- a/src/main/java/wordle/domain/GameWord.java +++ b/src/main/java/wordle/domain/GameWord.java @@ -39,10 +39,6 @@ public Alphabet find(final int index) { return alphabets.get(index); } - public boolean isSameAs(final String word) { - return word().equals(word); - } - @Override public String word() { return alphabets.stream() diff --git a/src/main/java/wordle/domain/ResultType.java b/src/main/java/wordle/domain/ResultType.java index 47961842..4f940766 100644 --- a/src/main/java/wordle/domain/ResultType.java +++ b/src/main/java/wordle/domain/ResultType.java @@ -4,9 +4,5 @@ public enum ResultType { NONE, MATCHED, EXIST, - MISMATCHED; - - public boolean isNotEquals(final ResultType resultType) { - return this.equals(resultType); - } + MISMATCHED } diff --git a/src/test/java/wordle/domain/DictionaryReaderTest.java b/src/test/java/wordle/domain/DictionaryReaderTest.java index 7c7f0788..6f81da5b 100644 --- a/src/test/java/wordle/domain/DictionaryReaderTest.java +++ b/src/test/java/wordle/domain/DictionaryReaderTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.params.provider.ValueSource; import java.util.List; -import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; From 774a9bcdae2e5d4198ff2399934eac95cc838cbf Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 03:05:55 +0900 Subject: [PATCH 88/90] =?UTF-8?q?refactor:=20=EC=86=8C=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=20=EB=AC=B8=EA=B5=AC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/GameWord.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/wordle/domain/GameWord.java b/src/main/java/wordle/domain/GameWord.java index 5623abe3..82d4af63 100644 --- a/src/main/java/wordle/domain/GameWord.java +++ b/src/main/java/wordle/domain/GameWord.java @@ -23,7 +23,7 @@ public GameWord(final String word) { public GameWord(final List alphabets) { if (alphabets.size() != WORD_SIZE) { - throw new IllegalArgumentException("단어는 5글자의 소문자 알파벳으로 이루어져야 합니다"); + throw new IllegalArgumentException("단어는 5글자의 알파벳으로 이루어져야 합니다"); } this.alphabets = alphabets; } From 6b70b33f2601de6af6cdf140d8337156759611a5 Mon Sep 17 00:00:00 2001 From: woozi Date: Wed, 26 Jun 2024 03:09:29 +0900 Subject: [PATCH 89/90] =?UTF-8?q?refactor:=20Answer=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EC=A0=91=EA=B7=BC=20=EC=A0=9C=EC=96=B4=EC=9E=90=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/domain/Answer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/wordle/domain/Answer.java b/src/main/java/wordle/domain/Answer.java index 0648e2b7..cad25d45 100644 --- a/src/main/java/wordle/domain/Answer.java +++ b/src/main/java/wordle/domain/Answer.java @@ -9,8 +9,8 @@ public class Answer { private static final int START_INDEX = 0; - public static final long DEFAULT_COUNT = 0L; - public static final long DECREASE_COUNT_UNIT = 1L; + private static final long DEFAULT_COUNT = 0L; + private static final long DECREASE_COUNT_UNIT = 1L; private final GameWord word; From dd70ea8ed926de1dbb874f86ecd2f41bd0541fdf Mon Sep 17 00:00:00 2001 From: woozi Date: Sat, 29 Jun 2024 13:58:37 +0900 Subject: [PATCH 90/90] =?UTF-8?q?fix:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=97=90=20=EB=A7=9E=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EB=8B=A8=EC=96=B4=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=EC=9E=AC?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=AC=B8=EA=B5=AC=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/wordle/Game.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/wordle/Game.java b/src/main/java/wordle/Game.java index 135a00f9..2c1a937a 100644 --- a/src/main/java/wordle/Game.java +++ b/src/main/java/wordle/Game.java @@ -47,7 +47,7 @@ private Guess guess(final Dictionary dictionary) { if (dictionary.isExist(word)) { return new Guess(word); } - return guess(dictionary); + throw new IllegalArgumentException(); } catch (final Exception e) { outputView.wrongWord(); return guess(dictionary);