From 08a59e6a6522a71a5859e601fa9a89713c8736ee Mon Sep 17 00:00:00 2001 From: jylim Date: Tue, 11 Jun 2024 10:56:04 +0900 Subject: [PATCH 01/42] =?UTF-8?q?feat(domain):=20=EA=B8=B0=EC=B4=88=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ src/main/java/config/FileConfig.java | 5 +++++ src/main/java/controller/GameManager.java | 17 +++++++++++++++++ src/main/java/domain/Answer.java | 17 +++++++++++++++++ src/main/java/domain/Hint.java | 18 ++++++++++++++++++ src/main/java/domain/InputWord.java | 21 +++++++++++++++++++++ src/main/java/domain/MatchResult.java | 8 ++++++++ src/main/java/domain/MatchResults.java | 8 ++++++++ src/main/java/domain/MatchRule.java | 8 ++++++++ src/main/java/domain/Round.java | 19 +++++++++++++++++++ src/main/java/infra/WordLoader.java | 20 ++++++++++++++++++++ src/main/java/ui/HintView.java | 9 +++++++++ src/main/java/ui/RoundView.java | 7 +++++++ 13 files changed, 159 insertions(+) create mode 100644 src/main/java/config/FileConfig.java create mode 100644 src/main/java/controller/GameManager.java create mode 100644 src/main/java/domain/Answer.java create mode 100644 src/main/java/domain/Hint.java create mode 100644 src/main/java/domain/InputWord.java create mode 100644 src/main/java/domain/MatchResult.java create mode 100644 src/main/java/domain/MatchResults.java create mode 100644 src/main/java/domain/MatchRule.java create mode 100644 src/main/java/domain/Round.java create mode 100644 src/main/java/infra/WordLoader.java create mode 100644 src/main/java/ui/HintView.java create mode 100644 src/main/java/ui/RoundView.java diff --git a/README.md b/README.md index d3179421..99d54b93 100644 --- a/README.md +++ b/README.md @@ -87,3 +87,5 @@ spill - 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다. + + diff --git a/src/main/java/config/FileConfig.java b/src/main/java/config/FileConfig.java new file mode 100644 index 00000000..415f648d --- /dev/null +++ b/src/main/java/config/FileConfig.java @@ -0,0 +1,5 @@ +package config; + +public class FileConfig { + public final static String FILE_PATH = "src/main/resources/words.txt"; +} diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java new file mode 100644 index 00000000..98f28164 --- /dev/null +++ b/src/main/java/controller/GameManager.java @@ -0,0 +1,17 @@ +package controller; + +import domain.MatchResults; +import domain.Round; + +import java.util.ArrayList; +import java.util.List; + +public class GameManager { + private Round round; + private List matchResults; + public GameManager() { + this.matchResults = new ArrayList<>(); + } + + +} diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java new file mode 100644 index 00000000..19f5f722 --- /dev/null +++ b/src/main/java/domain/Answer.java @@ -0,0 +1,17 @@ +package domain; + +public class Answer { + private String value; + + public Answer(String value) { + this.value = value; + } + + Boolean exists(char inputChar) { + return true; + } + + Boolean isCorrect(int index, char inputChar) { + return true; + } +} diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java new file mode 100644 index 00000000..94436281 --- /dev/null +++ b/src/main/java/domain/Hint.java @@ -0,0 +1,18 @@ +package domain; + +public enum Hint { + + CORRECT("🟩"), //\uD83D\\uDFE9 + EXIST("🟨"), //\uD83D\\uDFE8 + NOT_EXIST("⬜"); + + private final String hint; + + Hint(String hint) { + this.hint = hint; + } + + public String getHint() { + return hint; + } +} diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java new file mode 100644 index 00000000..cfadc267 --- /dev/null +++ b/src/main/java/domain/InputWord.java @@ -0,0 +1,21 @@ +package domain; + +import java.util.List; + +public class InputWord { + private String values; + private List availableWords; + + public InputWord(String values, List availableWords) { + this.values = values; + this.availableWords = availableWords; + validate(values); + } + + private void validate(String input) { + if(this.availableWords.contains(input)){ + throw new IllegalArgumentException("입력 불가능한 단어입니다."); + } + } + +} diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java new file mode 100644 index 00000000..b98a183a --- /dev/null +++ b/src/main/java/domain/MatchResult.java @@ -0,0 +1,8 @@ +package domain; + +public class MatchResult { + private char inputChar; + private Hint hint; +} + + diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java new file mode 100644 index 00000000..0222b8be --- /dev/null +++ b/src/main/java/domain/MatchResults.java @@ -0,0 +1,8 @@ +package domain; + +import java.util.List; + +public class MatchResults { + private List results; + +} diff --git a/src/main/java/domain/MatchRule.java b/src/main/java/domain/MatchRule.java new file mode 100644 index 00000000..173e3dd8 --- /dev/null +++ b/src/main/java/domain/MatchRule.java @@ -0,0 +1,8 @@ +package domain; + +// 비교하는 룰 +public class MatchRule { + MatchResults match(InputWord input, Answer answer) { + return new MatchResults(); + } +} diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java new file mode 100644 index 00000000..e00f6d4a --- /dev/null +++ b/src/main/java/domain/Round.java @@ -0,0 +1,19 @@ +package domain; + +public class Round { + private int limit; + private int current; + + public Round(int limit, int current) { + this.limit = limit; + this.current = current; + } + + void goNext() { + this.current++; + } + + Boolean isLastRound() { + return this.current >= this.limit; + } +} diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java new file mode 100644 index 00000000..5e4216b0 --- /dev/null +++ b/src/main/java/infra/WordLoader.java @@ -0,0 +1,20 @@ +package infra; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +public class WordLoader { + + private WordLoader() { + } + + public static List read(String filePath) { + try { + return Files.readAllLines(Paths.get(filePath)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java new file mode 100644 index 00000000..bf73f391 --- /dev/null +++ b/src/main/java/ui/HintView.java @@ -0,0 +1,9 @@ +package ui; + +import domain.MatchResults; + +public class HintView { + public void render(MatchResults matchResults) { + System.out.println("render grid"); + } +} diff --git a/src/main/java/ui/RoundView.java b/src/main/java/ui/RoundView.java new file mode 100644 index 00000000..9eb547c0 --- /dev/null +++ b/src/main/java/ui/RoundView.java @@ -0,0 +1,7 @@ +package ui; + +public class RoundView { + public void render() { + System.out.println("render round"); + } +} From b8a2253a99b32d7434f0537571bafcad6476ef0a Mon Sep 17 00:00:00 2001 From: jylim Date: Tue, 11 Jun 2024 16:48:48 +0900 Subject: [PATCH 02/42] =?UTF-8?q?feat(WordleApplication):=20GameManager=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=9D=BC=EB=B3=84=20=EB=8B=A8=EC=96=B4=20=EC=84=A0=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/WordleApplication.java | 11 +++++++++++ src/main/java/controller/GameManager.java | 12 ++++++++++++ src/main/java/domain/Answer.java | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/main/java/WordleApplication.java diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java new file mode 100644 index 00000000..7261af69 --- /dev/null +++ b/src/main/java/WordleApplication.java @@ -0,0 +1,11 @@ +import controller.GameManager; +import infra.WordLoader; + +public class WordleApplication { + public static void main(String[] args) { + String filePath = "src/main/resources/english_words_10k_mit.txt"; + GameManager gameManager = new GameManager(WordLoader.read(filePath)); + gameManager.startGame(); + } + +} diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 98f28164..dad23503 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,5 +1,6 @@ package controller; +import domain.Answer; import domain.MatchResults; import domain.Round; @@ -9,9 +10,20 @@ public class GameManager { private Round round; private List matchResults; + private Answer answer; public GameManager() { this.matchResults = new ArrayList<>(); } + public GameManager(List wordList) { + this.round = new Round(5, 0); // 총 6번과 시작은 항상 0 + this.matchResults = new ArrayList<>(); + this.answer = Answer.from(wordList); + } + + public void startGame() { + + } + } diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index 19f5f722..bea331e5 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -1,5 +1,10 @@ package domain; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; + public class Answer { private String value; @@ -14,4 +19,17 @@ Boolean exists(char inputChar) { Boolean isCorrect(int index, char inputChar) { return true; } + + public static Answer from(List avaliableWords) { + LocalDate currentDate = LocalDate.now(); + LocalDate fixedDate = LocalDate.of(2021, 6, 19); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); + int formattedDate = Integer.parseInt(currentDate.format(formatter)); + int fixedFormattedDate = Integer.parseInt(fixedDate.format(formatter)); + + int idx = (formattedDate - fixedFormattedDate) % avaliableWords.size(); + + return new Answer(avaliableWords.get(idx)); + } } From e640bb707fe313d057a58a2fdb872044adbd1b44 Mon Sep 17 00:00:00 2001 From: jylim Date: Thu, 13 Jun 2024 09:31:04 +0900 Subject: [PATCH 03/42] =?UTF-8?q?feat:=20domain=20=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/WordleApplication.java | 12 ++++++-- src/main/java/controller/GameManager.java | 5 +++- src/main/java/domain/Answer.java | 36 +++++++++++++++-------- src/main/java/domain/Hint.java | 2 +- src/main/java/domain/InputWord.java | 30 +++++++++++++++---- src/main/java/domain/MatchResult.java | 24 ++++++++++++++- src/main/java/domain/MatchResults.java | 10 ++++++- src/main/java/infra/WordLoader.java | 3 +- src/main/java/ui/GuideTextView.java | 8 +++++ 9 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 src/main/java/ui/GuideTextView.java diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 7261af69..54f604c0 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -1,11 +1,17 @@ +import config.FileConfig; import controller.GameManager; import infra.WordLoader; +import java.util.List; + public class WordleApplication { public static void main(String[] args) { - String filePath = "src/main/resources/english_words_10k_mit.txt"; - GameManager gameManager = new GameManager(WordLoader.read(filePath)); - gameManager.startGame(); + + List words = WordLoader.read(FileConfig.FILE_PATH); + GameManager gameManager = new GameManager(words); + + gameManager.start(); + } } diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index dad23503..0ca1af19 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -4,6 +4,7 @@ import domain.MatchResults; import domain.Round; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,7 @@ public GameManager() { public GameManager(List wordList) { this.round = new Round(5, 0); // 총 6번과 시작은 항상 0 this.matchResults = new ArrayList<>(); - this.answer = Answer.from(wordList); + this.answer = new Answer(LocalDate.now(), wordList); } public void startGame() { @@ -26,4 +27,6 @@ public void startGame() { } + public void start() { + } } diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index bea331e5..eefad993 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -1,9 +1,11 @@ -package domain; +package domain; +import java.time.Duration; import java.time.LocalDate; -import java.time.format.DateTimeFormatter; +import java.time.Period; import java.util.List; +import java.util.Objects; public class Answer { private String value; @@ -12,24 +14,34 @@ public Answer(String value) { this.value = value; } + public Answer(LocalDate currentDate, List availableWords) { + LocalDate fixedDate = LocalDate.of(2021, 6, 19); + int diffDay = Period.between(fixedDate, currentDate).getDays(); + int index = diffDay % availableWords.size(); + this.value = availableWords.get(index); + } + + Boolean exists(char inputChar) { - return true; + return value.indexOf(inputChar) != -1; } Boolean isCorrect(int index, char inputChar) { - return true; + return value.indexOf(inputChar) == index; } - public static Answer from(List avaliableWords) { - LocalDate currentDate = LocalDate.now(); - LocalDate fixedDate = LocalDate.of(2021, 6, 19); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); - int formattedDate = Integer.parseInt(currentDate.format(formatter)); - int fixedFormattedDate = Integer.parseInt(fixedDate.format(formatter)); + Answer answer = (Answer) o; - int idx = (formattedDate - fixedFormattedDate) % avaliableWords.size(); + return Objects.equals(value, answer.value); + } - return new Answer(avaliableWords.get(idx)); + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; } } diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index 94436281..df8ed4da 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -15,4 +15,4 @@ public enum Hint { public String getHint() { return hint; } -} +} \ No newline at end of file diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java index cfadc267..1ecdb61b 100644 --- a/src/main/java/domain/InputWord.java +++ b/src/main/java/domain/InputWord.java @@ -1,21 +1,39 @@ package domain; +import java.util.ArrayList; import java.util.List; public class InputWord { - private String values; + private String value; private List availableWords; - public InputWord(String values, List availableWords) { - this.values = values; + public MatchResults match(Answer answer){ + ArrayList matchResults = new ArrayList<>(); + for(int i = 0; i< value.length(); i++){ + char c = value.charAt(i); + if(answer.isCorrect(i, c)){ + matchResults.add(new MatchResult(c, Hint.CORRECT)); + continue; + } + if(answer.exists(c)){ + matchResults.add(new MatchResult(c, Hint.EXIST)); + continue; + } + matchResults.add(new MatchResult(c, Hint.NOT_EXIST)); + } + return new MatchResults(matchResults); + } + + public InputWord(String value, List availableWords) { + this.value = value; this.availableWords = availableWords; - validate(values); + validate(value); } private void validate(String input) { - if(this.availableWords.contains(input)){ + if(!this.availableWords.contains(input)){ throw new IllegalArgumentException("입력 불가능한 단어입니다."); } } -} +} \ No newline at end of file diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index b98a183a..6e99960f 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -3,6 +3,28 @@ public class MatchResult { private char inputChar; private Hint hint; -} + public MatchResult(char inputChar, Hint hint) { + this.inputChar = inputChar; + this.hint = hint; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MatchResult that = (MatchResult) o; + + if (inputChar != that.inputChar) return false; + return hint == that.hint; + } + + @Override + public int hashCode() { + int result = inputChar; + result = 31 * result + (hint != null ? hint.hashCode() : 0); + return result; + } +} diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 0222b8be..fb393939 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -1,8 +1,16 @@ package domain; import java.util.List; +import java.util.Objects; public class MatchResults { private List results; -} + public MatchResults(List results) { + this.results = results; + } + + public List getResults() { + return results; + } +} \ No newline at end of file diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java index 5e4216b0..5d683ca8 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordLoader.java @@ -1,3 +1,4 @@ + package infra; import java.io.IOException; @@ -7,7 +8,7 @@ public class WordLoader { - private WordLoader() { + public WordLoader() { } public static List read(String filePath) { diff --git a/src/main/java/ui/GuideTextView.java b/src/main/java/ui/GuideTextView.java new file mode 100644 index 00000000..b611b214 --- /dev/null +++ b/src/main/java/ui/GuideTextView.java @@ -0,0 +1,8 @@ +package ui; + +public class GuideTextView { + public void render() { + System.out.println("WORDLE을 6번 만에 맞춰 보세요."); + System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); + } +} \ No newline at end of file From cd10e1b3f9efcd3ea9f3faac4ed66e9092b7d209 Mon Sep 17 00:00:00 2001 From: jylim Date: Thu, 13 Jun 2024 09:31:17 +0900 Subject: [PATCH 04/42] =?UTF-8?q?test:=20domain=20=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/AnswerTest.java | 22 +++++++ src/test/java/domain/InputWordTest.java | 70 +++++++++++++++++++++++ src/test/java/domain/MatchResultTest.java | 16 ++++++ src/test/java/infra/WordLoaderTest.java | 17 ++++++ src/test/resources/words.txt | 5 ++ 5 files changed, 130 insertions(+) create mode 100644 src/test/java/domain/AnswerTest.java create mode 100644 src/test/java/domain/InputWordTest.java create mode 100644 src/test/java/domain/MatchResultTest.java create mode 100644 src/test/java/infra/WordLoaderTest.java create mode 100644 src/test/resources/words.txt diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java new file mode 100644 index 00000000..026b4cd8 --- /dev/null +++ b/src/test/java/domain/AnswerTest.java @@ -0,0 +1,22 @@ + +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class AnswerTest { + @Test + @DisplayName("정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다") + void answerSelectTest(){ + List words = List.of("apple", "banana", "cherry", "date", "elderberry"); + Answer answer = new Answer(LocalDate.of(2021, 6, 20), words); + + assertThat(answer).isEqualTo(new Answer("banana")); + } +} diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java new file mode 100644 index 00000000..58658eab --- /dev/null +++ b/src/test/java/domain/InputWordTest.java @@ -0,0 +1,70 @@ + +package 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 java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + + +class InputWordTest { + @DisplayName("입력단어 유효성 검증 성공 테스트") + void validateSuccessInputWord() { + List words = List.of("apples", "cherry"); + assertDoesNotThrow(() -> new InputWord("cherry", words)); + + } + + + @Test + @DisplayName("입력단어 유효성 검증 실패 테스트") + void + validateFailInputWord() { + List words = List.of("apples", "banana"); + assertThrows(IllegalArgumentException.class,() -> new InputWord("pangyo", words)); + } + + @Test + @DisplayName("입력단어와 정답 비교") + void matchTest() { + List words = List.of("apples", "banana", "cherry"); + + InputWord inputWord = new InputWord("cherry", words); + Answer answer = new Answer("zzzrxx"); + MatchResults matchResults = inputWord.match(answer); + + assertThat(matchResults.getResults()).containsExactly( + new MatchResult('c', Hint.CORRECT), + new MatchResult('h', Hint.EXIST), + new MatchResult('e', Hint.NOT_EXIST), + new MatchResult('r', Hint.NOT_EXIST), + new MatchResult('r', Hint.NOT_EXIST), + new MatchResult('y', Hint.NOT_EXIST) + ); + } + + @Test + @DisplayName("입력단어와 정답 위치 확인 테스트") + void matchLocationTest() { + List words = List.of("xxxrxr"); + + InputWord inputWord = new InputWord("xxxrxr", words); + Answer answer = new Answer("cherry"); + MatchResults matchResults = inputWord.match(answer); + + assertThat(matchResults.getResults()).containsExactly( + new MatchResult('x', Hint.NOT_EXIST), + new MatchResult('x', Hint.NOT_EXIST), + new MatchResult('x', Hint.NOT_EXIST), + new MatchResult('r', Hint.CORRECT), + new MatchResult('x', Hint.NOT_EXIST), + new MatchResult('r', Hint.EXIST) + ); + } +} diff --git a/src/test/java/domain/MatchResultTest.java b/src/test/java/domain/MatchResultTest.java new file mode 100644 index 00000000..4c578f0c --- /dev/null +++ b/src/test/java/domain/MatchResultTest.java @@ -0,0 +1,16 @@ +package domain; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class MatchResultTest { + + @Test + void equalsTest(){ + MatchResult matchResult1 = new MatchResult('a', Hint.CORRECT); + MatchResult matchResult2 = new MatchResult('a', Hint.CORRECT); + + assertEquals(matchResult1, matchResult2); + } +} \ No newline at end of file diff --git a/src/test/java/infra/WordLoaderTest.java b/src/test/java/infra/WordLoaderTest.java new file mode 100644 index 00000000..40b205fe --- /dev/null +++ b/src/test/java/infra/WordLoaderTest.java @@ -0,0 +1,17 @@ +package infra; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class WordLoaderTest { + @Test + @DisplayName("단어목록파일 읽기") + void loadWordsFromFile(){ + List words = WordLoader.read("src/test/resources/words.txt"); + assertThat(words).hasSize(5); + } +} \ No newline at end of file diff --git a/src/test/resources/words.txt b/src/test/resources/words.txt new file mode 100644 index 00000000..bc35cd4a --- /dev/null +++ b/src/test/resources/words.txt @@ -0,0 +1,5 @@ +cigar +rebut +sissy +humph +awake \ No newline at end of file From 41c538d38027a3d791587c2540e3ff4b1d30e692 Mon Sep 17 00:00:00 2001 From: jylim Date: Thu, 13 Jun 2024 09:41:42 +0900 Subject: [PATCH 05/42] =?UTF-8?q?chore:=20Scacnner=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ui/HintView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java index bf73f391..556163d1 100644 --- a/src/main/java/ui/HintView.java +++ b/src/main/java/ui/HintView.java @@ -1,9 +1,14 @@ package ui; import domain.MatchResults; +import java.util.Scanner; public class HintView { public void render(MatchResults matchResults) { +// Scanner sc = new Scanner(System.in); +// return sc.nextLine(); + System.out.println("render grid"); } } +1 \ No newline at end of file From 18beffc969a908824a31344cc07eccf98ed723dc Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:18:05 +0900 Subject: [PATCH 06/42] =?UTF-8?q?chore:=20=EB=AA=85=EC=8B=9C=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EC=88=98=EB=AA=85=EC=9C=BC=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/main/java/domain/Hint.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index df8ed4da..ee879abc 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -6,13 +6,13 @@ public enum Hint { EXIST("🟨"), //\uD83D\\uDFE8 NOT_EXIST("⬜"); - private final String hint; + private final String tile; Hint(String hint) { - this.hint = hint; + this.tile = hint; } - public String getHint() { - return hint; + public String getTile() { + return tile; } -} \ No newline at end of file +} From 8534b1a73f3f0b335382ac03a688df01ffd42954 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:19:08 +0900 Subject: [PATCH 07/42] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EA=B0=80=20=EC=9E=88=EC=9D=84=20=EB=95=8C=20=EC=B2=AB?= =?UTF-8?q?=EB=B2=88=EC=A7=B8=20idx=EB=A5=BC=20=EB=A6=AC=ED=84=B4=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=98=A4=EB=A5=98=EC=98=A4=20=EC=9D=B8=EB=8D=B1?= =?UTF-8?q?=EC=8A=A4=EC=9D=98=20=EB=8B=A8=EC=96=B4=20=EB=B9=84=EA=B5=90?= =?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/main/java/domain/Answer.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index eefad993..8198a1e8 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -1,4 +1,3 @@ - package domain; import java.time.Duration; @@ -20,14 +19,12 @@ public Answer(LocalDate currentDate, List availableWords) { int index = diffDay % availableWords.size(); this.value = availableWords.get(index); } - - Boolean exists(char inputChar) { return value.indexOf(inputChar) != -1; } Boolean isCorrect(int index, char inputChar) { - return value.indexOf(inputChar) == index; + return value.charAt(index) == inputChar; } @Override From f43ebb4bcaacfde0fd7206950b1d1a6b7ef5ed9e Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:20:05 +0900 Subject: [PATCH 08/42] =?UTF-8?q?feat:=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20Iterator=20=EC=83=81?= =?UTF-8?q?=EC=86=8D=20=EB=B0=8F=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResult.java | 9 +++++++++ src/main/java/domain/MatchResults.java | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 6e99960f..6a89555e 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -9,6 +9,15 @@ public MatchResult(char inputChar, Hint hint) { this.hint = hint; } + public String getTile() { + return hint.getTile(); + } + + + public boolean isCorrect() { + return Hint.CORRECT.equals(hint); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index fb393939..f750eb9a 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -1,16 +1,26 @@ package domain; +import java.util.Iterator; import java.util.List; import java.util.Objects; -public class MatchResults { +public class MatchResults implements Iterable { private List results; public MatchResults(List results) { this.results = results; } + @Override + public Iterator iterator() { + return results.iterator(); + } + public List getResults() { return results; } -} \ No newline at end of file + + public boolean isEndGame() { + return results.stream().allMatch(MatchResult::isCorrect); + } +} From f1d4626c2316203bf2371d407395b3ebb48968e4 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:20:23 +0900 Subject: [PATCH 09/42] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=81=B4=EB=9E=98=EC=8A=A4=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/domain/MatchRule.java | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/main/java/domain/MatchRule.java diff --git a/src/main/java/domain/MatchRule.java b/src/main/java/domain/MatchRule.java deleted file mode 100644 index 173e3dd8..00000000 --- a/src/main/java/domain/MatchRule.java +++ /dev/null @@ -1,8 +0,0 @@ -package domain; - -// 비교하는 룰 -public class MatchRule { - MatchResults match(InputWord input, Answer answer) { - return new MatchResults(); - } -} From 3d86ff7d37baa3e25c42e8840d9dfe3c91078e6e Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:21:01 +0900 Subject: [PATCH 10/42] =?UTF-8?q?feat:=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EB=85=B8=EC=B6=9C=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=A9=94=EC=86=8C=EB=93=9C=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/main/java/domain/Round.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index e00f6d4a..305fbd1e 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -9,11 +9,23 @@ public Round(int limit, int current) { this.current = current; } - void goNext() { + public void goNext() { this.current++; } Boolean isLastRound() { return this.current >= this.limit; } + + public int getLimit() { + return limit; + } + + public int getCurrent() { + return current; + } + + public boolean isNotFinalRound() { + return current <= limit; + } } From bdc209402d9d8105420aeac6fc9f3dab25828115 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:21:58 +0900 Subject: [PATCH 11/42] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C=20view=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/infra/WordLoader.java | 1 - src/main/java/ui/HintView.java | 16 +++++++++------- src/main/java/ui/InputView.java | 13 +++++++++++++ src/main/java/ui/RoundView.java | 4 ++-- 4 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 src/main/java/ui/InputView.java diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java index 5d683ca8..b11de611 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordLoader.java @@ -1,4 +1,3 @@ - package infra; import java.io.IOException; diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java index 556163d1..4ec2f3fd 100644 --- a/src/main/java/ui/HintView.java +++ b/src/main/java/ui/HintView.java @@ -1,14 +1,16 @@ package ui; import domain.MatchResults; -import java.util.Scanner; -public class HintView { - public void render(MatchResults matchResults) { -// Scanner sc = new Scanner(System.in); -// return sc.nextLine(); +import java.util.List; - System.out.println("render grid"); +public class HintView { + public void render(List matchResults) { + matchResults.forEach(matchResultEachRound -> { + matchResultEachRound.forEach(matchResult -> { + System.out.print(matchResult.getTile()); + }); + System.out.println(); + }); } } -1 \ No newline at end of file diff --git a/src/main/java/ui/InputView.java b/src/main/java/ui/InputView.java new file mode 100644 index 00000000..a074578e --- /dev/null +++ b/src/main/java/ui/InputView.java @@ -0,0 +1,13 @@ +package ui; + +import java.util.Scanner; + +public class InputView { + private Scanner scanner = new Scanner(System.in); + public String input() { + System.out.println("정답을 입력해 주세요."); + + return scanner.nextLine(); + } + +} diff --git a/src/main/java/ui/RoundView.java b/src/main/java/ui/RoundView.java index 9eb547c0..16f8c246 100644 --- a/src/main/java/ui/RoundView.java +++ b/src/main/java/ui/RoundView.java @@ -1,7 +1,7 @@ package ui; public class RoundView { - public void render() { - System.out.println("render round"); + public void render(int current, int max) { + System.out.printf("%d/%d%n", current, max); } } From 2b28b8dc64005df93f0eab532087e567b52011ab Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 11:22:16 +0900 Subject: [PATCH 12/42] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EA=B8=B0?= =?UTF-8?q?=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/main/java/controller/GameManager.java | 52 ++++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 0ca1af19..ed84d6c1 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,8 +1,13 @@ package controller; import domain.Answer; +import domain.InputWord; import domain.MatchResults; import domain.Round; +import ui.GuideTextView; +import ui.HintView; +import ui.InputView; +import ui.RoundView; import java.time.LocalDate; import java.util.ArrayList; @@ -12,21 +17,56 @@ public class GameManager { private Round round; private List matchResults; private Answer answer; - public GameManager() { + + private List availableWords; + + private GuideTextView guideTextView; + private InputView inputView; + private HintView hintView; + private RoundView roundView; + private boolean isEndGame = false; + + protected GameManager() { this.matchResults = new ArrayList<>(); + this.availableWords = new ArrayList<>(); } - public GameManager(List wordList) { - this.round = new Round(5, 0); // 총 6번과 시작은 항상 0 + public GameManager(List availableWords) { + this.answer = new Answer(LocalDate.now(), availableWords); + this.availableWords = availableWords; + this.round = new Round(6, 1); this.matchResults = new ArrayList<>(); - this.answer = new Answer(LocalDate.now(), wordList); + this.guideTextView = new GuideTextView(); + this.inputView = new InputView(); + this.hintView = new HintView(); + this.roundView = new RoundView(); } - public void startGame() { + public void start() { + guideTextView.render(); + while(!this.isEndGame && round.isNotFinalRound()) { + startRound(); + } } + private void startRound() { + // 라운드 입력 view + String input = inputView.input(); - public void start() { + InputWord inputWord = new InputWord(input, this.availableWords); + MatchResults matchResultOfInput = inputWord.match(answer); + this.matchResults.add(matchResultOfInput); + + // 정답 확인 + boolean isEndGame = matchResultOfInput.isEndGame(); + if(isEndGame) { + roundView.render(round.getCurrent(),round.getLimit()); + this.isEndGame = isEndGame; + } + + // 힌트 노출 + hintView.render(this.matchResults); + round.goNext(); } } From 77f092342d5ed1c5c1032d42f5533341ff388a98 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:38:51 +0900 Subject: [PATCH 13/42] =?UTF-8?q?refact:=20=ED=9E=8C=ED=8A=B8=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=EB=8E=81=EC=8A=A4=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ui/HintView.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java index 4ec2f3fd..c28ca158 100644 --- a/src/main/java/ui/HintView.java +++ b/src/main/java/ui/HintView.java @@ -1,16 +1,19 @@ package ui; +import domain.MatchResult; import domain.MatchResults; -import java.util.List; - public class HintView { - public void render(List matchResults) { + public void render(MatchResults matchResults) { matchResults.forEach(matchResultEachRound -> { - matchResultEachRound.forEach(matchResult -> { - System.out.print(matchResult.getTile()); - }); + renderTiles(matchResultEachRound); System.out.println(); }); } + + private void renderTiles(MatchResult matchResultEachRound) { + matchResultEachRound.forEach(matchResult -> { + System.out.print(matchResult.getTile()); + }); + } } From 1d5c4c7e8f3e3bba52b81e4c58247d76a73db07f Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:40:09 +0900 Subject: [PATCH 14/42] =?UTF-8?q?refactor:=20Answer,=20InputWord=EB=A5=BC?= =?UTF-8?q?=20=EA=B0=99=EC=9D=80=20=EC=86=8D=EC=84=B1=EC=9D=B8=20Word?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Answer.java | 44 ------------ src/main/java/domain/InputWord.java | 39 ----------- src/main/java/domain/Word.java | 101 ++++++++++++++++++++++++++++ src/main/java/ui/GuideTextView.java | 2 +- 4 files changed, 102 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/domain/Answer.java delete mode 100644 src/main/java/domain/InputWord.java create mode 100644 src/main/java/domain/Word.java diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java deleted file mode 100644 index 8198a1e8..00000000 --- a/src/main/java/domain/Answer.java +++ /dev/null @@ -1,44 +0,0 @@ -package domain; - -import java.time.Duration; -import java.time.LocalDate; -import java.time.Period; -import java.util.List; -import java.util.Objects; - -public class Answer { - private String value; - - public Answer(String value) { - this.value = value; - } - - public Answer(LocalDate currentDate, List availableWords) { - LocalDate fixedDate = LocalDate.of(2021, 6, 19); - int diffDay = Period.between(fixedDate, currentDate).getDays(); - int index = diffDay % availableWords.size(); - this.value = availableWords.get(index); - } - Boolean exists(char inputChar) { - return value.indexOf(inputChar) != -1; - } - - Boolean isCorrect(int index, char inputChar) { - return value.charAt(index) == inputChar; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Answer answer = (Answer) o; - - return Objects.equals(value, answer.value); - } - - @Override - public int hashCode() { - return value != null ? value.hashCode() : 0; - } -} diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java deleted file mode 100644 index 1ecdb61b..00000000 --- a/src/main/java/domain/InputWord.java +++ /dev/null @@ -1,39 +0,0 @@ -package domain; - -import java.util.ArrayList; -import java.util.List; - -public class InputWord { - private String value; - private List availableWords; - - public MatchResults match(Answer answer){ - ArrayList matchResults = new ArrayList<>(); - for(int i = 0; i< value.length(); i++){ - char c = value.charAt(i); - if(answer.isCorrect(i, c)){ - matchResults.add(new MatchResult(c, Hint.CORRECT)); - continue; - } - if(answer.exists(c)){ - matchResults.add(new MatchResult(c, Hint.EXIST)); - continue; - } - matchResults.add(new MatchResult(c, Hint.NOT_EXIST)); - } - return new MatchResults(matchResults); - } - - public InputWord(String value, List availableWords) { - this.value = value; - this.availableWords = availableWords; - validate(value); - } - - private void validate(String input) { - if(!this.availableWords.contains(input)){ - throw new IllegalArgumentException("입력 불가능한 단어입니다."); - } - } - -} \ No newline at end of file diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java new file mode 100644 index 00000000..54ba2187 --- /dev/null +++ b/src/main/java/domain/Word.java @@ -0,0 +1,101 @@ +package domain; + +import java.time.LocalDate; +import java.time.Period; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Word { + private final static int MAX_LENGTH = 5; + private final String value; + + protected Word(String value) { + this.value = value; + } + + public static Word createAnswer(LocalDate currentDate, List availableWords) { + LocalDate fixedDate = LocalDate.of(2021, 6, 19); + int diffDay = Period.between(fixedDate, currentDate).getDays(); + int index = diffDay % availableWords.size(); + + return new Word(availableWords.get(index)); + } + + public static Word createInput(String value, List availableWords) { + validate(value, availableWords); + return new Word(value); + } + + public MatchResult match(Word word) { + List hints = IntStream.range(0, value.length()) + .mapToObj(i -> getHint(word.getCharBy(i), i)) + .collect(Collectors.toList()); + + return new MatchResult(hints); + } + + private Hint getHint(Character character, int index) { + if (isCorrect(index, character)) { + return Hint.CORRECT; + } + if (exists(character)) { + return Hint.EXIST; + } + return Hint.NOT_EXIST; + } + + private char getCharBy(int i) { + return value.charAt(i); + } + + private Boolean exists(char inputChar) { + return value.indexOf(inputChar) != -1; + } + + private Boolean isCorrect(int index, char inputChar) { + return value.charAt(index) == inputChar; + } + + private static void validate(String input, List availableWords) { + validateLength(input); + + validateOnlyEnglish(input); + + validateContain(input, availableWords); + } + + private static void validateOnlyEnglish(String input) { + if (!input.matches("^[a-zA-Z]+$")) { + throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); + } + } + + private static void validateLength(String input) { + if (input.length() != MAX_LENGTH) { + throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); + } + } + + private static void validateContain(String input, List availableWords) { + if (!availableWords.contains(input)) { + throw new IllegalArgumentException("입력 불가능한 단어입니다."); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Word answer = (Word) o; + + return Objects.equals(value, answer.value); + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } +} diff --git a/src/main/java/ui/GuideTextView.java b/src/main/java/ui/GuideTextView.java index b611b214..3c6ef5a2 100644 --- a/src/main/java/ui/GuideTextView.java +++ b/src/main/java/ui/GuideTextView.java @@ -5,4 +5,4 @@ public void render() { System.out.println("WORDLE을 6번 만에 맞춰 보세요."); System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); } -} \ No newline at end of file +} From babbf2c60a5cbfffd33c55eba49cf48b32eef05b Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:40:51 +0900 Subject: [PATCH 15/42] =?UTF-8?q?refactor:=20MatchResults=EC=99=80=20Match?= =?UTF-8?q?Result=EB=A5=BC=20=EC=9D=BC=EA=B8=89=EC=BB=AC=EB=9E=99=EC=85=98?= =?UTF-8?q?=EC=9C=BC=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/main/java/domain/Hint.java | 4 +++ src/main/java/domain/MatchResult.java | 45 ++++++++++++++------------ src/main/java/domain/MatchResults.java | 17 ++++++---- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index ee879abc..98849476 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -15,4 +15,8 @@ public enum Hint { public String getTile() { return tile; } + + public static boolean isCorrect(Hint hint) { + return Hint.CORRECT.equals(hint); + } } diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 6a89555e..de1a7cac 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -1,39 +1,42 @@ package domain; -public class MatchResult { - private char inputChar; - private Hint hint; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; - public MatchResult(char inputChar, Hint hint) { - this.inputChar = inputChar; - this.hint = hint; - } +public class MatchResult implements Iterable{ + private final List hints; - public String getTile() { - return hint.getTile(); + public MatchResult(List hints) { + this.hints = hints; } - - public boolean isCorrect() { - return Hint.CORRECT.equals(hint); + public MatchResult() { + this.hints = new ArrayList<>(); } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public Iterator iterator() { + return hints.iterator(); + } - MatchResult that = (MatchResult) o; + public boolean isEndGame() { + return hints.stream().allMatch(Hint::isCorrect); + } - if (inputChar != that.inputChar) return false; - return hint == that.hint; + public void add(Hint hint) { + hints.add(hint); } @Override public int hashCode() { - int result = inputChar; - result = 31 * result + (hint != null ? hint.hashCode() : 0); - return result; + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this.hints.equals(((MatchResult) obj).hints); } } + diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index f750eb9a..815cf05e 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -1,8 +1,8 @@ package domain; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Objects; public class MatchResults implements Iterable { private List results; @@ -11,16 +11,21 @@ public MatchResults(List results) { this.results = results; } - @Override - public Iterator iterator() { - return results.iterator(); + public MatchResults() { + this.results = new ArrayList<>(); } + public List getResults() { return results; } - public boolean isEndGame() { - return results.stream().allMatch(MatchResult::isCorrect); + @Override + public Iterator iterator() { + return this.results.iterator(); + } + + public void add(MatchResult matchResultOfInput) { + this.results.add(matchResultOfInput); } } From f01a856353eade1228008068c3f794d6d36efa4d Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:41:19 +0900 Subject: [PATCH 16/42] =?UTF-8?q?refactor:=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=82=AC=ED=95=AD=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EC=8B=9C=EC=9E=91=20=EA=B8=B0=EB=8A=A5=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/controller/GameManager.java | 45 +++++++++++++---------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index ed84d6c1..0a94d401 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,22 +1,21 @@ package controller; -import domain.Answer; -import domain.InputWord; +import domain.MatchResult; import domain.MatchResults; import domain.Round; +import domain.Word; import ui.GuideTextView; import ui.HintView; import ui.InputView; import ui.RoundView; import java.time.LocalDate; -import java.util.ArrayList; import java.util.List; public class GameManager { private Round round; - private List matchResults; - private Answer answer; + private MatchResults matchResults; + private Word answer; private List availableWords; @@ -24,18 +23,16 @@ public class GameManager { private InputView inputView; private HintView hintView; private RoundView roundView; - private boolean isEndGame = false; + private boolean isWinning = false; protected GameManager() { - this.matchResults = new ArrayList<>(); - this.availableWords = new ArrayList<>(); } public GameManager(List availableWords) { - this.answer = new Answer(LocalDate.now(), availableWords); + this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; this.round = new Round(6, 1); - this.matchResults = new ArrayList<>(); + this.matchResults = new MatchResults(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); this.hintView = new HintView(); @@ -45,7 +42,7 @@ public GameManager(List availableWords) { public void start() { guideTextView.render(); - while(!this.isEndGame && round.isNotFinalRound()) { + while(!this.isWinning && round.isNotFinalRound()) { startRound(); } } @@ -54,19 +51,29 @@ private void startRound() { // 라운드 입력 view String input = inputView.input(); - InputWord inputWord = new InputWord(input, this.availableWords); - MatchResults matchResultOfInput = inputWord.match(answer); - this.matchResults.add(matchResultOfInput); + Word inputWord; + try { + inputWord = Word.createInput(input, this.availableWords); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return; + } - // 정답 확인 - boolean isEndGame = matchResultOfInput.isEndGame(); - if(isEndGame) { + checkAnswer(inputWord); + + if(this.isWinning) { roundView.render(round.getCurrent(),round.getLimit()); - this.isEndGame = isEndGame; } - // 힌트 노출 hintView.render(this.matchResults); round.goNext(); } + + private void checkAnswer(Word inputWord) { + MatchResult matchResultOfInput = answer.match(inputWord); + this.matchResults.add(matchResultOfInput); + + this.isWinning = matchResultOfInput.isEndGame(); + } + } From aab91e415f0dc5a35ae54c9684849e4a0280d388 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:41:39 +0900 Subject: [PATCH 17/42] =?UTF-8?q?refactor(test):=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=9C=20=EA=B5=AC=EC=A1=B0=EC=97=90=20=EB=A7=9E=EA=B2=8C=20?= =?UTF-8?q?test=20=EB=A1=9C=EC=A7=81=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/domain/AnswerTest.java | 66 +++++++++++++++++++++-- src/test/java/domain/InputWordTest.java | 52 ++++++------------ src/test/java/domain/MatchResultTest.java | 16 ------ 3 files changed, 76 insertions(+), 58 deletions(-) delete mode 100644 src/test/java/domain/MatchResultTest.java diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index 026b4cd8..e084f5c9 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -1,4 +1,3 @@ - package domain; import org.junit.jupiter.api.DisplayName; @@ -8,15 +7,72 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; class AnswerTest { @Test @DisplayName("정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다") - void answerSelectTest(){ + void answerSelectTest() { List words = List.of("apple", "banana", "cherry", "date", "elderberry"); - Answer answer = new Answer(LocalDate.of(2021, 6, 20), words); + Word answer = Word.createAnswer(LocalDate.of(2021, 6, 20), words); + + assertThat(answer).isEqualTo(new Word("banana")); + } + + + @Test + @DisplayName("입력단어와 정답 비교") + void matchTest() { + List words = List.of("apple", "banan", "cherr"); + + Word inputWord = Word.createInput("cherr", words); + Word answer = new Word("czzzh"); + MatchResult matchResults = answer.match(inputWord); + + MatchResult expected = new MatchResult(List.of( + Hint.CORRECT, + Hint.EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST + )); + assertThat(matchResults).isEqualTo(expected); + } + + @Test + @DisplayName("입력단어와 중복 단어 위치 확인 테스트") + void matchLocationTest() { + List words = List.of("rxxrx"); + + Word inputWord = Word.createInput("rxxrx", words); + Word answer = new Word("cherr"); + MatchResult matchResults = answer.match(inputWord); + + MatchResult expected = new MatchResult(List.of( + Hint.EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.CORRECT, + Hint.NOT_EXIST + )); + assertThat(matchResults).isEqualTo(expected); + } + + @Test + @DisplayName("전부정답인 경우") + void test() { + List words = List.of("colon"); + + Word inputWord = Word.createInput("colon", words); + Word answer = new Word("colon"); + MatchResult matchResults = answer.match(inputWord); - assertThat(answer).isEqualTo(new Answer("banana")); + MatchResult expected = new MatchResult(List.of( + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT + )); + assertThat(matchResults).isEqualTo(expected); } } diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 58658eab..1f4d296b 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -1,15 +1,10 @@ - package 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 java.util.ArrayList; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -17,7 +12,7 @@ class InputWordTest { @DisplayName("입력단어 유효성 검증 성공 테스트") void validateSuccessInputWord() { List words = List.of("apples", "cherry"); - assertDoesNotThrow(() -> new InputWord("cherry", words)); + assertDoesNotThrow(() -> Word.createInput("cherry", words)); } @@ -27,44 +22,27 @@ void validateSuccessInputWord() { void validateFailInputWord() { List words = List.of("apples", "banana"); - assertThrows(IllegalArgumentException.class,() -> new InputWord("pangyo", words)); + assertThrows(IllegalArgumentException.class,() -> Word.createInput("pangyo", words)); } @Test - @DisplayName("입력단어와 정답 비교") - void matchTest() { - List words = List.of("apples", "banana", "cherry"); - - InputWord inputWord = new InputWord("cherry", words); - Answer answer = new Answer("zzzrxx"); - MatchResults matchResults = inputWord.match(answer); - - assertThat(matchResults.getResults()).containsExactly( - new MatchResult('c', Hint.CORRECT), - new MatchResult('h', Hint.EXIST), - new MatchResult('e', Hint.NOT_EXIST), - new MatchResult('r', Hint.NOT_EXIST), - new MatchResult('r', Hint.NOT_EXIST), - new MatchResult('y', Hint.NOT_EXIST) - ); + @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") + void validateInputWordLength() { + List words = List.of("apple", "abcdef"); + assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcdef", words)); } - @Test - @DisplayName("입력단어와 정답 위치 확인 테스트") - void matchLocationTest() { - List words = List.of("xxxrxr"); - InputWord inputWord = new InputWord("xxxrxr", words); - Answer answer = new Answer("cherry"); - MatchResults matchResults = inputWord.match(answer); + @Test + @DisplayName("입력단어 영단어 유효성 검증 실패 테스트") + void validateInputWordOnlyEnglish() { + List words = List.of("apple", "abcd1", "안녕하세요"); - assertThat(matchResults.getResults()).containsExactly( - new MatchResult('x', Hint.NOT_EXIST), - new MatchResult('x', Hint.NOT_EXIST), - new MatchResult('x', Hint.NOT_EXIST), - new MatchResult('r', Hint.CORRECT), - new MatchResult('x', Hint.NOT_EXIST), - new MatchResult('r', Hint.EXIST) + assertAll( + () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcd1", words)), + () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("안녕하세요", words)) ); } + + } diff --git a/src/test/java/domain/MatchResultTest.java b/src/test/java/domain/MatchResultTest.java deleted file mode 100644 index 4c578f0c..00000000 --- a/src/test/java/domain/MatchResultTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package domain; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class MatchResultTest { - - @Test - void equalsTest(){ - MatchResult matchResult1 = new MatchResult('a', Hint.CORRECT); - MatchResult matchResult2 = new MatchResult('a', Hint.CORRECT); - - assertEquals(matchResult1, matchResult2); - } -} \ No newline at end of file From 106c07df933f2b75236042090a7c4be5a9e9fd05 Mon Sep 17 00:00:00 2001 From: jylim Date: Sun, 16 Jun 2024 15:42:50 +0900 Subject: [PATCH 18/42] =?UTF-8?q?chore:=20String=EC=9D=84=20Intstream?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20hint=20=EA=B2=B0=EA=B3=BC=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20=EB=B0=94=EB=A1=9C=20=EB=A6=AC=ED=84=B4=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20String=EC=9D=84=20Lis?= =?UTF-8?q?t=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=B4=EC=95=BC?= =?UTF-8?q?=ED=95=98=EB=8A=94=EC=A7=80=20=EA=B3=A0=EB=AF=BC=EC=9D=B4=20?= =?UTF-8?q?=EB=8D=94=20=ED=95=84=EC=9A=94=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Word.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 54ba2187..5a0dd462 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -32,7 +32,6 @@ public MatchResult match(Word word) { List hints = IntStream.range(0, value.length()) .mapToObj(i -> getHint(word.getCharBy(i), i)) .collect(Collectors.toList()); - return new MatchResult(hints); } From e6da42bd424bf08da3912d67e8f3cc69e0829478 Mon Sep 17 00:00:00 2001 From: jylim Date: Mon, 17 Jun 2024 08:16:34 +0900 Subject: [PATCH 19/42] =?UTF-8?q?chore:=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=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Word.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 5a0dd462..9111d611 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -30,7 +30,7 @@ public static Word createInput(String value, List availableWords) { public MatchResult match(Word word) { List hints = IntStream.range(0, value.length()) - .mapToObj(i -> getHint(word.getCharBy(i), i)) + .mapToObj(i -> getHint(value.charAt(i), i)) .collect(Collectors.toList()); return new MatchResult(hints); } @@ -45,10 +45,6 @@ private Hint getHint(Character character, int index) { return Hint.NOT_EXIST; } - private char getCharBy(int i) { - return value.charAt(i); - } - private Boolean exists(char inputChar) { return value.indexOf(inputChar) != -1; } From 62efc4652b8845bd44d73993baef8e7dad79b883 Mon Sep 17 00:00:00 2001 From: jylim Date: Mon, 17 Jun 2024 21:23:52 +0900 Subject: [PATCH 20/42] =?UTF-8?q?doc:=20README.md=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EB=B0=8F=20=EB=A6=AC=ED=8E=99=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20=ED=8F=AC=EC=9D=B8=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 --- README.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 99d54b93..903ed09c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # 미션 - 워들 +## 🙆🏻‍♀️페어 구성🙆🏻 +- 점프 +- 얄뭉 +--- + ## 🔍 진행 방식 - 미션은 **과제 진행 요구 사항**, **기능 요구 사항**, **프로그래밍 요구 사항** 세 가지로 구성되어 있다. @@ -12,13 +17,16 @@ 선풍적인 인기를 끌었던 영어 단어 맞추기 게임이다. -- 6x5 격자를 통해서 5글자 단어를 6번 만에 추측한다. -- 플레이어가 답안을 제출하면 프로그램이 정답과 제출된 단어의 각 알파벳 종류와 위치를 비교해 판별한다. -- 판별 결과는 흰색의 타일이 세 가지 색(초록색/노란색/회색) 중 하나로 바뀌면서 표현된다. - - 맞는 글자는 초록색, 위치가 틀리면 노란색, 없으면 회색 +- [x] 게임 진행 메시지를 출력한다. +- [x] 격자를 통해서 5글자 단어를 6번 만에 추측한다. +- [x] 플레이어가 답안을 제출하면 프로그램이 정답과 제출된 단어의 각 알파벳 종류와 위치를 비교해 판별한다. + - [x] 입력 단어는 영단어야 한다. + - [x] 단어의 수는 5글자여야 한다. + - [x] 단어는 `words.txt`에 포함된 단어여야 한다. +- [x] 판별 결과는 흰색의 타일이 세 가지 색(초록색/노란색/회색) 중 하나로 바뀌면서 표현된다. + - 맞는 글자는 초록색(🟩), 위치가 틀리면 노란색(🟨), 없으면 회색(⬜) - 두 개의 동일한 문자를 입력하고 그중 하나가 회색으로 표시되면 해당 문자 중 하나만 최종 단어에 나타난다. -- 정답과 답안은 `words.txt`에 존재하는 단어여야 한다. -- 정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다. +- [x] 정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다. ### 입출력 요구 사항 @@ -87,5 +95,36 @@ spill - 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다. +--- +### 구현 목록 +- 단어 불러오기 +- 매일 바뀌는 정답단어 선택 +- 단어 입력 + - 입력시 단어목록에 있나 검증 +- 비교 로직 + - 같을때, 있을떄, 없을때 따른 비교결과 +- 게임로직 + - 6회 초과시 게임오버 + - 정답시 게임클리어 +- ui + - 비교 결과, 라운드 출력 - +--- +### 리팩터링 포인트 +- [x] final 붙혀주기 +- [x] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. +- [x] InputWord와 Answer를 합치기? +- [x] match 에 for 문안 함수로 발라내기 +- [x] isEndGame 플래그 변수 네이밍 변경 + - [x] 검증 + - [x] 5글자 검증 +- [x] 영단어 검증 +- [x] 예외 try catch +- [x] GameManager에 있는 List 의 변수명 변경 +- [x] HintView에 3depth 줄이기 +- [x] InputWord의 마지막 테스트함수 이름 +- [x] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 +- ~~- 구조 변경~~ + - ~~- GameManager의 의존성 줄여두기~~ + - ~~-String 말고 char 배열로 쓸지? -> 좀 더 고민해보기~~ + - ~~-분리된 view 부분 합칠지?~~ From a986ed0a16dbe92c5bca9a592e78818fd3d19315 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 10:17:15 +0900 Subject: [PATCH 21/42] =?UTF-8?q?chore:=20=EC=83=81=EC=88=98=EA=B0=80=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20=EB=B3=80=EC=88=98=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?lowerCamelCase=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/config/FileConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/config/FileConfig.java b/src/main/java/config/FileConfig.java index 415f648d..a074292a 100644 --- a/src/main/java/config/FileConfig.java +++ b/src/main/java/config/FileConfig.java @@ -1,5 +1,5 @@ package config; public class FileConfig { - public final static String FILE_PATH = "src/main/resources/words.txt"; + public static final String filePath = "src/main/resources/words.txt"; } From 21c735dbf2e36df65bd69501ac1d0aac2295f9de Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 10:17:33 +0900 Subject: [PATCH 22/42] =?UTF-8?q?chore:=20=EC=98=A4=ED=83=80=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/domain/Hint.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index 98849476..33903afa 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -2,14 +2,14 @@ public enum Hint { - CORRECT("🟩"), //\uD83D\\uDFE9 - EXIST("🟨"), //\uD83D\\uDFE8 + CORRECT("🟩"), // \uD83D\uDFE9 + EXIST("🟨"), // \uD83D\uDFE8 NOT_EXIST("⬜"); private final String tile; - Hint(String hint) { - this.tile = hint; + Hint(String tile) { + this.tile = tile; } public String getTile() { From f9a565b08f4fb06c642e0f51475dea3fa977aed3 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 10:20:35 +0900 Subject: [PATCH 23/42] =?UTF-8?q?chore:=20=EA=B8=B0=EB=B3=B8=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20protected=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/infra/WordLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java index b11de611..9b922cf1 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordLoader.java @@ -7,7 +7,7 @@ public class WordLoader { - public WordLoader() { + protected WordLoader() { } public static List read(String filePath) { From 1b8bf73503e2cef7dbec9592b5ae2c0d4269a4a4 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 10:29:58 +0900 Subject: [PATCH 24/42] =?UTF-8?q?fix:=20=EC=A0=95=EB=8B=B5=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EB=B9=84=EA=B5=90=20=EB=A1=9C=EC=A7=81=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/WordleApplication.java | 2 +- src/main/java/domain/Word.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 54f604c0..24bb9b50 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -7,7 +7,7 @@ public class WordleApplication { public static void main(String[] args) { - List words = WordLoader.read(FileConfig.FILE_PATH); + List words = WordLoader.read(FileConfig.filePath); GameManager gameManager = new GameManager(words); gameManager.start(); diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 9111d611..9347c1fe 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -30,11 +30,15 @@ public static Word createInput(String value, List availableWords) { public MatchResult match(Word word) { List hints = IntStream.range(0, value.length()) - .mapToObj(i -> getHint(value.charAt(i), i)) + .mapToObj(i -> getHint(word.getChar(i), i)) .collect(Collectors.toList()); return new MatchResult(hints); } + private Character getChar(int i) { + return value.charAt(i); + } + private Hint getHint(Character character, int index) { if (isCorrect(index, character)) { return Hint.CORRECT; From f116a6972cd45ba3a3cc6922868063a3535b096b Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 10:50:41 +0900 Subject: [PATCH 25/42] =?UTF-8?q?chore:=20=EC=9B=90=EC=8B=9C=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=83=81=EC=88=98=EB=8A=94=20HigherCamelCase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/WordleApplication.java | 2 +- src/main/java/config/FileConfig.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 24bb9b50..54f604c0 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -7,7 +7,7 @@ public class WordleApplication { public static void main(String[] args) { - List words = WordLoader.read(FileConfig.filePath); + List words = WordLoader.read(FileConfig.FILE_PATH); GameManager gameManager = new GameManager(words); gameManager.start(); diff --git a/src/main/java/config/FileConfig.java b/src/main/java/config/FileConfig.java index a074292a..5ec26a26 100644 --- a/src/main/java/config/FileConfig.java +++ b/src/main/java/config/FileConfig.java @@ -1,5 +1,5 @@ package config; public class FileConfig { - public static final String filePath = "src/main/resources/words.txt"; + public static final String FILE_PATH = "src/main/resources/words.txt"; } From ae34f0981e067951794fdb65b619ed08978581e0 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 11:42:26 +0900 Subject: [PATCH 26/42] =?UTF-8?q?refact:=20Stream.toList=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/main/java/domain/Word.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 9347c1fe..ca99f11f 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -6,6 +6,7 @@ import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; public class Word { private final static int MAX_LENGTH = 5; @@ -29,9 +30,10 @@ public static Word createInput(String value, List availableWords) { } public MatchResult match(Word word) { - List hints = IntStream.range(0, value.length()) - .mapToObj(i -> getHint(word.getChar(i), i)) - .collect(Collectors.toList()); + List hints = Stream.iterate(0, i -> i + 1) + .limit(value.length()) + .map(i -> getHint(word.getChar(i), i)) + .toList(); return new MatchResult(hints); } From d45e4ded0b19b12fd93d26afe1b07df7f8d52dac Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:39:01 +0900 Subject: [PATCH 27/42] =?UTF-8?q?refact:=20=EC=9D=BC=EC=B9=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=8B=A8=EC=96=B4=EA=B0=80=20=EC=9E=88=EC=9D=84=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EB=8B=A4=EB=A5=B8=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=EB=8A=94=20NOT=5FEXIST=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=ED=81=B4=EB=9E=98=EC=8A=A4=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/main/java/domain/HintLetter.java | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/domain/HintLetter.java diff --git a/src/main/java/domain/HintLetter.java b/src/main/java/domain/HintLetter.java new file mode 100644 index 00000000..dff6b46c --- /dev/null +++ b/src/main/java/domain/HintLetter.java @@ -0,0 +1,47 @@ +package domain; + +import java.util.List; +import java.util.Objects; + +public class HintLetter { + + private final Character letter; + private Hint hint; + + public HintLetter(Character letter, Hint hint) { + this.letter = letter; + this.hint = hint; + } + + public boolean isCorrectHint() { + return Hint.isCorrect(hint); + } + + public void changeCorrectToNotExist(List correctedChar) { + if(correctedChar.contains(letter) && !isCorrectHint()) { + this.hint = Hint.NOT_EXIST; + } + } + + public String getHintTile() { + return hint.getTile(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HintLetter that = (HintLetter) o; + return Objects.equals(letter, that.letter) && hint == that.hint; + } + + @Override + public int hashCode() { + return Objects.hash(letter, hint); + } + + + +} + + From 5a536b95624e9917cef946d0a7dbbec63eae02c5 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:39:26 +0900 Subject: [PATCH 28/42] =?UTF-8?q?refact:=20HintLetter=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResult.java | 42 ++++++++++++++++---------- src/main/java/domain/MatchResults.java | 12 +++----- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index de1a7cac..7a36679a 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -1,41 +1,51 @@ package domain; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; -public class MatchResult implements Iterable{ - private final List hints; +public class MatchResult { - public MatchResult(List hints) { + private final List hints; + + public MatchResult(List hints) { this.hints = hints; } - public MatchResult() { + protected MatchResult() { this.hints = new ArrayList<>(); } - @Override - public Iterator iterator() { - return hints.iterator(); - } public boolean isEndGame() { - return hints.stream().allMatch(Hint::isCorrect); + return hints.stream() + .allMatch(HintLetter::isCorrectHint); } - public void add(Hint hint) { - hints.add(hint); + + public void add(HintLetter hintLetter) { + hints.add(hintLetter); + } + + public String getHintTiles() { + return hints.stream() + .map(HintLetter::getHintTile) + .collect(Collectors.joining()); } @Override - public int hashCode() { - return super.hashCode(); + public boolean equals(Object o) { + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MatchResult that = (MatchResult) o; + return Objects.equals(hints, that.hints); } @Override - public boolean equals(Object obj) { - return this.hints.equals(((MatchResult) obj).hints); + public int hashCode() { + return Objects.hashCode(hints); } } diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 815cf05e..b08e63a1 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -7,7 +7,7 @@ public class MatchResults implements Iterable { private List results; - public MatchResults(List results) { + protected MatchResults(List results) { this.results = results; } @@ -15,17 +15,13 @@ public MatchResults() { this.results = new ArrayList<>(); } - - public List getResults() { - return results; + public void add(MatchResult matchResultOfInput) { + this.results.add(matchResultOfInput); } + @Override public Iterator iterator() { return this.results.iterator(); } - - public void add(MatchResult matchResultOfInput) { - this.results.add(matchResultOfInput); - } } From 1e02fe63ff352d8f8de36d64c85886072bf095fe Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:39:55 +0900 Subject: [PATCH 29/42] =?UTF-8?q?fix:=20HintLetter=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=95=EB=8B=B5=20=EB=A1=9C=EC=A7=81=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/domain/Word.java | 43 +++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index ca99f11f..ef841d1a 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -2,10 +2,7 @@ import java.time.LocalDate; import java.time.Period; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.IntStream; +import java.util.*; import java.util.stream.Stream; public class Word { @@ -25,27 +22,51 @@ public static Word createAnswer(LocalDate currentDate, List availableWor } public static Word createInput(String value, List availableWords) { - validate(value, availableWords); +// validate(value, availableWords); return new Word(value); } public MatchResult match(Word word) { - List hints = Stream.iterate(0, i -> i + 1) + List correctedChar = new ArrayList<>(); + + List hintLetters = getHintLetters(word, correctedChar); + + hintLetters.forEach(hintLetter -> hintLetter.changeCorrectToNotExist(correctedChar)); + + return new MatchResult(hintLetters); + } + + private List getHintLetters(Word word, List correctedChar) { + return Stream.iterate(0, i -> i + 1) .limit(value.length()) - .map(i -> getHint(word.getChar(i), i)) + .map(i -> getHintLetter(value, word, i, correctedChar)) .toList(); - return new MatchResult(hints); } + + private HintLetter getHintLetter(String value, Word word, Integer i, List correctedChar) { + Hint hint = getHint(word, i); + + if (Hint.isCorrect(hint)) { + correctedChar.add(word.getChar(i)); + } + + return new HintLetter(word.getChar(i), hint); + } + + private Character getChar(int i) { return value.charAt(i); } - private Hint getHint(Character character, int index) { - if (isCorrect(index, character)) { + private Hint getHint(Word word, int index) { + char inputChar = word.getChar(index); + + if (isCorrect(index, inputChar)) { return Hint.CORRECT; } - if (exists(character)) { + + if (exists(inputChar)) { return Hint.EXIST; } return Hint.NOT_EXIST; From fe0cbb25ba5e863a200690b33615d679dc98f716 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:40:15 +0900 Subject: [PATCH 30/42] =?UTF-8?q?refact:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ui/HintView.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java index c28ca158..23f492ee 100644 --- a/src/main/java/ui/HintView.java +++ b/src/main/java/ui/HintView.java @@ -5,15 +5,11 @@ public class HintView { public void render(MatchResults matchResults) { - matchResults.forEach(matchResultEachRound -> { - renderTiles(matchResultEachRound); - System.out.println(); - }); + matchResults.forEach(HintView::drawTiles); } - private void renderTiles(MatchResult matchResultEachRound) { - matchResultEachRound.forEach(matchResult -> { - System.out.print(matchResult.getTile()); - }); + private static void drawTiles(MatchResult matchResultEachRound) { + System.out.print(matchResultEachRound.getHintTiles()); + System.out.println(); } } From b443f7bdad16b582063f371030c26f405c922037 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:40:23 +0900 Subject: [PATCH 31/42] =?UTF-8?q?refact:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Round.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 305fbd1e..4a872a73 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -1,7 +1,7 @@ package domain; public class Round { - private int limit; + private final int limit; private int current; public Round(int limit, int current) { @@ -13,10 +13,6 @@ public void goNext() { this.current++; } - Boolean isLastRound() { - return this.current >= this.limit; - } - public int getLimit() { return limit; } From fa4d0ff4308e51f632476616625f44d25a78a2b5 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 14:40:34 +0900 Subject: [PATCH 32/42] =?UTF-8?q?refact:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=97=94=ED=84=B0=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 0a94d401..e7fcf205 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -72,7 +72,6 @@ private void startRound() { private void checkAnswer(Word inputWord) { MatchResult matchResultOfInput = answer.match(inputWord); this.matchResults.add(matchResultOfInput); - this.isWinning = matchResultOfInput.isEndGame(); } From 62e8b94b518d6f6125d7b7c5c44054e35b61bd0e Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 15:36:06 +0900 Subject: [PATCH 33/42] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=20=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=8B=9C=20=EA=B2=8C=EC=9E=84=20=EC=A2=85=EB=A3=8C=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EA=B3=A0,=20=EC=9E=AC=EC=8B=9C=EB=8F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 33 ++++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index e7fcf205..a6bc3b2b 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -48,27 +48,40 @@ public void start() { } private void startRound() { - // 라운드 입력 view - String input = inputView.input(); + Word inputWord = null; + boolean canCreateInputWord = false; - Word inputWord; - try { + while (!canCreateInputWord) { + String input = inputView.input(); inputWord = Word.createInput(input, this.availableWords); - } catch (IllegalArgumentException e) { - System.out.println(e.getMessage()); - return; + canCreateInputWord = inputWord.getAvailableWord(); } checkAnswer(inputWord); + renderResult(); + round.goNext(); + } - if(this.isWinning) { + private void renderResult() { + checkRenderRound(); + hintView.render(matchResults); + checkFinalRound(); + } + + private void checkRenderRound() { + if(this.isWinning || !round.isNotFinalRound()) { roundView.render(round.getCurrent(),round.getLimit()); } + } - hintView.render(this.matchResults); - round.goNext(); + private void checkFinalRound() { + if(!this.isWinning && round.isFinalRound()) { + roundView.render(round.getCurrent(),round.getLimit()); + roundView.renderLoseGame();; + } } + private void checkAnswer(Word inputWord) { MatchResult matchResultOfInput = answer.match(inputWord); this.matchResults.add(matchResultOfInput); From b056160befe1247b6e8a87c87a2fb942e65d8ac9 Mon Sep 17 00:00:00 2001 From: jylim Date: Fri, 28 Jun 2024 15:36:26 +0900 Subject: [PATCH 34/42] =?UTF-8?q?refact:=20=EB=A7=88=EC=A7=80=EB=A7=89=20?= =?UTF-8?q?=EC=8B=9C=EB=8F=84=EA=B9=8C=EC=A7=80=20=EC=8B=A4=ED=8C=A8=20?= =?UTF-8?q?=EC=8B=9C=20=EB=AC=B8=EA=B5=AC=20=EB=85=B8=EC=B6=9C=20=ED=9B=84?= =?UTF-8?q?=20=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Round.java | 4 +++ src/main/java/domain/Word.java | 50 ++++++++++++++++++++++++--------- src/main/java/ui/RoundView.java | 4 +++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 4a872a73..668e2512 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -24,4 +24,8 @@ public int getCurrent() { public boolean isNotFinalRound() { return current <= limit; } + + public boolean isFinalRound() { + return current == limit; + } } diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index ef841d1a..cdd93a89 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -8,9 +8,16 @@ public class Word { private final static int MAX_LENGTH = 5; private final String value; + private boolean availableWord; - protected Word(String value) { + public Word(String value) { this.value = value; + this.availableWord = false; + } + + public Word(String value, boolean availableWord) { + this.value = value; + this.availableWord = availableWord; } public static Word createAnswer(LocalDate currentDate, List availableWords) { @@ -22,8 +29,8 @@ public static Word createAnswer(LocalDate currentDate, List availableWor } public static Word createInput(String value, List availableWords) { -// validate(value, availableWords); - return new Word(value); + boolean availableWord = isvalidate(value, availableWords); + return new Word(value, availableWord); } public MatchResult match(Word word) { @@ -80,30 +87,45 @@ private Boolean isCorrect(int index, char inputChar) { return value.charAt(index) == inputChar; } - private static void validate(String input, List availableWords) { - validateLength(input); + private static boolean isvalidate(String input, List availableWords) { + if(validateLength(input)) { + return false; + } - validateOnlyEnglish(input); + if(validateOnlyEnglish(input)) { + return false; + } - validateContain(input, availableWords); +// return !validateContain(input, availableWords); + return true; } - private static void validateOnlyEnglish(String input) { + private static boolean validateOnlyEnglish(String input) { if (!input.matches("^[a-zA-Z]+$")) { - throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); + System.out.println("영단어를 입력해주세요. [" + input + "]"); + return true; } + return false; } - private static void validateLength(String input) { + private static boolean validateLength(String input) { if (input.length() != MAX_LENGTH) { - throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); + System.out.println(MAX_LENGTH + "자리의 단어를 입력해주세요."); + return true; } + return false; } - private static void validateContain(String input, List availableWords) { + private static boolean validateContain(String input, List availableWords) { if (!availableWords.contains(input)) { - throw new IllegalArgumentException("입력 불가능한 단어입니다."); + System.out.println("입력 불가능한 단어입니다."); + return true; } + return false; + } + + public boolean getAvailableWord() { + return availableWord; } @Override @@ -120,4 +142,6 @@ public boolean equals(Object o) { public int hashCode() { return value != null ? value.hashCode() : 0; } + + } diff --git a/src/main/java/ui/RoundView.java b/src/main/java/ui/RoundView.java index 16f8c246..936e8e12 100644 --- a/src/main/java/ui/RoundView.java +++ b/src/main/java/ui/RoundView.java @@ -4,4 +4,8 @@ public class RoundView { public void render(int current, int max) { System.out.printf("%d/%d%n", current, max); } + + public void renderLoseGame() { + System.out.print("시도 가능 횟수가 종료되었습니다."); + } } From 42bcfe6e4fe8e7719902e150426c0fd9da849de1 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 07:20:01 +0900 Subject: [PATCH 35/42] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/config/FileConfig.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/config/FileConfig.java b/src/main/java/config/FileConfig.java index 5ec26a26..9eebf506 100644 --- a/src/main/java/config/FileConfig.java +++ b/src/main/java/config/FileConfig.java @@ -1,5 +1,8 @@ package config; public class FileConfig { + + protected FileConfig() { + } public static final String FILE_PATH = "src/main/resources/words.txt"; } From 486d28df415e085cea5343a0f4cca3dceefa51d4 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 07:46:06 +0900 Subject: [PATCH 36/42] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=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/main/java/controller/GameManager.java | 24 ++++++++--------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index a6bc3b2b..8e54083a 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -13,21 +13,16 @@ import java.util.List; public class GameManager { - private Round round; - private MatchResults matchResults; - private Word answer; - - private List availableWords; - - private GuideTextView guideTextView; - private InputView inputView; - private HintView hintView; - private RoundView roundView; + private final Round round; + private final MatchResults matchResults; + private final Word answer; + private final GuideTextView guideTextView; + private final InputView inputView; + private final HintView hintView; + private final RoundView roundView; + private final List availableWords; private boolean isWinning = false; - protected GameManager() { - } - public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; @@ -38,8 +33,6 @@ public GameManager(List availableWords) { this.hintView = new HintView(); this.roundView = new RoundView(); } - - public void start() { guideTextView.render(); while(!this.isWinning && round.isNotFinalRound()) { @@ -81,7 +74,6 @@ private void checkFinalRound() { } } - private void checkAnswer(Word inputWord) { MatchResult matchResultOfInput = answer.match(inputWord); this.matchResults.add(matchResultOfInput); From 83010de02156bfd99e7d5565f96bf8096e190ca1 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 07:46:24 +0900 Subject: [PATCH 37/42] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EA=B3=B5=EB=B0=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/WordleApplication.java | 2 -- src/main/java/domain/MatchResults.java | 10 +--------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 54f604c0..6bfdff82 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -9,9 +9,7 @@ public static void main(String[] args) { List words = WordLoader.read(FileConfig.FILE_PATH); GameManager gameManager = new GameManager(words); - gameManager.start(); - } } diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index b08e63a1..ad14cbfc 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -5,21 +5,13 @@ import java.util.List; public class MatchResults implements Iterable { - private List results; - - protected MatchResults(List results) { - this.results = results; - } - + private final List results; public MatchResults() { this.results = new ArrayList<>(); } - public void add(MatchResult matchResultOfInput) { this.results.add(matchResultOfInput); } - - @Override public Iterator iterator() { return this.results.iterator(); From bf9fbea99713574919d3412b3575a85554c0cd06 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 07:54:49 +0900 Subject: [PATCH 38/42] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EB=82=B4=20=EB=A9=A4=EB=B2=84=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=EC=A0=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/main/java/domain/Hint.java | 2 -- src/main/java/domain/HintLetter.java | 13 +++++-------- src/main/java/domain/MatchResult.java | 9 --------- src/main/java/domain/Word.java | 22 ++++++++++------------ src/main/java/infra/WordLoader.java | 1 - src/main/java/ui/InputView.java | 2 +- 6 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index 33903afa..71565059 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -1,11 +1,9 @@ package domain; public enum Hint { - CORRECT("🟩"), // \uD83D\uDFE9 EXIST("🟨"), // \uD83D\uDFE8 NOT_EXIST("⬜"); - private final String tile; Hint(String tile) { diff --git a/src/main/java/domain/HintLetter.java b/src/main/java/domain/HintLetter.java index dff6b46c..fc4a131f 100644 --- a/src/main/java/domain/HintLetter.java +++ b/src/main/java/domain/HintLetter.java @@ -4,8 +4,8 @@ import java.util.Objects; public class HintLetter { - private final Character letter; + private Hint hint; public HintLetter(Character letter, Hint hint) { @@ -13,16 +13,16 @@ public HintLetter(Character letter, Hint hint) { this.hint = hint; } - public boolean isCorrectHint() { - return Hint.isCorrect(hint); - } - public void changeCorrectToNotExist(List correctedChar) { if(correctedChar.contains(letter) && !isCorrectHint()) { this.hint = Hint.NOT_EXIST; } } + public boolean isCorrectHint() { + return Hint.isCorrect(hint); + } + public String getHintTile() { return hint.getTile(); } @@ -39,9 +39,6 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(letter, hint); } - - - } diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 7a36679a..034ced2f 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -6,24 +6,15 @@ import java.util.stream.Collectors; public class MatchResult { - private final List hints; - public MatchResult(List hints) { this.hints = hints; } - protected MatchResult() { - this.hints = new ArrayList<>(); - } - - public boolean isEndGame() { return hints.stream() .allMatch(HintLetter::isCorrectHint); } - - public void add(HintLetter hintLetter) { hints.add(hintLetter); } diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index cdd93a89..dc7f7c27 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -8,7 +8,7 @@ public class Word { private final static int MAX_LENGTH = 5; private final String value; - private boolean availableWord; + private final boolean availableWord; public Word(String value) { this.value = value; @@ -29,7 +29,7 @@ public static Word createAnswer(LocalDate currentDate, List availableWor } public static Word createInput(String value, List availableWords) { - boolean availableWord = isvalidate(value, availableWords); + boolean availableWord = isValidate(value, availableWords); return new Word(value, availableWord); } @@ -37,21 +37,24 @@ public MatchResult match(Word word) { List correctedChar = new ArrayList<>(); List hintLetters = getHintLetters(word, correctedChar); - hintLetters.forEach(hintLetter -> hintLetter.changeCorrectToNotExist(correctedChar)); return new MatchResult(hintLetters); } + public boolean getAvailableWord() { + return availableWord; + } + private List getHintLetters(Word word, List correctedChar) { return Stream.iterate(0, i -> i + 1) .limit(value.length()) - .map(i -> getHintLetter(value, word, i, correctedChar)) + .map(i -> getHintLetter(word, i, correctedChar)) .toList(); } - private HintLetter getHintLetter(String value, Word word, Integer i, List correctedChar) { + private HintLetter getHintLetter(Word word, Integer i, List correctedChar) { Hint hint = getHint(word, i); if (Hint.isCorrect(hint)) { @@ -87,7 +90,7 @@ private Boolean isCorrect(int index, char inputChar) { return value.charAt(index) == inputChar; } - private static boolean isvalidate(String input, List availableWords) { + private static boolean isValidate(String input, List availableWords) { if(validateLength(input)) { return false; } @@ -96,8 +99,7 @@ private static boolean isvalidate(String input, List availableWords) { return false; } -// return !validateContain(input, availableWords); - return true; + return !validateContain(input, availableWords); } private static boolean validateOnlyEnglish(String input) { @@ -124,10 +126,6 @@ private static boolean validateContain(String input, List availableWords return false; } - public boolean getAvailableWord() { - return availableWord; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java index 9b922cf1..1fdf55d6 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordLoader.java @@ -6,7 +6,6 @@ import java.util.List; public class WordLoader { - protected WordLoader() { } diff --git a/src/main/java/ui/InputView.java b/src/main/java/ui/InputView.java index a074578e..f5e8e011 100644 --- a/src/main/java/ui/InputView.java +++ b/src/main/java/ui/InputView.java @@ -3,7 +3,7 @@ import java.util.Scanner; public class InputView { - private Scanner scanner = new Scanner(System.in); + private final Scanner scanner = new Scanner(System.in); public String input() { System.out.println("정답을 입력해 주세요."); From 922446c9e4b86eac6b0fb66ab6c7ed361ab87628 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 08:01:20 +0900 Subject: [PATCH 39/42] =?UTF-8?q?refactor:=20Round=EC=97=90=20=EB=84=98?= =?UTF-8?q?=EA=B2=A8=EC=A4=84=20=EB=B3=80=EC=88=98=20=EC=83=81=EC=88=98?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 8e54083a..9ce6b27f 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -13,6 +13,9 @@ import java.util.List; public class GameManager { + + private final static int LIMIT = 6; + private final static int CURRENT = 1; private final Round round; private final MatchResults matchResults; private final Word answer; @@ -26,7 +29,7 @@ public class GameManager { public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; - this.round = new Round(6, 1); + this.round = new Round(LIMIT, CURRENT); this.matchResults = new MatchResults(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); From 43345b39176e334ce7e937f3dcdabd84b23f582d Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 08:41:19 +0900 Subject: [PATCH 40/42] =?UTF-8?q?test:=20=EB=8B=A8=EC=96=B4=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Word.java | 4 +- src/test/java/domain/AnswerTest.java | 110 ++++++++++++------------ src/test/java/domain/InputWordTest.java | 72 ++++++++++------ src/test/resources/words.txt | 15 +++- 4 files changed, 118 insertions(+), 83 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index dc7f7c27..fdeaa368 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -82,11 +82,11 @@ private Hint getHint(Word word, int index) { return Hint.NOT_EXIST; } - private Boolean exists(char inputChar) { + private boolean exists(char inputChar) { return value.indexOf(inputChar) != -1; } - private Boolean isCorrect(int index, char inputChar) { + private boolean isCorrect(int index, char inputChar) { return value.charAt(index) == inputChar; } diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index e084f5c9..e6e2b4f2 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -19,60 +19,60 @@ void answerSelectTest() { } - @Test - @DisplayName("입력단어와 정답 비교") - void matchTest() { - List words = List.of("apple", "banan", "cherr"); - - Word inputWord = Word.createInput("cherr", words); - Word answer = new Word("czzzh"); - MatchResult matchResults = answer.match(inputWord); - - MatchResult expected = new MatchResult(List.of( - Hint.CORRECT, - Hint.EXIST, - Hint.NOT_EXIST, - Hint.NOT_EXIST, - Hint.NOT_EXIST - )); - assertThat(matchResults).isEqualTo(expected); - } - - @Test - @DisplayName("입력단어와 중복 단어 위치 확인 테스트") - void matchLocationTest() { - List words = List.of("rxxrx"); - - Word inputWord = Word.createInput("rxxrx", words); - Word answer = new Word("cherr"); - MatchResult matchResults = answer.match(inputWord); +// @Test +// @DisplayName("입력단어와 정답 비교") +// void matchTest() { +// List words = List.of("apple", "banan", "cherr"); +// +// Word inputWord = Word.createInput("cherr", words); +// Word answer = new Word("czzzh"); +// MatchResult matchResults = answer.match(inputWord); +// +// MatchResult expected = new MatchResult(List.of( +// Hint.CORRECT, +// Hint.EXIST, +// Hint.NOT_EXIST, +// Hint.NOT_EXIST, +// Hint.NOT_EXIST +// )); +// assertThat(matchResults).isEqualTo(expected); +// } - MatchResult expected = new MatchResult(List.of( - Hint.EXIST, - Hint.NOT_EXIST, - Hint.NOT_EXIST, - Hint.CORRECT, - Hint.NOT_EXIST - )); - assertThat(matchResults).isEqualTo(expected); - } - - @Test - @DisplayName("전부정답인 경우") - void test() { - List words = List.of("colon"); - - Word inputWord = Word.createInput("colon", words); - Word answer = new Word("colon"); - MatchResult matchResults = answer.match(inputWord); - - MatchResult expected = new MatchResult(List.of( - Hint.CORRECT, - Hint.CORRECT, - Hint.CORRECT, - Hint.CORRECT, - Hint.CORRECT - )); - assertThat(matchResults).isEqualTo(expected); - } +// @Test +// @DisplayName("입력단어와 중복 단어 위치 확인 테스트") +// void matchLocationTest() { +// List words = List.of("rxxrx"); +// +// Word inputWord = Word.createInput("rxxrx", words); +// Word answer = new Word("cherr"); +// MatchResult matchResults = answer.match(inputWord); +// +// MatchResult expected = new MatchResult(List.of( +// Hint.EXIST, +// Hint.NOT_EXIST, +// Hint.NOT_EXIST, +// Hint.CORRECT, +// Hint.NOT_EXIST +// )); +// assertThat(matchResults).isEqualTo(expected); +// } +// +// @Test +// @DisplayName("전부정답인 경우") +// void test() { +// List words = List.of("colon"); +// +// Word inputWord = Word.createInput("colon", words); +// Word answer = new Word("colon"); +// MatchResult matchResults = answer.match(inputWord); +// +// MatchResult expected = new MatchResult(List.of( +// Hint.CORRECT, +// Hint.CORRECT, +// Hint.CORRECT, +// Hint.CORRECT, +// Hint.CORRECT +// )); +// assertThat(matchResults).isEqualTo(expected); +// } } diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 1f4d296b..ce24429c 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -1,48 +1,70 @@ package domain; +import infra.WordLoader; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import java.util.List; +import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; class InputWordTest { - @DisplayName("입력단어 유효성 검증 성공 테스트") - void validateSuccessInputWord() { - List words = List.of("apples", "cherry"); - assertDoesNotThrow(() -> Word.createInput("cherry", words)); - } + private final List words = getWordList(); + @ParameterizedTest + @DisplayName("입력단어 유효성 검증 성공 테스트") + @MethodSource("provideContainedInputWords") + void validateSuccessInputWord(String input) { + assertTrue(words.contains(input)); + } - @Test + @ParameterizedTest @DisplayName("입력단어 유효성 검증 실패 테스트") - void - validateFailInputWord() { - List words = List.of("apples", "banana"); - assertThrows(IllegalArgumentException.class,() -> Word.createInput("pangyo", words)); + @ValueSource(strings = {"banana", "hello", "test", "world"}) + void validateFailInputWord(String input) { + Word word = Word.createInput(input, words); + assertFalse(word.getAvailableWord()); } - @Test + @ParameterizedTest + @ValueSource(strings = {"people"}) @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") - void validateInputWordLength() { - List words = List.of("apple", "abcdef"); - assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcdef", words)); + void validateInputWordLength(String input) { + assertTrue(words.contains(input)); + Word word = Word.createInput(input, words); + assertFalse(word.getAvailableWord()); } - - @Test + @ParameterizedTest @DisplayName("입력단어 영단어 유효성 검증 실패 테스트") - void validateInputWordOnlyEnglish() { - List words = List.of("apple", "abcd1", "안녕하세요"); - - assertAll( - () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcd1", words)), - () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("안녕하세요", words)) - ); + @MethodSource("provideWordsWithLength") + void validateInputWordOnlyEnglish(String input, boolean isRightWord) { + if (!isRightWord) { + Word word = Word.createInput(input, words); + assertFalse(word.getAvailableWord()); + } else { + assertTrue(words.contains(input)); + } } + private static List getWordList() { + return WordLoader.read("src/test/resources/words.txt"); + } + private static Stream provideContainedInputWords() { + return Stream.of("serve", "sssss", "eeeee", "naval"); + } + public static Stream provideWordsWithLength() { + return Stream.of( + new Object[]{"안녕하세요", false}, + new Object[]{"12345", false}, + new Object[]{"serve", true} + ); + } } diff --git a/src/test/resources/words.txt b/src/test/resources/words.txt index bc35cd4a..aecf6e73 100644 --- a/src/test/resources/words.txt +++ b/src/test/resources/words.txt @@ -2,4 +2,17 @@ cigar rebut sissy humph -awake \ No newline at end of file +awake +blush +focal +evade +naval +serve +heath +dwarf +model +serve +sssss +eeeee +people +안녕하세요 From ae1a0b5ce5481291626e611dff5929f3b7143669 Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 08:52:15 +0900 Subject: [PATCH 41/42] =?UTF-8?q?test:=20=EB=8B=A8=EC=96=B4=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=EC=AA=BC=EA=B0=9C=EC=84=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Word.java | 12 ++++++------ src/test/java/domain/InputWordTest.java | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index fdeaa368..71982161 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -91,18 +91,18 @@ private boolean isCorrect(int index, char inputChar) { } private static boolean isValidate(String input, List availableWords) { - if(validateLength(input)) { + if(isWrongLength(input)) { return false; } - if(validateOnlyEnglish(input)) { + if(notOnlyEnglish(input)) { return false; } - return !validateContain(input, availableWords); + return !isNotContain(input, availableWords); } - private static boolean validateOnlyEnglish(String input) { + public static boolean notOnlyEnglish(String input) { if (!input.matches("^[a-zA-Z]+$")) { System.out.println("영단어를 입력해주세요. [" + input + "]"); return true; @@ -110,7 +110,7 @@ private static boolean validateOnlyEnglish(String input) { return false; } - private static boolean validateLength(String input) { + public static boolean isWrongLength(String input) { if (input.length() != MAX_LENGTH) { System.out.println(MAX_LENGTH + "자리의 단어를 입력해주세요."); return true; @@ -118,7 +118,7 @@ private static boolean validateLength(String input) { return false; } - private static boolean validateContain(String input, List availableWords) { + public static boolean isNotContain(String input, List availableWords) { if (!availableWords.contains(input)) { System.out.println("입력 불가능한 단어입니다."); return true; diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index ce24429c..a84ab604 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -36,9 +36,7 @@ void validateFailInputWord(String input) { @ValueSource(strings = {"people"}) @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") void validateInputWordLength(String input) { - assertTrue(words.contains(input)); - Word word = Word.createInput(input, words); - assertFalse(word.getAvailableWord()); + assertTrue(Word.isWrongLength(input)); } @ParameterizedTest @@ -49,7 +47,7 @@ void validateInputWordOnlyEnglish(String input, boolean isRightWord) { Word word = Word.createInput(input, words); assertFalse(word.getAvailableWord()); } else { - assertTrue(words.contains(input)); + assertFalse(Word.notOnlyEnglish(input)); } } From 8100660c3a9126033a75416be934a2a69c47f83d Mon Sep 17 00:00:00 2001 From: jylim Date: Sat, 29 Jun 2024 10:25:38 +0900 Subject: [PATCH 42/42] =?UTF-8?q?test:=20=EC=A0=95=EB=8B=B5=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResult.java | 1 - src/main/java/domain/Word.java | 14 +-- src/test/java/domain/AnswerTest.java | 147 ++++++++++++++---------- src/test/java/domain/InputWordTest.java | 1 - src/test/java/infra/WordLoaderTest.java | 4 +- src/test/resources/words.txt | 6 +- 6 files changed, 96 insertions(+), 77 deletions(-) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 034ced2f..a848a04e 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -1,6 +1,5 @@ package domain; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 71982161..970a76b0 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -12,7 +12,7 @@ public class Word { public Word(String value) { this.value = value; - this.availableWord = false; + this.availableWord = true; } public Word(String value, boolean availableWord) { @@ -126,20 +126,16 @@ public static boolean isNotContain(String input, List availableWords) { return false; } + @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Word answer = (Word) o; - - return Objects.equals(value, answer.value); + if (!(o instanceof Word word)) return false; + return getAvailableWord() == word.getAvailableWord() && Objects.equals(value, word.value); } @Override public int hashCode() { - return value != null ? value.hashCode() : 0; + return Objects.hash(value, getAvailableWord()); } - - } diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index e6e2b4f2..01ebaa71 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -1,78 +1,103 @@ package domain; +import infra.WordLoader; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import java.time.LocalDate; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; class AnswerTest { - @Test + private final List words = getWordList(); + Word answer = Word.createAnswer(LocalDate.of(2021, 6, 20), words); + + + @ParameterizedTest + @ValueSource(strings = {"serve"}) @DisplayName("정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다") - void answerSelectTest() { - List words = List.of("apple", "banana", "cherry", "date", "elderberry"); - Word answer = Word.createAnswer(LocalDate.of(2021, 6, 20), words); + void answerSelectTest(String input) { + assertThat(answer).isEqualTo(new Word(input)); + } + - assertThat(answer).isEqualTo(new Word("banana")); + @ParameterizedTest + @MethodSource("provideInputAnswer") + @DisplayName("입력단어와 정답 비교") + void matchTest(String input, List hintLetters) { + Word inputWord = Word.createInput(input, words); + MatchResult matchResults = answer.match(inputWord); + + MatchResult expected = new MatchResult(hintLetters); + assertThat(matchResults).isEqualTo(expected); } -// @Test -// @DisplayName("입력단어와 정답 비교") -// void matchTest() { -// List words = List.of("apple", "banan", "cherr"); -// -// Word inputWord = Word.createInput("cherr", words); -// Word answer = new Word("czzzh"); -// MatchResult matchResults = answer.match(inputWord); -// -// MatchResult expected = new MatchResult(List.of( -// Hint.CORRECT, -// Hint.EXIST, -// Hint.NOT_EXIST, -// Hint.NOT_EXIST, -// Hint.NOT_EXIST -// )); -// assertThat(matchResults).isEqualTo(expected); -// } - -// @Test -// @DisplayName("입력단어와 중복 단어 위치 확인 테스트") -// void matchLocationTest() { -// List words = List.of("rxxrx"); -// -// Word inputWord = Word.createInput("rxxrx", words); -// Word answer = new Word("cherr"); -// MatchResult matchResults = answer.match(inputWord); -// -// MatchResult expected = new MatchResult(List.of( -// Hint.EXIST, -// Hint.NOT_EXIST, -// Hint.NOT_EXIST, -// Hint.CORRECT, -// Hint.NOT_EXIST -// )); -// assertThat(matchResults).isEqualTo(expected); -// } -// -// @Test -// @DisplayName("전부정답인 경우") -// void test() { -// List words = List.of("colon"); -// -// Word inputWord = Word.createInput("colon", words); -// Word answer = new Word("colon"); -// MatchResult matchResults = answer.match(inputWord); -// -// MatchResult expected = new MatchResult(List.of( -// Hint.CORRECT, -// Hint.CORRECT, -// Hint.CORRECT, -// Hint.CORRECT, -// Hint.CORRECT -// )); -// assertThat(matchResults).isEqualTo(expected); -// } + @ParameterizedTest + @MethodSource("provideLocationAnswer") + @DisplayName("입력단어와 중복 단어 위치 확인 테스트") + void matchLocationTest(String input, List hintLetters) { + Word inputWord = Word.createInput(input, words); + MatchResult matchResults = answer.match(inputWord); + + MatchResult expected = new MatchResult(hintLetters); + assertThat(matchResults).isEqualTo(expected); + } + + + private static List getWordList() { + return WordLoader.read("src/test/resources/words.txt"); + } + + + public static Stream provideInputAnswer() { + return Stream.of( + new Object[]{"serve", List.of(new HintLetter('s', Hint.CORRECT), + new HintLetter('e', Hint.CORRECT), + new HintLetter('r', Hint.CORRECT), + new HintLetter('v', Hint.CORRECT), + new HintLetter('e', Hint.CORRECT))}, + new Object[]{"sssss", List.of(new HintLetter('s', Hint.CORRECT), + new HintLetter('s', Hint.NOT_EXIST), + new HintLetter('s', Hint.NOT_EXIST), + new HintLetter('s', Hint.NOT_EXIST), + new HintLetter('s', Hint.NOT_EXIST))}, + new Object[]{"eeeee", List.of(new HintLetter('e', Hint.NOT_EXIST), + new HintLetter('e', Hint.CORRECT), + new HintLetter('e', Hint.NOT_EXIST), + new HintLetter('e', Hint.NOT_EXIST), + new HintLetter('e', Hint.CORRECT))}, + new Object[]{"grade", List.of(new HintLetter('g', Hint.NOT_EXIST), + new HintLetter('r', Hint.EXIST), + new HintLetter('a', Hint.NOT_EXIST), + new HintLetter('d', Hint.NOT_EXIST), + new HintLetter('e', Hint.CORRECT))} + ); + } + + public static Stream provideLocationAnswer() { + return Stream.of( + new Object[]{"cigar", List.of(new HintLetter('c', Hint.NOT_EXIST), + new HintLetter('i', Hint.NOT_EXIST), + new HintLetter('g', Hint.NOT_EXIST), + new HintLetter('a', Hint.NOT_EXIST), + new HintLetter('r', Hint.EXIST))}, + new Object[]{"sissy", List.of(new HintLetter('s', Hint.CORRECT), + new HintLetter('i', Hint.NOT_EXIST), + new HintLetter('s', Hint.NOT_EXIST), + new HintLetter('s', Hint.NOT_EXIST), + new HintLetter('y', Hint.NOT_EXIST))}, + new Object[]{"naval", List.of(new HintLetter('n', Hint.NOT_EXIST), + new HintLetter('a', Hint.NOT_EXIST), + new HintLetter('v', Hint.EXIST), + new HintLetter('a', Hint.NOT_EXIST), + new HintLetter('l', Hint.NOT_EXIST))} + ); + } } diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index a84ab604..26de85e0 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -14,7 +14,6 @@ class InputWordTest { - private final List words = getWordList(); @ParameterizedTest diff --git a/src/test/java/infra/WordLoaderTest.java b/src/test/java/infra/WordLoaderTest.java index 40b205fe..7705c7f9 100644 --- a/src/test/java/infra/WordLoaderTest.java +++ b/src/test/java/infra/WordLoaderTest.java @@ -12,6 +12,6 @@ class WordLoaderTest { @DisplayName("단어목록파일 읽기") void loadWordsFromFile(){ List words = WordLoader.read("src/test/resources/words.txt"); - assertThat(words).hasSize(5); + assertThat(words).hasSize(18); } -} \ No newline at end of file +} diff --git a/src/test/resources/words.txt b/src/test/resources/words.txt index aecf6e73..eecd8ac1 100644 --- a/src/test/resources/words.txt +++ b/src/test/resources/words.txt @@ -1,5 +1,5 @@ cigar -rebut +serve sissy humph awake @@ -9,9 +9,9 @@ evade naval serve heath -dwarf +grade model -serve +rebut sssss eeeee people