ต้นแบบแบล็คแจ็ค C #
ฉันต้องการความคิดเห็นเกี่ยวกับโค้ดของฉันฉันเพิ่งเริ่มเขียนโค้ดด้วย C # แต่ฉันมีความรู้เกี่ยวกับ Lua และ Python มีอะไรที่ฉันต้องเปลี่ยน / ทำความสะอาดเพื่อให้ง่ายขึ้นหรือไม่?
using System;
using System.Linq;
class MainClass {
public static void Main () {
int[] cards = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10};
Console.WriteLine("Welcome to Blackjack. Here are your draws.");
Random drawCard = new Random();
int draw1 = drawCard.Next(cards.Min(), cards.Max());
int draw2 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You recieved a " + draw1 + " card!");
Console.WriteLine("You recieved a " + draw2 + " card!");
int sum1 = draw1 + draw2;
if (sum1 == 21) //Blackjack Ending
{
Console.WriteLine("Congratulations! You got " + sum1 + "!");
}
else if (sum1 >= 11) //Choice of 3rd draw
{
Console.WriteLine("Is " + sum1 + " enough?");
bool cont1 = false;
drawChoice(cont1); //Call the draw choice function
if (cont1 == true)
{
int draw3 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You drawed a " + draw3 + " card!");
int sum2 = draw3 + sum1;
Console.WriteLine("You have a total of " + sum2 + ".");
if (sum2 > 21) Console.WriteLine("Game Over!");
}
else //NPC's turn starts
{
}
}
else //Player has less than 11 cards, auto draw
{
Console.WriteLine("You have a total of " + sum1 + ".");
Console.WriteLine("You will be forced to draw another card.");
int draw3 = drawCard.Next(cards.Min(), cards.Max());
Console.WriteLine("You drawed a " + draw3 + " card!");
int sum2 = draw3 + sum1;
Console.WriteLine("You have a total of " + sum2 + ".");
}
}
static void drawChoice(bool contChoice) //Function for player to choose whether to draw
{
Console.WriteLine("Would you like to draw another card? Y/N");
string choice1 = Console.ReadLine();
if (choice1 == "Y" || choice1 == "y")
{
contChoice = true;
Console.WriteLine(contChoice);
}
else if (choice1 == "N" || choice1 == "n")
{
contChoice = false;
Console.WriteLine(contChoice);
}
}
}
คำตอบ
ฉันได้ทำโปรเจ็กต์ที่คล้ายกันด้วยตัวเองมันสนุกดีจริงๆ!
1. ติดตามคะแนน
สิ่งแรกที่ฉันสังเกตเห็นคือคุณติดตามผลรวมของค่าสำหรับผู้เล่นและน่าจะเป็นของเจ้ามือด้วย แต่คะแนนของมือสามารถเปลี่ยนแปลงได้อย่างมากในขณะที่เล่น
1.1. ผลรวมอ่อนในกระบอง
แบล็คแจ็คมีแนวคิดนี้เรียกว่าผลรวมอ่อนซึ่งหมายความว่าผลรวมทั้งหมดอาจมีมูลค่าแตกต่างกันขึ้นอยู่กับว่ามีเอซหรือไม่ ตัวอย่างเช่นหากผู้เล่นมีเอซ (1) และ 7 ที่จริงจะนับเป็น 18 (11 + 7) แต่ถ้าผู้เล่นคนเดียวกันดึงอีก 7 คนผลรวมของพวกเขาจะเป็น 15 (1 + 7 + 7) มูลค่าของเอซจะเปลี่ยนไปเมื่อคุณจั่วไพ่เพิ่มขึ้นดังนั้นคุณจะมีเวลาเก็บคะแนนได้ง่ายขึ้นหากคุณแยกไพ่ออกจากกัน สามารถทำได้โดยใช้คอลเลกชัน
1.2. คอลเลกชัน
คอลเล็กชันคือสิ่งต่างๆเช่นอาร์เรย์ (ซึ่งคุณเคยใช้แล้ว) รายการและพจนานุกรม รายชื่อจำนวนเต็มเป็นตัวเลือกที่ดีในการแสดงคอลเลกชันการ์ดปัจจุบันของผู้เล่น (หรือเจ้ามือ) เนื่องจากสามารถเปลี่ยนขนาดได้โดยไม่ต้องบ่น ยิ่งไปกว่านั้นรายการยังมีฟังก์ชันในตัวสำหรับรับผลรวมของตัวเลขทั้งหมดที่อยู่ในนั้นค่าต่ำสุดและค่าสูงสุดของรายการและอื่น ๆ อีกมากมาย คุณสามารถใช้ฟังก์ชันในตัวเหล่านี้เพื่อประโยชน์ของคุณได้เช่นเดียวกับข้อเท็จจริงที่ว่าคุณทราบตัวเลขภายในรายการอยู่เสมอเพื่อตรวจสอบว่ายอดรวมของใครบางคนอ่อนหรือไม่
2. เกมวน
เกมแบล็คแจ็คเล่นด้วยไพ่จำนวน จำกัด ในชีวิตจริง แต่แน่นอนว่าในรหัสคุณไม่ต้องกังวลเรื่องนั้น หากผู้เล่น (ไม่) โชคดีวาดเอซต่อไปในที่สุดพวกเขาก็จะตี 21 และจบรอบ อย่างไรก็ตามเนื่องจากคุณไม่สามารถคาดเดาได้ว่าเมื่อใดที่ผู้เล่น (หรือเจ้ามือ) จะแพ้คุณสามารถใช้สิ่งที่เรียกว่าเกมวนซ้ำได้ ลูปเกมสำหรับแบล็คแจ็คเริ่มดำเนินการตามตรรกะของเกมเมื่อผู้เล่นหรือเจ้ามือยืนยันว่าต้องการจั่วไพ่และเมื่อดำเนินการเสร็จแล้วระบบจะขอให้ทำซ้ำหากจำเป็น
2.1. เงื่อนไขในการเลือกบัตรอื่น
คุณจะสังเกตเห็นว่าผู้เล่นมีอิสระอย่างมากในการเล่นแบล็คแจ็คพวกเขาสามารถจั่วไพ่ไปเรื่อย ๆ จนกว่าพวกเขาจะได้ 21 หรือมากกว่าซึ่งจุดนั้นจะสิ้นสุดลงสำหรับพวกเขา อย่างไรก็ตามเจ้ามือไม่มีอิสระขนาดนั้น คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ทางออนไลน์
ไม่ว่าจะด้วยวิธีใดหากคุณคิดเกี่ยวกับเรื่องนี้ทั้งผู้เล่นและเจ้ามือในบางจุดจะตัดสินใจว่าจะจั่วหรือไม่จั่วไพ่ใบอื่น คุณตรวจสอบ"Y"
หรือ"N"
เมื่อได้รับอินพุตซึ่งเหมาะสม
2.2. การแปลการป้อนข้อความเป็นtrue
หรือfalse
DrawChoice
วิธีการของคุณจะเปลี่ยนแปลงbool
ขึ้นอยู่กับอินพุตของผู้เล่น แต่คุณสามารถ refactor วิธีการนั้นเพื่อให้ได้รับ a string
และส่งคืน a bool
. ด้วยวิธีนี้คุณสามารถแปลข้อมูลที่ผู้ใช้ป้อนโดยตรงเป็นtrue
(ใช่ขอการ์ดใบอื่นให้ฉัน) หรือfalse
(ไม่ฉันไม่ต้องการการ์ดใบอื่น) อาจมีลักษณะดังนี้:
// One option
public static bool DrawChoice(string input)
{
if (input == "Y" || input == "y") // You could also use input.ToLower() == "y"
{
return true;
}
else // If it's not "Y" or "y", it's gonna be "N" or "n"
{
return false;
}
// else if (input == "N" || input == "n")
// {
// return false;
// }
}
// Alternative one-liner
public static bool DrawChoice2(string input) => input.ToLower() == "y";
ย้อนกลับไปที่แนวคิดของเกมวนตอนนี้คุณมีเงื่อนไขที่กำหนดว่าการวนซ้ำของเกมจะดำเนินต่อไปหรือไม่ การใช้งานที่เป็นไปได้อย่างหนึ่งคือ:
string choice = Console.ReadLine();
while (DrawChoice(choice)) // No need to write "== true" or "== false"
{
// Stuff that happens if a player or the dealer draws another card
choice = Console.ReadLine() // Ask again once the game logic has executed
}
// Stuff that happens when the loop ends
2.3. วาดการ์ด
แบล็คแจ็คเป็นเกมไพ่ดังนั้นคุณจะต้องจั่วไพ่เป็นจำนวนมากไม่ว่าจะเป็นสำหรับผู้เล่นหรือเจ้ามือ หากมีบางสิ่งเกิดขึ้นบ่อยครั้งในเกมโดยทั่วไปควรทำให้เป็นวิธีการเพื่อที่คุณจะได้ไม่ต้องเขียนตรรกะเดียวกันในที่ต่างๆ
การใช้งานปัจจุบันของคุณดึงค่าสุ่มระหว่างค่าต่ำสุดและสูงสุดของอาร์เรย์การ์ดของคุณ จากเอกสารเราเรียนรู้สิ่งต่อไปนี้:
Next(Int32 minValue, Int32 maxValue)
32 บิตลงนามจำนวนเต็มมากกว่าหรือเท่ากับ
minValue
และน้อยกว่าmaxValue
; นั่นคือช่วงของค่าส่งคืนรวมถึงminValue
แต่ไม่maxValue
รวม ถ้าminValue
เท่าเทียมกันmaxValue
,minValue
จะถูกส่งกลับ
ดังนั้นเมื่อคุณเขียนNext(1, 10)
(จากขั้นต่ำและสูงสุด) คุณจะได้ 9 มากที่สุดอีกประเด็นหนึ่งคือแม้ว่าคุณจะแก้ไขการนำไปใช้งานNext(1, 11)
คุณจะมีความน่าจะเป็นเท่ากันที่จะได้รับค่าใด ๆ ตั้งแต่ 1 ถึง 10 แต่เนื่องจากมีการ์ดหลายใบ ในสำรับที่มีค่า 10 ควรแสดงบ่อยกว่าไพ่ที่ไม่ใช่ 10 ใบ
โชคดีที่อาร์เรย์ของคุณมีการกระจายไพ่ที่ถูกต้องอยู่แล้วดังนั้นคุณสามารถสร้างตำแหน่งสุ่มที่ถูกต้องเพื่อรับค่าที่สอดคล้องกันจากอาร์เรย์ของคุณได้
ในตอนท้ายของวันสิ่งที่คุณจะได้รับจะมีลักษณะดังนี้:
public static int DrawCard()
{
int[] cards = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 };
int card;
// Implement random draw here
return card;
}
จากนั้นคุณสามารถทำอะไรแบบนี้เพื่อจั่วไพ่ซ้ำ ๆ :
// You could also use a list, which is more flexible
public static int[] DrawCard(int count)
{
int[] drawn = new int[count];
for (int i = 0; i < count; i++)
{
drawn[i] = DrawCard();
}
return drawn;
}
หวังว่านี่จะช่วยได้! ขอให้โชคดีและสนุก!
เพียงไม่กี่บันทึกเพื่อให้คุณสามารถปรับปรุงโค้ดของคุณ:
int sum1 = draw1 + draw2; if (sum1 == 21) //Blackjack Ending { Console.WriteLine("Congratulations! You got " + sum1 + "!"); }
สิ่งนี้จะไม่เป็นความจริงเลยเพราะ
- คุณไม่มีเอซในไพ่ที่มีความหมายที่เป็นไปได้ถึงสิบเอ็ด
maxValue
ในRandom.Next(int minValue, int maxValue)เป็นพิเศษผูกพันบนของจำนวนสุ่มกลับ
ในvoid drawChoice(bool contChoice)
อาร์กิวเมนต์เมธอดcontChoice
คือประเภทค่า คุณไม่สามารถปรับเปลี่ยนได้อย่างที่คุณคิด หลังจากออกจากวิธีการโดยไม่คำนึงว่าผู้ใช้พิมพ์ y หรือ n ค่าของcont1
ยังคงfalse
อยู่ คุณควรเปลี่ยนลายเซ็นวิธีการที่ไม่มีอาร์กิวเมนต์ แต่ให้ส่งกลับไฟล์bool
.
if (cont1 == true)
เนื่องจากcont1
เป็นบูลแล้วคุณไม่จำเป็นต้องเปรียบเทียบกับบูล คุณก็สามารถใช้มันเป็นสภาพเหมือนif (cont1)
และถ้าคุณจะต้องตรวจสอบสภาพอากาศตัวแปรบูลเป็นที่ที่คุณจะใช้false
if (!cont1)
ฉันไม่แน่ใจว่าจะมีประโยชน์แค่ไหน แต่ IMHO คุณต้องมีการตรวจสอบโค้ดที่ครบถ้วนกับคนที่พูดคุยกับคุณผ่านรหัส มีหลายอย่างที่ "ผิด" ที่นี่ แต่เมื่อบอกว่าฉันสงสัยว่าเป้าหมายของคุณคืออะไรกับ C # - คุณแค่เขียนสคริปต์บางอย่างออกมาเพื่อเรียนรู้ไวยากรณ์อย่างรวดเร็วหรือคุณต้องการทำความเข้าใจวิธีการออกแบบสิ่งต่างๆใน C # ให้ดีขึ้น
ถ้ามีคนมาหาฉันในสภาพแวดล้อมแบบมืออาชีพสิ่งแรกที่ฉันจะบอกพวกเขา: "คุณต้องสามารถทดสอบสิ่งนี้ได้" จากนั้นฉันจะพูดถึง TDD และพยายามชี้ให้เห็นว่าโค้ดนี้มีโครงสร้างอย่างไรให้ทำมากเกินไป ไม่มีนามธรรมและทุกอย่างมีขั้นตอนมาก ทุกชั้นเรียนควรทำ 1 อย่าง คนที่ฉันแน่ใจว่าจะเถียงกับฉันในประเด็นนี้ ไม่ว่าจะด้วยวิธีใดการที่คุณมีเพียง 1 คลาสนั้นไม่ดี
ที่ผ่านมาสำหรับ "เคล็ดลับ C # ด่วน 2 นาที" ทั่วไป ฉันจะใช้การแจงนับสำหรับไพ่แทนที่จะเป็น 10, 10, 10 ฉันมี 10 แจ็คควีนเอซ ใช้ var แทน if (cont1 == true)
เหมือนกับif(cont1)
. ใช้ตัวแปรที่มีชื่อดีกว่า: ดูที่ cont1 ฉันไม่รู้ว่ามันหมายถึงอะไร
JansthcirlU ยังนำเสนอคอลเลกชัน เมื่อดูที่รหัสนี้ดูเหมือนว่าคุณไม่เข้าใจดังนั้นฉันจะเน้นตรงนี้เช่นกัน
เขียนโค้ดต่อไป :)