ต้นแบบแบล็คแจ็ค C #

Aug 18 2020

ฉันต้องการความคิดเห็นเกี่ยวกับโค้ดของฉันฉันเพิ่งเริ่มเขียนโค้ดด้วย 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);
    }
  }
}

คำตอบ

6 JansthcirlU Aug 18 2020 at 22:18

ฉันได้ทำโปรเจ็กต์ที่คล้ายกันด้วยตัวเองมันสนุกดีจริงๆ!

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;
}

หวังว่านี่จะช่วยได้! ขอให้โชคดีและสนุก!

9 Heslacher Aug 18 2020 at 14:33

เพียงไม่กี่บันทึกเพื่อให้คุณสามารถปรับปรุงโค้ดของคุณ:

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)และถ้าคุณจะต้องตรวจสอบสภาพอากาศตัวแปรบูลเป็นที่ที่คุณจะใช้falseif (!cont1)

3 rball Aug 19 2020 at 00:27

ฉันไม่แน่ใจว่าจะมีประโยชน์แค่ไหน แต่ IMHO คุณต้องมีการตรวจสอบโค้ดที่ครบถ้วนกับคนที่พูดคุยกับคุณผ่านรหัส มีหลายอย่างที่ "ผิด" ที่นี่ แต่เมื่อบอกว่าฉันสงสัยว่าเป้าหมายของคุณคืออะไรกับ C # - คุณแค่เขียนสคริปต์บางอย่างออกมาเพื่อเรียนรู้ไวยากรณ์อย่างรวดเร็วหรือคุณต้องการทำความเข้าใจวิธีการออกแบบสิ่งต่างๆใน C # ให้ดีขึ้น

ถ้ามีคนมาหาฉันในสภาพแวดล้อมแบบมืออาชีพสิ่งแรกที่ฉันจะบอกพวกเขา: "คุณต้องสามารถทดสอบสิ่งนี้ได้" จากนั้นฉันจะพูดถึง TDD และพยายามชี้ให้เห็นว่าโค้ดนี้มีโครงสร้างอย่างไรให้ทำมากเกินไป ไม่มีนามธรรมและทุกอย่างมีขั้นตอนมาก ทุกชั้นเรียนควรทำ 1 อย่าง คนที่ฉันแน่ใจว่าจะเถียงกับฉันในประเด็นนี้ ไม่ว่าจะด้วยวิธีใดการที่คุณมีเพียง 1 คลาสนั้นไม่ดี

ที่ผ่านมาสำหรับ "เคล็ดลับ C # ด่วน 2 นาที" ทั่วไป ฉันจะใช้การแจงนับสำหรับไพ่แทนที่จะเป็น 10, 10, 10 ฉันมี 10 แจ็คควีนเอซ ใช้ var แทน if (cont1 == true)เหมือนกับif(cont1). ใช้ตัวแปรที่มีชื่อดีกว่า: ดูที่ cont1 ฉันไม่รู้ว่ามันหมายถึงอะไร

JansthcirlU ยังนำเสนอคอลเลกชัน เมื่อดูที่รหัสนี้ดูเหมือนว่าคุณไม่เข้าใจดังนั้นฉันจะเน้นตรงนี้เช่นกัน

เขียนโค้ดต่อไป :)