diff --git a/src/main/java/nextstep/blackJack/Foo.java b/src/main/java/nextstep/blackJack/Foo.java new file mode 100644 index 00000000..498eb014 --- /dev/null +++ b/src/main/java/nextstep/blackJack/Foo.java @@ -0,0 +1,4 @@ +package nextstep.blackJack; + +public class Foo { +} diff --git a/src/main/java/nextstep/blackJack/GameUser.java b/src/main/java/nextstep/blackJack/GameUser.java new file mode 100644 index 00000000..891b692b --- /dev/null +++ b/src/main/java/nextstep/blackJack/GameUser.java @@ -0,0 +1,7 @@ +package nextstep.blackJack; + +public class GameUser extends Gamer { + public GameUser(String name) { + super(name); + } +} diff --git a/src/main/java/nextstep/blackJack/Gamer.java b/src/main/java/nextstep/blackJack/Gamer.java new file mode 100644 index 00000000..45e604b2 --- /dev/null +++ b/src/main/java/nextstep/blackJack/Gamer.java @@ -0,0 +1,67 @@ +package nextstep.blackJack; + +import nextstep.blackJack.deck.Card; +import nextstep.blackJack.deck.CardNumber; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public abstract class Gamer { + private final Set cards; + private final String name; + private Integer balance; + private Integer cardSum = 0; + public Gamer(final String name) { + this.name = name; + this.balance = 100000; + this.cards = new HashSet<>(); + } + + public void betMoney(Integer betMoney) { + this.balance -= betMoney; + } + + public String getName(){ + return this.name; + } + + public Integer getBalance() { + return balance; + } + + public void addCard(Card card) { + if (!cards.contains(card)){ + cardSum += card.getCardNumber().getNumber(); + } + cards.add(card); + } + + public boolean isHaveAce(){ + return this.cards.stream().map(Card::getCardNumber).anyMatch(CardNumber::isAce); + } + + public boolean isFull(){ + return this.cardSum > 21; + } + + public Integer getSum() { +// cardSum = cards.stream().map(Card::getCardNumber).map(CardNumber::getNumber).reduce(0, Integer::sum); + return cardSum; + } + + private void calculateAce(){ + if (isHaveAce()){ + this.cardSum = getMax(); + } + } + + private int getMax() { + return Math.max(getAbsoluteSum(cardSum),getAbsoluteSum(cards.stream().map(Card::getCardNumber).map(CardNumber::getNumber).reduce(0, Integer::sum) + 10)); + } + + private int getAbsoluteSum(int cardSum){ + return Math.abs(cardSum - 21); + } +} diff --git a/src/main/java/nextstep/blackJack/Trump.java b/src/main/java/nextstep/blackJack/Trump.java new file mode 100644 index 00000000..f829d0d4 --- /dev/null +++ b/src/main/java/nextstep/blackJack/Trump.java @@ -0,0 +1,12 @@ +package nextstep.blackJack; + +public abstract class Trump { + + public static void createCardsByGameStart() { + + } + + public static Trump drawRandomCard() { + return null; + } +} diff --git a/src/main/java/nextstep/blackJack/deck/Card.java b/src/main/java/nextstep/blackJack/deck/Card.java new file mode 100644 index 00000000..fd769036 --- /dev/null +++ b/src/main/java/nextstep/blackJack/deck/Card.java @@ -0,0 +1,33 @@ +package nextstep.blackJack.deck; + +import java.util.Objects; + +public class Card { + private final CardShape cardShape; + private final CardNumber cardNumber; + public Card(CardShape cardShape, CardNumber cardNumber) { + this.cardShape = cardShape; + this.cardNumber = cardNumber; + } + + public CardShape getCardShape() { + return cardShape; + } + + public CardNumber getCardNumber() { + return cardNumber; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Card card = (Card) o; + return cardShape == card.cardShape && cardNumber == card.cardNumber; + } + + @Override + public int hashCode() { + return Objects.hash(cardShape, cardNumber); + } +} diff --git a/src/main/java/nextstep/blackJack/deck/CardNumber.java b/src/main/java/nextstep/blackJack/deck/CardNumber.java new file mode 100644 index 00000000..a59cd1c5 --- /dev/null +++ b/src/main/java/nextstep/blackJack/deck/CardNumber.java @@ -0,0 +1,26 @@ +package nextstep.blackJack.deck; + +public enum CardNumber { + ACE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + J(10), Q(10), K(10); + private final Integer number; + + CardNumber(Integer number) { + this.number = number; + } + public Integer getNumber() { + return this.number; + } + + public boolean isAce(){ + return this.equals(ACE); + } +} diff --git a/src/main/java/nextstep/blackJack/deck/CardShape.java b/src/main/java/nextstep/blackJack/deck/CardShape.java new file mode 100644 index 00000000..4829388b --- /dev/null +++ b/src/main/java/nextstep/blackJack/deck/CardShape.java @@ -0,0 +1,21 @@ +package nextstep.blackJack.deck; + +import java.util.Arrays; + +public enum CardShape { + SPADE("SPADE"), + HEART("HEART"), + DIAMOND("DIAMOND"), + CLOVER("CLOVER"); + + private final String name; + + CardShape(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/src/main/java/nextstep/blackJack/deck/Cards.java b/src/main/java/nextstep/blackJack/deck/Cards.java new file mode 100644 index 00000000..39bbadbe --- /dev/null +++ b/src/main/java/nextstep/blackJack/deck/Cards.java @@ -0,0 +1,41 @@ +package nextstep.blackJack.deck; + +import java.util.*; + +public class Cards { + private final Stack cards; + + private Cards() { + this.cards = createCards(); + } + + public int size(){ + return cards.size(); + } + + public static Cards ofGame(){ + return new Cards(); + } + + public void shuffleCards(){ + Collections.shuffle(this.cards); + } + + private void addToCards(CardShape cardShape, Stack cards) { + for (CardNumber cardNumber : CardNumber.values()) { + cards.add(new Card(cardShape, cardNumber)); + } + } + + public Stack createCards() { + Stack cards = new Stack<>(); + for (CardShape cardShape : CardShape.values()) { + addToCards(cardShape, cards); + } + return cards; + } + + public Card pickCard() { + return cards.pop(); + } +} diff --git a/src/main/java/nextstep/blackJack/deck/ShuffleStrategy.java b/src/main/java/nextstep/blackJack/deck/ShuffleStrategy.java new file mode 100644 index 00000000..f7800a57 --- /dev/null +++ b/src/main/java/nextstep/blackJack/deck/ShuffleStrategy.java @@ -0,0 +1,8 @@ +package nextstep.blackJack.deck; + +import java.util.Stack; + +@FunctionalInterface +public interface ShuffleStrategy { + void shuffle(Stack cards); +} diff --git a/src/main/java/nextstep/fp/Lambda.java b/src/main/java/nextstep/fp/Lambda.java index bd68fe1c..ff3502e9 100644 --- a/src/main/java/nextstep/fp/Lambda.java +++ b/src/main/java/nextstep/fp/Lambda.java @@ -1,5 +1,6 @@ package nextstep.fp; +import java.util.EnumMap; import java.util.List; public class Lambda { @@ -18,39 +19,22 @@ public static void printAllLambda(List numbers) { } public static void runThread() { - new Thread(new Runnable() { - @Override - public void run() { - System.out.println("Hello from thread"); - } - }).start(); + new Thread(() -> System.out.println("Hello from thread")).start(); } public static int sumAll(List numbers) { - int total = 0; - for (int number : numbers) { - total += number; - } - return total; + return sumByCondition(numbers, number -> true); } public static int sumAllEven(List numbers) { - int total = 0; - for (int number : numbers) { - if (number % 2 == 0) { - total += number; - } - } - return total; + return sumByCondition(numbers, number -> number % 2 == 0); } public static int sumAllOverThree(List numbers) { - int total = 0; - for (int number : numbers) { - if (number > 3) { - total += number; - } - } - return total; + return sumByCondition(numbers, number -> number > 3); + } + + public static int sumByCondition(List numbers, SumWithCondition sumWithCondition){ + return numbers.stream().filter(sumWithCondition::sumCondition).reduce(0, Integer::sum); } } diff --git a/src/main/java/nextstep/fp/StreamStudy.java b/src/main/java/nextstep/fp/StreamStudy.java index b446983a..23bc3c60 100644 --- a/src/main/java/nextstep/fp/StreamStudy.java +++ b/src/main/java/nextstep/fp/StreamStudy.java @@ -5,8 +5,10 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; public class StreamStudy { @@ -27,6 +29,19 @@ public static void printLongestWordTop100() throws IOException { .get("src/main/resources/fp/war-and-peace.txt")), StandardCharsets.UTF_8); List words = Arrays.asList(contents.split("[\\P{L}]+")); + words.stream() + .filter(s -> s.length() > 12) + .sorted(Comparator.comparing(String::length).reversed()) + .distinct() + .limit(100) + .map(String::toLowerCase) + .forEach(System.out::println); + + + //단어의 길이가 12자를 초과하는 단어를 추출한다. + //12자가 넘는 단어 중 길이가 긴 순서로 100개의 단어를 추출한다. + //단어 중복을 허용하지 않는다. 즉, 서로 다른 단어 100개를 추출해야 한다. + //추출한 100개의 단어를 출력한다. 모든 단어는 소문자로 출력해야 한다. // TODO 이 부분에 구현한다. } @@ -39,6 +54,6 @@ public static long sumAll(List numbers) { } public static long sumOverThreeAndDouble(List numbers) { - return 0; + return numbers.stream().filter(x -> x > 3).map(x -> x * 2).reduce(0, Integer::sum); } } \ No newline at end of file diff --git a/src/main/java/nextstep/fp/SumWithCondition.java b/src/main/java/nextstep/fp/SumWithCondition.java new file mode 100644 index 00000000..cabf7cae --- /dev/null +++ b/src/main/java/nextstep/fp/SumWithCondition.java @@ -0,0 +1,7 @@ +package nextstep.fp; + +import java.util.List; +@FunctionalInterface +public interface SumWithCondition { + boolean sumCondition(int number); +} diff --git a/src/main/java/nextstep/optional/ComputerStore.java b/src/main/java/nextstep/optional/ComputerStore.java index 2695c967..a026861b 100644 --- a/src/main/java/nextstep/optional/ComputerStore.java +++ b/src/main/java/nextstep/optional/ComputerStore.java @@ -3,6 +3,8 @@ import nextstep.optional.Computer.Soundcard; import nextstep.optional.Computer.USB; +import java.util.Optional; + public class ComputerStore { public static final String UNKNOWN_VERSION = "UNKNOWN"; @@ -21,6 +23,7 @@ public static String getVersion(Computer computer) { } public static String getVersionOptional(Computer computer) { - return null; + return Optional.ofNullable(computer).map(Computer::getSoundcard).map(Soundcard::getUsb).map(USB::getVersion).orElse(UNKNOWN_VERSION); +// return null; } } diff --git a/src/main/java/nextstep/optional/Expression.java b/src/main/java/nextstep/optional/Expression.java index 1c98cd6a..2dff471d 100644 --- a/src/main/java/nextstep/optional/Expression.java +++ b/src/main/java/nextstep/optional/Expression.java @@ -1,5 +1,13 @@ package nextstep.optional; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + enum Expression { PLUS("+"), MINUS("-"), TIMES("*"), DIVIDE("/"); @@ -12,14 +20,19 @@ enum Expression { private static boolean matchExpression(Expression e, String expression) { return expression.equals(e.expression); } + public String getExpression(){ + return this.expression; + } + private static final Map expressionMap = Collections.unmodifiableMap( + Arrays.stream(values()).collect(Collectors.toMap(Expression::getExpression, Function.identity())) + ); static Expression of(String expression) { - for (Expression v : values()) { - if (matchExpression(v, expression)) { - return v; - } - } - - throw new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression)); + return Optional.ofNullable(expressionMap.get(expression)).orElseThrow( + () -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression)) + ); +// return Arrays.stream(values()).filter(v -> matchExpression(v, expression)).findAny().orElseThrow( +// () -> new IllegalArgumentException(String.format("%s는 사칙연산에 해당하지 않는 표현식입니다.", expression)) +// ); } } diff --git a/src/main/java/nextstep/optional/User.java b/src/main/java/nextstep/optional/User.java index 9614c2f4..2035ba19 100644 --- a/src/main/java/nextstep/optional/User.java +++ b/src/main/java/nextstep/optional/User.java @@ -1,5 +1,7 @@ package nextstep.optional; +import java.util.Optional; + public class User { private String name; private Integer age; @@ -33,7 +35,7 @@ public static boolean ageIsInRange1(User user) { } public static boolean ageIsInRange2(User user) { - return false; + return Optional.ofNullable(user).map(User::getAge).filter(age -> age > 30 && age < 45).isPresent(); } @Override diff --git a/src/main/java/nextstep/optional/Users.java b/src/main/java/nextstep/optional/Users.java index 6293040d..5c87ee72 100644 --- a/src/main/java/nextstep/optional/Users.java +++ b/src/main/java/nextstep/optional/Users.java @@ -13,11 +13,6 @@ public class Users { new User("honux", 45)); User getUser(String name) { - for (User user : users) { - if (user.matchName(name)) { - return user; - } - } - return DEFAULT_USER; + return users.stream().filter(user -> user.matchName(name)).findAny().orElse(DEFAULT_USER); } } diff --git a/src/test/java/nextstep/blackJack/BlackJackTest.java b/src/test/java/nextstep/blackJack/BlackJackTest.java new file mode 100644 index 00000000..adb81420 --- /dev/null +++ b/src/test/java/nextstep/blackJack/BlackJackTest.java @@ -0,0 +1,15 @@ +package nextstep.blackJack; + +import nextstep.blackJack.deck.Cards; +import org.junit.jupiter.api.Test; + +public class BlackJackTest { + @Test + void gameStartAndPickCard(){ + Gamer gamer = new GameUser("DK"); + Cards deck = Cards.ofGame(); + deck.shuffleCards(); + gamer.addCard(deck.pickCard()); + gamer.addCard(deck.pickCard()); + } +} diff --git a/src/test/java/nextstep/blackJack/CardTest.java b/src/test/java/nextstep/blackJack/CardTest.java new file mode 100644 index 00000000..be332dae --- /dev/null +++ b/src/test/java/nextstep/blackJack/CardTest.java @@ -0,0 +1,41 @@ +package nextstep.blackJack; + +import nextstep.blackJack.deck.Card; +import nextstep.blackJack.deck.CardNumber; +import nextstep.blackJack.deck.CardShape; +import nextstep.blackJack.deck.Cards; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class CardTest { + @Test + void pickCardTest(){ + Cards cards = Cards.ofGame(); + Card card = cards.pickCard(); + assertThat(card).isEqualTo(new Card(CardShape.CLOVER, CardNumber.K)); // 젤 끝놈 + } + + @Test + void pickShuffledCardTest(){ + Cards cards = Cards.ofGame(); + cards.shuffleCards(); + Card card = cards.pickCard(); + assertThat(card).isNotEqualTo(new Card(CardShape.CLOVER, CardNumber.K)); // 젤 끝놈이고, 1/48 확률로 실패한다... + assertThat(cards.size()).isEqualTo(47); + } + + @Test + void cardSizeTest(){ + Cards cards = Cards.ofGame(); + assertThat(cards.createCards().size()).isEqualTo(48); + cards.pickCard(); + assertThat(cards.size()).isEqualTo(47); + } + + @Test + void getCardInfoTest(){ + Card card = new Card(CardShape.SPADE, CardNumber.ACE); + + } +} diff --git a/src/test/java/nextstep/blackJack/GamerTest.java b/src/test/java/nextstep/blackJack/GamerTest.java new file mode 100644 index 00000000..a1b0f8d5 --- /dev/null +++ b/src/test/java/nextstep/blackJack/GamerTest.java @@ -0,0 +1,10 @@ +package nextstep.blackJack; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class GamerTest { + + +} \ No newline at end of file diff --git a/src/test/java/nextstep/blackJack/UserTest.java b/src/test/java/nextstep/blackJack/UserTest.java new file mode 100644 index 00000000..dea79682 --- /dev/null +++ b/src/test/java/nextstep/blackJack/UserTest.java @@ -0,0 +1,81 @@ +package nextstep.blackJack; + +import nextstep.blackJack.deck.Card; +import nextstep.blackJack.deck.CardNumber; +import nextstep.blackJack.deck.CardShape; +import nextstep.blackJack.deck.Cards; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class UserTest { + @Test + void userCreateTest() { + String name = "DK"; + Gamer gamer = new GameUser(name); + assertThat(gamer.getName()).isEqualTo(name); + } + + @Test + void userMoneyTest(){ + Integer betMoney = 10000; + Gamer gamer = new GameUser("DK"); + gamer.betMoney(betMoney); // 베팅 하면 잔고 차감하고 머니 리턴해야함 + assertThat(gamer.getBalance()).isEqualTo(90000); + } + @Test + void addCard() { + Cards cards = Cards.ofGame(); + cards.shuffleCards(); + Card card = cards.pickCard(); + Gamer gamer = new GameUser("DK"); + gamer.addCard(card); + assertThat(gamer.getSum()).isNotEqualTo(0); + } + + @Test + void isContainsAce() { + Card card = new Card(CardShape.SPADE, CardNumber.ACE); + Gamer gamer = new GameUser("DK"); + gamer.addCard(card); + assertThat(gamer.isHaveAce()).isTrue(); + } + + @Test + void userSetTest_NO_DUPLICATE() { + Card card = new Card(CardShape.SPADE, CardNumber.J); + Card card1 = new Card(CardShape.SPADE, CardNumber.Q); + Card card2 = new Card(CardShape.SPADE, CardNumber.K); + Gamer gamer = new GameUser("DK"); + gamer.addCard(card); + gamer.addCard(card1); + gamer.addCard(card2); + assertThat(gamer.isFull()).isTrue(); + } + @Test + void userSetTest_DUPLICATE() { + Card card = new Card(CardShape.SPADE, CardNumber.K); + Card card1 = new Card(CardShape.SPADE, CardNumber.K); + Card card2 = new Card(CardShape.SPADE, CardNumber.K); + Gamer gamer = new GameUser("DK"); + gamer.addCard(card); + gamer.addCard(card1); + gamer.addCard(card2); + assertThat(gamer.getSum()).isEqualTo(10); + } + + @Test + void userSetDoWorks(){ + // ACE 를 가지고 있을 경우, 절대값 현재 섬 - 21vs 현재섬 + 10 - 21 중 더 가까운 녀석으로 ACE를 취급해야 한다. + Card card = new Card(CardShape.SPADE, CardNumber.ACE); + Card card1 = new Card(CardShape.SPADE, CardNumber.K); + Card card2 = new Card(CardShape.SPADE, CardNumber.Q); + Card card3 = new Card(CardShape.SPADE, CardNumber.J); + Gamer gamer = new GameUser("DK"); + gamer.addCard(card); + gamer.addCard(card1); + gamer.addCard(card2); + gamer.addCard(card3); + + } +} diff --git a/src/test/java/nextstep/fp/CarTest.java b/src/test/java/nextstep/fp/CarTest.java index 1ab1106f..6058318a 100644 --- a/src/test/java/nextstep/fp/CarTest.java +++ b/src/test/java/nextstep/fp/CarTest.java @@ -8,12 +8,7 @@ public class CarTest { @Test public void 이동() { Car car = new Car("pobi", 0); - Car actual = car.move(new MoveStrategy() { - @Override - public boolean isMovable() { - return true; - } - }); + Car actual = car.move(() -> true); assertThat(actual).isEqualTo(new Car("pobi", 1)); }