C # Prototipe Blackjack

Aug 18 2020

Saya ingin umpan balik tentang kode saya, saya baru mengenal pengkodean dengan C # tetapi saya memiliki beberapa pengetahuan tentang Lua dan Python. Apakah ada yang perlu saya ubah / bersihkan agar lebih sederhana?

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

Jawaban

6 JansthcirlU Aug 18 2020 at 22:18

Saya sendiri sebenarnya telah membuat proyek serupa, itu sangat menyenangkan!

1. Melacak skor

Hal pertama yang saya perhatikan adalah Anda melacak jumlah nilai untuk pemain dan mungkin juga untuk dealer, tetapi skor tangan sebenarnya dapat berubah secara dramatis saat bermain.

1.1. Total lembut di blackjack

Blackjack memiliki konsep yang disebut soft totals, yang berarti jumlah total dapat memiliki nilai yang berbeda tergantung apakah ada kartu as atau tidak. Misalnya, jika seorang pemain memiliki ace (1) dan 7, itu sebenarnya dihitung sebagai 18 (11 + 7). Tetapi jika pemain yang sama itu menarik 7 lainnya, totalnya akan menjadi 15 (1 + 7 + 7). Nilai ace berubah saat Anda menarik lebih banyak kartu, jadi Anda akan lebih mudah menyimpan skor jika Anda memisahkan kartu satu sama lain. Ini dapat dilakukan dengan menggunakan koleksi.

1.2. Koleksi

Koleksi adalah hal-hal seperti array (yang telah Anda gunakan), daftar, dan kamus. Daftar bilangan bulat adalah kandidat yang baik untuk mewakili koleksi kartu pemain (atau dealer) saat ini, karena mereka dapat mengubah ukuran tanpa mengeluh. Selain itu, daftar memiliki fungsi bawaan untuk mendapatkan jumlah semua angka di dalamnya, nilai minimum dan maksimum dari daftar dan banyak lagi. Anda dapat menggunakan fungsi bawaan tersebut untuk keuntungan Anda, serta fakta bahwa Anda selalu mengetahui angka-angka di dalam daftar untuk menentukan apakah total seseorang lunak atau tidak.

2. Game loop

Permainan blackjack dimainkan dengan jumlah kartu yang terbatas dalam kehidupan nyata, tetapi tentu saja dalam kode Anda tidak perlu khawatir tentang itu. Jika pemain (tidak) beruntung terus menggambar ace, mereka pada akhirnya akan tetap mencapai 21 dan mengakhiri ronde. Namun, karena Anda tidak dapat memprediksi kapan seorang pemain (atau dealer) akan kalah, Anda dapat menggunakan sesuatu yang disebut game loop. Putaran permainan untuk blackjack mulai menjalankan semua logika permainan setelah pemain atau dealer mengonfirmasi bahwa mereka ingin menarik kartu, dan setelah selesai dijalankan, itu akan meminta untuk diulang jika perlu.

2.1. Ketentuan untuk memilih kartu lain

Anda akan melihat bahwa pemain memiliki banyak kebebasan dalam blackjack, mereka dapat terus menarik kartu sampai mereka mendapatkan 21 atau pergi, pada titik mana putaran berakhir untuk mereka. Dealer, bagaimanapun, tidak memiliki kebebasan itu. Anda dapat menemukan lebih banyak informasi tentang itu secara online.

Either way, jika Anda memikirkannya, baik pemain dan dealer pada suatu saat membuat keputusan untuk menggambar atau tidak menarik kartu lain. Anda melakukan pemeriksaan "Y"atau "N"ketika diberi masukan, yang masuk akal.

2.2. Menerjemahkan input teks ke trueataufalse

DrawChoiceMetode Anda mengubah a booltergantung pada input pemain, tetapi Anda juga bisa memfaktor ulang metode itu sehingga ia menerima stringdan mengembalikan a bool. Dengan begitu, Anda dapat langsung menerjemahkan masukan pengguna ke true(ya, beri saya kartu lain) atau false(tidak, saya tidak ingin kartu lain). Ini bisa terlihat seperti ini:

// 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";

Kembali ke ide game loop, Anda sekarang memiliki kondisi yang menentukan apakah game loop berlanjut atau tidak. Salah satu implementasi yang mungkin adalah ini:

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. Kartu gambar

Blackjack adalah permainan kartu, oleh karena itu Anda akan banyak menggambar kartu, baik itu untuk pemain atau dealer. Jika sesuatu sering terjadi dalam gim, sebaiknya buatlah menjadi metode sehingga Anda tidak perlu menulis logika yang sama di tempat yang berbeda.

Implementasi Anda saat ini menarik nilai acak antara minimum dan maksimum dari larik kartu Anda. Dari dokumentasi tersebut, kami mempelajari hal-hal berikut:

Next(Int32 minValue, Int32 maxValue)

Integer bertanda tangan 32-bit lebih besar dari atau sama dengan minValuedan kurang dari maxValue; Artinya, rentang nilai yang dikembalikan termasuk minValue tetapi tidak maxValue . Jika minValuesama maxValue, minValuedikembalikan.

Jadi ketika Anda menulis Next(1, 10)(dari min dan max), Anda paling banyak akan mendapatkan 9. Masalah lainnya adalah bahwa meskipun Anda memperbaiki implementasinya Next(1, 11), Anda akan memiliki probabilitas yang sama untuk mendapatkan nilai apa pun dari 1 hingga 10. Tetapi karena ada banyak kartu di tumpukan yang memiliki nilai 10, mereka harus muncul lebih sering daripada kartu non-10.

Untungnya, array Anda sudah memiliki distribusi kartu yang benar, jadi Anda dapat membuat posisi acak yang valid untuk mendapatkan nilai yang sesuai dari array Anda.

Pada akhirnya, hasil akhir yang akan Anda dapatkan akan terlihat seperti ini:

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

Dan kemudian Anda bahkan dapat melakukan hal seperti ini untuk menggambar kartu berulang kali:

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

Semoga ini membantu! Semoga berhasil dan selamat bersenang - senang!

9 Heslacher Aug 18 2020 at 14:33

Hanya beberapa catatan sehingga Anda dapat meningkatkan kode Anda:

int sum1 = draw1 + draw2;

if (sum1 == 21) //Blackjack Ending
{
  Console.WriteLine("Congratulations! You got " + sum1 + "!");
}

Ini tidak akan pernah benar, karena

  • Anda tidak memiliki tempat di kartu yang ace yang berarti memiliki kemungkinan nilai sebelas.
  • yang maxValuedi Random.Next(int minValue, int maxValue)adalah eksklusif batas atas jumlah acak kembali.

Dalam void drawChoice(bool contChoice)argumen metode contChoiceadalah tipe nilai. Anda tidak dapat memodifikasinya seperti yang Anda pikirkan. Setelah meninggalkan metode terlepas dari apakah pengguna mengetik y atau n nilai cont1tetap false. Anda harus mengubah tanda tangan metode agar tidak memiliki argumen selain mengembalikan bool.

if (cont1 == true)  

karena cont1sudah menjadi bool Anda tidak perlu membandingkannya dengan bool. Anda cukup menggunakannya sebagai kondisi seperti if (cont1)dan jika Anda perlu memeriksa apakah variabel bool falseakan digunakan if (!cont1).

3 rball Aug 19 2020 at 00:27

Saya tidak yakin seberapa membantu saya di sini, tetapi IMHO Anda harus memiliki tinjauan kode lengkap dengan seseorang yang membujuk Anda melalui kode. Ada banyak hal yang "salah" di sini, tetapi setelah mengatakan bahwa saya bertanya-tanya apa tujuan Anda dengan C # - apakah Anda hanya membuat skrip sesuatu dengan cepat untuk mempelajari sintaks, atau apakah Anda ingin lebih memahami cara merancang berbagai hal di C #.

Jika seseorang datang kepada saya dengan ini dalam pengaturan profesional, hal pertama yang akan saya katakan kepada mereka: "Anda harus bisa menguji ini". Saya kemudian akan berbicara tentang TDD, dan benar-benar mencoba menunjukkan bagaimana kode ini disusun untuk melakukan terlalu banyak hal. Tidak ada abstraksi, dan semuanya sangat prosedural. Setiap kelas harus melakukan 1 hal. Orang-orang yang saya yakin akan berdebat dengan saya tentang hal ini. Bagaimanapun, fakta bahwa Anda hanya memiliki 1 kelas itu buruk.

Lewat itu, hanya untuk "tip C # cepat 2 menit". Saya akan menggunakan enumerasi untuk kartu-kartu itu jadi alih-alih 10, 10, 10, saya akan memiliki 10, Jack, Queen, Ace. Gunakan var sebagai gantinya. if (cont1 == true)sama dengan if(cont1). Gunakan variabel bernama lebih baik: Hanya melihat cont1 saya tidak tahu apa artinya.

JansthcirlU juga mengangkat koleksi. Melihat kode ini, sepertinya Anda tidak memahaminya jadi saya akan sangat fokus di sini juga.

Terus koding :)