Java'da zar atma simülasyonu
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
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:
Kime:int round = 1; while(round<=3){ //... round++; }for(int round = 1; round <= 3; round++) { //... } - Birden çok değişkeni tek satırda bildirmek Java'da iyi bir uygulama
int dice1, dice2, dice3;olarak görülmez . - Bir rastgele oluşturmak
floatve sonra onu bir'e dönüştürmek yerine,intdoğrudan birintile oluşturunThreadLocalRandom.current().nextInt(6). Dokümanlar . - İlk satırı ile yazdırabilirsiniz
System.out.format. Kimden:
Kime:System.out.println(); System.out.println("Dice 1 : " + dice1 + " Dice 2 : " + dice2 + " Dice 3 : " + dice3);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ı verebilirsinLab6Part3. - 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
}
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");
}
} // 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.
- 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, birelseblok olduğunu görmek için yorumun ötesine geçmem gerekecek . - 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.