Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4기][3주차] Wordle 과제 제출 - 꾸잉 #22

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
37050a2
docs: 설계
Mar 28, 2023
d7785d1
feat: Application 생성
Mar 28, 2023
f3616e1
feat: Application 생성
Mar 28, 2023
3bd7935
feat: WordleGame 생성
Mar 28, 2023
682f05d
feat(ing): WordleGame 구현중
Mar 28, 2023
3d7eaab
feat(ing): WorldGame 구현중
Mar 28, 2023
28febda
test 커밋
JuHyun419 Apr 1, 2023
4b711c6
test 커밋 롤백
JuHyun419 Apr 1, 2023
bcffe2e
Merge branch 'main' of https://github.com/koola97620/java-wordle
JuHyun419 Apr 1, 2023
f05e0e0
refactor: WordleController 추가
Apr 1, 2023
55094e4
feat: WordleComparerTest 추가
Apr 1, 2023
5fd31fa
test(failed): WordleComparerTest 실패하는 테스트 추가
Apr 1, 2023
8df9e4e
feat: 작업자 교체 -> 꾸잉
Apr 1, 2023
56cd31a
Merge branch 'main' of https://github.com/koola97620/java-wordle
JuHyun419 Apr 1, 2023
af78dea
feat: 사용자 단어와 정답 단어 비교 메서드 추가
JuHyun419 Apr 1, 2023
5180d8b
refactor: 오타 수정
JuHyun419 Apr 1, 2023
0604c8d
feat: 사용자 단어와 정답 단어 비교 메서드 추가
JuHyun419 Apr 1, 2023
a883121
feat(ing): tile 관련 객체 추가
JuHyun419 Apr 1, 2023
4ea07ba
feat(ing): Wordle getter 추가
JuHyun419 Apr 1, 2023
9d111d6
feat(ing): 컴파일 에러 제거
JuHyun419 Apr 1, 2023
b417e17
feat: 비교테스트 진행중 작업자 교체 -> 꾸잉
Apr 1, 2023
5583978
feat(ing): Wordle 체크 로직 구현
JuHyun419 Apr 1, 2023
b09e81d
feat(ing):
JuHyun419 Apr 2, 2023
c48d1e4
feat: words.txt 에서 정답 검색 및 Tile 출력코드 추가
Apr 2, 2023
47a7c4f
refactor: 유효성 검증 추가, 요구사항에 맞는 depth 수정, 불필요한 코드 제거
JuHyun419 Apr 2, 2023
ed0ccb5
refactor: 유효성 검증 추가, 요구사항에 맞는 depth 수정, 불필요한 코드 제거
JuHyun419 Apr 2, 2023
78dacf8
refactor: 유효성 검사 추가, 메서드명 변경, 출력로직 변경
Apr 2, 2023
2d8703e
refactor: 미사용 코드 제거
Apr 2, 2023
5e29353
test: TilesTest, WordleGameTest 추가
Apr 2, 2023
7d1a14e
test: Tile, Wordle, Wordles 테스트 추가
JuHyun419 Apr 2, 2023
6f44dda
Merge branch 'main' of https://github.com/koola97620/java-wordle
JuHyun419 Apr 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,26 @@ spill
- else 예약어를 쓰지 않는다.
- 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다.
- else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다.

## 규칙

- 25분동안 한명이 코딩하고 5분 쉬고 교대

## 설계

### 패키지 설계

- domain
- view


### 최초 설계

- Application#main()
- WordleGames - 6개의 WordleGame
- worldGames#start()
- input: 입력한 단어, output : Tile 5개
- Word - 5개의 Tile
- Tile - 네모하나 (흰색, 노란색, 초록색, 회색)
- AnswerFinder
- words.txt 에서 정답을 추출하는 로직이 하나 필요함.
10 changes: 10 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import controller.WordleController;
import domain.WordleGames;

public class Application {

public static void main(String[] args) {
WordleController wordleController = new WordleController();
wordleController.start();
}
}
66 changes: 66 additions & 0 deletions src/main/java/controller/WordleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package controller;

import domain.WordleGames;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

import static view.output.OutputView.printMain;

public class WordleController {
private final String FILE_NAME = "words.txt";

public void start() {
printMain();

String answer = searchAnswer();

WordleGames wordleGames = new WordleGames();
wordleGames.start(answer);
}

private String searchAnswer() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c: searchAnswer 메서드에서 너무 많은 역할을 수행하지 않나 합니다. 파일 읽기 부분을 분리해보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋네요 ㅎㅎ 너무 많은 역할을 하는 듯 합니다.
감사합니다 🙇

ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream(FILE_NAME);
List<String> strings = new ArrayList<>();
try {
strings = readFromInputStream(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
Long index = calculateAnswerIndex(strings);
return strings.get(index.intValue());
}

private Long calculateAnswerIndex(List<String> strings) {
LocalDate today = LocalDate.now();
LocalDate date = LocalDate.of(2021, 6, 19);
long diffDays = Math.abs(ChronoUnit.DAYS.between(today, date));
return diffDays % strings.size();
}
Comment on lines +41 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c: "몇 번째 인덱스를 추출할 것인가"는 핵심 로직에 속한다고 생각해서 테스트 가능한 형태로 변경해보면 좋을 것 같습니다 :)


private List<String> readFromInputStream(InputStream inputStream) throws IOException {
List<String> txtFileLine;
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
txtFileLine = extractTextLines(br);
}
return txtFileLine;
}
Comment on lines +48 to +54
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a: txtFileLine 변수는 최초 생성시점부터 반환까지 값의 변경에 대한 요구사항이 없습니다. 개인적으로는 생성한 후 변경하여 반환하는 형태보다, 가능한 바로 반환하는 형태가 휴먼 에러를 방지하고 가독성에 도움이 된다고 생각합니다. (언제 값이 변하는지, 언제 반환하는지 추적하지 않아도 됨)

리스트를 생성하고, 리스트에 값을 대입한 다음, 리스트를 반환한다 이 세 가지 행위를 try 블록 안에서 해결하는 것도 고려해주세요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 말씀하신대로 바로 반환하는 형태를 주로 선호하긴 합니다~
감사합니다!


private List<String> extractTextLines(BufferedReader br) throws IOException {
List<String> txtFileLine = new ArrayList<>();
String line;

while ((line = br.readLine()) != null) {
txtFileLine.add(line);
}

return txtFileLine;
}
}
32 changes: 32 additions & 0 deletions src/main/java/domain/Tile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package domain;

import java.util.List;
import java.util.stream.Collectors;

public class Tile {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a: Tile 과 tileColors 의 관계를 말로 설명하면 "타일"은 "다섯 개의 타일 색"을 갖는다고 표현하게되는데 약간 어색하다고 느껴지네요.

private final int LIMIT_SIZE = 5;

private final List<TileColor> tileColors;

public Tile(List<TileColor> tileColors) {
validate(tileColors);
this.tileColors = tileColors;
}

private void validate(List<TileColor> tileColors) {
if (tileColors.size() != LIMIT_SIZE) {
throw new IllegalArgumentException("TileColors 사이즈는 5 이어야 합니다. 현재 size: " + tileColors.size());
}
}

public boolean isAllGreen() {
return tileColors.stream()
.allMatch(t -> t.equals(TileColor.GREEN));
}

public String printTile() {
return tileColors.stream()
.map(TileColor::getTile)
.collect(Collectors.joining());
}
}
20 changes: 20 additions & 0 deletions src/main/java/domain/TileColor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package domain;

public enum TileColor {

WHITE("⬜"),

YELLOW("🟨"),

GREEN("🟩");

private final String tile;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

직전 댓글과 비슷한 의견입니다 :) 이 값은 "타일색.타일" 형태로 사용하게 되고, 표현이 어색한 것 같습니다.


TileColor(String tile) {
this.tile = tile;
}

public String getTile() {
return tile;
}
}
29 changes: 29 additions & 0 deletions src/main/java/domain/Tiles.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package domain;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Tiles {

// 5 * n 타일
private List<Tile> tiles = new ArrayList<>();
private boolean allGreen;

public void addTiles(Tile tile) {
tiles.add(tile);
if(tile.isAllGreen()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a: 정렬(cmd+opt+L)을 누르면 코드 변경이 생길 것 같습니다!

this.allGreen = true;
}
}

public boolean hasAllGreen() {
return allGreen;
}

public String print() {
return tiles.stream()
.map(Tile::printTile)
.collect(Collectors.joining("\n"));
}
}
29 changes: 29 additions & 0 deletions src/main/java/domain/Wordle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package domain;

import java.util.Objects;

public class Wordle {

private final char word;

public Wordle(char word) {
this.word = word;
}

public char getWord() {
return word;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Wordle wordle = (Wordle) o;
return word == wordle.word;
}

@Override
public int hashCode() {
return Objects.hash(word);
}
}
8 changes: 8 additions & 0 deletions src/main/java/domain/WordleGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package domain;

public class WordleGame {

public Tile start(Wordles wordles) {
return new Tile(wordles.makeTileColorList());
}
}
39 changes: 39 additions & 0 deletions src/main/java/domain/WordleGames.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package domain;

import view.output.OutputView;

import static view.input.InputView.inputPlayerWordle;
import static view.output.OutputView.printInputAnswer;

public class WordleGames {
private final int START_COUNT = 1;
private final int END_COUNT = 6;

private WordleGame wordleGame = new WordleGame();


Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a: 개행을 하나 줄일 수 있을 것 같아요!

public Tiles start(String answer) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r: 규칙인 15 라인을 초과한 메서드입니다 👻

Tiles tiles = new Tiles();

int count = START_COUNT;
do {
printInputAnswer();

String input = inputPlayerWordle();
Wordles answerWordles = new Wordles(answer, input);

Tile tile = wordleGame.start(answerWordles);
tiles.addTiles(tile);
OutputView.printTile(tiles);

count++;
} while(isContinueGame(tiles, count));

return tiles;
}

private boolean isContinueGame(Tiles tiles, int count) {
return !tiles.hasAllGreen() && count <= END_COUNT;
}

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

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Wordles {
public static final int WORD_SIZE = 5;
private final List<Wordle> answer;
private final List<Wordle> input;

public Wordles(String answer, String input) {
this.answer = toWords(answer);
this.input = toWords(input);
}

private List<Wordle> toWords(String word) {
validateWord(word);

List<Wordle> words = new ArrayList<>();

for (char ch : word.toCharArray()) {
words.add(new Wordle(ch));
}

return words;
}

private void validateWord(String word) {
Objects.requireNonNull(word, "word must not null, word: " + word);

if (word.length() != WORD_SIZE) {
throw new IllegalArgumentException("word 단어의 길이는 5글자여야 합니다. 현재 길이: " + word.length());
}

if (!isAlpha(word)) {
throw new IllegalArgumentException("word 단어는 영문자여야 합니다. 현재 단어: " + word);
}

}

private boolean isAlpha(String s) {
return s.matches("^[a-zA-Z]*$");
}

public List<TileColor> makeTileColorList() {
List<TileColor> tileColors = new ArrayList<>();
int size = answer.size();

for (int i = 0; i < size; i++) {
makeTileColor(tileColors, i);
}
return tileColors;
}

private List<TileColor> makeTileColor(List<TileColor> tileColors, int i) {
if (isSameWordIndex(i)) {
tileColors.add(TileColor.GREEN);
return tileColors;
}

if (isSameWordDifferentIndex(i)) {
tileColors.add(TileColor.YELLOW);
return tileColors;
}

tileColors.add(TileColor.WHITE);
return tileColors;
}

private boolean isSameWordIndex(int i) {
return answer.get(i).getWord() == input.get(i).getWord();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c: 디미터의 법칙 위반이라고 생각합니다 🤔

}

private boolean isSameWordDifferentIndex(int i) {
return answer.contains(input.get(i));
}

}
15 changes: 15 additions & 0 deletions src/main/java/view/input/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package view.input;

import java.util.Scanner;

public class InputView {

private InputView() { }

private static final Scanner SCANNER = new Scanner(System.in);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호.. 스캐너를 상수로 만들어둘 수 있군요 ㅋㅋ


public static String inputPlayerWordle() {
return SCANNER.nextLine();
}

}
23 changes: 23 additions & 0 deletions src/main/java/view/output/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package view.output;

import domain.Tiles;

public class OutputView {

private OutputView() {
}

Comment on lines +7 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private 생성자 👍👍

public static void printMain() {
System.out.println("WORDLE을 6번 만에 맞춰 보세요.");
System.out.println("시도의 결과는 타일의 색 변화로 나타납니다.");
}

public static void printInputAnswer() {
System.out.println("정답을 입력해 주세요.");
}

public static void printTile(Tiles tiles) {
System.out.println(tiles.print());
}

}
Loading