Simulasi lempar dadu di Java
Untuk salah satu lab saya, saya perlu menulis program java lengkap yang akan mensimulasikan permainan taruhan dadu "sangat sederhana". Spesifikasinya adalah sebagai berikut: mensimulasikan lemparan 3 dadu. Jika Anda melempar tiga angka enam maka Anda menang$20; if you throw three of any other value then you win $10; jika Anda melempar dua dadu yang nilainya sama maka Anda menang$5. If none of the conditions above are met, then you would lose $1.
Contoh Berjalan: Lempar Dadu
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
Kode yang dihasilkan yang saya tulis untuk mengatasi masalah ini adalah sebagai berikut:
/**
* 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++;
}
}
}
Masalah yang saya hadapi dengan pendekatan ini adalah bahwa meskipun kode berfungsi sebagaimana mestinya, saya ingin memiliki cara yang lebih sederhana untuk menulis two-of-a-kind daripada memiliki tiga pernyataan "jika". Tujuan saya dalam hal ini, adalah untuk membuat pernyataan tiga arah "atau" daripada membandingkan dadu1 dengan dadu 2 dan 3, dan dadu 2 dengan dadu 1 dan 3, dll ...
else if (dice1 == dice2 || dice1 == dice3 || dice2 == dice3) {
System.out.println("Congratulations : You threw TWO - " + somethings?? + "s");
System.out.println("You win $5");
Jika saya melakukan itu, bagaimana saya bisa mencetak nilai pasangan yang telah saya identifikasi?
Jawaban
Selamat datang di CodeReview. Mengenai masalah Anda, solusi cepatnya adalah:
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");
}
Operator terner membuat kodenya lebih kompak, tetapi dalam kasus ini saya pikir itu sedikit kurang dapat dibaca daripada rantai if-else.
Beberapa saran lain:
- While-loop dapat diganti dengan loop-for yang lebih nyaman. Dari:
Untuk:int round = 1; while(round<=3){ //... round++; }for(int round = 1; round <= 3; round++) { //... } - Mendeklarasikan beberapa variabel dalam satu baris
int dice1, dice2, dice3;tidak dianggap sebagai praktik yang baik di Java. - Alih-alih membuat acak
floatdan kemudian mentransmisikannya keint, buat langsungintdenganThreadLocalRandom.current().nextInt(6). Docs . - Anda dapat mencetak baris pertama dengan
System.out.format. Dari:
Untuk: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) - Nama kelas harus PascalCase . Daripada
Lab6_part3Anda bisa menamainyaLab6Part3. - Nyatakan konstanta untuk jumlah putaran, agar lebih mudah mengubahnya. Sebagai contoh:
public class Lab6Part3 { private static final int ROUNDS = 3; public static void main(String[] args) { for(int round = 1; round <= ROUNDS; round++) { //... } }
Pendekatan lain adalah menghasilkan tiga angka dengan Random#intsdan menghitung frekuensi:
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
}
Anda tidak perlu memiliki 3 pernyataan else_if. Ada 3 skenario di mana Anda berada dalam kasus "dua bentuk". dadu1 == dadu2, dadu1 == dadu3, dadu2 == dadu3. Blok if pertama Anda menangkap 2 dari skenario ini. Satu-satunya pilihan lain adalah jika dadu2 == dadu3.
Jika Anda memikirkannya, blok else_If Anda yang ketiga akan selalu membuat evaluasi yang benar di salah satu dari dua blok pertama, jadi kode Anda tidak akan pernah mencapainya.
// 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) {
Tolong jangan lakukan ini. Jika Anda ingin menggunakan setengah berpelukan else, harap tulis selalu pada dua baris yang berurutan.
}
else if (dice1 == dice2 || dice1 == dice3) {
// Two of a kind (PRINT "dice1")
Ada dua alasan.
- Jika saya ingin mengetahui bahwa strukturnya sudah selesai, dengan cara ini saya dapat melihat hanya dengan melihat satu baris melewati
}. Dengan dokumen asli Anda, saya harus melihat sejumlah baris yang berubah-ubah ke pernyataan berikutnya. Ini menjadi sangat buruk karena blok komentar semakin lama. Sangat mungkin untuk menulis komentar yang lebih tinggi dari satu layar. Artinya, alih-alih hanya menggulir sedikit lebih jauh, saya perlu membuka halaman melewati komentar untuk melihat bahwa adaelseblok. - Jika seseorang menggunakan sesuatu yang memformat ulang kode untuk ditempatkan
elsedi baris yang sama dengan}, komentar tersebut tetap harus dipindahkan. Kemudian meskipun mereka memformatnya kembali, komentar tersebut akan dipindahkan. Hal ini menyebabkan kebingungan dalam kendali sumber. Jadi katakan saja seperti yang akan dilakukan oleh pemformat ulang sejak awal.
Bahasa C-style pada umumnya memiliki penanganan blok yang membingungkan. Karena mereka menggunakan }keduanya untuk mengakhiri struktur dan hanya untuk mengakhiri blok dalam struktur berkelanjutan. Yaitu mereka tidak memiliki cara untuk mengatakan bahwa ifstruktur berakhir versus melanjutkan dengan elsesemacam itu. Untuk mengimbanginya, kita harus menggunakan konvensi pengkodean. Dan salah satu konvensi paling sederhana, yang melampaui gaya, adalah jangan pernah meletakkan kurung kurawal ( }atau {) lebih dari satu baris dari kata kunci terkait jika ada.