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

[블랙잭 게임 미션] 김지혜 1단계 리퀘스트 #1

Open
wants to merge 11 commits into
base: Revivekirin
Choose a base branch
from
Open
Binary file added src/main/java/blackjack/.DS_Store
Binary file not shown.
68 changes: 68 additions & 0 deletions src/main/java/blackjack/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package blackjack;

import java.util.HashMap;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.Map;
import java.util.Collections;

import java.util.Scanner;

public class Application {

public static void main(String[] args) {
Map<String, List<Integer>> Cards = CardDictionary.createCardDictionary();

List<String> Dealer = Arrays.asList("딜러");
List<String> participants = getInput("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)", s -> Arrays.asList(s.split(",")));
ParticipantSize(participants); //예외 처리

Collections.shuffle(participants);

Map<String, CardGameSimulator.ParticipantState> participantStates = CardGameSimulator.simulateCardGame(participants, Cards);
Map<String, CardGameSimulator.ParticipantState> dealerState = CardGameSimulator.simulateCardGame(Dealer, Cards);

for (String participant : participants) {
for (Map.Entry<String, CardGameSimulator.ParticipantState> entry : participantStates.entrySet()) {
Between16And21.SumBetween16And21(participant, entry, Cards);
}
}


for (Map.Entry<String, CardGameSimulator.ParticipantState> entry : dealerState.entrySet()) {
Between16And21.DealerBetween16And21(Dealer.get(0), entry, Cards);
}


for (String participant : participants) {
for (Map.Entry<String, CardGameSimulator.ParticipantState> entry : participantStates.entrySet()) {
DecideResult.CompareWithDealer();
}

}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

main 메서드가 static이기 때문에 다른 메서드들도 대부분 static 으로 작성된 것 같군요!!
이에 관련해서 팁을 드리자면
BlackJackGame이란 객체를 만들고 main 에서는

BlackJackGame blackJackGame = new BlackJaclGame(...)
backjackGame.startGame()

을 main에서 호출하는 것으로 변경하면 static method를 줄일 수 있을 겁니다!!


private static <T> T getInput(String prompt, Function<String, T> parser) {
T participants;

Scanner scanner = new Scanner(System.in);
System.out.println(prompt);
String userinput = scanner.nextLine();
participants = parser.apply(userinput);
return participants;
}

private static void ParticipantSize(List<String> participants) {
if (participants.size() > 25) {
throw new IllegalArgumentException("가능한 참가 인원을 초과하였습니다.");
}
}





}

58 changes: 58 additions & 0 deletions src/main/java/blackjack/Between16And21.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package blackjack;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Between16And21 {
Copy link
Contributor

Choose a reason for hiding this comment

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

객체지향은 현실에 있을 법한 네이밍을 가진 객체에서 적절한 책임을 분배하는 것이 중요합니다.
그래서 내부에 정의된 메서드들을 Player, Delear라는 객체로 만들고
canReceiveCard 과 같은 메서드들을 통해 대체하도록 만드는 것이 좋아보입니다!
딜러가 카드를 받을 수 있는 규칙을 딜러가 정의한다면 적절한 책임 분배라 볼 수 있겠죠?

public static void SumBetween16And21(String participant, Map.Entry<String, CardGameSimulator.ParticipantState> participantEntry, Map<String, List<Integer>> Cards) {
while(true) {
CardGameSimulator.ParticipantState participantState = participantEntry.getValue();
int sum = participantState.getSum(Cards);

if (sum < 16 || sum >=21) {
break;
}

if (sum > 16 && sum < 21) {
System.out.println(participant+ "는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)");
Scanner scanner = new Scanner(System.in);
String answer = scanner.nextLine();

if("y".equalsIgnoreCase(answer)) {
Map.Entry<String, Integer> extraCard = CardGameSimulator.getRandomCard(Cards);
int extraCardValue = extraCard.getValue();
String extraCardName = extraCard.getKey();
participantState.updateSumAndNameList(extraCardValue, extraCardName);

System.out.println(participant + "카드: " + participantState.printlist());
//16과 21인지 판단하고 만약 중간이라면 다시 SumBetween16and21 실행 아니면 continue
} else if ("n".equalsIgnoreCase(answer)) {
System.out.println(participant + "카드: " + participantState.printlist());
break;

}
}
}
}

public static void DealerBetween16And21(String Dealer, Map.Entry<String, CardGameSimulator.ParticipantState> DealerEntry, Map<String, List<Integer>> Cards) {
CardGameSimulator.ParticipantState DealerState = DealerEntry.getValue();
int sum = DealerState.getSum(Cards);

while(true) {
if (sum > 21 || (16 < sum && sum <= 21)) {
break;
}

if (sum < 16) {
Map.Entry<String, Integer> extraCard = CardGameSimulator.getRandomCard(Cards);
int extraCardValue = extraCard.getValue();
String extraCardName = extraCard.getKey();
DealerState.updateSumAndNameList(extraCardValue, extraCardName); //DealerEntry<name, Map<String, CardGameSimulator.ParticipantState>
break;
}
}
}
}
40 changes: 40 additions & 0 deletions src/main/java/blackjack/CardDictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package blackjack;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

public class CardDictionary {
public static Map<String, List<Integer>> createCardDictionary() {
Map<String, List<Integer>> Cards = new HashMap<>();

for (int i = 2; i <= 10; i++) {
for (String suit : new String[]{"하트", "스페이드", "클로버", "다이아몬드"}) {
String cardName = i + suit;
List<Integer> values = new ArrayList<>();
values.add(i);
Cards.put(cardName, values);
}
}

for (String suit : new String[]{"하트", "스페이드", "클로버", "다이아몬드"}) {
for (String face : new String[]{"J", "Q", "K"}) {
String cardName = face + suit;
List<Integer> values = new ArrayList<>();
values.add(10);
Cards.put(cardName, values);
}
}

for (String suit : new String[]{"하트", "스페이드", "클로버", "다이아몬드"}) {
String cardName = suit + "Ace";
List<Integer> values = new ArrayList<>();
values.add(1);
values.add(11);
Cards.put(cardName, values);
}
return Cards; //HashMap [[key: 카드 이름, value = 카드 숫자]]
}
}
// Making functional interface!!!!!!!!!
98 changes: 98 additions & 0 deletions src/main/java/blackjack/CardGameSimulator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package blackjack;

import java.util.*;


public class CardGameSimulator {

public static class ParticipantState {
private int sum;
private List<String> cardlist;
Copy link
Contributor

Choose a reason for hiding this comment

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

내부 class를 사용해주셨군요!
저만의 내부 class 사용 기준을 공유드리자면

내부 클래스 어떻게 쓰는가?
내부 클래스는 크게 non-static, static으로 선언할 수 있습니다.
다만 non-static class는 메모리 누수를 발생시킬 수 있어서 외부 클래스(내부 클래스가 정의된 클래스)에서 사용되는 상황에만 사용합니다. 참고 글

내부 클래스 언제 쓰는가?
사실 내부 클래스 자체를 거의 사용하지 않지만 사용한다면
non-static 클래스의 경우
외부 클래스(내부 클래스가 정의된 클래스)에서만 사용하는 interface 구현체가 있다면
어차피 항상 같이 사라지거나 변경되고 외부 클래스만 사용하기 때문에 내부 class를 사용합니다.
static 클래스의 경우
외부 클래스에 대한 converter 같은 객체를 정의할 때 사용합니다.
non-static 클래스와의 차이는 외부 클래스가 아닌 다른 class에서 접근이 가능하다는 점입니다.

앞서 말했듯이 저는 inner class를 대부분 사용하지 않습니다.
내부 class는 응집도를 높혀주지만 class 파악이 힘들어지기 때문이죠 ㅎㅎ
그렇기 때문에 위와 같이 converter 혹은 내부에서만 사용되는 interface 구현체에만 사용합니다!
이 기준은 추후에 바뀔 수 있으나 지금 단계에서는 객체로 온전히 분리해서 구현해주셔도 좋을 것 같습니다 ㅎㅎ


public ParticipantState() {
this.sum = 0;
this.cardlist = new ArrayList<>();
}

public int printsum() {
return this.sum;
}

public List<String> printlist() {
return this.cardlist;
}

public int getSum(Map<String, List<Integer>> Cards) {

CardOperation sumOperation = shuffledCard -> {
int value = shuffledCard.getValue();
this.sum += value;
};

performCardOperation(Cards, sumOperation);

return this.sum;
}

public void updateSumAndNameList(int value, String cardNames) {
this.sum += value;
this.cardlist.add(cardNames);
}
}

public static Map<String, ParticipantState> simulateCardGame(List<String> participants, Map<String, List<Integer>> Cards) {
Map<String, ParticipantState> participantStates = new HashMap<>();

for(String participant : participants) {
participantStates.put(participant, new ParticipantState());
}

for (String participant : participants) {
ParticipantState participantState = participantStates.get(participant);
performCardOperation(Cards, shuffledCard -> {
int value = shuffledCard.getValue();
String cardName = shuffledCard.getKey();
participantState.updateSumAndNameList(value, cardName);
});
}
return participantStates;

}

interface CardOperation {
void operate(Map.Entry<String, Integer> shuffledCard);
}

private static void performCardOperation(Map<String, List<Integer>> Cards, CardOperation operation) {
for(int i = 0; i < 2; i++) {
Map.Entry<String, Integer> shuffledCard = getRandomCard(Cards);
operation.operate(shuffledCard);
}
}

public static Map.Entry<String, Integer> getRandomCard(Map<String, List<Integer>> Cards) {
String randomCardName = getRandomCardName(Cards.keySet());

List<Integer> cardValues = Cards.get(randomCardName);

int cardvalue = cardValues.get(0);

Cards.remove(randomCardName);

return new AbstractMap.SimpleEntry<>(randomCardName, cardvalue);
}

public static <T> T getRandomCardName(Set<T> keySet) {
int randomIndex = new Random().nextInt(keySet.size());
Iterator<T> iterator = keySet.iterator();
for(int i = 0; i< randomIndex; i++) {
iterator.next();

}
return iterator.next();
}
}




16 changes: 16 additions & 0 deletions src/main/java/blackjack/DecideResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package blackjack;

import java.util.Map;

public class DecideResult {
public static int DealerScore() {

}
Revivekirin marked this conversation as resolved.
Show resolved Hide resolved

public static void CompareWithDealer() {

}

// Calculate "딜러" ParticipantState.printsum()
// Compare each participant's sum value with dealer
}