2014-07-17 3 views
1

나는 Java 기술을 향상시키기 위해 블랙 잭 시뮬레이터를 구축하고 타격 할 때 서로 통신하도록 클래스를 가져 오는 데 문제가 있습니다.다른 클래스의 메서드를 호출하여 비 정적으로 유지

플레이어와 딜러에게 공통적 인 방법을 포함하는 휴먼 클래스를 만들고 있는데, 그 중 하나 인 히트 클래스입니다. 나는 카드 덱을 만드는 클래스 덱을 가지고 있는데이 클래스는 getCard라는 메서드를 가지고있다. Human에서는 hit 메소드가 Deck 클래스에서 getCard를 호출하기를 원합니다.

이 메서드는 Deck 클래스의 인스턴스 변수 인 데크에서 카드를 제거해야하므로 getCard를 정적으로 만들고 싶지 않습니다. Human 클래스 내에서 새로운 갑판 인스턴스를 만들고 싶지 않습니다. 인간당 한 갑판이 아니라 게임 당 하나의 갑판 만 필요하기 때문입니다.

어떻게 제대로 수행 할 수 있습니까?

//Removes a random card from the deck and deletes it from the deck. 
//It removes one card per call to the function. 
    public Card getCard(){ 
     Random rand = new Random(); 
     int index = rand.nextInt(deck.size()); 

     Card toDeal = new Card (deck.get(index).getName(), 
           deck.get(index).getSuit(), 
           deck.get(index).getValue()); 

     deck.remove(index); 

     return toDeal; 
    } 
: 지금의 IDE (넷빈즈) 여기
hand.add(Deck().getCard()); 

는 갑판 클래스의 getCard 방법입니다, 기호, 인간의 히트 방법이 줄 방법 ​​덱()를 찾을 수 없습니다 "라는

:

그리고 여기, 나는 두 클래스를 포함하고 내가 뭔가를 포함하지 않았다

경우
public void hit(){ 
    hand.add(Deck().getCard()); 
} 

인간 클래스의 히트 방법

package blackjack; 

import java.util.*; 

public class Deck { 

    private static int numSuits = 4; 
    private static int numRanks = 13; 
    private static int numCards = numSuits * numRanks; 

    private ArrayList<Card> deck; 

    public Deck() { 

     String suit = null; 
     String name = null;   
     int value = 0; 
     deck = new ArrayList<Card>(); 

     for (int i=1; i<=numSuits; i++){ 
      for (int j=1; j <= numRanks; j++){ 
       switch (i){ 
        case 1: suit = "Clubs"; break; 
        case 2: suit = "Diamonds"; break; 
        case 3: suit = "Hearts"; break; 
        case 4: suit = "Spades"; break; 
       } 

       switch (j){ 
        case 1: name = "Ace"; value = 0; break; 
        case 2: name = "Two"; value = 2; break; 
        case 3: name = "Three"; value = 3; break; 
        case 4: name = "Four"; value =4; break; 
        case 5: name = "Five"; value = 5; break;        
        case 6: name = "Six"; value = 6; break; 
        case 7: name = "Seven"; value = 7; break; 
        case 8: name = "Eight"; value = 8; break; 
        case 9: name = "Nine"; value = 9; break; 
        case 10: name = "Ten"; value = 10; break;       
        case 11: name = "Jack"; value = 10; break; 
        case 12: name = "Queen"; value = 10; break; 
        case 13: name = "King"; value = 10; break;       
       } 

       Card card = new Card (name, suit, value); 
       deck.add(card); 
      } 
     } 
    } 

    public int getSize(){ 
     return deck.size(); 
    } 

    public void printDeck(){ 

     for (Card card : deck){ 
      System.out.println(card); 
     } 
    } 

//Removes a random card from the deck and deletes it from the deck. 
//It removes one card per call to the function. 
    public Card getCard(){ 
     Random rand = new Random(); 
     int index = rand.nextInt(deck.size()); 

     Card toDeal = new Card (deck.get(index).getName(), 
           deck.get(index).getSuit(), 
           deck.get(index).getValue()); 

     deck.remove(index); 

     return toDeal; 
    } 
} 

그리고 (불완전) 인간 클래스 :

public class Human { 
    private int handValue; 
    private String name; 
    private ArrayList<Card> hand; 

    public Human(String name){ 
     this.handValue = 0; 
     this.name = name; 
     this.hand = null; 
    } 

    public void setName(String name){ 
     this.name = name; 
    } 

    public String getName(){ 
     return name; 
    } 

    public int getHandValue(ArrayList<Card> hand){ 

     for (Card card: hand){ 
      handValue += card.getValue(); 
     } 

     return handValue; 
    } 

    public void hit(){ 
     hand.add(Deck().getCard()); 
    } 


} 

그리고 마지막으로, 카드 클래스의 생성자 :

public Card(String name, String suit, int value){ 
     this.name = name; 
     this.suit = suit; 
     this.value = value; 
    } 
+1

것은 ('hand.add 시도 (새로운 Deck()) .getCard());'- Deck'의 anon 인스턴스를 만들고 그것의'getCard()'메소드를 호출하십시오. 아니면,'hit()'메소드를'public void hit (갑판 데크) { hand.add (deck.getCard());로 변경할 수 있습니다. }' – ochi

+1

덱에 대한 참조를 Human 객체로 전달할 수 없습니까? – clearlyspam23

+0

상당한 재 작업이 필요하지만 어떤 플레이어가 어떤 카드를 가지고 있는지 추적 할 수 있습니다 (플레이어가 카드를 가지고있는 목록을 쉽게 보관할 수 있지만 데크에 다시 참조 할 필요는 없습니다). 장기적으로 더 쉬워 질 수 있을까요? –

답변

3

아직 데크의 인스턴스를 생성하지 않는.

new Deck()으로 어딘가에 갑판 인스턴스를 만듭니다. 클래스 Game 만들기

  • , 그것은 하나의 Deck를 작성하고 Human 인스턴스에 대한 참조를 전달합니다

    그런 다음을 통해이 하나 개의 데크에 대한 참조를 공유 할 수 있습니다.

  • Deck을 싱글 톤 클래스로 지정하십시오. [주의 : 싱글 톤은 자주 눈살을 찌푸리게됩니다. 나중에 동일한 응용 프로그램에서 여러 개의 데크를 조작하고 싶다면 어떻게해야합니까?]

예를 들어, 다음은 HumanDeck 참조 전달할 수있는 방법은 다음과 같습니다

class Human { 
      ... 
      private Deck deck; 

      public Human(String name, Deck deck) { 
       ... 
       this.deck = deck; 
      } 

을 그리고 여기 당신이 hit()을 구현하는 것이 방법은 다음과 같습니다

  public void hit(){ 
       hand.add(deck.getCard()); 
      } 
+0

감사합니다. Andy. 이것은 가장 합리적인 것 같습니다. 코드를 살펴보면 모든 인간에게는 자체 데크가있는 것처럼 보이지만 인간에게 호출 할 때마다 새로 생성되는 것이 아니라 전달되는 한 중요하지 않습니다. 내 머리를 감싸는 것은 조금 어렵지만, 모든 인간은 자신의 덱 사본을 가지게 될 것입니다. 그러나 실생활에서 블랙 잭을 할 때는 그렇지 않습니다. 한 가지 대안은 위의 @blurfus에서 제안한 적중 방법이 호출 될 때만 데크를 전달하는 것입니다. – mks212

+1

@ user2926358 - 위의 코드로, 모든 인간은 자신의 갑판 복사본을 가지고 있지 않습니다. 대신, 모든 인간은 데크 인스턴스에 * 참조 *를 가지고 있습니다. 모든 인간에게 동일하고 단일의 공유 덱 인스턴스에 대한 참조를 제공 할 수 있습니다. Java의 모든 오브젝트 변수는 오브젝트 자체가 아니라 참조입니다. –

+1

이 경우 실제 생활과 매우 유사합니다. 모두가 끄는 탁자 위에 한 개의 갑판이 있습니다. – mks212

3

귀하의 문제가 있다는 점에서, 참조 중 하나입니다 Human에 실제 사용중인 Deck를 나타내는 Deck 필드가 있는지 확인한 다음 hit() 메서드에서 Deck 인스턴스의 getCard() 메서드를 호출해야합니다. Human의 생성자 또는 setDeck(Deck deck) setter 메서드에서 실제 참조에 유효한 참조를 전달할 수 있습니다.


예외적으로, 카드 놀이는 열거 형을 사용하는 고전적인 유스 케이스로 자주 사용됩니다. 예를 들어 :

enum Rank { 
    ACE("Ace", 1, 11), TWO("Two", 2, 2), THREE("Three", 3, 3), 
    FOUR("Four", 4, 4), FIVE("Five", 5, 5), SIX("Six", 6, 6), 
    SEVEN("Seven", 7, 7), EIGHT("Eight", 8, 8), NINE("Nine", 9, 9), 
    TEN("Ten", 10, 10), JACK("Jack", 10, 10), QUEEN("Queen", 10, 10), 
    KING("King", 10, 10); 

    private int value1; 
    private int value2; 
    private String name; 

    private Rank(String name, int value1, int value2) { 
     this.value1 = value1; 
     this.value2 = value2; 
     this.name = name; 
    } 

    public int getValue1() { 
     return value1; 
    } 

    public int getValue2() { 
     return value2; 
    } 

    public String getName() { 
     return name; 
    } 

} 

enum Suit { 
    CLUBS, DIAMONDS, HEARTS, SPADES 
} 

class Card { 
    private Rank rank; 
    private Suit suit; 

    public Card(Rank rank, Suit suit) { 
     this.rank = rank; 
     this.suit = suit; 
    } 

    public Rank getRank() { 
     return rank; 
    } 

    public Suit getSuit() { 
     return suit; 
    } 

} 

class Deck { 
    List<Card> cards = new ArrayList<>(); 

    public Deck() { 
     for (Suit suit : Suit.values()) { 
     for (Rank rank : Rank.values()) { 
      cards.add(new Card(rank, suit)); 
     } 
     } 
     Collections.shuffle(cards); // shuffle them 
    } 

    // other methods including deal here 
} 
+0

예, 카드에 대해 본 적이 있습니다. 나는 enum에 대한 경험이 없지만 게임을 마친 후에 그것을 할 계획이다. 그러나 코드가 얼마나 짧았는지 살펴보면 지금은 매우 유혹적입니다. – mks212

관련 문제