Java'da zar atma simülasyonu

Oct 30 2020

Laboratuvarlarımdan biri için "çok basit" bir zar bahis oyununu simüle edecek eksiksiz bir java programı yazmam gerekiyor. Spesifikasyonlar aşağıdaki gibidir: 3 zar atma simülasyonu. Üç altı atarsan kazanırsın$20; if you throw three of any other value then you win $10; aynı değerde iki zar atarsan kazanırsın$5. If none of the conditions above are met, then you would lose $1.

Örnek Çalıştırmalar: Zar Atma

Dice 1 : 2     Dice 2 : 1    Dice 3 : 2
Congratulations : You threw TWO - 2s
You win $5 Dice 1 : 2 Dice 2 : 2 Dice 3 : 2 Congratulations : You threw THREE - 2s You win $10

Dice 1 : 4    Dice 2 : 6    Dice 3 : 3
Unfortunately : You did not throw anything of value
You lose $1

Bu sorunu çözmek için yazdığım ortaya çıkan kod şu şekilde:

/**
 * SRN: 507-147-9
 */
public class Lab6_part3 {

    public static void main(String[] args) {

        // define vars
        int round = 1;
        int dice1, dice2, dice3;

        while (round <= 3) {

            dice1 = 1 + (int)(Math.random() * 6);
            dice2 = 1 + (int)(Math.random() * 6);
            dice3 = 1 + (int)(Math.random() * 6);

            System.out.println();
            System.out.println("Dice 1 : " + dice1 + "    Dice 2 : " + dice2 + "    Dice 3 : " + dice3);

            // Three of a kind
            if ((dice1 == dice2) && (dice1 == dice3)) { // 3-of-a-kind (D1)                              

                // Rolls three sixes
                if (dice1 == 6) {
                    System.out.println("Congratulations : You threw THREE - 6s");
                    System.out.println("You win $20");
                } else {
                    // Rolls three of anything else
                    System.out.println("Congratulations : You threw THREE - " + dice1 + "s");
                    System.out.println("You win $10"); } } // Two of a kind (PRINT "dice1") else if (dice1 == dice2 || dice1 == dice3) { System.out.println("Congratulations : You threw TWO - " + dice1 + "s"); System.out.println("You win $5");
            } 
            
            // Two of a kind (PRINT "dice2")
            else if (dice2 == dice1 || dice2 == dice3) {                              
                System.out.println("Congratulations : You threw TWO - " + dice2 + "s");
                System.out.println("You win $5"); } // Two of a kind (PRINT "dice3") else if (dice3 == dice1 || dice3 == dice2) { System.out.println("Congratulations : You threw TWO - " + dice3 + "s"); System.out.println("You win $5");
            } 
            // Did not throw anything of value
            else {
                System.out.println("Unfortunately : You did not throw anything of value");
                System.out.println("You lose $1");
            }
            round++;
        }
    }
}

Bu yaklaşımla karşılaştığım sorun şu ki, kod olması gerektiği gibi çalışsa da, üç "eğer" ifadesi kullanmak yerine türünün ikisini yazmak için daha basit bir yol kullanmak istiyorum. Buradaki amacım, zar 1'i 2 ve 3 numaralı zarlarla ve 2 numaralı zarları 1 ve 3 numaralı zarlarla vb. Karşılaştırmak yerine üç yönlü "veya" bir ifade oluşturmaktır.

else if (dice1 == dice2 || dice1 == dice3 || dice2 == dice3) {                              
    System.out.println("Congratulations : You threw TWO - " + somethings?? + "s");
    System.out.println("You win $5"); 

Bunu yapacak olsaydım, belirlediğim çiftin değerini nasıl yazdırabilirdim?

Yanıtlar

7 Marc Oct 30 2020 at 14:37

CodeReview'a hoş geldiniz. Sorununuzla ilgili olarak hızlı bir çözüm:

else if (dice1 == dice2 || dice1 == dice3 || dice2 == dice3) {       
    int doubleNum = dice1 == dice2 ? dice1 : dice1 == dice3 ? dice1 : dice3;
    System.out.println("Congratulations : You threw TWO - " + doubleNum + "s");
    System.out.println("You win $5"); 
}

Üçlü operatör, kodu daha kompakt hale getirir, ancak bu durumda, bir zincirden biraz daha az okunabilir olduğunu düşünüyorum if-else.

Birkaç başka öneri:

  • While döngüsü, daha uygun bir döngü ile değiştirilebilir. Kimden:
    int round = 1;
    while(round<=3){
        //...
        round++;
    }
    
    Kime:
    for(int round = 1; round <= 3; round++) {
        //...
    }
    
  • Birden çok değişkeni tek satırda bildirmek Java'da iyi bir uygulamaint dice1, dice2, dice3; olarak görülmez .
  • Bir rastgele oluşturmak floatve sonra onu bir'e dönüştürmek yerine, intdoğrudan bir intile oluşturun ThreadLocalRandom.current().nextInt(6). Dokümanlar .
  • İlk satırı ile yazdırabilirsiniz System.out.format. Kimden:
    System.out.println();
    System.out.println("Dice 1 : " + dice1 + "    Dice 2 : " + dice2 + "    Dice 3 : " + dice3);
    
    Kime:
    System.out.format("%nDice 1 :  %d    Dice 2 : %d    Dice 3 : %n", dice1, dice2, dice3)
    
  • Sınıf isimleri PascalCase olmalıdır . Yerine Lab6_part3adını verebilirsin Lab6Part3.
  • Değiştirmeyi kolaylaştırmak için tur sayısı için bir sabit beyan edin. Örneğin:
    public class Lab6Part3 {
    
        private static final int ROUNDS = 3;
    
        public static void main(String[] args) {
            for(int round = 1; round <= ROUNDS; round++) {
                //...
            }
    }
    

Diğer bir yaklaşım, Random#intsfrekanslarla üç sayı üretmek ve bunları hesaplamaktır:

Random r = new Random();
// Generate three random numbers from 1 to 6
IntStream diceRolls = r.ints(3, 1, 7);

// Generate map of frequencies
Map<Integer, Long> freq = diceRolls.boxed()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

boolean winner = false;
for (Entry<Integer, Long> entry : freq.entrySet()) {
    int number = entry.getKey();
    long times = entry.getValue();
    if (times == 3) {
        // Three of a kind ...
        winner = true;
    } else if (times == 2) {
        // Two of a kind...
        System.out.println("Congratulations : You threw TWO - " + number + "s");
        System.out.println("You win $5");
        winner = true;
    }
}
if(!winner) {
    // Did not throw anything of value
}
2 SavvasParastatidis Oct 30 2020 at 21:40

3 else_if ifadesine sahip olmanız gerekmez. "Bir tür iki" durumda olduğunuz 3 senaryo vardır. dice1 == zar2, zar1 == zar3, zar2 == zar3. İlk if bloğunuz bu senaryolardan 2'sini yakalar. Diğer tek seçenek ise dice2 == dice3'tür.

Bunu düşünürseniz, üçüncü else_If bloğunuz her zaman ilk iki bloktan birinde gerçek bir değerlendirme oluşturur, böylece kodunuz ona asla ulaşmaz.

// Two of a kind (PRINT "dice1")
else if (dice1 == dice2 || dice1 == dice3) {
    System.out.println("Congratulations : You threw TWO - " + dice1 + "s");
    System.out.println("You win $5"); } // Two of a kind (PRINT "dice2") else if (dice2 == dice3) { System.out.println("Congratulations : You threw TWO - " + dice2 + "s"); System.out.println("You win $5");
}
2 mdfst13 Oct 31 2020 at 18:20
        }
        
        // Two of a kind (PRINT "dice1")
        else if (dice1 == dice2 || dice1 == dice3) {

Lütfen bunu yapmayın. Yarı sarılmış olanı kullanmak istiyorsanız else, lütfen her zaman iki ardışık satıra yazın.

        }
        else if (dice1 == dice2 || dice1 == dice3) {
          // Two of a kind (PRINT "dice1")

Bunun iki sebebi var.

  1. Yapının bittiğini bilmek istersem, bu şekilde }. Orijinalinizle, bir sonraki ifadeye rastgele sayıda satıra bakmam gerekir. Bu, özellikle yorum blokları uzadıkça kötüleşir. Tek bir ekrandan daha uzun bir yorum yazmak tamamen mümkün. Yani, sadece biraz daha ileriye kaydırmak yerine, bir elseblok olduğunu görmek için yorumun ötesine geçmem gerekecek .
  2. Birisi kodu ile elseaynı satıra koymak için yeniden biçimlendiren bir şey kullanırsa }, yine de yorumu taşımak zorunda kalacaktır. Sonra yeniden biçimlendirseler bile, yorum hareket edecektir. Bu, kaynak kontrolünde karışıklığa neden olur. Öyleyse, onu yeniden biçimlendiricinin başından itibaren yapacağı şekilde koyun.

Genel olarak C tarzı diller kafa karıştırıcı blok işlemeye sahiptir. Çünkü }hem yapıyı sonlandırmak hem de devam eden bir yapıda bloğu sonlandırmak için kullanırlar. Yani ifyapının sona erdiğini ve bir şekilde devam ettiğini söylemelerinin hiçbir yolu yok else. Telafi etmek için kodlama kuralları kullanmalıyız. Ve stili aşan en basit kurallardan biri, varsa ilişkili anahtar kelimeden asla bir küme ayracı ( }veya {) birden fazla satır uzağa koymamaktır.