From da90527995fe591c3f6242ef63fba3115fc97d82 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 18:49:32 +0900 Subject: [PATCH 01/47] =?UTF-8?q?feat:=20=EC=A0=95=EB=8B=B5=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Answer.java | 44 ++++++++++++++++++++++++++++ src/test/java/domain/AnswerTest.java | 21 +++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/main/java/domain/Answer.java create mode 100644 src/test/java/domain/AnswerTest.java diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java new file mode 100644 index 00000000..79369317 --- /dev/null +++ b/src/main/java/domain/Answer.java @@ -0,0 +1,44 @@ +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 true; + } + + Boolean isCorrect(int index, char inputChar) { + return true; + } + + @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/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java new file mode 100644 index 00000000..7b468265 --- /dev/null +++ b/src/test/java/domain/AnswerTest.java @@ -0,0 +1,21 @@ +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")); + } +} From a1ad7ff339737fe29a8bb9e09556daebe8c58721 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 18:56:03 +0900 Subject: [PATCH 02/47] =?UTF-8?q?feat:=20=EB=8B=A8=EC=96=B4=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9D=BD=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: filepath config class --- src/main/java/config/FileConfig.java | 5 +++++ src/main/java/infra/WordLoader.java | 20 ++++++++++++++++++++ src/test/java/infra/WordLoaderTest.java | 17 +++++++++++++++++ src/test/resources/words.txt | 5 +++++ 4 files changed, 47 insertions(+) create mode 100644 src/main/java/config/FileConfig.java create mode 100644 src/main/java/infra/WordLoader.java create mode 100644 src/test/java/infra/WordLoaderTest.java create mode 100644 src/test/resources/words.txt 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/infra/WordLoader.java b/src/main/java/infra/WordLoader.java new file mode 100644 index 00000000..b11de611 --- /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 { + + public 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/test/java/infra/WordLoaderTest.java b/src/test/java/infra/WordLoaderTest.java new file mode 100644 index 00000000..1d1a87b0 --- /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); + } +} diff --git a/src/test/resources/words.txt b/src/test/resources/words.txt new file mode 100644 index 00000000..3195f258 --- /dev/null +++ b/src/test/resources/words.txt @@ -0,0 +1,5 @@ +cigar +rebut +sissy +humph +awake From ca9d324162226996ae35d6a9e1e14ff6807020ba Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 19:00:14 +0900 Subject: [PATCH 03/47] =?UTF-8?q?feat:=20=EC=8B=9C=EC=9E=91=20=EC=95=88?= =?UTF-8?q?=EB=82=B4=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 게임 안내 문구 출력 뷰 컴포넌트 --- src/main/java/WordleApplication.java | 17 +++++++++++++++++ src/main/java/ui/GuideTextView.java | 8 ++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/main/java/WordleApplication.java create mode 100644 src/main/java/ui/GuideTextView.java diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java new file mode 100644 index 00000000..54f604c0 --- /dev/null +++ b/src/main/java/WordleApplication.java @@ -0,0 +1,17 @@ +import config.FileConfig; +import controller.GameManager; +import infra.WordLoader; + +import java.util.List; + +public class WordleApplication { + 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/ui/GuideTextView.java b/src/main/java/ui/GuideTextView.java new file mode 100644 index 00000000..3c6ef5a2 --- /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("시도의 결과는 타일의 색 변화로 나타납니다."); + } +} From c0b32cb48e7744af4d6f27ac6df7a22cefab6d9b Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 19:59:50 +0900 Subject: [PATCH 04/47] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=8B=A8=EC=96=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/InputWord.java | 21 +++++++++++++++++ src/test/java/domain/InputWordTest.java | 31 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 src/main/java/domain/InputWord.java create mode 100644 src/test/java/domain/InputWordTest.java diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java new file mode 100644 index 00000000..d68c037b --- /dev/null +++ b/src/main/java/domain/InputWord.java @@ -0,0 +1,21 @@ +package domain; + +import java.util.List; + +public class InputWord { + private String value; + private List availableWords; + + 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("입력 불가능한 단어입니다."); + } + } + +} diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java new file mode 100644 index 00000000..1d41c8b1 --- /dev/null +++ b/src/test/java/domain/InputWordTest.java @@ -0,0 +1,31 @@ +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.List; + +import static org.junit.jupiter.api.Assertions.*; + + +class InputWordTest { + + private List words = List.of("apple", "banana", "cherry", "date", "elderberry"); + + @Test + @DisplayName("입력단어 유효성 검증 성공 테스트") + void validateSuccessInputWord() { + assertDoesNotThrow(() -> new InputWord("date", words)); + + } + + + @Test + @DisplayName("입력단어 유효성 검증 실패 테스트") + void validateFailInputWord() { + assertThrows(IllegalArgumentException.class,() -> new InputWord("pangyo", words)); + } + +} From be1f118af61ede3686443e1c7bbfdd52fdaf5f20 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 20:53:43 +0900 Subject: [PATCH 05/47] =?UTF-8?q?feat:=20=EB=B9=84=EA=B5=90=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 비교 로직 feat: 비교결과 일급 객체 --- src/main/java/domain/Answer.java | 4 ++-- src/main/java/domain/InputWord.java | 18 +++++++++++++++ src/main/java/domain/MatchResult.java | 31 ++++++++++++++++++++++++++ src/main/java/domain/MatchResults.java | 16 +++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/main/java/domain/MatchResult.java create mode 100644 src/main/java/domain/MatchResults.java diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index 79369317..94a34eff 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -20,11 +20,11 @@ public Answer(LocalDate currentDate, List availableWords) { 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; } @Override diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java index d68c037b..934389c7 100644 --- a/src/main/java/domain/InputWord.java +++ b/src/main/java/domain/InputWord.java @@ -1,11 +1,29 @@ 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; diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java new file mode 100644 index 00000000..ac666f73 --- /dev/null +++ b/src/main/java/domain/MatchResult.java @@ -0,0 +1,31 @@ +package domain; + +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 new file mode 100644 index 00000000..1aa5a6bf --- /dev/null +++ b/src/main/java/domain/MatchResults.java @@ -0,0 +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; + } +} From 3012f26cdf09c0dbf1cf8751e13416c955158305 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Tue, 11 Jun 2024 20:54:18 +0900 Subject: [PATCH 06/47] =?UTF-8?q?test:=20=EB=B9=84=EA=B5=90=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 힌트 객체 --- src/main/java/domain/Hint.java | 18 ++++++++ src/test/java/domain/InputWordTest.java | 50 ++++++++++++++++++++--- src/test/java/domain/MatchResultTest.java | 16 ++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/main/java/domain/Hint.java create mode 100644 src/test/java/domain/MatchResultTest.java 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/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 1d41c8b1..a9b32f1e 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -5,27 +5,65 @@ 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 { - - private List words = List.of("apple", "banana", "cherry", "date", "elderberry"); - - @Test @DisplayName("입력단어 유효성 검증 성공 테스트") void validateSuccessInputWord() { - assertDoesNotThrow(() -> new InputWord("date", words)); + List words = List.of("apples", "cherry"); + assertDoesNotThrow(() -> new InputWord("cherry", words)); } @Test @DisplayName("입력단어 유효성 검증 실패 테스트") - void validateFailInputWord() { + 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..f1e93a80 --- /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); + } +} From 450e186046c74d948fd858da319b1884becdb9a5 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 13 Jun 2024 18:44:39 +0900 Subject: [PATCH 07/47] =?UTF-8?q?fix:=20isCorrent=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Answer.java | 2 +- src/test/java/domain/InputWordTest.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index 94a34eff..8198a1e8 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -24,7 +24,7 @@ Boolean exists(char inputChar) { } Boolean isCorrect(int index, char inputChar) { - return value.indexOf(inputChar) == index; + return value.charAt(index) == inputChar; } @Override diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index a9b32f1e..f5c98049 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -66,4 +66,22 @@ void matchLocationTest() { new MatchResult('r', Hint.EXIST) ); } + + @Test + @DisplayName("입력단어와 정답 위치 확인 테스트") + void test() { + List words = List.of("colon"); + + InputWord inputWord = new InputWord("colon", words); + Answer answer = new Answer("colon"); + MatchResults matchResults = inputWord.match(answer); + + assertThat(matchResults.getResults()).containsExactly( + new MatchResult('c', Hint.CORRECT), + new MatchResult('o', Hint.CORRECT), + new MatchResult('l', Hint.CORRECT), + new MatchResult('o', Hint.CORRECT), + new MatchResult('n', Hint.CORRECT) + ); + } } From 76a9bbeff40c615dabea8eb90741c7e53ea6e8fb Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 13 Jun 2024 18:45:04 +0900 Subject: [PATCH 08/47] =?UTF-8?q?refactor:=20=ED=83=80=EC=9D=BC=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=20=EB=B3=80=EC=88=98=EB=AA=85=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/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 94436281..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; } } From 1350d0003dec700620ff0840d7266457199e872c Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 13 Jun 2024 18:46:48 +0900 Subject: [PATCH 09/47] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=ED=9B=84=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=EA=B9=8C=EC=A7=80=20=EB=A1=9C=EC=A7=81=201?= =?UTF-8?q?=ED=9A=8C=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 | 63 +++++++++++++++++++++++ src/main/java/domain/MatchResult.java | 4 ++ src/main/java/domain/MatchResults.java | 8 ++- src/main/java/domain/Round.java | 19 +++++++ src/main/java/ui/HintView.java | 16 ++++++ src/main/java/ui/InputView.java | 13 +++++ src/main/java/ui/RoundView.java | 7 +++ src/main/resources/words.txt | 2 +- 8 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/main/java/controller/GameManager.java create mode 100644 src/main/java/domain/Round.java create mode 100644 src/main/java/ui/HintView.java create mode 100644 src/main/java/ui/InputView.java create mode 100644 src/main/java/ui/RoundView.java diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java new file mode 100644 index 00000000..29a4b78b --- /dev/null +++ b/src/main/java/controller/GameManager.java @@ -0,0 +1,63 @@ +package controller; + +import domain.Answer; +import domain.InputWord; +import domain.MatchResults; +import domain.Round; +import ui.GuideTextView; +import ui.HintView; +import ui.InputView; + +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 List availableWords; + + private GuideTextView guideTextView; + private InputView inputView; + private HintView hintView; + + protected GameManager() { + this.matchResults = new ArrayList<>(); + this.availableWords = new ArrayList<>(); + } + + 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.guideTextView = new GuideTextView(); + this.inputView = new InputView(); + this.hintView = new HintView(); + } + + + public void start() { + guideTextView.render(); + + // 라운드 입력 view + System.out.println(this.answer); + String input = inputView.input(); + + InputWord inputWord = new InputWord(input, this.availableWords); + MatchResults matchResultOfInput = inputWord.match(answer); + this.matchResults.add(matchResultOfInput); + + // 힌트 노출 + hintView.render(this.matchResults); + + // 정답 확인 + // 저 + + + + + } +} diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index ac666f73..ff3dc119 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -9,6 +9,10 @@ public MatchResult(char inputChar, Hint hint) { this.hint = hint; } + public String getTile() { + return hint.getTile(); + } + @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 1aa5a6bf..bc110823 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -1,15 +1,21 @@ 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; } 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/ui/HintView.java b/src/main/java/ui/HintView.java new file mode 100644 index 00000000..4ec2f3fd --- /dev/null +++ b/src/main/java/ui/HintView.java @@ -0,0 +1,16 @@ +package ui; + +import domain.MatchResults; + +import java.util.List; + +public class HintView { + public void render(List matchResults) { + matchResults.forEach(matchResultEachRound -> { + matchResultEachRound.forEach(matchResult -> { + System.out.print(matchResult.getTile()); + }); + System.out.println(); + }); + } +} 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 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"); + } +} diff --git a/src/main/resources/words.txt b/src/main/resources/words.txt index e6be7404..da5dde07 100644 --- a/src/main/resources/words.txt +++ b/src/main/resources/words.txt @@ -6,7 +6,7 @@ awake blush focal evade -naval +navalc serve heath dwarf From 82b774bba62060c1814c3fce315d316ee99c36ce Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 13 Jun 2024 19:35:25 +0900 Subject: [PATCH 10/47] =?UTF-8?q?feat:=20=EC=A0=95=EB=8B=B5=EC=9D=B4?= =?UTF-8?q?=EB=A9=B4=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=9B=84=20=EA=B2=8C=EC=9E=84=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 11 ++++++++--- src/main/java/domain/MatchResult.java | 5 +++++ src/main/java/domain/MatchResults.java | 4 ++++ src/main/java/domain/Round.java | 8 ++++++++ src/main/java/ui/RoundView.java | 4 ++-- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 29a4b78b..029a9716 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -7,6 +7,7 @@ import ui.GuideTextView; import ui.HintView; import ui.InputView; +import ui.RoundView; import java.time.LocalDate; import java.util.ArrayList; @@ -22,6 +23,7 @@ public class GameManager { private GuideTextView guideTextView; private InputView inputView; private HintView hintView; + private RoundView roundView; protected GameManager() { this.matchResults = new ArrayList<>(); @@ -36,6 +38,7 @@ public GameManager(List availableWords) { this.guideTextView = new GuideTextView(); this.inputView = new InputView(); this.hintView = new HintView(); + this.roundView = new RoundView(); } @@ -50,12 +53,14 @@ public void start() { MatchResults matchResultOfInput = inputWord.match(answer); this.matchResults.add(matchResultOfInput); + // 정답 확인 + if(matchResultOfInput.isEndGame()) { + roundView.render(round.getCurrent(),round.getLimit()); + } + // 힌트 노출 hintView.render(this.matchResults); - // 정답 확인 - // 저 - diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index ff3dc119..427b3f87 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -13,6 +13,11 @@ 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 bc110823..f750eb9a 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -19,4 +19,8 @@ public Iterator iterator() { public List getResults() { return results; } + + public boolean isEndGame() { + return results.stream().allMatch(MatchResult::isCorrect); + } } diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index e00f6d4a..05167b4d 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -16,4 +16,12 @@ void goNext() { Boolean isLastRound() { return this.current >= this.limit; } + + public int getLimit() { + return limit; + } + + public int getCurrent() { + return current; + } } 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 6077df05e3f953a3891467a6ef51797efa9262d9 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 13 Jun 2024 19:45:40 +0900 Subject: [PATCH 11/47] =?UTF-8?q?feat:=206=ED=9A=8C=20=EB=B0=98=EB=B3=B5?= =?UTF-8?q?=20=EB=A3=A8=ED=94=84=20=EB=8F=8C=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 16 ++++++++++------ src/main/java/domain/Round.java | 6 +++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 029a9716..ed84d6c1 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -24,6 +24,7 @@ public class GameManager { private InputView inputView; private HintView hintView; private RoundView roundView; + private boolean isEndGame = false; protected GameManager() { this.matchResults = new ArrayList<>(); @@ -44,9 +45,13 @@ public GameManager(List availableWords) { public void start() { guideTextView.render(); + while(!this.isEndGame && round.isNotFinalRound()) { + startRound(); + } + } + private void startRound() { // 라운드 입력 view - System.out.println(this.answer); String input = inputView.input(); InputWord inputWord = new InputWord(input, this.availableWords); @@ -54,15 +59,14 @@ public void start() { this.matchResults.add(matchResultOfInput); // 정답 확인 - if(matchResultOfInput.isEndGame()) { + boolean isEndGame = matchResultOfInput.isEndGame(); + if(isEndGame) { roundView.render(round.getCurrent(),round.getLimit()); + this.isEndGame = isEndGame; } // 힌트 노출 hintView.render(this.matchResults); - - - - + round.goNext(); } } diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 05167b4d..305fbd1e 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -9,7 +9,7 @@ public Round(int limit, int current) { this.current = current; } - void goNext() { + public void goNext() { this.current++; } @@ -24,4 +24,8 @@ public int getLimit() { public int getCurrent() { return current; } + + public boolean isNotFinalRound() { + return current <= limit; + } } From b978226d482ed4b9a7a081e20b06993ae764f8c0 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 13:13:35 +0900 Subject: [PATCH 12/47] =?UTF-8?q?feat:=20=EB=8B=A8=EC=96=B4=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EC=88=98=20=EC=A0=9C=ED=95=9C=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 46 +++++++++++++++++++++++++ src/main/java/domain/InputWord.java | 14 ++++---- src/test/java/domain/InputWordTest.java | 7 ++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d3179421..f7b52fba 100644 --- a/README.md +++ b/README.md @@ -87,3 +87,49 @@ spill - 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다. + +--- + +### 구현 목록 +- 단어 불러오기 +- 매일 바뀌는 정답단어 선택 +- 단어 입력 + - 입력시 단어목록에 있나 검증 +- 비교 로직 + - 같을때, 있을떄, 없을때 따른 비교결과 +- 게임로직 + - 6회 초과시 게임오버 + - 정답시 게임클리어 +- ui + - 비교 결과, 라운드 출력 + + +### 회고 +240608 +- 도메인 클래스만 만들어보기 +- 패키지구조 +- 8:50 ~ 9:30 + +240611 +- 단어목록 읽어오기 +- 비교로직없이 한사이클 돌기? + - ui 전부 구현 + + +## 리팩터링 포인트 +- [ ] final 붙혀주기 +- [ ] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. +- [ ] InputWord와 Answer를 합치기? +- [ ] match 에 for 문안 함수로 발라내기 +- [ ] isEndGame 플래그 변수 네이밍 변경 +- [ ] 검증 + - [x] 5글자 검증 + - [ ] 영단어 검증 +- [ ] 예외 try catch +- [ ] GameManager에 있는 List 의 변수명 변경 +- [ ] HintView에 3depth 줄이기 +- [ ] InputWOrd의 마지막 테스트함수 이름 +- [ ] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 +- [ ] new InputWord 매번 할 필요 없음 +- [ ] GameManager의 의존성 줄여두기 +- [ ] String 말고 char 배열로 쓸지? diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java index 934389c7..bcf91edc 100644 --- a/src/main/java/domain/InputWord.java +++ b/src/main/java/domain/InputWord.java @@ -4,8 +4,8 @@ import java.util.List; public class InputWord { - private String value; - private List availableWords; + private final String value; + private final static int MAX_LENGTH = 5; public MatchResults match(Answer answer){ ArrayList matchResults = new ArrayList<>(); @@ -26,12 +26,14 @@ public MatchResults match(Answer answer){ public InputWord(String value, List availableWords) { this.value = value; - this.availableWords = availableWords; - validate(value); + validate(value, availableWords); } - private void validate(String input) { - if(!this.availableWords.contains(input)){ + private void validate(String input, List availableWords) { + if(input.length() != MAX_LENGTH){ + throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); + } + if(!availableWords.contains(input)){ throw new IllegalArgumentException("입력 불가능한 단어입니다."); } } diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index f5c98049..f00f18f6 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -29,6 +29,13 @@ void validateSuccessInputWord() { assertThrows(IllegalArgumentException.class,() -> new InputWord("pangyo", words)); } + @Test + @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") + void validateInputWordLength() { + List words = List.of("apple", "abcdef"); + assertThrows(IllegalArgumentException.class,() -> new InputWord("abcdef", words)); + } + @Test @DisplayName("입력단어와 정답 비교") void matchTest() { From 83d0f2932af707a5eb8a127fe5ebb0cfceb618d4 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 13:24:06 +0900 Subject: [PATCH 13/47] =?UTF-8?q?feat:=20=EC=98=81=EC=96=B4=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EB=A7=8C=20=EC=9E=85=EB=A0=A5=ED=95=98=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/main/java/domain/InputWord.java | 19 +++++++++++++++++++ src/test/java/domain/InputWordTest.java | 15 ++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f7b52fba..e77e2326 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,9 @@ spill - [ ] InputWord와 Answer를 합치기? - [ ] match 에 for 문안 함수로 발라내기 - [ ] isEndGame 플래그 변수 네이밍 변경 -- [ ] 검증 +- [x] 검증 - [x] 5글자 검증 - - [ ] 영단어 검증 + - [x] 영단어 검증 - [ ] 예외 try catch - [ ] GameManager에 있는 List 의 변수명 변경 - [ ] HintView에 3depth 줄이기 diff --git a/src/main/java/domain/InputWord.java b/src/main/java/domain/InputWord.java index bcf91edc..a174b7ed 100644 --- a/src/main/java/domain/InputWord.java +++ b/src/main/java/domain/InputWord.java @@ -30,12 +30,31 @@ public InputWord(String value, List availableWords) { } private void validate(String input, List availableWords) { + validateLength(input); + + validateOnlyEnglish(input); + + validateContain(input, availableWords); + } + + private void validateOnlyEnglish(String input) { + if(!input.matches("^[a-zA-Z]+$")){ + throw new IllegalArgumentException("영단어를 입력해주세요. [{" + input + "}]"); + } + } + + private void validateLength(String input) { if(input.length() != MAX_LENGTH){ throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); } + } + + private void validateContain(String input, List availableWords) { if(!availableWords.contains(input)){ throw new IllegalArgumentException("입력 불가능한 단어입니다."); } } + + } diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index f00f18f6..7bfe3421 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -2,10 +2,7 @@ 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; @@ -36,6 +33,18 @@ void validateInputWordLength() { assertThrows(IllegalArgumentException.class,() -> new InputWord("abcdef", words)); } + + @Test + @DisplayName("입력단어 영단어 유효성 검증 실패 테스트") + void validateInputWordOnlyEnglish() { + List words = List.of("apple", "abcd1", "안녕하세요"); + + assertAll( + () -> assertThrows(IllegalArgumentException.class,() -> new InputWord("abcd1", words)), + () -> assertThrows(IllegalArgumentException.class,() -> new InputWord("안녕하세요", words)) + ); + } + @Test @DisplayName("입력단어와 정답 비교") void matchTest() { From 4ccbeb908a0d60190026da8c9bf5462afd778ae9 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 13:29:39 +0900 Subject: [PATCH 14/47] =?UTF-8?q?feat:=20=EB=8B=A8=EC=96=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=8B=9C=20=EC=97=90=EB=9F=AC=EB=82=98=EB=A9=B4=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EC=8B=9C=EB=8F=84=ED=95=98=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/controller/GameManager.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e77e2326..f9ede2df 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ spill - [x] 검증 - [x] 5글자 검증 - [x] 영단어 검증 -- [ ] 예외 try catch +- [x] 예외 try catch - [ ] GameManager에 있는 List 의 변수명 변경 - [ ] HintView에 3depth 줄이기 - [ ] InputWOrd의 마지막 테스트함수 이름 diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index ed84d6c1..148b8bd6 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -54,7 +54,14 @@ private void startRound() { // 라운드 입력 view String input = inputView.input(); - InputWord inputWord = new InputWord(input, this.availableWords); + InputWord inputWord; + try { + inputWord = new InputWord(input, this.availableWords); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return; + } + MatchResults matchResultOfInput = inputWord.match(answer); this.matchResults.add(matchResultOfInput); From 29474bf08e3d641bcd6d3e864aa9a23ee13ccd06 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 14:07:14 +0900 Subject: [PATCH 15/47] =?UTF-8?q?refactor:=20MatchResult=EC=97=90=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=EC=95=8A=EB=8A=94=20inputC?= =?UTF-8?q?har=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/controller/GameManager.java | 13 +++---- src/main/java/domain/Answer.java | 23 ++++++++++++- src/main/java/domain/Hint.java | 4 +++ src/main/java/domain/InputWord.java | 42 +++++++++++++---------- src/main/java/domain/MatchResult.java | 42 +++++++++-------------- src/main/java/domain/MatchResults.java | 17 +++++---- src/main/java/ui/HintView.java | 15 ++++---- 7 files changed, 91 insertions(+), 65 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 148b8bd6..2b68b390 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,9 +1,6 @@ package controller; -import domain.Answer; -import domain.InputWord; -import domain.MatchResults; -import domain.Round; +import domain.*; import ui.GuideTextView; import ui.HintView; import ui.InputView; @@ -15,7 +12,7 @@ public class GameManager { private Round round; - private List matchResults; + private MatchResults matchResults; private Answer answer; private List availableWords; @@ -27,15 +24,13 @@ public class GameManager { private boolean isEndGame = false; protected GameManager() { - this.matchResults = new ArrayList<>(); - this.availableWords = new ArrayList<>(); } 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.matchResults = new MatchResults(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); this.hintView = new HintView(); @@ -62,7 +57,7 @@ private void startRound() { return; } - MatchResults matchResultOfInput = inputWord.match(answer); + MatchResult matchResultOfInput = answer.match(inputWord); this.matchResults.add(matchResultOfInput); // 정답 확인 diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java index 8198a1e8..886d8274 100644 --- a/src/main/java/domain/Answer.java +++ b/src/main/java/domain/Answer.java @@ -1,6 +1,5 @@ package domain; -import java.time.Duration; import java.time.LocalDate; import java.time.Period; import java.util.List; @@ -27,6 +26,24 @@ Boolean isCorrect(int index, char inputChar) { return value.charAt(index) == inputChar; } + + public MatchResult match(InputWord inputWord) { + MatchResult matchResult = new MatchResult(); + for(int i = 0; i< inputWord.getLength(); i++){ + char c = inputWord.getCharBy(i); + if(isCorrect(i, c)){ + matchResult.add(Hint.CORRECT); + continue; + } + if(exists(c)){ + matchResult.add(Hint.EXIST); + continue; + } + matchResult.add(Hint.NOT_EXIST); + } + return matchResult; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -41,4 +58,8 @@ public boolean equals(Object o) { 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 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/InputWord.java b/src/main/java/domain/InputWord.java index a174b7ed..2706af72 100644 --- a/src/main/java/domain/InputWord.java +++ b/src/main/java/domain/InputWord.java @@ -7,28 +7,32 @@ public class InputWord { private final String value; private final static int MAX_LENGTH = 5; - 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 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; validate(value, availableWords); } + public int getLength() { + return value.length(); + } + private void validate(String input, List availableWords) { validateLength(input); @@ -39,7 +43,7 @@ private void validate(String input, List availableWords) { private void validateOnlyEnglish(String input) { if(!input.matches("^[a-zA-Z]+$")){ - throw new IllegalArgumentException("영단어를 입력해주세요. [{" + input + "}]"); + throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); } } @@ -56,5 +60,7 @@ private void validateContain(String input, List availableWords) { } - + public char getCharBy(int i) { + return value.charAt(i); + } } diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 427b3f87..384a4a21 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -1,39 +1,31 @@ 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; - - MatchResult that = (MatchResult) o; - - if (inputChar != that.inputChar) return false; - return hint == that.hint; + public Iterator iterator() { + return hints.iterator(); } - @Override - public int hashCode() { - int result = inputChar; - result = 31 * result + (hint != null ? hint.hashCode() : 0); - return result; + public boolean isEndGame() { + return hints.stream().allMatch(Hint::isCorrect); + } + + public void add(Hint hint) { + hints.add(hint); } } 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); } } 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 e1c13e929e961ffbd0bf9eca12cbad9cfd9a8527 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 14:18:14 +0900 Subject: [PATCH 16/47] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/MatchResultTest.java | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/test/java/domain/MatchResultTest.java diff --git a/src/test/java/domain/MatchResultTest.java b/src/test/java/domain/MatchResultTest.java deleted file mode 100644 index f1e93a80..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); - } -} From 13ece198442cd2312cf97de6784a54475b28d2a3 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 14:19:24 +0900 Subject: [PATCH 17/47] =?UTF-8?q?refactor(test):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=B0=EA=B3=BC=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=89=BD=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit InputWordTest -> AnswerTest로 위치 변경 --- src/main/java/domain/MatchResult.java | 12 ++++- src/test/java/domain/AnswerTest.java | 61 ++++++++++++++++++++++++- src/test/java/domain/InputWordTest.java | 54 ---------------------- 3 files changed, 70 insertions(+), 57 deletions(-) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 384a4a21..de1a7cac 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -23,10 +23,20 @@ public Iterator iterator() { public boolean isEndGame() { return hints.stream().allMatch(Hint::isCorrect); } - + public void add(Hint hint) { hints.add(hint); } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this.hints.equals(((MatchResult) obj).hints); + } } diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index 7b468265..c6d95830 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -7,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); assertThat(answer).isEqualTo(new Answer("banana")); } + + + @Test + @DisplayName("입력단어와 정답 비교") + void matchTest() { + List words = List.of("apple", "banan", "cherr"); + + InputWord inputWord = new InputWord("cherr", words); + Answer answer = new Answer("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"); + + InputWord inputWord = new InputWord("rxxrx", words); + Answer answer = new Answer("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"); + + InputWord inputWord = new InputWord("colon", words); + Answer answer = new Answer("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 7bfe3421..e8f319d8 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -45,59 +45,5 @@ void validateInputWordOnlyEnglish() { ); } - @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) - ); - } - - @Test - @DisplayName("입력단어와 정답 위치 확인 테스트") - void test() { - List words = List.of("colon"); - - InputWord inputWord = new InputWord("colon", words); - Answer answer = new Answer("colon"); - MatchResults matchResults = inputWord.match(answer); - - assertThat(matchResults.getResults()).containsExactly( - new MatchResult('c', Hint.CORRECT), - new MatchResult('o', Hint.CORRECT), - new MatchResult('l', Hint.CORRECT), - new MatchResult('o', Hint.CORRECT), - new MatchResult('n', Hint.CORRECT) - ); - } } From 961f2b6422f8812f3783de0674bd4426771ff903 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 14:22:07 +0900 Subject: [PATCH 18/47] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index c6d95830..1295a299 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -39,7 +39,7 @@ void matchTest() { } @Test - @DisplayName("입력단어와 정답 위치 확인 테스트") + @DisplayName("입력단어와 중복 단어 위치 확인 테스트") void matchLocationTest() { List words = List.of("rxxrx"); @@ -58,7 +58,7 @@ void matchLocationTest() { } @Test - @DisplayName("입력단어와 정답 위치 확인 테스트") + @DisplayName("전부정답인 경우") void test() { List words = List.of("colon"); From 4ed2af839f7e572a4b5c0207f9e14fc16a2807a0 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 14:51:26 +0900 Subject: [PATCH 19/47] =?UTF-8?q?refactor:=20InputWord=EC=99=80=20AnswerWo?= =?UTF-8?q?rd=EB=A5=BC=20=ED=95=A9=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++-- src/main/java/controller/GameManager.java | 35 ++++---- src/main/java/domain/Answer.java | 65 -------------- src/main/java/domain/InputWord.java | 66 -------------- src/main/java/domain/Word.java | 101 ++++++++++++++++++++++ src/test/java/domain/AnswerTest.java | 16 ++-- src/test/java/domain/InputWordTest.java | 10 +-- 7 files changed, 142 insertions(+), 167 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/README.md b/README.md index f9ede2df..fdc68c11 100644 --- a/README.md +++ b/README.md @@ -118,18 +118,18 @@ spill ## 리팩터링 포인트 - [ ] final 붙혀주기 -- [ ] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. -- [ ] InputWord와 Answer를 합치기? +- [x] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. +- [x] InputWord와 Answer를 합치기? - [ ] match 에 for 문안 함수로 발라내기 -- [ ] isEndGame 플래그 변수 네이밍 변경 +- [x] isEndGame 플래그 변수 네이밍 변경 - [x] 검증 - [x] 5글자 검증 - [x] 영단어 검증 - [x] 예외 try catch -- [ ] GameManager에 있는 List 의 변수명 변경 -- [ ] HintView에 3depth 줄이기 -- [ ] InputWOrd의 마지막 테스트함수 이름 -- [ ] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 -- [ ] new InputWord 매번 할 필요 없음 +- [x] GameManager에 있는 List 의 변수명 변경 +- [x] HintView에 3depth 줄이기 +- [x] InputWOrd의 마지막 테스트함수 이름 +- [x] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 - [ ] GameManager의 의존성 줄여두기 - [ ] String 말고 char 배열로 쓸지? + diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 2b68b390..0a94d401 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,19 +1,21 @@ package controller; -import domain.*; +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 MatchResults matchResults; - private Answer answer; + private Word answer; private List availableWords; @@ -21,13 +23,13 @@ public class GameManager { private InputView inputView; private HintView hintView; private RoundView roundView; - private boolean isEndGame = false; + private boolean isWinning = false; protected GameManager() { } 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 MatchResults(); @@ -40,7 +42,7 @@ public GameManager(List availableWords) { public void start() { guideTextView.render(); - while(!this.isEndGame && round.isNotFinalRound()) { + while(!this.isWinning && round.isNotFinalRound()) { startRound(); } } @@ -49,26 +51,29 @@ private void startRound() { // 라운드 입력 view String input = inputView.input(); - InputWord inputWord; + Word inputWord; try { - inputWord = new InputWord(input, this.availableWords); + inputWord = Word.createInput(input, this.availableWords); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); return; } - MatchResult matchResultOfInput = answer.match(inputWord); - this.matchResults.add(matchResultOfInput); + checkAnswer(inputWord); - // 정답 확인 - boolean isEndGame = matchResultOfInput.isEndGame(); - if(isEndGame) { + 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(); + } + } diff --git a/src/main/java/domain/Answer.java b/src/main/java/domain/Answer.java deleted file mode 100644 index 886d8274..00000000 --- a/src/main/java/domain/Answer.java +++ /dev/null @@ -1,65 +0,0 @@ -package domain; - -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; - } - - - public MatchResult match(InputWord inputWord) { - MatchResult matchResult = new MatchResult(); - for(int i = 0; i< inputWord.getLength(); i++){ - char c = inputWord.getCharBy(i); - if(isCorrect(i, c)){ - matchResult.add(Hint.CORRECT); - continue; - } - if(exists(c)){ - matchResult.add(Hint.EXIST); - continue; - } - matchResult.add(Hint.NOT_EXIST); - } - return matchResult; - } - - @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 2706af72..00000000 --- a/src/main/java/domain/InputWord.java +++ /dev/null @@ -1,66 +0,0 @@ -package domain; - -import java.util.ArrayList; -import java.util.List; - -public class InputWord { - private final String value; - private final static int MAX_LENGTH = 5; - -// 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; - validate(value, availableWords); - } - - public int getLength() { - return value.length(); - } - - private void validate(String input, List availableWords) { - validateLength(input); - - validateOnlyEnglish(input); - - validateContain(input, availableWords); - } - - private void validateOnlyEnglish(String input) { - if(!input.matches("^[a-zA-Z]+$")){ - throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); - } - } - - private void validateLength(String input) { - if(input.length() != MAX_LENGTH){ - throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); - } - } - - private void validateContain(String input, List availableWords) { - if(!availableWords.contains(input)){ - throw new IllegalArgumentException("입력 불가능한 단어입니다."); - } - } - - - public char getCharBy(int i) { - return value.charAt(i); - } -} diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java new file mode 100644 index 00000000..729716c2 --- /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; + +public class Word { + private final static int MAX_LENGTH = 5; + private 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) { + MatchResult matchResult = new MatchResult(); + for(int i = 0; i< word.getLength(); i++){ + char c = word.getCharBy(i); + if(isCorrect(i, c)){ + matchResult.add(Hint.CORRECT); + continue; + } + if(exists(c)){ + matchResult.add(Hint.EXIST); + continue; + } + matchResult.add(Hint.NOT_EXIST); + } + return matchResult; + } + + private char getCharBy(int i) { + return value.charAt(i); + } + + private int getLength() { + return this.value.length(); + } + + 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/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index 1295a299..e084f5c9 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -13,9 +13,9 @@ class AnswerTest { @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); + Word answer = Word.createAnswer(LocalDate.of(2021, 6, 20), words); - assertThat(answer).isEqualTo(new Answer("banana")); + assertThat(answer).isEqualTo(new Word("banana")); } @@ -24,8 +24,8 @@ void answerSelectTest() { void matchTest() { List words = List.of("apple", "banan", "cherr"); - InputWord inputWord = new InputWord("cherr", words); - Answer answer = new Answer("czzzh"); + Word inputWord = Word.createInput("cherr", words); + Word answer = new Word("czzzh"); MatchResult matchResults = answer.match(inputWord); MatchResult expected = new MatchResult(List.of( @@ -43,8 +43,8 @@ void matchTest() { void matchLocationTest() { List words = List.of("rxxrx"); - InputWord inputWord = new InputWord("rxxrx", words); - Answer answer = new Answer("cherr"); + Word inputWord = Word.createInput("rxxrx", words); + Word answer = new Word("cherr"); MatchResult matchResults = answer.match(inputWord); MatchResult expected = new MatchResult(List.of( @@ -62,8 +62,8 @@ void matchLocationTest() { void test() { List words = List.of("colon"); - InputWord inputWord = new InputWord("colon", words); - Answer answer = new Answer("colon"); + Word inputWord = Word.createInput("colon", words); + Word answer = new Word("colon"); MatchResult matchResults = answer.match(inputWord); MatchResult expected = new MatchResult(List.of( diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index e8f319d8..336dc5de 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -13,7 +13,7 @@ class InputWordTest { @DisplayName("입력단어 유효성 검증 성공 테스트") void validateSuccessInputWord() { List words = List.of("apples", "cherry"); - assertDoesNotThrow(() -> new InputWord("cherry", words)); + assertDoesNotThrow(() -> Word.createInput("cherry", words)); } @@ -23,14 +23,14 @@ 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 validateInputWordLength() { List words = List.of("apple", "abcdef"); - assertThrows(IllegalArgumentException.class,() -> new InputWord("abcdef", words)); + assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcdef", words)); } @@ -40,8 +40,8 @@ void validateInputWordOnlyEnglish() { List words = List.of("apple", "abcd1", "안녕하세요"); assertAll( - () -> assertThrows(IllegalArgumentException.class,() -> new InputWord("abcd1", words)), - () -> assertThrows(IllegalArgumentException.class,() -> new InputWord("안녕하세요", words)) + () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcd1", words)), + () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("안녕하세요", words)) ); } From d1dcaea7f5edfdca8931d2315dbb2c850fea4b69 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 15:25:41 +0900 Subject: [PATCH 20/47] =?UTF-8?q?refactor:=20Word=EC=9D=98=20match=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EC=95=88=20depth=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hint 판단로직 함수로 분리함 --- README.md | 4 +-- src/main/java/domain/Word.java | 42 ++++++++++++------------- src/main/java/infra/WordLoader.java | 2 +- src/test/java/domain/InputWordTest.java | 1 - 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index fdc68c11..0d2f722e 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ spill - [ ] final 붙혀주기 - [x] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. - [x] InputWord와 Answer를 합치기? -- [ ] match 에 for 문안 함수로 발라내기 +- [x] match 에 for 문안 함수로 발라내기 - [x] isEndGame 플래그 변수 네이밍 변경 - [x] 검증 - [x] 5글자 검증 @@ -128,7 +128,7 @@ spill - [x] 예외 try catch - [x] GameManager에 있는 List 의 변수명 변경 - [x] HintView에 3depth 줄이기 -- [x] InputWOrd의 마지막 테스트함수 이름 +- [x] InputWord의 마지막 테스트함수 이름 - [x] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 - [ ] GameManager의 의존성 줄여두기 - [ ] String 말고 char 배열로 쓸지? diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 729716c2..54ba2187 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -4,10 +4,12 @@ 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 String value; + private final String value; protected Word(String value) { this.value = value; @@ -17,6 +19,7 @@ public static Word createAnswer(LocalDate currentDate, List availableWor 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)); } @@ -26,30 +29,27 @@ public static Word createInput(String value, List availableWords) { } public MatchResult match(Word word) { - MatchResult matchResult = new MatchResult(); - for(int i = 0; i< word.getLength(); i++){ - char c = word.getCharBy(i); - if(isCorrect(i, c)){ - matchResult.add(Hint.CORRECT); - continue; - } - if(exists(c)){ - matchResult.add(Hint.EXIST); - continue; - } - matchResult.add(Hint.NOT_EXIST); + 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; } - return matchResult; + if (exists(character)) { + return Hint.EXIST; + } + return Hint.NOT_EXIST; } private char getCharBy(int i) { return value.charAt(i); } - private int getLength() { - return this.value.length(); - } - private Boolean exists(char inputChar) { return value.indexOf(inputChar) != -1; } @@ -67,19 +67,19 @@ private static void validate(String input, List availableWords) { } private static void validateOnlyEnglish(String input) { - if(!input.matches("^[a-zA-Z]+$")){ + if (!input.matches("^[a-zA-Z]+$")) { throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); } } private static void validateLength(String input) { - if(input.length() != MAX_LENGTH){ + if (input.length() != MAX_LENGTH) { throw new IllegalArgumentException(MAX_LENGTH + "자리의 단어를 입력해주세요."); } } private static void validateContain(String input, List availableWords) { - if(!availableWords.contains(input)){ + if (!availableWords.contains(input)) { throw new IllegalArgumentException("입력 불가능한 단어입니다."); } } diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordLoader.java index b11de611..92825ca4 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordLoader.java @@ -7,7 +7,7 @@ public class WordLoader { - public WordLoader() { + public WordLoader() { } public static List read(String filePath) { diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 336dc5de..1f4d296b 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -5,7 +5,6 @@ import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; From ebcec6bb14277ca4870c361c6290bb16514428f9 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 15:29:13 +0900 Subject: [PATCH 21/47] =?UTF-8?q?docs:=20readme=20=EC=97=90=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=84=B0=EB=A7=81=ED=95=9C=EA=B2=83=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0d2f722e..e000e1c2 100644 --- a/README.md +++ b/README.md @@ -103,21 +103,8 @@ spill - ui - 비교 결과, 라운드 출력 - -### 회고 -240608 -- 도메인 클래스만 만들어보기 -- 패키지구조 -- 8:50 ~ 9:30 - -240611 -- 단어목록 읽어오기 -- 비교로직없이 한사이클 돌기? - - ui 전부 구현 - - ## 리팩터링 포인트 -- [ ] final 붙혀주기 +- [x] final 붙혀주기 - [x] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. - [x] InputWord와 Answer를 합치기? - [x] match 에 for 문안 함수로 발라내기 @@ -129,7 +116,9 @@ spill - [x] GameManager에 있는 List 의 변수명 변경 - [x] HintView에 3depth 줄이기 - [x] InputWord의 마지막 테스트함수 이름 -- [x] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 -- [ ] GameManager의 의존성 줄여두기 -- [ ] String 말고 char 배열로 쓸지? +- [x] MatchResult에 inputChar가 쓰이지 않고 있어서 클래스 자체를 지우고 그냥 Hint만 쓰기 +- ~~[ ] 구조 변경~~ + - ~~[ ] GameManager의 의존성 줄여두기~~ + - ~~[ ] String 말고 char 배열로 쓸지? -> 좀 더 고민해보기~~ + - ~~[ ] 분리된 view 부분 합칠지?~~ From a004c58e38fd351239dbc93758d39ada526acd1b Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:12:06 +0900 Subject: [PATCH 22/47] =?UTF-8?q?refactor:=20final=20=ED=95=A0=EC=88=98?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EA=B2=83=20=EB=8B=AC=EC=95=84=EC=A3=BC?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResults.java | 2 +- src/main/java/domain/Round.java | 2 +- src/main/java/ui/InputView.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 815cf05e..0672b713 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -5,11 +5,11 @@ import java.util.List; public class MatchResults implements Iterable { - private List results; public MatchResults(List results) { this.results = results; } + private final List results; public MatchResults() { this.results = new ArrayList<>(); diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 305fbd1e..0430acde 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) { 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 3dc51bafefd7559d6997f716feb9c75c10eb8b97 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:12:33 +0900 Subject: [PATCH 23/47] =?UTF-8?q?refactor:=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=EC=97=90=20tile=20=EB=B0=9B=EB=8A=94=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=9D=B4=EB=A6=84=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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index 98849476..23b5d3e1 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -8,8 +8,8 @@ public enum Hint { private final String tile; - Hint(String hint) { - this.tile = hint; + Hint(String tile) { + this.tile = tile; } public String getTile() { From cc4f9929b3429ef4b547f55c16aeb82deb25faba Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:12:52 +0900 Subject: [PATCH 24/47] =?UTF-8?q?remove:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResult.java | 5 ----- src/main/java/domain/MatchResults.java | 9 --------- src/main/java/domain/Round.java | 4 ---- 3 files changed, 18 deletions(-) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index de1a7cac..7ccbeacb 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.Iterator; import java.util.List; @@ -11,10 +10,6 @@ public MatchResult(List hints) { this.hints = hints; } - public MatchResult() { - this.hints = new ArrayList<>(); - } - @Override public Iterator iterator() { return hints.iterator(); diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 0672b713..76a50d2d 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -5,21 +5,12 @@ import java.util.List; public class MatchResults implements Iterable { - - public MatchResults(List results) { - this.results = results; - } private final List results; public MatchResults() { this.results = new ArrayList<>(); } - - public List getResults() { - return results; - } - @Override public Iterator iterator() { return this.results.iterator(); diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 0430acde..4a872a73 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -13,10 +13,6 @@ public void goNext() { this.current++; } - Boolean isLastRound() { - return this.current >= this.limit; - } - public int getLimit() { return limit; } From 126c6c844b1ae0f164ccb62ff80bbaf2f22d04b0 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:52:01 +0900 Subject: [PATCH 25/47] =?UTF-8?q?feat:=20MatchResult=20equals=20=EB=8B=A4?= =?UTF-8?q?=EB=A5=B8=ED=81=B4=EB=9E=98=EC=8A=A4=EB=8A=94=20false=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/MatchResult.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 7ccbeacb..133f0151 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -30,6 +30,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if(obj == null) return false; + if(obj.getClass() != this.getClass()) return false; return this.hints.equals(((MatchResult) obj).hints); } } From f2b681757b97eed16174530af70f93dbb2eadfb8 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 18:03:06 +0900 Subject: [PATCH 26/47] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20getCharBy=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/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 54ba2187..bd2bf1c6 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(word.value.charAt(i), i)) .collect(Collectors.toList()); return new MatchResult(hints); @@ -46,10 +46,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 832b82abe36e5c3c81352ea42f245ceb5b21a6f5 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:18:37 +0900 Subject: [PATCH 27/47] =?UTF-8?q?refactor:=20=ED=95=84=EB=93=9C=EC=97=90?= =?UTF-8?q?=20final=20=EB=8B=AC=EC=95=84=EC=A3=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 0a94d401..b0b87433 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -13,21 +13,19 @@ import java.util.List; public class GameManager { - private Round round; - private MatchResults matchResults; - private Word answer; + private final static int ROUND_LIMIT = 6; + private final Round round; + private final MatchResults matchResults; + private final Word answer; - private List availableWords; + private final List availableWords; - private GuideTextView guideTextView; - private InputView inputView; - private HintView hintView; - private RoundView roundView; + private final GuideTextView guideTextView; + private final InputView inputView; + private final HintView hintView; + private final RoundView roundView; private boolean isWinning = false; - protected GameManager() { - } - public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; From db374dad5cbbc7d998ff99452d73d34908334ecd Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:23:15 +0900 Subject: [PATCH 28/47] =?UTF-8?q?refactor:=20Round=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=8B=9C=20=ED=98=84=EC=9E=AC=EB=9D=BC=EC=9A=B4=EB=93=9C?= =?UTF-8?q?=EB=8A=94=201=EB=A1=9C=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 2 +- src/main/java/domain/Round.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index b0b87433..8b53450f 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -29,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(ROUND_LIMIT); this.matchResults = new MatchResults(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 4a872a73..f063f79b 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -4,11 +4,15 @@ public class Round { private final int limit; private int current; - public Round(int limit, int current) { + private Round(int limit, int current) { this.limit = limit; this.current = current; } + public Round(int limit) { + this(limit, 1); + } + public void goNext() { this.current++; } From e91405c2dea10c7c6e47c27ae612d71f649161ae Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:23:34 +0900 Subject: [PATCH 29/47] =?UTF-8?q?refactor:=20=EB=9D=BC=EC=9A=B4=EB=93=9C?= =?UTF-8?q?=20=EC=A0=9C=ED=95=9C=20=EC=A3=BC=EC=9E=85=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=84=9C=20=EC=B6=9C=EB=A0=A5=ED=95=98=EA=B2=8C=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/controller/GameManager.java | 2 +- src/main/java/ui/GuideTextView.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 8b53450f..cefb31e1 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -39,7 +39,7 @@ public GameManager(List availableWords) { public void start() { - guideTextView.render(); + guideTextView.render(round.getLimit()); while(!this.isWinning && round.isNotFinalRound()) { startRound(); } diff --git a/src/main/java/ui/GuideTextView.java b/src/main/java/ui/GuideTextView.java index 3c6ef5a2..8f8dea1c 100644 --- a/src/main/java/ui/GuideTextView.java +++ b/src/main/java/ui/GuideTextView.java @@ -1,8 +1,8 @@ package ui; public class GuideTextView { - public void render() { - System.out.println("WORDLE을 6번 만에 맞춰 보세요."); + public void render(int roundLimit) { + System.out.printf("WORDLE을 %d번 만에 맞춰 보세요.\n", roundLimit); System.out.println("시도의 결과는 타일의 색 변화로 나타납니다."); } } From e15dd60c633e80a3afaa2791bd5228f5922e4759 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:41:54 +0900 Subject: [PATCH 30/47] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80?= =?UTF-8?q?=EC=95=8A=EA=B3=A0=20getter/setter=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 18 ++++++++++++++---- src/main/java/domain/MatchResult.java | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index cefb31e1..3f08a5eb 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -17,6 +17,7 @@ public class GameManager { private final Round round; private final MatchResults matchResults; private final Word answer; + private boolean isWinning; private final List availableWords; @@ -24,7 +25,6 @@ public class GameManager { private final InputView inputView; private final HintView hintView; private final RoundView roundView; - private boolean isWinning = false; public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); @@ -40,7 +40,7 @@ public GameManager(List availableWords) { public void start() { guideTextView.render(round.getLimit()); - while(!this.isWinning && round.isNotFinalRound()) { + while(isNotWinning() && round.isNotFinalRound()) { startRound(); } } @@ -59,7 +59,7 @@ private void startRound() { checkAnswer(inputWord); - if(this.isWinning) { + if(isWinning()) { roundView.render(round.getCurrent(),round.getLimit()); } @@ -70,8 +70,18 @@ private void startRound() { private void checkAnswer(Word inputWord) { MatchResult matchResultOfInput = answer.match(inputWord); this.matchResults.add(matchResultOfInput); + setWinning(matchResultOfInput.isWinning()); + } + + private boolean isNotWinning(){ + return !isWinning(); + } - this.isWinning = matchResultOfInput.isEndGame(); + private boolean isWinning() { + return isWinning; } + private void setWinning(boolean winning) { + isWinning = winning; + } } diff --git a/src/main/java/domain/MatchResult.java b/src/main/java/domain/MatchResult.java index 133f0151..e2e55b50 100644 --- a/src/main/java/domain/MatchResult.java +++ b/src/main/java/domain/MatchResult.java @@ -15,7 +15,7 @@ public Iterator iterator() { return hints.iterator(); } - public boolean isEndGame() { + public boolean isWinning() { return hints.stream().allMatch(Hint::isCorrect); } From dc59ce20e1e92ba6c35ce092bb243f2e2c90da9d Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:42:17 +0900 Subject: [PATCH 31/47] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EB=8B=A8=EC=88=9C=ED=95=98=EA=B2=8C=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/MatchResults.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 76a50d2d..063dbbb8 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -16,7 +16,7 @@ public Iterator iterator() { return this.results.iterator(); } - public void add(MatchResult matchResultOfInput) { - this.results.add(matchResultOfInput); + public void add(MatchResult matchResult) { + this.results.add(matchResult); } } From 7079129d07728db9442b3bf0d9c2184de27c1ef8 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Sun, 16 Jun 2024 17:43:11 +0900 Subject: [PATCH 32/47] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=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 | 3 --- src/main/java/controller/GameManager.java | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 54f604c0..6fb20f0c 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -6,12 +6,9 @@ public class WordleApplication { 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/controller/GameManager.java b/src/main/java/controller/GameManager.java index 3f08a5eb..6709c03e 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -46,7 +46,6 @@ public void start() { } private void startRound() { - // 라운드 입력 view String input = inputView.input(); Word inputWord; From 43b3e080dc81e4cf7698c6cacd804d362e2666a5 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Mon, 17 Jun 2024 21:14:15 +0900 Subject: [PATCH 33/47] =?UTF-8?q?doc:=20readme=20=EC=9B=90=EB=9E=98?= =?UTF-8?q?=EC=9E=88=EB=8D=98=20=EB=82=B4=EC=9A=A9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 92 +------------------------------------------------------ 1 file changed, 1 insertion(+), 91 deletions(-) diff --git a/README.md b/README.md index e000e1c2..199b9e86 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,5 @@ # 미션 - 워들 -## 🔍 진행 방식 - -- 미션은 **과제 진행 요구 사항**, **기능 요구 사항**, **프로그래밍 요구 사항** 세 가지로 구성되어 있다. -- 세 개의 요구 사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다. -- **기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다.** - ---- - -## 🚀 기능 요구 사항 - -선풍적인 인기를 끌었던 영어 단어 맞추기 게임이다. - -- 6x5 격자를 통해서 5글자 단어를 6번 만에 추측한다. -- 플레이어가 답안을 제출하면 프로그램이 정답과 제출된 단어의 각 알파벳 종류와 위치를 비교해 판별한다. -- 판별 결과는 흰색의 타일이 세 가지 색(초록색/노란색/회색) 중 하나로 바뀌면서 표현된다. - - 맞는 글자는 초록색, 위치가 틀리면 노란색, 없으면 회색 - - 두 개의 동일한 문자를 입력하고 그중 하나가 회색으로 표시되면 해당 문자 중 하나만 최종 단어에 나타난다. -- 정답과 답안은 `words.txt`에 존재하는 단어여야 한다. -- 정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다. - -### 입출력 요구 사항 - -#### 실행 결과 예시 - -``` -WORDLE을 6번 만에 맞춰 보세요. -시도의 결과는 타일의 색 변화로 나타납니다. -정답을 입력해 주세요. -hello - -⬜⬜🟨🟩⬜ - -정답을 입력해 주세요. -label - -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 - -정답을 입력해 주세요. -spell - -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 -🟩🟩⬜🟩🟩 - -정답을 입력해 주세요. -spill - -4/6 - -⬜⬜🟨🟩⬜ -🟨⬜⬜⬜🟩 -🟩🟩⬜🟩🟩 -🟩🟩🟩🟩🟩 -``` - ---- - -## 🎯 프로그래밍 요구 사항 - -- JDK 21 버전에서 실행 가능해야 한다. -- 프로그램 실행의 시작점은 `Application`의 `main()`이다. -- `build.gradle` 파일은 변경할 수 없으며, **제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다.** -- 프로그램 종료 시 `System.exit()`를 호출하지 않는다. -- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. -- 자바 코드 컨벤션을 지키면서 프로그래밍한다. - - 기본적으로 [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)를 원칙으로 한다. - - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. -- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다. - - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. - - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. -- 3항 연산자를 쓰지 않는다. -- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. -- JUnit 5와 AssertJ를 이용하여 정리한 기능 목록이 정상적으로 작동하는지 테스트 코드로 확인한다. - - 테스트 도구 사용법이 익숙하지 않다면 아래 문서를 참고하여 학습한 후 테스트를 구현한다. - - [JUnit 5 User Guide](https://junit.org/junit5/docs/current/user-guide) - - [AssertJ User Guide](https://assertj.github.io/doc) - - [AssertJ Exception Assertions](https://www.baeldung.com/assertj-exception-assertion) - - [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) -- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다. - - 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다. -- else 예약어를 쓰지 않는다. - - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. - - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. -- 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. - - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. - - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다. - ---- - ### 구현 목록 - 단어 불러오기 - 매일 바뀌는 정답단어 선택 @@ -103,7 +13,7 @@ spill - ui - 비교 결과, 라운드 출력 -## 리팩터링 포인트 +### 리팩터링 포인트 - [x] final 붙혀주기 - [x] Inputword 에 availableWords 상태로 가지고 있을 필요는 없다. - [x] InputWord와 Answer를 합치기? From 59449a3c2238dce09f020356970bbc9956da7f45 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Wed, 26 Jun 2024 22:37:08 +0900 Subject: [PATCH 34/47] =?UTF-8?q?fix(test):=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EA=B9=A8=EC=A7=80=EB=8A=94?= =?UTF-8?q?=EA=B2=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/InputWordTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 1f4d296b..2246cd0a 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -9,11 +9,11 @@ class InputWordTest { + @Test @DisplayName("입력단어 유효성 검증 성공 테스트") void validateSuccessInputWord() { - List words = List.of("apples", "cherry"); - assertDoesNotThrow(() -> Word.createInput("cherry", words)); - + List words = List.of("apple", "xxxxx"); + assertDoesNotThrow(() -> Word.createInput("apple", words)); } From 11352b8bd09f355daf3af6b21cfca752a2fe7934 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 00:22:08 +0900 Subject: [PATCH 35/47] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=EC=9D=98=20=EA=B0=99=EC=9D=80=EA=B8=80=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=97=AC=EB=9F=AC=EB=B2=88=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EB=90=A0=EB=95=8C=20=EA=B3=A0=EB=A0=A4=EB=AA=BB=ED=95=9C=20?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=93=A4=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/Word.java | 38 ++++---- src/test/java/domain/AnswerTest.java | 126 ++++++++++++++++++++------- 2 files changed, 118 insertions(+), 46 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index bd2bf1c6..c1f25624 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -4,15 +4,14 @@ 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; + private final String letters; protected Word(String value) { - this.value = value; + this.letters = value; } public static Word createAnswer(LocalDate currentDate, List availableWords) { @@ -28,30 +27,39 @@ public static Word createInput(String value, List availableWords) { return new Word(value); } - public MatchResult match(Word word) { - List hints = IntStream.range(0, value.length()) - .mapToObj(i -> getHint(word.value.charAt(i), i)) - .collect(Collectors.toList()); + public MatchResult match(Word otherWord) { + boolean[] visited = new boolean[letters.length()]; + List hints = IntStream.range(0, letters.length()) + .mapToObj(i -> matchLetter(otherWord, visited, i)) + .toList(); return new MatchResult(hints); } - private Hint getHint(Character character, int index) { - if (isCorrect(index, character)) { + private Hint matchLetter(Word otherWord, boolean[] visited, int index) { + if(isCorrect(index, otherWord.letters.charAt(index))){ + visited[index] = true; return Hint.CORRECT; } - if (exists(character)) { + + char otherWordChar = otherWord.letters.charAt(index); + if(this.exists(otherWordChar, visited)){ + visited[letters.indexOf(otherWordChar)] = true; return Hint.EXIST; } + return Hint.NOT_EXIST; } - private Boolean exists(char inputChar) { - return value.indexOf(inputChar) != -1; + private Boolean exists(char letter, boolean[] visited) { + return IntStream.range(0, letters.length()) + .filter(i -> !visited[i] && letters.charAt(i) == letter) + .findFirst() + .isPresent(); } private Boolean isCorrect(int index, char inputChar) { - return value.charAt(index) == inputChar; + return letters.charAt(index) == inputChar; } private static void validate(String input, List availableWords) { @@ -87,11 +95,11 @@ public boolean equals(Object o) { Word answer = (Word) o; - return Objects.equals(value, answer.value); + return Objects.equals(letters, answer.letters); } @Override public int hashCode() { - return value != null ? value.hashCode() : 0; + return letters != null ? letters.hashCode() : 0; } } diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index e084f5c9..00d6372c 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -18,61 +18,125 @@ void answerSelectTest() { assertThat(answer).isEqualTo(new Word("banana")); } - @Test - @DisplayName("입력단어와 정답 비교") - void matchTest() { - List words = List.of("apple", "banan", "cherr"); + void 전부_일치인_경우() { + Word answer = new Word("colon"); + Word inputWord = new Word("colon"); + MatchResult matchResults = answer.match(inputWord); - Word inputWord = Word.createInput("cherr", words); - Word answer = new Word("czzzh"); + assertThat(matchResults).containsExactly( + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT, + Hint.CORRECT + ); + } + + @Test + void 일치인_문자가_중복인_경우() { + Word answer = new Word("oozzz"); + Word inputWord = new Word("ooxxx"); MatchResult matchResults = answer.match(inputWord); - MatchResult expected = new MatchResult(List.of( + assertThat(matchResults).containsExactly( + Hint.CORRECT, 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"); + void 존재하는_문자가_중복인_경우() { + Word answer = new Word("zzzoo"); + Word inputWord = new Word("ooxxx"); MatchResult matchResults = answer.match(inputWord); - MatchResult expected = new MatchResult(List.of( + assertThat(matchResults).containsExactly( + Hint.EXIST, 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"); + void 전부_없는_경우() { + Word answer = new Word("xxxxx"); + Word inputWord = new Word("ooooo"); + MatchResult matchResults = answer.match(inputWord); - Word inputWord = Word.createInput("colon", words); - Word answer = new Word("colon"); + assertThat(matchResults).containsExactly( + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST + ); + } + + @Test + void 전부_존재하는_경우() { + Word answer = new Word("edbca"); + Word inputWord = new Word("abcde"); MatchResult matchResults = answer.match(inputWord); - MatchResult expected = new MatchResult(List.of( - Hint.CORRECT, - Hint.CORRECT, + assertThat(matchResults).containsExactly( + Hint.EXIST, + Hint.EXIST, + Hint.EXIST, + Hint.EXIST, + Hint.EXIST + ); + } + + @Test + void 같은문자_두번_입력시_먼저_일치한_문자가_나오면_다른하나는_없다고_나와야한다() { + Word answer = new Word("oxxxx"); + Word inputWord = new Word("oozzz"); + MatchResult matchResults = answer.match(inputWord); + + assertThat(matchResults).containsExactly( Hint.CORRECT, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST + ); + } + + // 와잼님이 짜준 테스트 + @Test + void 같은문자_두번_입력시_하나가_존재하면_다른하나는_없다고_나와야한다() { + Word answerWord = new Word("oxxxx"); // 정답 + Word inputWord = new Word("zoozz"); // input + + MatchResult results = answerWord.match(inputWord); + + assertThat(results).containsExactly( + Hint.NOT_EXIST, + Hint.EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST); + } + + @Test + void 같은문자_두번_입력시_하나가_먼저_일치하고_다음것이_존재하는경우() { + Word answerWord = new Word("ooxxx"); + Word inputWord = new Word("ozozz"); + + MatchResult results = answerWord.match(inputWord); + + assertThat(results).containsExactly( Hint.CORRECT, - Hint.CORRECT - )); - assertThat(matchResults).isEqualTo(expected); + Hint.NOT_EXIST, + Hint.EXIST, + Hint.NOT_EXIST, + Hint.NOT_EXIST + ); } } From 01ecb311e3ba2e13b4fba4d67fb17a4c06bc1092 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 03:01:12 +0900 Subject: [PATCH 36/47] =?UTF-8?q?refactor:=20isCorrect=20=EC=8A=A4?= =?UTF-8?q?=ED=83=9C=ED=8B=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/domain/Hint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/Hint.java b/src/main/java/domain/Hint.java index 23b5d3e1..e617e102 100644 --- a/src/main/java/domain/Hint.java +++ b/src/main/java/domain/Hint.java @@ -16,7 +16,7 @@ public String getTile() { return tile; } - public static boolean isCorrect(Hint hint) { - return Hint.CORRECT.equals(hint); + public boolean isCorrect() { + return this == CORRECT; } } From fc9ef84336e99bbd5257e2b63f46d9326d16b734 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 03:01:46 +0900 Subject: [PATCH 37/47] fix: typo --- src/main/resources/words.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/words.txt b/src/main/resources/words.txt index da5dde07..e6be7404 100644 --- a/src/main/resources/words.txt +++ b/src/main/resources/words.txt @@ -6,7 +6,7 @@ awake blush focal evade -navalc +naval serve heath dwarf From 9685a01955793e74f3fb241f72b262850fdc6b0b Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 04:07:23 +0900 Subject: [PATCH 38/47] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=20=ED=8C=90=EB=8B=A8=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=84=20MatchResult=EC=97=90=20=EC=9C=84=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 52 ++++++----------------- src/main/java/domain/MatchResults.java | 20 ++++++++- src/main/java/domain/Round.java | 15 ++----- src/main/java/domain/Word.java | 5 +++ src/main/java/ui/AnswerView.java | 9 ++++ 5 files changed, 51 insertions(+), 50 deletions(-) create mode 100644 src/main/java/ui/AnswerView.java diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 6709c03e..b89f2aad 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -4,45 +4,40 @@ import domain.MatchResults; import domain.Round; import domain.Word; -import ui.GuideTextView; -import ui.HintView; -import ui.InputView; -import ui.RoundView; +import ui.*; import java.time.LocalDate; import java.util.List; public class GameManager { - private final static int ROUND_LIMIT = 6; - private final Round round; private final MatchResults matchResults; private final Word answer; - private boolean isWinning; - private final List availableWords; - private final GuideTextView guideTextView; private final InputView inputView; private final HintView hintView; private final RoundView roundView; + private final AnswerView answerView; public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; - this.round = new Round(ROUND_LIMIT); this.matchResults = new MatchResults(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); this.hintView = new HintView(); this.roundView = new RoundView(); + this.answerView = new AnswerView(); } - public void start() { - guideTextView.render(round.getLimit()); - while(isNotWinning() && round.isNotFinalRound()) { + guideTextView.render(Round.ROUND_LIMIT); + while(matchResults.shouldContinueGame()) { startRound(); } + if(matchResults.isNotWinning()) { + answerView.render(answer); + } } private void startRound() { @@ -50,37 +45,18 @@ private void startRound() { Word inputWord; try { - inputWord = Word.createInput(input, this.availableWords); + inputWord = Word.createInput(input, availableWords); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); return; } - checkAnswer(inputWord); - - if(isWinning()) { - roundView.render(round.getCurrent(),round.getLimit()); + MatchResult matchResult = answer.match(inputWord); + if(matchResult.isWinning()) { + roundView.render(matchResults.currentRound(), Round.ROUND_LIMIT); } + matchResults.add(matchResult); - hintView.render(this.matchResults); - round.goNext(); - } - - private void checkAnswer(Word inputWord) { - MatchResult matchResultOfInput = answer.match(inputWord); - this.matchResults.add(matchResultOfInput); - setWinning(matchResultOfInput.isWinning()); - } - - private boolean isNotWinning(){ - return !isWinning(); - } - - private boolean isWinning() { - return isWinning; - } - - private void setWinning(boolean winning) { - isWinning = winning; + hintView.render(matchResults); } } diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/MatchResults.java index 063dbbb8..bf8567f9 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/MatchResults.java @@ -5,6 +5,7 @@ import java.util.List; public class MatchResults implements Iterable { + private final Round round = new Round(); private final List results; public MatchResults() { @@ -17,6 +18,23 @@ public Iterator iterator() { } public void add(MatchResult matchResult) { - this.results.add(matchResult); + results.add(matchResult); + round.goNext(); + } + + public boolean shouldContinueGame() { + return round.isNotFinalRound() && isNotWinning(); + } + + public int currentRound() { + return round.getCurrent(); + } + + public boolean isWinning() { + return this.results.stream().anyMatch(MatchResult::isWinning); + } + + public boolean isNotWinning() { + return !isWinning(); } } diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index f063f79b..5482c6be 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -1,26 +1,19 @@ package domain; public class Round { + public final static int ROUND_LIMIT = 3; private final int limit; private int current; - private Round(int limit, int current) { - this.limit = limit; - this.current = current; - } - - public Round(int limit) { - this(limit, 1); + public Round() { + limit = ROUND_LIMIT; + current = 1; } public void goNext() { this.current++; } - public int getLimit() { - return limit; - } - public int getCurrent() { return current; } diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index c1f25624..ab429e95 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -36,6 +36,10 @@ public MatchResult match(Word otherWord) { return new MatchResult(hints); } + public String getString() { + return letters; + } + private Hint matchLetter(Word otherWord, boolean[] visited, int index) { if(isCorrect(index, otherWord.letters.charAt(index))){ visited[index] = true; @@ -102,4 +106,5 @@ public boolean equals(Object o) { public int hashCode() { return letters != null ? letters.hashCode() : 0; } + } diff --git a/src/main/java/ui/AnswerView.java b/src/main/java/ui/AnswerView.java new file mode 100644 index 00000000..7830efee --- /dev/null +++ b/src/main/java/ui/AnswerView.java @@ -0,0 +1,9 @@ +package ui; + +import domain.Word; + +public class AnswerView { + public void render(Word answer) { + System.out.println(answer.getString()); + } +} From ee43ca343304a1f64d5e28e3eb157029a1c4b540 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 04:14:03 +0900 Subject: [PATCH 39/47] =?UTF-8?q?refactor:=20MatchResult=20=ED=95=98?= =?UTF-8?q?=EB=8A=94=EC=9D=BC=EC=9D=B4=20=EB=A7=8E=EC=95=84=EC=A0=B8?= =?UTF-8?q?=EC=84=9C=20=EA=B7=B8=EB=9F=B4=EC=8B=B8=ED=95=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 16 ++++++++-------- .../domain/{MatchResults.java => GameState.java} | 14 +++++++------- src/main/java/ui/HintView.java | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) rename src/main/java/domain/{MatchResults.java => GameState.java} (64%) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index b89f2aad..84165ba5 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,7 +1,7 @@ package controller; import domain.MatchResult; -import domain.MatchResults; +import domain.GameState; import domain.Round; import domain.Word; import ui.*; @@ -10,7 +10,7 @@ import java.util.List; public class GameManager { - private final MatchResults matchResults; + private final GameState state; private final Word answer; private final List availableWords; private final GuideTextView guideTextView; @@ -22,7 +22,7 @@ public class GameManager { public GameManager(List availableWords) { this.answer = Word.createAnswer(LocalDate.now(), availableWords); this.availableWords = availableWords; - this.matchResults = new MatchResults(); + this.state = new GameState(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); this.hintView = new HintView(); @@ -32,10 +32,10 @@ public GameManager(List availableWords) { public void start() { guideTextView.render(Round.ROUND_LIMIT); - while(matchResults.shouldContinueGame()) { + while(state.shouldContinueGame()) { startRound(); } - if(matchResults.isNotWinning()) { + if(state.isNotWinning()) { answerView.render(answer); } } @@ -53,10 +53,10 @@ private void startRound() { MatchResult matchResult = answer.match(inputWord); if(matchResult.isWinning()) { - roundView.render(matchResults.currentRound(), Round.ROUND_LIMIT); + roundView.render(state.currentRound(), Round.ROUND_LIMIT); } - matchResults.add(matchResult); + state.add(matchResult); - hintView.render(matchResults); + hintView.render(state); } } diff --git a/src/main/java/domain/MatchResults.java b/src/main/java/domain/GameState.java similarity index 64% rename from src/main/java/domain/MatchResults.java rename to src/main/java/domain/GameState.java index bf8567f9..de955185 100644 --- a/src/main/java/domain/MatchResults.java +++ b/src/main/java/domain/GameState.java @@ -4,21 +4,21 @@ import java.util.Iterator; import java.util.List; -public class MatchResults implements Iterable { +public class GameState implements Iterable { private final Round round = new Round(); - private final List results; + private final List matchResults; - public MatchResults() { - this.results = new ArrayList<>(); + public GameState() { + this.matchResults = new ArrayList<>(); } @Override public Iterator iterator() { - return this.results.iterator(); + return matchResults.iterator(); } public void add(MatchResult matchResult) { - results.add(matchResult); + matchResults.add(matchResult); round.goNext(); } @@ -31,7 +31,7 @@ public int currentRound() { } public boolean isWinning() { - return this.results.stream().anyMatch(MatchResult::isWinning); + return matchResults.stream().anyMatch(MatchResult::isWinning); } public boolean isNotWinning() { diff --git a/src/main/java/ui/HintView.java b/src/main/java/ui/HintView.java index c28ca158..ae485612 100644 --- a/src/main/java/ui/HintView.java +++ b/src/main/java/ui/HintView.java @@ -1,10 +1,10 @@ package ui; import domain.MatchResult; -import domain.MatchResults; +import domain.GameState; public class HintView { - public void render(MatchResults matchResults) { + public void render(GameState matchResults) { matchResults.forEach(matchResultEachRound -> { renderTiles(matchResultEachRound); System.out.println(); From d086b9a2695a76978745fd83d4010360e8f95aad Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:05:18 +0900 Subject: [PATCH 40/47] =?UTF-8?q?fix:=20=EC=B5=9C=EB=8C=80=EB=9D=BC?= =?UTF-8?q?=EC=9A=B4=EB=93=9C=20=EC=98=A4=ED=83=80=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/Round.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/domain/Round.java b/src/main/java/domain/Round.java index 5482c6be..304671e8 100644 --- a/src/main/java/domain/Round.java +++ b/src/main/java/domain/Round.java @@ -1,7 +1,6 @@ package domain; - public class Round { - public final static int ROUND_LIMIT = 3; + public final static int ROUND_LIMIT = 6; private final int limit; private int current; From 0b8b73476c12e9b2c18dd91060478793b8ec4e0d Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:40:48 +0900 Subject: [PATCH 41/47] =?UTF-8?q?refactor:=20=EB=8B=A8=EC=96=B4=EA=B0=80?= =?UTF-8?q?=EB=90=A0=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A8=EB=8B=A4=EB=8A=94=20=EB=84=A4=EC=9D=B4=EB=B0=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/WordleApplication.java | 6 +++--- .../java/infra/{WordLoader.java => WordStringLoader.java} | 8 ++------ .../{WordLoaderTest.java => WordStringLoaderTest.java} | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) rename src/main/java/infra/{WordLoader.java => WordStringLoader.java} (71%) rename src/test/java/infra/{WordLoaderTest.java => WordStringLoaderTest.java} (72%) diff --git a/src/main/java/WordleApplication.java b/src/main/java/WordleApplication.java index 6fb20f0c..a5b87199 100644 --- a/src/main/java/WordleApplication.java +++ b/src/main/java/WordleApplication.java @@ -1,13 +1,13 @@ import config.FileConfig; import controller.GameManager; -import infra.WordLoader; +import infra.WordStringLoader; import java.util.List; public class WordleApplication { public static void main(String[] args) { - List words = WordLoader.read(FileConfig.FILE_PATH); - GameManager gameManager = new GameManager(words); + List wordStringList = WordStringLoader.readAll(FileConfig.FILE_PATH); + GameManager gameManager = new GameManager(wordStringList); gameManager.start(); } diff --git a/src/main/java/infra/WordLoader.java b/src/main/java/infra/WordStringLoader.java similarity index 71% rename from src/main/java/infra/WordLoader.java rename to src/main/java/infra/WordStringLoader.java index 92825ca4..19612090 100644 --- a/src/main/java/infra/WordLoader.java +++ b/src/main/java/infra/WordStringLoader.java @@ -5,12 +5,8 @@ import java.nio.file.Paths; import java.util.List; -public class WordLoader { - - public WordLoader() { - } - - public static List read(String filePath) { +public class WordStringLoader { + public static List readAll(String filePath) { try { return Files.readAllLines(Paths.get(filePath)); } catch (IOException e) { diff --git a/src/test/java/infra/WordLoaderTest.java b/src/test/java/infra/WordStringLoaderTest.java similarity index 72% rename from src/test/java/infra/WordLoaderTest.java rename to src/test/java/infra/WordStringLoaderTest.java index 1d1a87b0..51b4fceb 100644 --- a/src/test/java/infra/WordLoaderTest.java +++ b/src/test/java/infra/WordStringLoaderTest.java @@ -7,11 +7,11 @@ import static org.assertj.core.api.Assertions.assertThat; -class WordLoaderTest { +class WordStringLoaderTest { @Test @DisplayName("단어목록파일 읽기") void loadWordsFromFile(){ - List words = WordLoader.read("src/test/resources/words.txt"); + List words = WordStringLoader.readAll("src/test/resources/words.txt"); assertThat(words).hasSize(5); } } From 84eb91588846e183852848b8e16add9110a46363 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:45:40 +0900 Subject: [PATCH 42/47] =?UTF-8?q?refactor:=20=EC=A0=95=EB=8B=B5=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=83=9D=EC=84=B1=20=EC=B1=85=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?WordDictionary=EB=A1=9C=20=EC=98=AE=EA=B8=B0=EA=B3=A0=20Word?= =?UTF-8?q?=EC=9D=98=20=EC=83=9D=EC=84=B1=EC=B1=85=EC=9E=84=20=EC=A4=84?= =?UTF-8?q?=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/GameManager.java | 21 ++++++---------- src/main/java/domain/Word.java | 23 +++-------------- src/main/java/domain/WordDictionary.java | 24 ++++++++++++++++++ src/test/java/domain/AnswerTest.java | 12 --------- src/test/java/domain/InputWordTest.java | 26 +++++--------------- src/test/java/domain/WordDictionaryTest.java | 21 ++++++++++++++++ 6 files changed, 63 insertions(+), 64 deletions(-) create mode 100644 src/main/java/domain/WordDictionary.java create mode 100644 src/test/java/domain/WordDictionaryTest.java diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 84165ba5..78d7fb4e 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -1,9 +1,6 @@ package controller; -import domain.MatchResult; -import domain.GameState; -import domain.Round; -import domain.Word; +import domain.*; import ui.*; import java.time.LocalDate; @@ -11,17 +8,15 @@ public class GameManager { private final GameState state; - private final Word answer; - private final List availableWords; private final GuideTextView guideTextView; private final InputView inputView; private final HintView hintView; private final RoundView roundView; private final AnswerView answerView; + private final WordDictionary wordDictionary; - public GameManager(List availableWords) { - this.answer = Word.createAnswer(LocalDate.now(), availableWords); - this.availableWords = availableWords; + public GameManager(List wordStringList) { + this.wordDictionary = new WordDictionary(wordStringList); this.state = new GameState(); this.guideTextView = new GuideTextView(); this.inputView = new InputView(); @@ -31,21 +26,21 @@ public GameManager(List availableWords) { } public void start() { + Word answer = wordDictionary.answerWord(LocalDate.now()); guideTextView.render(Round.ROUND_LIMIT); while(state.shouldContinueGame()) { - startRound(); + startRound(answer); } if(state.isNotWinning()) { answerView.render(answer); } } - private void startRound() { + private void startRound(Word answer) { String input = inputView.input(); - Word inputWord; try { - inputWord = Word.createInput(input, availableWords); + inputWord = new Word(input); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); return; diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index ab429e95..6ff96207 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -10,21 +10,9 @@ public class Word { private final static int MAX_LENGTH = 5; private final String letters; - protected Word(String value) { - this.letters = 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 Word(String letters) { + validate(letters); + this.letters = letters; } public MatchResult match(Word otherWord) { @@ -66,12 +54,9 @@ private Boolean isCorrect(int index, char inputChar) { return letters.charAt(index) == inputChar; } - private static void validate(String input, List availableWords) { + private static void validate(String input) { validateLength(input); - validateOnlyEnglish(input); - - validateContain(input, availableWords); } private static void validateOnlyEnglish(String input) { diff --git a/src/main/java/domain/WordDictionary.java b/src/main/java/domain/WordDictionary.java new file mode 100644 index 00000000..82dacf05 --- /dev/null +++ b/src/main/java/domain/WordDictionary.java @@ -0,0 +1,24 @@ +package domain; + +import java.time.LocalDate; +import java.time.Period; +import java.util.List; + +public class WordDictionary { + private final List words; + + public WordDictionary(List words) { + this.words = words; + } + + public Word answerWord(LocalDate currentDate) { + int index = getIndex(currentDate); + return new Word(words.get(index)); + } + + private int getIndex(LocalDate currentDate) { + LocalDate fixedDate = LocalDate.of(2021, 6, 19); + int diffDay = Period.between(fixedDate, currentDate).getDays(); + return diffDay % words.size(); + } +} diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/AnswerTest.java index 00d6372c..3108ea2c 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/AnswerTest.java @@ -1,22 +1,10 @@ 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; class AnswerTest { - @Test - @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); - - assertThat(answer).isEqualTo(new Word("banana")); - } @Test void 전부_일치인_경우() { diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index 2246cd0a..cbbb11e4 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; import java.util.List; @@ -10,39 +11,24 @@ class InputWordTest { @Test - @DisplayName("입력단어 유효성 검증 성공 테스트") + @DisplayName("단어 생성 성공 테스트") void validateSuccessInputWord() { - List words = List.of("apple", "xxxxx"); - assertDoesNotThrow(() -> Word.createInput("apple", words)); - } - - - @Test - @DisplayName("입력단어 유효성 검증 실패 테스트") - void - validateFailInputWord() { - List words = List.of("apples", "banana"); - assertThrows(IllegalArgumentException.class,() -> Word.createInput("pangyo", words)); + assertDoesNotThrow(() -> new Word("apple")); } @Test @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") void validateInputWordLength() { - List words = List.of("apple", "abcdef"); - assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcdef", words)); + assertThrows(IllegalArgumentException.class,() -> new Word("abcdef")); } @Test @DisplayName("입력단어 영단어 유효성 검증 실패 테스트") void validateInputWordOnlyEnglish() { - List words = List.of("apple", "abcd1", "안녕하세요"); - assertAll( - () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("abcd1", words)), - () -> assertThrows(IllegalArgumentException.class,() -> Word.createInput("안녕하세요", words)) + () -> assertThrows(IllegalArgumentException.class,() -> new Word("abcd1")), + () -> assertThrows(IllegalArgumentException.class,() -> new Word("안녕하세요")) ); } - - } diff --git a/src/test/java/domain/WordDictionaryTest.java b/src/test/java/domain/WordDictionaryTest.java new file mode 100644 index 00000000..dee44da1 --- /dev/null +++ b/src/test/java/domain/WordDictionaryTest.java @@ -0,0 +1,21 @@ +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; + +class WordDictionaryTest { + @Test + @DisplayName("정답은 매일 바뀌며 ((현재 날짜 - 2021년 6월 19일) % 배열의 크기) 번째의 단어이다") + void answerSelectTest() { + List words = List.of("apple", "spill", "naval"); + LocalDate now = LocalDate.of(2021, 6, 20); + WordDictionary wordDictionary = new WordDictionary(words); + + assertThat(wordDictionary.answerWord(now)).isEqualTo(new Word("spill")); + } +} From 86f8ec282b2376c6539a1ffc216972bff656c2d0 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:47:00 +0900 Subject: [PATCH 43/47] =?UTF-8?q?refactor(test):=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A8=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=82=B4=EC=9A=A9?= =?UTF-8?q?=EA=B9=8C=EC=A7=80=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/infra/WordStringLoaderTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/infra/WordStringLoaderTest.java b/src/test/java/infra/WordStringLoaderTest.java index 51b4fceb..188e16ce 100644 --- a/src/test/java/infra/WordStringLoaderTest.java +++ b/src/test/java/infra/WordStringLoaderTest.java @@ -12,6 +12,12 @@ class WordStringLoaderTest { @DisplayName("단어목록파일 읽기") void loadWordsFromFile(){ List words = WordStringLoader.readAll("src/test/resources/words.txt"); - assertThat(words).hasSize(5); + assertThat(words).containsExactly( + "cigar", + "rebut", + "sissy", + "humph", + "awake" + ); } } From d259f53de8ff74c8af8a6d0b508064d6a8a4c53b Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:49:47 +0900 Subject: [PATCH 44/47] =?UTF-8?q?refactor(test):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9D=B4=EB=A6=84=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 => WordCompareTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/test/java/domain/{AnswerTest.java => WordCompareTest.java} (99%) diff --git a/src/test/java/domain/AnswerTest.java b/src/test/java/domain/WordCompareTest.java similarity index 99% rename from src/test/java/domain/AnswerTest.java rename to src/test/java/domain/WordCompareTest.java index 3108ea2c..d9d29004 100644 --- a/src/test/java/domain/AnswerTest.java +++ b/src/test/java/domain/WordCompareTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; -class AnswerTest { +class WordCompareTest { @Test void 전부_일치인_경우() { From c18b653e7c2e8112c98c7a4423922629e7344ef1 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Thu, 27 Jun 2024 23:56:02 +0900 Subject: [PATCH 45/47] =?UTF-8?q?refactor:=20word.isCorrect=EB=8A=94=20?= =?UTF-8?q?=EC=96=B4=EA=B0=90=EC=9D=B4=20=EC=9D=B4=EC=83=81=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=A6=84=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/Word.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 6ff96207..888f4594 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -1,7 +1,5 @@ package domain; -import java.time.LocalDate; -import java.time.Period; import java.util.List; import java.util.Objects; import java.util.stream.IntStream; @@ -29,7 +27,7 @@ public String getString() { } private Hint matchLetter(Word otherWord, boolean[] visited, int index) { - if(isCorrect(index, otherWord.letters.charAt(index))){ + if(hasCorrect(index, otherWord.letters.charAt(index))){ visited[index] = true; return Hint.CORRECT; } @@ -50,8 +48,8 @@ private Boolean exists(char letter, boolean[] visited) { .isPresent(); } - private Boolean isCorrect(int index, char inputChar) { - return letters.charAt(index) == inputChar; + private Boolean hasCorrect(int index, char letter) { + return letters.charAt(index) == letter; } private static void validate(String input) { From a55d0ff67560a6bc8a513e4062b1c974030079f0 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Fri, 28 Jun 2024 00:09:10 +0900 Subject: [PATCH 46/47] =?UTF-8?q?refactor:=20=EC=9E=85=EB=A0=A5=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=97=90=EB=9F=AC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Word.java | 13 +++++-------- .../domain/exception/LetterNotEnglishException.java | 7 +++++++ .../domain/exception/OverMaxLengthException.java | 7 +++++++ src/test/java/domain/InputWordTest.java | 11 +++++------ 4 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 src/main/java/domain/exception/LetterNotEnglishException.java create mode 100644 src/main/java/domain/exception/OverMaxLengthException.java diff --git a/src/main/java/domain/Word.java b/src/main/java/domain/Word.java index 888f4594..cce4080f 100644 --- a/src/main/java/domain/Word.java +++ b/src/main/java/domain/Word.java @@ -1,5 +1,8 @@ package domain; +import domain.exception.LetterNotEnglishException; +import domain.exception.OverMaxLengthException; + import java.util.List; import java.util.Objects; import java.util.stream.IntStream; @@ -59,19 +62,13 @@ private static void validate(String input) { private static void validateOnlyEnglish(String input) { if (!input.matches("^[a-zA-Z]+$")) { - throw new IllegalArgumentException("영단어를 입력해주세요. [" + input + "]"); + throw new LetterNotEnglishException("영단어를 입력해주세요. [" + 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("입력 불가능한 단어입니다."); + throw new OverMaxLengthException(MAX_LENGTH + "자리의 단어를 입력해주세요."); } } diff --git a/src/main/java/domain/exception/LetterNotEnglishException.java b/src/main/java/domain/exception/LetterNotEnglishException.java new file mode 100644 index 00000000..6b6af6d6 --- /dev/null +++ b/src/main/java/domain/exception/LetterNotEnglishException.java @@ -0,0 +1,7 @@ +package domain.exception; + +public class LetterNotEnglishException extends RuntimeException { + public LetterNotEnglishException(String message) { + super(message); + } +} diff --git a/src/main/java/domain/exception/OverMaxLengthException.java b/src/main/java/domain/exception/OverMaxLengthException.java new file mode 100644 index 00000000..ac86f50c --- /dev/null +++ b/src/main/java/domain/exception/OverMaxLengthException.java @@ -0,0 +1,7 @@ +package domain.exception; + +public class OverMaxLengthException extends RuntimeException { + public OverMaxLengthException(String message) { + super(message); + } +} diff --git a/src/test/java/domain/InputWordTest.java b/src/test/java/domain/InputWordTest.java index cbbb11e4..e0a46d73 100644 --- a/src/test/java/domain/InputWordTest.java +++ b/src/test/java/domain/InputWordTest.java @@ -1,10 +1,9 @@ package domain; +import domain.exception.LetterNotEnglishException; +import domain.exception.OverMaxLengthException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; - -import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -19,7 +18,7 @@ void validateSuccessInputWord() { @Test @DisplayName("입력단어 글자수 유효성 검증 실패 테스트") void validateInputWordLength() { - assertThrows(IllegalArgumentException.class,() -> new Word("abcdef")); + assertThrows(OverMaxLengthException.class,() -> new Word("abcdef")); } @@ -27,8 +26,8 @@ void validateInputWordLength() { @DisplayName("입력단어 영단어 유효성 검증 실패 테스트") void validateInputWordOnlyEnglish() { assertAll( - () -> assertThrows(IllegalArgumentException.class,() -> new Word("abcd1")), - () -> assertThrows(IllegalArgumentException.class,() -> new Word("안녕하세요")) + () -> assertThrows(LetterNotEnglishException.class,() -> new Word("abcd1")), + () -> assertThrows(LetterNotEnglishException.class,() -> new Word("안녕하세요")) ); } } From 02ba623a0600ade9f5ac791653f352b18242faa9 Mon Sep 17 00:00:00 2001 From: who-is-hu Date: Fri, 28 Jun 2024 00:21:39 +0900 Subject: [PATCH 47/47] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EB=8B=A8?= =?UTF-8?q?=EC=96=B4=20=EC=82=AC=EC=A0=84=EC=97=90=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EA=B2=80=EC=82=AC=20=EB=B9=BC=EB=A8=B9=EC=9D=80?= =?UTF-8?q?=EA=B2=83=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/controller/GameManager.java | 10 +++++++--- src/main/java/domain/WordDictionary.java | 12 +++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/controller/GameManager.java b/src/main/java/controller/GameManager.java index 78d7fb4e..5d7a117b 100644 --- a/src/main/java/controller/GameManager.java +++ b/src/main/java/controller/GameManager.java @@ -28,10 +28,10 @@ public GameManager(List wordStringList) { public void start() { Word answer = wordDictionary.answerWord(LocalDate.now()); guideTextView.render(Round.ROUND_LIMIT); - while(state.shouldContinueGame()) { + while (state.shouldContinueGame()) { startRound(answer); } - if(state.isNotWinning()) { + if (state.isNotWinning()) { answerView.render(answer); } } @@ -45,9 +45,13 @@ private void startRound(Word answer) { System.out.println(e.getMessage()); return; } + if (wordDictionary.hasNot(inputWord)) { + System.out.println("사전에 없는 단어입니다."); + return; + } MatchResult matchResult = answer.match(inputWord); - if(matchResult.isWinning()) { + if (matchResult.isWinning()) { roundView.render(state.currentRound(), Round.ROUND_LIMIT); } state.add(matchResult); diff --git a/src/main/java/domain/WordDictionary.java b/src/main/java/domain/WordDictionary.java index 82dacf05..75edab8a 100644 --- a/src/main/java/domain/WordDictionary.java +++ b/src/main/java/domain/WordDictionary.java @@ -5,15 +5,21 @@ import java.util.List; public class WordDictionary { - private final List words; + private final List words; public WordDictionary(List words) { - this.words = words; + this.words = words.stream() + .map(Word::new) + .toList(); } public Word answerWord(LocalDate currentDate) { int index = getIndex(currentDate); - return new Word(words.get(index)); + return words.get(index); + } + + public boolean hasNot(Word word) { + return !words.contains(word); } private int getIndex(LocalDate currentDate) {