작성
·
74
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
여기에 질문 내용을 남겨주세요.
코드리뷰 및 아이콘 출력 부탁드려요
안녕하세요. 자바 중급 마지막 문제를 풀어보았는데, 코드가 난잡한거 같습니다.
혹시 코드 리뷰나 틀린점을 짚어주시면 감사하겠습니다.
또한 아이콘 출력은 어려워서 이름으로 출력하게 했는데 아이콘 출력 나온는 법도 알려주시면 감사하겠습니다.
참고로 Suit 클래스는 영한님의 클래스를 재사용 하였습니다.
마지막으로 List가 비교적 사용이 쉬워서 List를 통한 풀이를 진행했는데,
HashMap이나 다른 컬렉션을 이용한 풀이도 있을까요?
package class2_8Iterator.MyArray.cardGame;
/**
* 카드에 대한 속성을 정의하는 클래스
* 1. 문양을 가진다
* 2. 번호를 가진다
* 3. 소팅이 가능하다
*/
import static class2_8Iterator.MyArray.cardGame.Suit.*;
public class Card implements Comparable<Card>{
private final Suit suit;
private Integer cardNumber;
public Card(Suit cardIcon, Integer cardNumber ){
this.cardNumber = cardNumber;
this.suit = cardIcon;
}
/**문양을 비교하기 위해 숫자로 변환한다.
* */
public Integer iconConverter(String cardIcon) {
if(SPADE.getIcon().equals(cardIcon)) {
return 1;
}
else if(HEART.getIcon().equals(cardIcon)){
return 2;
}
else if(DIAMOND.getIcon().equals(cardIcon)) {
return 3;
}
else if (CLUB.getIcon().equals(cardIcon)) {
return 4;
}
return 0;
}
public Suit getSuit() {
return suit;
}
/*
@Override
public String toString() {
return "Card{" +
"icon=" + icon +
", cardNumber=" + cardNumber +
'}';
}
*/
@Override
public String toString(){
return cardNumber+"("+suit+")";
}
/**
* 문양을 비교하고 같은 문양이면 숫자가 더 큰게 먼저 앞으로 나온다.
* */
@Override
public int compareTo(Card card) {
Integer thisIcon = iconConverter(this.suit.getIcon());
Integer inputIcon = iconConverter(card.suit.getIcon());
if(this.cardNumber==cardNumber){
return thisIcon<inputIcon ? -1 : (thisIcon==inputIcon ? 0 : 1);
}
else
return this.cardNumber<cardNumber ? -1 : (this.cardNumber==cardNumber ? 0 : 1);
}
public int numberCompareTo(Card card){
return this.cardNumber<card.cardNumber ? -1 : (this.cardNumber==card.cardNumber ? 0: 1);
}
public Suit getIcon() {
return suit;
}
public Integer getCardNumber() {
return cardNumber;
}
public void setCardNumber(Integer cardNumber) {
this.cardNumber = cardNumber;
}
}
package class2_8Iterator.MyArray.cardGame;
public enum Suit {
SPADE("♠"), // 스페이드(♠)
HEART("♥"),// 하트(♥)
DIAMOND("♦"),// 다이아몬드(♦)
CLUB("♣");// 클로버(♣)
private String icon;
Suit(String icon){
this.icon=icon;
}
public String getIcon() {
return icon;
}
}
package class2_8Iterator.MyArray.cardGame;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static class2_8Iterator.MyArray.cardGame.Suit.*;
/**
* 카드를 이용하여 덱을 구성한다.
* */
public class Deck {
private Card card;
private List<Card> masterDeck;
private List<Card> spadeDeck = new ArrayList<Card>();
private List<Card> heartDeck = new ArrayList<Card>();
private List<Card> diamondDeck = new ArrayList<Card>();
private List<Card> clubDeck = new ArrayList<Card>();
/***
*
*/
public Deck(){
for(int i =1 ;i <= 13; i++){
card = new Card(SPADE,i);
spadeDeck.add(card);
}
for(int i =1 ;i <= 13; i++){
card= new Card(HEART,i);
heartDeck.add(card);
}
for(int i =1 ;i <= 13; i++){
card = new Card(CLUB,i);
clubDeck.add(card);
}
for(int i =1 ;i <= 13; i++){
card =new Card(DIAMOND,i);
diamondDeck.add(card);
}
/**배열 합치기
* */
List<Card> mergedDeck1 = Stream.of(clubDeck, diamondDeck)
.flatMap(Collection::stream)
.collect(Collectors.toList());
List<Card> mergedDeck2 = Stream.of(spadeDeck,heartDeck)
.flatMap(Collection::stream)
.collect(Collectors.toList());
masterDeck = Stream.of(mergedDeck1, mergedDeck2)
.flatMap(Collection::stream)
.collect(Collectors.toList());
Collections.shuffle(masterDeck);
/***
* 덱 생성 확인을 위한 디버깅
*/
// for(Card cardEntry :deck){
//
// System.out.println(cardEntry.getCardNumber() + "," + cardEntry.getIcon());
//
// }
// System.out.println("size ie "+ deck.size());
// System.out.println( masterDeck.getClass());
}
public List<Card>getMaterDeck(){
return masterDeck;
}
}
package class2_8Iterator.MyArray.cardGame;
import java.util.ArrayList;
import java.util.List;
/**
* DECK에서 카드를 뽑아 패에 넣는다.
* */
public class Player {
List<Card> hands = new ArrayList<>();
Deck deck = new Deck();
// new 연산자 (메모리에 올리기) 안쓰면 nullPointerException 터진다
Integer [] cardNumberList = new Integer[5];
Integer totalNumber = 0;
public void drawCard(int turn){
List<Card> playableDeck = deck.getMaterDeck();
Card inputCard = playableDeck.get(turn);
hands.add(inputCard);
playableDeck.remove(turn);
}
public Integer getSumOfCardNumber(){
for(int i = 0 ; i <5;i++){
Card handCard = hands.get(i);
cardNumberList[i] = handCard.getCardNumber();
totalNumber = totalNumber+cardNumberList[i];
}
return totalNumber;
}
}
package class2_8Iterator.MyArray.cardGame;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.util.*;
public class CardGameMain {
public static void main(String args[]) {
Player player1 = new Player();
Player player2 = new Player();
Deck deck = new Deck();
// List<Card> playerList1 = new ArrayList<>();
// List<Card> playerList2 = new ArrayList<>();
for (int i = 0; i < 10; i++) {
if(i%2!=0){
player2.drawCard(i);
}
else
player1.drawCard(i);
}
//Player 클래스의 hands에 값을 넣었으나 다른 값을 참조하니까 자꾸 OUTOFINDEX 에러 나옴
//다음 코드는 hands내 값을 디버깅 할때 사용 한다
System.out.println("player1의 카드 리스트 "+Arrays.toString(player1.hands.toArray()));
System.out.println("player2의 카드 리스트 "+Arrays.toString(player2.hands.toArray()));
/*** TODO
* 1.손패 카드를 소팅하고
* 2. 카드 번호의 계를 구한다.
*/
Arrays.sort(player1.hands.toArray());
Arrays.sort(player2.hands.toArray());
System.out.println("==================정렬후 카드 패==================");
System.out.println("player1의 카드 리스트 "+Arrays.toString(player1.hands.toArray()));
System.out.println("player2의 카드 리스트 "+Arrays.toString(player2.hands.toArray()));
System.out.println("================== 카드 패 숫자 합계 =============");
System.out.println(player1.getSumOfCardNumber());
System.out.println(player2.getSumOfCardNumber());
if(player1.getSumOfCardNumber()> player2.getSumOfCardNumber()){
System.out.println("플레이어 1이 이겼습니다");
}else {
System.out.println("플레이어 2가 이겼습니다");
}
}
}
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
정현님께서 자바 중급 코드 리뷰와 아이콘 출력에 대한 질문을 주셨습니다. 코드리뷰를 통한 몇 가지 개선 방안과 아이콘 출력을 설명드리겠습니다.
코드 구조 개선
iconConverter
메소드는 Suit
의 열거형 값을 정수로 매핑하는데 사용되고 있습니다. 불필요한 코드로 보이며, Suit
에 직접 정수 값을 갖도록 변경할 수 있습니다.compareTo
메소드는 카드 게임의 특성에 맞추어 문양 우선 순위를 적용하고, 다음으로 숫자를 비교하도록 하였습니다. 그러나, iconConverter
를 사용하여 값을 변환할 필요 없이 Suit
의 ordinal 값을 사용할 수 있습니다.아이콘 출력
Suit
클래스에서 설정된 기호들을 사용하면 됩니다. 이미 toString()
메서드에서 suit
을 사용하여 아이콘을 포함한 출력이 가능하도록 되어있습니다. 기존 코드로도 아이콘을 출력하도록 잘 구현되어 있습니다.List 대신 다른 컬렉션 활용
List
대신 Map
을 사용할 경우, 키를 이용해 특정 카드에 접근하기는 수월할 수 있지만, 게임 규칙에 따라 List
가 더 적절할 수 있습니다. 특히, 카드 덱은 순서가 중요하기 때문에 List
를 사용하는 것이 적합합니다.Stream API 사용
masterDeck
을 생성할 때 Stream.of
를 사용하는 대신 List.addAll
을 활용하면 깔끔하게 덱을 합칠 수 있습니다.다음은 개선된 Card 클래스의 코드 예시입니다:
package class2_8Iterator.MyArray.cardGame;
public class Card implements Comparable<Card> {
private final Suit suit;
private Integer cardNumber;
public Card(Suit suit, Integer cardNumber ) {
this.suit = suit;
this.cardNumber = cardNumber;
}
public Suit getSuit() {
return suit;
}
public Integer getCardNumber() {
return cardNumber;
}
@Override
public String toString() {
return cardNumber + "(" + suit.getIcon() + ")";
}
@Override
public int compareTo(Card card) {
int suitComparison = this.suit.ordinal() - card.suit.ordinal();
if (suitComparison != 0) {
return suitComparison;
}
return this.cardNumber - card.cardNumber;
}
}
정현님이 작성하신 코드는 이미 잘 작성되어 있으며, 작은 최적화와 리팩토링을 통해 가독성을 향상시킬 수 있습니다. 궁금한 점이 있으면 추가로 질문 부탁드립니다!
혹시 더 상세한 조언이 필요하시면, Stack Overflow의 spring-boot
태그를 사용하여 질문을 검색하거나 새로운 질문을 올리는 것도 추천드립니다.
Spring Boot Reference Documentation
Executable Jar Format - Alternative Single Jar Solutions