Skip to content
87 changes: 87 additions & 0 deletions LEARNING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
## 어떤 것을 배우는 데 집중했는가?
[객체 간의 관계]메시지를 가지고 설계해보기 (각자가 책임을 가지고 있다고 가정하고 해당 객체가 필요한 요청을 메시지로 표현)
- 이번주 목표가 관계를 맺는 것인데... 어떻게 하면 좋은 관계를 맺을 수 있을까 고민했음
- 그러다가 '객체지향의 사실과 오해'란 책이 생각났고 (ch5) 책에서 알아가게 된 것을 적용해보려고 함



## 배우는 방법을 배우는 것...ㅋㅋㅋㅋ

나는 이번 과제를 진행하면서 무엇을 얻으려 했고 무엇을 얻는게 좋다고 생각했을까?

원하는 것을 너무 잘 알려주셨다.

먼저
- 1주차 목표는 함수를 분리하는 연습
- 2주차 목표는 += 클래스 분리하는 연습
- 3주차 목표는 += 여러 개의 클래스를 분리한 후 서로 관계를 맺어 하나의 프로그램을 완성

이런 것들을 통해서
- 자바 언어의 기본적인 문법을 익히고
- 프로그래밍 구현에 대한 다른 접근 방식을 경험
할 것을 기대하신 것 같다

극단적인 연습?(요구사항을 통한) 을 통해서 어떤 깨달음을 얻어갈까?

나는 어떻게 학습 했을까?
얼마나 성장했을까?


### 내 생각
알려주려는 개념의 이름이 아니라 요구사항등을 통해서 함수, 클래스 분리와 객체지향의 개념을 자연스럽게 경험할 수 있는 프로젝트여서 좋았음


언어 + 개념



어떻게 성장하는 것이 도움이 될까??

주도적으로 학습할 수 있는지?? -> 그렇다면 주도적이라는게 무엇일까?? (열정 + 끈기 + 방향? 이것들을 혼자 잡아가는 건가?)





### 내가 생각하기에 내가 채워가야하는 부분??
설계하는 연습 (질 + 양) // 설계하고 그것을 구현하고 내가 했던 것을 반복하면서 더 나아지는 연습을 해야함, 지루하다 생각하냐???!

좋은 개발자가 되기 위해서는 어떻게 진행하는게 좋을까??

내가 생각하는 좋은 개발자??
코드를 읽기도 쉽고 (실력)
함께 개발하기 좋고 (의사소통, 성실성)


이 과정을 하면서 단련하기 좋은 것
- 반복적인 연습 (버전관리 + 테스트)
- 새로운 언어를 어떻게 공부하는게 좋을지?
- 새로운 환경에 어떻게 적응하는게 좋을지?
- 특정 개념? 을 스스로 공부해나가는 방식 (내가 무엇을 배울 때 어떻게 접근하는지를 관찰하는 것도 좋은 습관인 것 같다)
- 공부한 개념을 스스로 정리? (남에게 말하려면 용어나.. 그것을 어떻게 설명하면 좋을지가 틀이 잡혀야함)

+
나는 이 과정을 하면서 정말로 테스트나 객체지향 같은 개념들이 유용한지 그리고 도움이 되는지를 확인 할 수 있을 것 같다
그리고 어떻게 짜면 좋을지에 대한 고민을 조금은 해가는 것 같다 (이 고민이 거기서 끝나지 않고 그 고민을 해결하기 위한 연구로 갔으면)


이렇게 배워가는 과정이 있고 내가 계속할 수 있음을 느끼고
조금씩 늘어가는 모습을 스스로 확인 할 수 있을 때
개발을 계속 할 것이란 확신을 스스로, 그리고 남이 봐도 있게 되지 않을까?




### 히스토리 (배운 과정)
1. 일단 공부 전에 스스로 설계
2. 공부
- 객체지향 (객체지향의 사실과 오해)
- 입력 어떻게 확실히 하는지 (자바에서 받은 입력 처리)
- 좋은? exception 처리
- 테스트?
3. 구현


#### 참조
- http://woowabros.github.io/tools/2017/07/10/java-enum-uses.html // java enum
- https://examples.javacodegeeks.com/core-java/mockito/mockito-verify-example/ // mockito verify
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## 기능목록
-[x] 게임을 실행 (전체적인 실행 흐름)
-[x] 유저에게 돈 받아내기
-[x] 올바른 입력인지 확인 (숫자로만 구성된 입력인지, 음 아닌 정수인지)
-[x] 로또 만들기
-[x] 셔플로 만들기
- 올바른 로또인지 확인하는 부분 (1~45까지의 수, 중복 없음, 총 6개)
- 만든 함수에서 예외처리 (ex.. 뽑을 집합보다 뽑을 갯수가 많은 경우)
-[x] 당첨로또 알아내기
-[x] 올바른 입력인지 확인
-[x] 유저의 로또 결과 분석하기


121 changes: 121 additions & 0 deletions src/main/java/LottoReaderFromUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import domain.Lotto;
import domain.LottoInfo;
import domain.LottoReader;
import domain.WinningLotto;

import java.util.*;
import java.util.regex.Pattern;

public class LottoReaderFromUser implements LottoReader {
private static final int INVALID = -1;

private Scanner sc;

public LottoReaderFromUser() {
this.sc = new Scanner(System.in);
}

@Override
public WinningLotto readWinningLotto() {
System.out.println();

var nums = _readWinningNumsUntilSucceed();

var bonusNo = _readBonusNoUntilSucceed(nums);

return new WinningLotto(new Lotto(nums), bonusNo);
}

private List<Integer> _numsStrToNums(String numsStr) {
if (!Pattern.matches("^[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,*$", numsStr)) {
return new ArrayList();
}

var nums = new ArrayList<Integer>();
for (var numStr : numsStr.split(",")) {
nums.add(Integer.parseInt(numStr));
}
return nums;
}

private boolean isAllUnique(List<Integer> nums) {
var set = new HashSet<Integer>();
for (var num : nums) {
set.add(num);
}
return nums.size() == set.size();
}

private boolean isAllValidLottoNum(List<Integer> nums) {
for (var num : nums) {
if (!LottoInfo.isLottoNum(num)) return false;
}
return true;
}

private boolean isValidLottoNums(List<Integer> nums) {
if (!isAllValidLottoNum(nums)) {
System.out.printf("입력되는 번호는 %d ~ %d 사이의 번호여야 합니다.\n", LottoInfo.LOTTO_NUM_START, LottoInfo.LOTTO_NUM_END);
return false;
}
if (!isAllUnique(nums)) {
System.out.println("중복되는 번호가 없어야 합니다.");
return false;
}
return nums.size() == LottoInfo.LOTTO_LENGTH;
}

private List<Integer> _tryReadWinningNums() {
var numsStr = sc.nextLine();
System.out.println("line: " + numsStr);
var nums = _numsStrToNums(numsStr);

if (!isValidLottoNums(nums)) return new ArrayList();

return nums;
}

private List<Integer> _readWinningNumsUntilSucceed() {
List<Integer> winningNums = new ArrayList();
while (winningNums.size() != LottoInfo.LOTTO_LENGTH) {
System.out.println("지난 주 당첨 번호를 입력해 주세요.");
System.out.println("정확한 입력을 위해 ','와 숫자만 사용해서 입력해주세요. 6개의 번호가 필요합니다 ex) 1,2,3,4,5,6");
winningNums = _tryReadWinningNums();
}
return winningNums;
}

private int _readInt() {
System.out.println("보너스 볼을 입력해 주세요");
int num = INVALID;

try {
num = sc.nextInt();
} catch (InputMismatchException e) {
System.out.printf("got: \n" + sc.nextLine());
sc.nextLine();
}
return num;
}

private int _tryReadBonusNo(List<Integer> nums) {
var bonusNo = _readInt();
if (bonusNo == INVALID || !LottoInfo.isLottoNum(bonusNo)) {
System.out.printf("로또번호는 %d ~ %d 인 숫자입니다\n", LottoInfo.LOTTO_NUM_START, LottoInfo.LOTTO_NUM_END);
return INVALID;
}
if (nums.contains(bonusNo)) {
System.out.println("보너스 볼은 당첨번호와 동일 할 수 없습니다.\n당첨번호 " + Arrays.toString(nums.toArray()));
return INVALID;
}
return bonusNo;
}

private int _readBonusNoUntilSucceed(List<Integer> nums) {
var bonusNo = INVALID;
while (bonusNo == INVALID) {
bonusNo = _tryReadBonusNo(nums);
}
return bonusNo;
}
}
16 changes: 16 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import domain.LottoGame;

import java.util.Random;

public class Main {

public static void main(String[] args) {
var game = new LottoGame(
new MoneyReaderFromUser(),
new MyLottoFactory(new NumberPickerByShuffling(new Random())),
new LottoReaderFromUser(),
new MyLottoAnalyzer()
);
game.run();
}
}
41 changes: 41 additions & 0 deletions src/main/java/MoneyReaderFromUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import domain.MoneyReader;

import java.util.InputMismatchException;
import java.util.Scanner;

public class MoneyReaderFromUser implements MoneyReader {
private static final int INVALID = -1;

private Scanner sc;

public MoneyReaderFromUser() {
this.sc = new Scanner(System.in);
}

@Override
public int readMoney() {
var money = _readInt();

while (!isValidMoney(money)) {
System.out.println("잘못된 입력입니다. 음 아닌 정수를 입력해주세요");
money = _readInt();
}
return money;
}

private boolean isValidMoney(int money) {
return INVALID < money;
}

private int _readInt() {
System.out.println("구입금액을 입력해 주세요.");
int num = INVALID;

try {
num = sc.nextInt();
} catch (InputMismatchException e) {
System.out.printf("got: \n" + sc.nextLine());
}
return num;
}
}
58 changes: 58 additions & 0 deletions src/main/java/MyLottoAnalyzer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import domain.Lotto;
import domain.LottoAnalyzer;
import domain.Rank;
import domain.WinningLotto;

import java.util.HashMap;
import java.util.List;

public class MyLottoAnalyzer implements LottoAnalyzer {
private static final Rank[] ranksForPrint = {Rank.FIFTH, Rank.FOURTH, Rank.THIRD, Rank.SECOND, Rank.FIRST};

@Override
public void analyze(WinningLotto winningLotto, List<Lotto> lottos, int usedMoney) {
System.out.println("당첨 통계\n--------\n");

var counter = _initCounter(winningLotto, lottos);
System.out.println(generateMatchStr(counter));

if (usedMoney == 0) {
System.out.println("로또를 구매하지 않았습니다.");
return;
}
System.out.printf("총 수익률은 %f입니다.", (double) countTotalWinningMoney(counter) / usedMoney);
}

private HashMap<Rank, Integer> _initCounter(WinningLotto winningLotto, List<Lotto> lottos) {
var counter = new HashMap<Rank, Integer>();

for (var lotto : lottos) {
var rank = winningLotto.match(lotto);

var cnt = counter.getOrDefault(rank, 0);
counter.put(rank, cnt + 1);
}
return counter;
}

private String generateMatchStr(HashMap<Rank, Integer> counter) {
var sb = new StringBuilder();
for (var r : ranksForPrint) {
sb.append(String.format("%d개 일치%s ", r.getCountOfMatch(), r == Rank.SECOND ? ", 보너스 볼 일치" : ""));
sb.append(String.format("(%d원)", r.getWinningMoney()));
sb.append(String.format("- %d개\n", counter.getOrDefault(r, 0)));
}
return sb.toString();
}

private long countTotalWinningMoney(HashMap<Rank, Integer> counter) {
long total = 0;

for (var r : counter.keySet()) {
long winningMoney = r.getWinningMoney();
total += winningMoney * counter.get(r);
}

return total;
}
}
30 changes: 30 additions & 0 deletions src/main/java/MyLottoFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import domain.LottoFactory;

import domain.Lotto;
import domain.LottoInfo;
import domain.NumberPicker;

import java.util.Arrays;
import java.util.stream.IntStream;

public class MyLottoFactory implements LottoFactory {

private NumberPicker picker;

public MyLottoFactory(NumberPicker picker) {
this.picker = picker;
}

@Override
public Lotto newLotto() {
var nums = IntStream.range(LottoInfo.LOTTO_NUM_START, LottoInfo.LOTTO_NUM_END + 1)
.boxed()
.toArray(Integer[]::new);

var pickedNums = picker.PickNums(nums, LottoInfo.LOTTO_LENGTH);

return new Lotto(Arrays.asList(pickedNums));
}
}


Loading