การจำลองการโยนลูกเต๋าใน Java
สำหรับหนึ่งในห้องทดลองของฉันฉันต้องเขียนโปรแกรม java ที่สมบูรณ์ซึ่งจะจำลองเกมเดิมพันลูกเต๋าที่ "ง่ายมาก" ข้อกำหนดมีดังนี้: จำลองการโยนลูกเต๋า 3 ลูก ถ้าคุณโยนสามหกคุณจะชนะ$20; if you throw three of any other value then you win $10; หากคุณทอยลูกเต๋าสองลูกซึ่งมีค่าเท่ากันคุณจะชนะ$5. If none of the conditions above are met, then you would lose $1.
ตัวอย่างการวิ่ง: ลูกเต๋าโยน
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
รหัสผลลัพธ์ที่ฉันเขียนเพื่อแก้ปัญหานี้มีดังนี้:
/**
* 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++;
}
}
}
ปัญหาที่ฉันพบกับแนวทางนี้คือแม้ว่าโค้ดจะทำงานตามที่ควรจะเป็น แต่ฉันก็อยากมีวิธีที่ง่ายกว่าในการเขียน two-of-a-kind แทนที่จะมีคำสั่ง "if" สามคำ เป้าหมายของฉันคือการสร้างคำสั่ง "หรือ" สามทางแทนที่จะเปรียบเทียบ dice1 กับลูกเต๋า 2 และ 3 และลูกเต๋า 2 กับลูกเต๋า 1 และ 3 ฯลฯ ...
else if (dice1 == dice2 || dice1 == dice3 || dice2 == dice3) {
System.out.println("Congratulations : You threw TWO - " + somethings?? + "s");
System.out.println("You win $5");
ถ้าฉันจะทำเช่นนั้นฉันจะพิมพ์ค่าของคู่ที่ฉันระบุได้อย่างไร?
คำตอบ
ยินดีต้อนรับสู่ CodeReview สำหรับปัญหาของคุณวิธีแก้ไขอย่างรวดเร็วคือ:
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");
}
ตัวดำเนินการ ternary ทำให้โค้ดมีขนาดกะทัดรัดขึ้น แต่ในกรณีนี้ฉันคิดว่ามันอ่านได้น้อยกว่า chain ของif-else.
คำแนะนำอื่น ๆ :
- while-loop สามารถแทนที่ได้ด้วย for-loop ที่สะดวกกว่า จาก:
ถึง:int round = 1; while(round<=3){ //... round++; }for(int round = 1; round <= 3; round++) { //... } - การประกาศตัวแปรหลายตัวในบรรทัดเดียว
int dice1, dice2, dice3;ไม่ถือเป็นแนวทางปฏิบัติที่ดีใน Java - แทนที่จะสร้างแบบสุ่ม
floatแล้วส่งไปยังintสร้างโดยตรงintด้วยThreadLocalRandom.current().nextInt(6). เอกสาร - คุณสามารถพิมพ์บรรทัดแรกด้วย
System.out.formatไฟล์. จาก:
ถึง: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) - ชื่อชั้นควรจะ PascalCase แทนที่จะคุณสามารถตั้งชื่อมัน
Lab6_part3Lab6Part3 - ประกาศค่าคงที่สำหรับจำนวนรอบเพื่อให้ง่ายต่อการเปลี่ยนแปลง ตัวอย่างเช่น:
public class Lab6Part3 { private static final int ROUNDS = 3; public static void main(String[] args) { for(int round = 1; round <= ROUNDS; round++) { //... } }
อีกวิธีหนึ่งคือการสร้างตัวเลขสามตัวRandom#intsและคำนวณความถี่:
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 งบ มี 3 สถานการณ์ที่คุณอยู่ในกรณี "two-fo-a-kind" dice1 == dice2, dice1 == dice3, dice2 == dice3 บล็อกแรกของคุณจับ 2 สถานการณ์เหล่านี้ได้ ทางเลือกเดียวคือถ้า dice2 == dice3
หากคุณคิดเช่นนั้นบล็อก else_If ที่สามของคุณจะสร้างการประเมินที่แท้จริงในหนึ่งในสองบล็อกแรกเสมอดังนั้นโค้ดของคุณจะไม่มีวันไปถึง
// 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) {
กรุณาอย่าทำเช่นนี้ หากคุณต้องการใช้ลูกครึ่งelseโปรดเขียนสองบรรทัดติดกันเสมอ
}
else if (dice1 == dice2 || dice1 == dice3) {
// Two of a kind (PRINT "dice1")
มีสองเหตุผล
- หากฉันต้องการทราบว่าโครงสร้างเสร็จสิ้นแล้ววิธีนี้ฉันสามารถดูได้โดยมองไปที่บรรทัดเดียวผ่าน
}. ด้วยต้นฉบับของคุณฉันจะต้องดูจำนวนบรรทัดโดยพลการในคำสั่งถัดไป สิ่งนี้จะไม่ดีเป็นพิเศษเมื่อบล็อกความคิดเห็นยาวขึ้น เป็นไปได้ทั้งหมดที่จะเขียนความคิดเห็นที่สูงกว่าหน้าจอเดียว หมายความว่าแทนที่จะเลื่อนไปไกลกว่านั้นฉันจะต้องเลื่อนหน้าลงมาจากความคิดเห็นเพื่อดูว่ามีelseบล็อกอยู่ - หากมีคนใช้สิ่งที่ฟอร์แมตโค้ดใหม่เพื่อให้
elseอยู่ในบรรทัดเดียวกับโค้ด}ก็จะต้องย้ายความคิดเห็นอยู่ดี จากนั้นแม้ว่าจะจัดรูปแบบกลับความคิดเห็นก็จะย้ายไป สิ่งนี้ทำให้เกิดความสับสนในการควบคุมแหล่งที่มา ดังนั้นให้วางวิธีที่นักปฏิรูปจะต้องทำตั้งแต่ต้น
ภาษารูปแบบ C โดยทั่วไปมีการจัดการบล็อกที่สับสน เนื่องจากใช้}ทั้งสองอย่างเพื่อสิ้นสุดโครงสร้างและเพียงเพื่อจบบล็อกในโครงสร้างต่อเนื่อง กล่าวคือพวกเขาไม่มีทางที่จะพูดได้ว่าifโครงสร้างกำลังจะสิ้นสุดเมื่อเทียบกับการดำเนินการต่อด้วยการelseเรียงลำดับ ในการชดเชยเราต้องใช้รูปแบบการเข้ารหัส และหนึ่งในรูปแบบที่ง่ายที่สุดซึ่งอยู่เหนือสไตล์คือห้ามใส่ปีกกา ( }หรือ{) มากกว่าหนึ่งบรรทัดห่างจากคีย์เวิร์ดที่เกี่ยวข้องหากมี