diff --git a/LEARNING.md b/LEARNING.md new file mode 100644 index 00000000..7dc9d471 --- /dev/null +++ b/LEARNING.md @@ -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 \ No newline at end of file diff --git a/README.md b/README.md index e69de29b..b7549f41 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,13 @@ +## 기능목록 +-[x] 게임을 실행 (전체적인 실행 흐름) +-[x] 유저에게 돈 받아내기 + -[x] 올바른 입력인지 확인 (숫자로만 구성된 입력인지, 음 아닌 정수인지) +-[x] 로또 만들기 + -[x] 셔플로 만들기 + - 올바른 로또인지 확인하는 부분 (1~45까지의 수, 중복 없음, 총 6개) + - 만든 함수에서 예외처리 (ex.. 뽑을 집합보다 뽑을 갯수가 많은 경우) +-[x] 당첨로또 알아내기 + -[x] 올바른 입력인지 확인 +-[x] 유저의 로또 결과 분석하기 + + diff --git a/src/main/java/LottoReaderFromUser.java b/src/main/java/LottoReaderFromUser.java new file mode 100644 index 00000000..cdd66281 --- /dev/null +++ b/src/main/java/LottoReaderFromUser.java @@ -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 _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(); + for (var numStr : numsStr.split(",")) { + nums.add(Integer.parseInt(numStr)); + } + return nums; + } + + private boolean isAllUnique(List nums) { + var set = new HashSet(); + for (var num : nums) { + set.add(num); + } + return nums.size() == set.size(); + } + + private boolean isAllValidLottoNum(List nums) { + for (var num : nums) { + if (!LottoInfo.isLottoNum(num)) return false; + } + return true; + } + + private boolean isValidLottoNums(List 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 _tryReadWinningNums() { + var numsStr = sc.nextLine(); + System.out.println("line: " + numsStr); + var nums = _numsStrToNums(numsStr); + + if (!isValidLottoNums(nums)) return new ArrayList(); + + return nums; + } + + private List _readWinningNumsUntilSucceed() { + List 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 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 nums) { + var bonusNo = INVALID; + while (bonusNo == INVALID) { + bonusNo = _tryReadBonusNo(nums); + } + return bonusNo; + } +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 00000000..1876fa5a --- /dev/null +++ b/src/main/java/Main.java @@ -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(); + } +} diff --git a/src/main/java/MoneyReaderFromUser.java b/src/main/java/MoneyReaderFromUser.java new file mode 100644 index 00000000..9e485465 --- /dev/null +++ b/src/main/java/MoneyReaderFromUser.java @@ -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; + } +} diff --git a/src/main/java/MyLottoAnalyzer.java b/src/main/java/MyLottoAnalyzer.java new file mode 100644 index 00000000..af3cd43c --- /dev/null +++ b/src/main/java/MyLottoAnalyzer.java @@ -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 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 _initCounter(WinningLotto winningLotto, List lottos) { + var counter = new HashMap(); + + 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 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 counter) { + long total = 0; + + for (var r : counter.keySet()) { + long winningMoney = r.getWinningMoney(); + total += winningMoney * counter.get(r); + } + + return total; + } +} diff --git a/src/main/java/MyLottoFactory.java b/src/main/java/MyLottoFactory.java new file mode 100644 index 00000000..c6f45709 --- /dev/null +++ b/src/main/java/MyLottoFactory.java @@ -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)); + } +} + + diff --git a/src/main/java/NumberPickerByShuffling.java b/src/main/java/NumberPickerByShuffling.java new file mode 100644 index 00000000..fae3dd23 --- /dev/null +++ b/src/main/java/NumberPickerByShuffling.java @@ -0,0 +1,40 @@ +import domain.NumberPicker; + +import java.util.Random; +import java.util.stream.IntStream; + +public class NumberPickerByShuffling implements NumberPicker { + + private Random rand; + + public NumberPickerByShuffling(Random rand) { + this.rand = rand; + } + + @Override + public Integer[] PickNums(Integer[] nums, int numPicked) { + var shuffledIdxs = initShuffledIdxs(nums.length); + + return IntStream.range(0, numPicked) + .map((i) -> nums[shuffledIdxs[i]]) + .boxed() + .toArray(Integer[]::new); + } + + private int[] initShuffledIdxs(int length) { + var idxs = IntStream.range(0, length).toArray(); + + IntStream.range(0, length).forEach((from) -> { + int to = rand.nextInt(length); + _swap(idxs, from, to); + }); + + return idxs; + } + + private void _swap(int[] nums, int from, int to) { + int tmp = nums[from]; + nums[from] = nums[to]; + nums[to] = tmp; + } +} diff --git a/src/main/java/domain/Lotto.java b/src/main/java/domain/Lotto.java index 06694869..ca851436 100644 --- a/src/main/java/domain/Lotto.java +++ b/src/main/java/domain/Lotto.java @@ -1,6 +1,10 @@ package domain; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * 로또 한장을 의미하는 객체 @@ -12,5 +16,29 @@ public Lotto(List numbers) { this.numbers = numbers; } + @Override + public String toString() { + ArrayList nums = new ArrayList(numbers); + Collections.sort(nums); + + var numStrs = IntStream.range(0, nums.size()) + .mapToObj(i -> Integer.toString(nums.get(i))) + .collect(Collectors.toList()); + + + return "[" + String.join(",", numStrs.toArray(new String[nums.size()])) + "]"; + } + // 추가 기능 구현 + public boolean contains(Integer num) { + return numbers.contains(num); + } + + public int countEqualNumbers(Lotto lotto) { + int countOfMatch = 0; + for (var num : numbers) { + countOfMatch += lotto.contains(num) ? 1 : 0; + } + return countOfMatch; + } } diff --git a/src/main/java/domain/LottoAnalyzer.java b/src/main/java/domain/LottoAnalyzer.java new file mode 100644 index 00000000..cc92b05b --- /dev/null +++ b/src/main/java/domain/LottoAnalyzer.java @@ -0,0 +1,7 @@ +package domain; + +import java.util.List; + +public interface LottoAnalyzer { + void analyze(WinningLotto winningLotto, List lottos, int usedMoney); +} diff --git a/src/main/java/domain/LottoFactory.java b/src/main/java/domain/LottoFactory.java new file mode 100644 index 00000000..8f1d8973 --- /dev/null +++ b/src/main/java/domain/LottoFactory.java @@ -0,0 +1,5 @@ +package domain; + +public interface LottoFactory { + Lotto newLotto(); +} diff --git a/src/main/java/domain/LottoGame.java b/src/main/java/domain/LottoGame.java new file mode 100644 index 00000000..808b426a --- /dev/null +++ b/src/main/java/domain/LottoGame.java @@ -0,0 +1,46 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LottoGame { + public static final int LOTTO_PRICE = 1000; + + + private MoneyReader moneyReader; + private LottoFactory lottoFactory; + private LottoReader lottoReader; + private LottoAnalyzer lottoAnalyzer; + + public LottoGame(MoneyReader moneyReader, + LottoFactory lottoFactory, + LottoReader lottoReader, + LottoAnalyzer lottoAnalyzer) { + this.moneyReader = moneyReader; + this.lottoFactory = lottoFactory; + this.lottoReader = lottoReader; + this.lottoAnalyzer = lottoAnalyzer; + } + + public void run() { + var money = moneyReader.readMoney(); + var numLottos = money / LOTTO_PRICE; + + var lottos = Stream.generate(() -> lottoFactory.newLotto()) + .limit(numLottos) + .collect(Collectors.toCollection(ArrayList::new)); + _printLottos(lottos); + + var winningLotto = lottoReader.readWinningLotto(); + System.out.println(winningLotto.toString()); + lottoAnalyzer.analyze(winningLotto, lottos, numLottos * LOTTO_PRICE); + } + + private void _printLottos(List lottos) { + System.out.println(); + System.out.printf("%d개를 구매했습니다.\n", lottos.size()); + lottos.forEach((lotto) -> System.out.println(lotto.toString())); + } +} diff --git a/src/main/java/domain/LottoInfo.java b/src/main/java/domain/LottoInfo.java new file mode 100644 index 00000000..f9ded207 --- /dev/null +++ b/src/main/java/domain/LottoInfo.java @@ -0,0 +1,11 @@ +package domain; + +public class LottoInfo { + public static final int LOTTO_NUM_START = 1; + public static final int LOTTO_NUM_END = 45; + public static final int LOTTO_LENGTH = 6; + + public static boolean isLottoNum(int num) { + return LottoInfo.LOTTO_NUM_START <= num && num <= LottoInfo.LOTTO_NUM_END; + } +} diff --git a/src/main/java/domain/LottoReader.java b/src/main/java/domain/LottoReader.java new file mode 100644 index 00000000..6644ea36 --- /dev/null +++ b/src/main/java/domain/LottoReader.java @@ -0,0 +1,5 @@ +package domain; + +public interface LottoReader { + WinningLotto readWinningLotto(); +} diff --git a/src/main/java/domain/MoneyReader.java b/src/main/java/domain/MoneyReader.java new file mode 100644 index 00000000..27ad477f --- /dev/null +++ b/src/main/java/domain/MoneyReader.java @@ -0,0 +1,5 @@ +package domain; + +public interface MoneyReader { + int readMoney(); +} diff --git a/src/main/java/domain/NumberPicker.java b/src/main/java/domain/NumberPicker.java new file mode 100644 index 00000000..a6678f2e --- /dev/null +++ b/src/main/java/domain/NumberPicker.java @@ -0,0 +1,5 @@ +package domain; + +public interface NumberPicker { + Integer[] PickNums(Integer[] nums, int lottoLength); +} diff --git a/src/main/java/domain/Rank.java b/src/main/java/domain/Rank.java index 00549b95..a9153f25 100644 --- a/src/main/java/domain/Rank.java +++ b/src/main/java/domain/Rank.java @@ -39,7 +39,7 @@ public static Rank valueOf(int countOfMatch, boolean matchBonus) { } for (Rank rank : values()) { - if (rank.matchCount(countOfMatch)) { + if (rank.matchCount(countOfMatch) && rank != SECOND) { return rank; } } diff --git a/src/main/java/domain/WinningLotto.java b/src/main/java/domain/WinningLotto.java index d810418b..51a15a17 100644 --- a/src/main/java/domain/WinningLotto.java +++ b/src/main/java/domain/WinningLotto.java @@ -12,8 +12,13 @@ public WinningLotto(Lotto lotto, int bonusNo) { this.bonusNo = bonusNo; } + @Override + public String toString() { + return lotto.toString() + String.format(" + [%d]", bonusNo); + } + public Rank match(Lotto userLotto) { - // TODO 로직 구현 - return null; + int countOfMatch = lotto.countEqualNumbers(userLotto); + return Rank.valueOf(countOfMatch, userLotto.contains(bonusNo)); } } diff --git a/src/test/java/MyLottoFactoryTest.java b/src/test/java/MyLottoFactoryTest.java new file mode 100644 index 00000000..b8d36298 --- /dev/null +++ b/src/test/java/MyLottoFactoryTest.java @@ -0,0 +1,27 @@ +import domain.LottoInfo; +import domain.NumberPicker; + +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class MyLottoFactoryTest { + + private MyLottoFactory factory; + private NumberPicker mockedPicker; + + @org.junit.Test + public void newLottoPickValidLength() { + mockedPicker = mock(NumberPickerByShuffling.class); + when(mockedPicker.PickNums(any(Integer[].class), eq(LottoInfo.LOTTO_LENGTH))) + .thenReturn(new Integer[LottoInfo.LOTTO_LENGTH]); + + factory = new MyLottoFactory(mockedPicker); + + // Act + factory.newLotto(); + + // Assert + verify(mockedPicker).PickNums(any(Integer[].class), eq(LottoInfo.LOTTO_LENGTH)); + } +} \ No newline at end of file diff --git a/src/test/java/NumberPickerByShufflingTest.java b/src/test/java/NumberPickerByShufflingTest.java new file mode 100644 index 00000000..eb291a82 --- /dev/null +++ b/src/test/java/NumberPickerByShufflingTest.java @@ -0,0 +1,111 @@ +import domain.NumberPicker; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Random; +import java.util.stream.IntStream; + +import static org.junit.Assert.*; + +public class NumberPickerByShufflingTest { + + private static final int NUM_PICKED = 6; + + private NumberPickerByShuffling picker; + + @Before + public void setUp() throws Exception { + picker = new NumberPickerByShuffling(new Random()); + } + + // 원하는 갯수만큼 뽑았는지 + // 중복 없이 뽑았는지 (입력 받은 갯수를 초과해서 뽑지 않도록) + + @Test + public void pickNumsWithVariousNumPicked() { + var nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + var pickedNums = new int[]{0, 1, 3, 5, 7, 10}; + + for (var numPicked : pickedNums) { + // Act + var got = picker.PickNums(nums, numPicked); + + // Assert + Assert.assertEquals(numPicked, got.length); + } + } + + @Test + public void pickNumsNonDuplicatedNums() { + var nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + int n = 100; + + IntStream.range(0, n).forEach((i) -> { + // Act + var picked = picker.PickNums(nums, NUM_PICKED); + var counter = initCounter(picked); + + Assert.assertEquals(NUM_PICKED, counter.size()); + }); + } + + @Test + public void pickNumsNonDuplicatedNumsPickValidNum() { + var nums = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + var counter = initCounter(nums); + + int n = 100; + + IntStream.range(0, n).forEach((i) -> { + // Act + var picked = picker.PickNums(nums, NUM_PICKED); + var pickedCounter = initCounter(picked); + + // Assert + for(var pickedNum : pickedCounter.keySet()) { + Assert.assertTrue(counter.containsKey(pickedNum)); + } + }); + } + + + @Test + public void pickNumsDuplicatedNums() { + var nums = new Integer[]{1, 2, 2, 2, 2, 4, 4, 5, 9, 9, 9, 9, 9, 9, 10, 81, 100}; + var counter = initCounter(nums); + + int n = 100; + + IntStream.range(0, n).forEach((i) -> { + // Act + var picked = picker.PickNums(nums, NUM_PICKED); + System.out.println(Arrays.toString(picked)); + var pickedCounter = initCounter(picked); + + // Assert + for(var pickedNum : pickedCounter.keySet()) { + Assert.assertTrue(counter.containsKey(pickedNum)); + Assert.assertTrue(pickedCounter.get(pickedNum) <= counter.get(pickedNum)); + } + }); + } + + private HashMap initCounter(Integer[] nums) { + var counter = new HashMap(); + for (var num : nums) { + if (counter.containsKey(num)) { + counter.put(num, counter.get(num) + 1); + continue; + } + counter.put(num, 1); + } + + return counter; + } +} \ No newline at end of file diff --git a/src/test/java/domain/LottoTest.java b/src/test/java/domain/LottoTest.java new file mode 100644 index 00000000..c78c9d7a --- /dev/null +++ b/src/test/java/domain/LottoTest.java @@ -0,0 +1,94 @@ +package domain; + +import com.sun.source.tree.AssertTree; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; + +import static org.junit.Assert.*; + +public class LottoTest { + private static final int LOTTO_NUM_START = 1; + private static final int LOTTO_NUM_END = 45; + + @Test + public void containsValids() { + List> numsList = Arrays.asList( + Arrays.asList(1, 2, 3, 4, 5, 6), + Arrays.asList(6, 5, 4, 3, 2, 1), + Arrays.asList(10, 20, 30, 40, 41, 45), + Arrays.asList(40, 30, 41, 45, 20, 10) + ); + + for (var nums : numsList) { + var lotto = new Lotto(nums); + + // Act & Assert + nums.forEach((num) -> { + Assert.assertTrue(lotto.contains(num)); + }); + } + } + + @Test + public void containsInvalids() { + List> numsList = Arrays.asList( + Arrays.asList(1, 2, 3, 4, 5, 6), + Arrays.asList(6, 5, 4, 3, 2, 1), + Arrays.asList(10, 20, 30, 40, 41, 45), + Arrays.asList(40, 30, 41, 45, 20, 10) + ); + + for (var nums : numsList) { + var lotto = new Lotto(nums); + + // Act & Assert + IntStream.range(LOTTO_NUM_START, LOTTO_NUM_END).forEach((num) -> { + if (nums.contains(num)) { + return; + } + Assert.assertFalse(lotto.contains(num)); + }); + } + } + + @Test + public void countEqualNumbers() { + List> numsList = Arrays.asList( + Arrays.asList(1, 2, 3, 4, 5, 6), + Arrays.asList(6, 5, 4, 3, 2, 1), + Arrays.asList(10, 20, 30, 40, 41, 45), + Arrays.asList(40, 30, 41, 45, 20, 10) + ); + List lottosForCompare = Arrays.asList( + new Lotto(Arrays.asList(1, 2, 3, 4, 5, 6)), + new Lotto(Arrays.asList(6, 5, 4, 3, 2, 1)), + new Lotto(Arrays.asList(10, 20, 30, 40, 41, 45)), + + new Lotto(Arrays.asList(2, 3, 10, 30, 41, 45)), + new Lotto(Arrays.asList(31, 32, 33, 34, 35, 36)) + ); + List> wantsList = Arrays.asList( + Arrays.asList(6, 6, 0, 2, 0), + Arrays.asList(6, 6, 0, 2, 0), + Arrays.asList(0, 0, 6, 4, 0), + Arrays.asList(0, 0, 6, 4, 0) + ); + + for (int i = 0; i < numsList.size(); i++) { + var lottoA = new Lotto(numsList.get(i)); + + // Act & Assert + for (int j = 0; j < lottosForCompare.size(); j++) { + var lottoB = lottosForCompare.get(j); + + Integer got = lottoA.countEqualNumbers(lottoB); + Assert.assertEquals(wantsList.get(i).get(j), got); + } + } + } +} \ No newline at end of file