2010-10-05 21 views
2

我想知道是否有人知道如何在java中實現代碼來打印滿屋子的所有情況。大約有3700種不同的情況。到目前爲止,我在2700左右,但我無法改變西裝,她是我迄今爲止。如何在Java中打印所有可能的「滿屋」?

public class FullHouseTest 
{// 
static int count = 1; 
static int [] cards ={1,2,3,4,5,6,7,8,9,10,11,12,13}; 
static int[] suit ={1,2,3,4}; 
static int[] suit2 ={2,3,4,1}; 
static int[] suit3 ={3,4,1,2}; 
public static void main(String[] args) 
{ 
    for(int k = 0; k< 12; k++) 
    { 
    for(int i = 0; i < 3; i++) 
    { 
    for (int t = 0; t <3; t++) 
    { 
    Card one = new Card(new Suit(suit[t]), new Pips(cards[k])); 
    Card two = new Card(new Suit(suit2[t]), new Pips(cards[k])); 
    Card three = new Card(new Suit(suit3[t]),new Pips(cards[k])); 

    for (int j =0; j < 12; j++) 
     { 
     Card four = new Card(new Suit(suit2[i]), new Pips(cards[j+1])); 
     Card five = new Card(new Suit(suit[i]), new Pips(cards[j+1])); 
     System.out.println("Hand:" + count + " | " + one + two + three + four + five); 
     count ++; 
     } 
    } 
    } 
    } 
    for(int i = 0; i < 3; i++) 
    { 
    for(int k = 0; k< 12; k++) 
    { 
    for(int s = 0; s<3; s++) 
    { 
     Card one = new Card(new Suit(suit[i]), new Pips(cards[k])); 
     Card two = new Card(new Suit(suit2[i]), new Pips(cards[k])); 
    for (int j =0; j < 12; j++) 
    { 

     Card three = new Card(new Suit(suit3[s]),new Pips(cards[j+1])); 
     Card four = new Card(new Suit(suit2[s]), new Pips(cards[j+1])); 
     Card five = new Card(new Suit(suit[s]), new Pips(cards[j+1])); 
     System.out.println("Hand:" + count + " | " + one + two + three + four + five); 
     count ++; 


    } 
    } 
    } 
    } 

} 
} 
+0

嗯,你說的Java浪漫滿屋...該代碼是難讀,請重新格式化,所以我們可以更容易地閱讀它 – 2010-10-05 23:28:02

+1

編輯標題爲java。如果你的意思是在JavaScript中做到這一點,那麼你必須從頭開始。 :D – 2010-10-05 23:30:56

+0

是的,請縮進多個空間。 – 2010-10-05 23:55:42

回答

2

在您繼續之前添加一些註釋到您的代碼。它可以幫助你理解發生了什麼,尤其是當你使用單個字符變量名稱嵌套4個循環時。

接下來,解決問題:完整的房子真正獨特的是什麼?這兩個點都是唯一的,但不能相同。這種3種套裝有3種不同的套裝(或者只是缺少一種套裝),而套裝有2種不同的套裝。

total_pips * (total_pips-1) * number_suits * (possible combinations of 2 suits) = 3744 
    13   12    4       6 

想想你可能從這個列表中錯過了什麼。如果您有任何具體的問題,只需編輯答案,我們會馬上得到它:)

1

在主要方法中太多的代碼。你需要在這裏更好地使用方法。

創建一個名爲isFullHouse(Card[] card)的方法,該方法接收5張卡片的陣列(或ArrayList),並將爲您確定手是否滿屋。

那麼你如何選擇創建所有可能的手的組合取決於你。每次你得到一隻新手時,請調用這個方法。它會爲你簡化一些事情。所有內容都很難閱讀。

至於如何存儲你的撲克牌。而不是所有這些數組,存儲一個0-51。您可以在陣列上使用除法和修飾運算符來確定您擁有的卡。該幻數是13。

i.e. The 47 card in the deck could be: 47/13=3 ; 47 % 13 = 8 

如果提前確定時間0 =心,1 =鑽石,2 =俱樂部和3 =黑桃,則可以確定這卡是9 of spades(8 + 1由於沒有值爲0的卡因此添加一個)

將所有這些想法存儲在自己的方法中,並且可以大大簡化您的循環。

+1

假設我的數學是正確的,有P(52,5)= 311,875,200可能的5張牌手。您的算法可能需要一段時間才能運行。 – 2010-10-06 01:25:29

+0

大多數情況下,除非算法被修剪爲省略套房,因爲他們對滿屋沒有任何限制。由於知道在任何給定時間你手中的任何值都不超過4(A-K),因此可以減少如何查看每個可能的手的算法。您還可以進一步修剪,通過對每套套房中的每套13套卡片進行4套套房的每個排列組合,形成一種三種套餐,並且兩套套餐的套餐也是相同的。 OP如何實現這一點取決於他。漫不經心。我的主要觀點是清理代碼以幫助它變得更具可讀性。 – Sean 2010-10-06 01:50:23

+0

2,598,960個可能的手。 (52!/(5!* 47!)),311磨似乎有點高。儘管如此,還是要看很多。 – Sean 2010-10-06 03:20:33

0

快速而骯髒。有很大的改進空間,但如果我的數學是正確的,這應該會給你所有的有效的整個房子的手組合。

公共類PrintFullHouse {

enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES} 
enum Rank {Ace, One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King} 

public static void main(String[] args) { 

    String[] ranks = new String[14]; 
    String[] suits = new String[4]; 

    populateSuits(suits); 
    populateCards(ranks); 

    int numberOfCombos = 0; 

    //Loop over all card values. This outer for loop is for the 3 of kind values. 3 Aces, 3 Twos, 3 Threes, etc 
    for(int card = 0; card < ranks.length; card++) 
    { 
     String firstCard = ranks[card]; 

     for(int suit1 = 0; suit1 < suits.length; suit1++) 
     { 
      for(int suit2 = suit1+1; suit2 < suits.length; suit2++) 
      { 
       for(int suit3 = suit2+1; suit3 < suits.length; suit3++) 
       { 
        //Loop over all card values that aren't equal to the firstCard.So we won't have 3 Aces and 2 Aces 
        for(int card2 = 0; card2 < ranks.length; card2++) 
        { 
         String secondCard = ranks[card2]; 

         //Dont Compare the 3 of a Kind and 2 pair when they are the same rank. ie Aces and Aces 
         if(firstCard.compareTo(secondCard) != 0){ 
          for(int othersuit1 = 0; othersuit1 < suits.length; othersuit1++) 
          { 
           for(int othersuit2 = othersuit1+1; othersuit2 < suits.length; othersuit2++) 
           { 
            //Found a valid combo if 3 of a kind have different suits, 2 pair have different suits, and card1 is not equal to card2 
            numberOfCombos++; 
            System.out.println(numberOfCombos+". "+firstCard+" "+suits[suit1]+" "+firstCard+" "+suits[suit2]+" "+firstCard+" "+suits[suit3]+ " " 
                 +secondCard+" "+suits[othersuit1]+" "+secondCard+" "+suits[othersuit2]); 
           } 
          } 
         } 
        }    
       } 
      } 
     } 
    } 
} 

private static void populateSuits(String[] suits) { 

    int index = 0; 
    for(Suit suit: Suit.values()) 
    { 
     suits[index++] = suit.toString(); 
    } 
} 

private static void populateCards(String[] ranks) { 

    int index = 0; 
    for(Rank rank: Rank.values()) 
    { 
     if(index != ranks.length) 
     ranks[index++] = rank.toString(); 
    } 
} 

}

1

我看到這個問題的一天(同時出病)。從那以後,我一直在爭論這個問題。一方面,它似乎是功課。 (這是一個簡單的問題,你的代碼很難理解,表明缺乏經驗。)

另一方面,我不介意幫忙。我不會做你的工作給你,但我可以爲你指明正確的方向...


第一步:定義問題。一旦明確定義,答案變得更直接。

A 「滿屋」,大概是5張卡片組成的三對一加一對。大概這是一個單一的遊戲。據推測,這是一套標準套牌(Ace,2,3,4,5,6,7,8,9,Jack,Queen,King)與西裝(黑桃,俱樂部,紅心,鑽石)。 (以下簡稱爲(A23456789JQK)和(SCHD)。)

你提到的3700個的組合。因此可以推測,你認爲手(2S,2C,2H,3H,3D)和(3D,3H,2H,2C,2S)是等同的而非獨特的。 (這實際上是一個非常重要的點,正如Sean & Loadmaster在他們的評論中提到的那樣,有311,875,200(52 * 51 * 50 * 49 * 48)可能的5張圖紙,但這些手中只有2,598,960不同!)

我們有(13 * 4)個可能的三對的一種。例如。對於每張排名卡片(例如3張),我們可以有4種3種({0S,3C,3H,3D},{3S,0C,3H,3D},{3S,3C,0H,3D },{3S,3C,3H,0D})。 (也許你開始注意到一種模式:0111 1011 1101 1110.)

給我們三個一樣的,假設它是一個單一的甲板和標準甲板遊戲,我們的配對必須是其餘12個剩餘的其中一個卡排名。對於每張卡片排名,一對卡片有六種可能性。例如。給定一個等級爲7的牌,我們可以有{7S,7C,0H,0D},{7S,0C,7H,0D},{7S,0C,0H,7D},{0S,7C,7H,0D} ,{0S,7C,0H,7D},{0S,0C,7H,7D})。 (同樣,也許您注意到圖案:1100 1010 1001 0110 0101 0011)

這給我們13 * 4 * 12 * 6 = 3744的組合。

從這裏是循環到打印出來的一件簡單的事情。

我建議你考慮更多的描述性變量名稱。雖然有地方和時間使用單字符循環變量,但這不是其中之一。編寫良好的代碼幾乎可以自我記錄,從而使文檔能夠專注於更復雜的更高級別的抽象。您節省的額外字符將在調試時耗費您的財富。如果需要,你可以像我一樣懶,學習emacs,使用(需要完成),(全局設置鍵「\ C - \\」'complete),鍵入前幾個字符並讓emacs爲你自動完成。

我建議你考慮支持,也許私人的方法。例如,您可能能夠這樣做:(它已經有一段時間,因爲我最後一次用Java編碼)

for (suit = 0; suit < 4 ; ++ suit) 
    private_printThreeOfAKind(card, suit!=0, suit!=1, suit!=2, suit!=3) 

那些三(!=)將是真實的,一個是假的。

關於打印對,您可能需要調查繼續聲明。參考文獻:http://en.wikipedia.org/wiki/Java_syntax#continue_statement

例如這將使你的情況下跳過其中一對卡相同等級爲三的一類:

if (threeOfAKindCard == pairCard) 
    continue; 

我建議你建立你的部分軟件。即使對專家來說,試圖建立一個完整的系統也很少有效。構建零件,測試它們,沖洗並重復。是的,這意味着寫腳手架代碼,你不會打開它。也許甚至是測試子類...但小步驟更容易工作。當你改善作爲一個程序員,你就可以採取更大的措施......

+0

感謝所有的幫助,我很早就想到了。問題是我很匆忙,避免把問題解決。我想通過打印所有的對來得到更好的理解。再次感謝您的幫助,時間和想到這個問題,並抱歉我的草率代碼。 – Tony 2010-10-11 21:14:56