C # Blackjack prototipi

Aug 18 2020

Kodumla ilgili biraz geri bildirim istiyorum, C # ile kodlama konusunda yeniyim ama Lua ve Python hakkında biraz bilgim var. Daha basit hale getirmek için değiştirmem / temizlemem gereken herhangi bir şey var mı?

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

Yanıtlar

6 JansthcirlU Aug 18 2020 at 22:18

Aslında ben de benzer bir proje yaptım, gerçekten çok eğlenceli!

1. Puanları takip etmek

İlk fark ettiğim şey, oyuncu için ve muhtemelen dağıtıcı için de değerlerin toplamını takip etmenizdir, ancak bir elin skoru oyun sırasında gerçekten önemli ölçüde değişebilir.

1.1. Blackjack'te yumuşak toplamlar

Blackjack'in yumuşak toplamlar adı verilen bu kavramı vardır , bu da toplam toplamın as olup olmadığına bağlı olarak farklı bir değere sahip olabileceği anlamına gelir. Örneğin, bir oyuncunun bir as (1) ve bir 7 varsa, bu aslında 18 (11 + 7) olarak sayılır. Ancak aynı oyuncu başka bir 7 çekerse, toplamları 15 (1 + 7 + 7) olacaktır. Siz daha fazla kart çekerken asın değeri değişir, bu nedenle kartları bir şekilde birbirinden ayrı tutarsanız, puanları tutmada daha kolay zamanınız olur. Bu, koleksiyonlar kullanılarak yapılabilir.

1.2. Koleksiyonlar

Koleksiyonlar, diziler (zaten kullanmış olduğunuz), listeler ve sözlükler gibi şeylerdir. Tam sayılar listesi, bir oyuncunun (veya krupiyenin) mevcut kart koleksiyonunu temsil etmek için iyi bir adaydır çünkü şikayet etmeden boyutlarını değiştirebilirler. Dahası, listeler, içlerindeki tüm sayıların toplamını, listenin minimum ve maksimum değerlerini ve çok daha fazlasını almak için yerleşik işlevlere sahiptir. Birinin toplamının yumuşak olup olmadığını belirlemek için listedeki sayıları her zaman bildiğiniz gerçeğinin yanı sıra, bu yerleşik işlevleri kendi yararınıza kullanabilirsiniz .

2. Oyun döngüsü

Blackjack oyunu gerçek hayatta sınırlı sayıda kartla oynanır, ancak elbette kodda bunun için endişelenmenize gerek yok. Şanslı bir oyuncu asları çekmeye devam ederse, sonunda 21'e ulaşır ve turu bitirir. Ancak, bir oyuncunun (veya krupiyenin) ne zaman kaybedeceğini tahmin edemeyeceğiniz için, oyun döngüsü adı verilen bir şey kullanabilirsiniz. Blackjack için oyun döngüsü, bir oyuncu veya krupiye bir kart çekmek istediğini onayladığında tüm oyun mantığını yürütmeye başlar ve uygulama tamamlandığında gerekirse tekrar etmesini ister.

2.1. Başka bir kart seçme koşulları

Oyuncunun blackjack'te çok fazla özgürlüğe sahip olduğunu fark edeceksiniz, 21 olana kadar kart çekmeye devam edebilir veya geçebilir, bu noktada tur onlar için biter. Ancak satıcı bu özgürlüğe sahip değil. Bununla ilgili daha fazla bilgiyi çevrimiçi olarak bulabilirsiniz.

Her iki durumda da, düşünürseniz, hem oyuncu hem de krupiye bir noktada başka bir kart çekip çekmeme kararını verir. Bir girdi için "Y"veya "N"verildiğinde bir kontrol yaparsınız , bu mantıklı.

2.2. Metin girişini trueveya metnini çevirmefalse

Kişisel DrawChoiceyöntem değiştiren bir booloyuncunun girişine bağlı, ama bir aldığı, böylece de bu yöntemi planı ayrı olabilir stringve döner bir bool. Bu şekilde, kullanıcının girişini doğrudan true(evet, bana başka bir kart verin) veya false(hayır, başka bir kart istemiyorum) olarak çevirebilirsiniz . Şunun gibi görünebilir:

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

Oyun döngüsü fikrine geri dönersek, artık oyun döngüsünün devam edip etmeyeceğini belirleyen bir koşulunuz var. Olası bir uygulama şu olabilir:

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. Çizim kartları

Blackjack bir kart oyunudur, bu nedenle ister oyuncu ister dağıtıcı olsun, çok kart çekeceksiniz. Oyunda sık sık bir şey olursa, bunu bir yöntem haline getirmek genellikle iyi bir fikirdir, böylece aynı mantığı farklı yerlere yazmak zorunda kalmazsınız.

Mevcut uygulamanız, kart dizinizin minimum ve maksimum değerleri arasında rastgele bir değer çekiyor. Belgelerden aşağıdakileri öğreniyoruz:

Next(Int32 minValue, Int32 maxValue)

32 bitlik işaretli tamsayı büyüktür veya eşittir minValueve küçüktür maxValue; diğer bir deyişle, dönüş değerleri aralığı içerir minValue ancak içermez maxValue . Eğer minValueeşittir maxValue, minValuedöndürülür.

Yani Next(1, 10)(min ve maks'dan) yazdığınızda , en fazla 9 alırsınız. Diğer bir sorun, uygulamayı olarak düzeltseniz bile Next(1, 11), 1'den 10'a kadar herhangi bir değer elde etmek için eşit olasılıklara sahip olacaksınız. Ancak birden fazla kart olduğu için 10 değerinde olan destede, 10 olmayan karttan daha sık görünmeleri gerekir.

Neyse ki, diziniz zaten doğru kart dağılımına sahiptir, bu nedenle dizinizden karşılık gelen değeri almak için geçerli bir rastgele konum oluşturabilirsiniz .

Günün sonunda, elde edeceğiniz şey şunun gibi görünecek:

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

Ve sonra tekrar tekrar kart çekmek için buna benzer bir şey bile yapabilirsiniz:

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

Bu yardımcı olur umarım! İyi şanslar ve iyi eğlenceler!

9 Heslacher Aug 18 2020 at 14:33

Kodunuzu geliştirebilmeniz için yalnızca birkaç not:

int sum1 = draw1 + draw2;

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

Bu asla doğru olmayacak çünkü

  • kartların hiçbir yerinde, on bir olası değerine sahip bir as yok.
  • maxValueiçerisinde Random.Next(int minValue, int maxValue)üst geri rasgele sayının bağlı özeldir.

Gelen void drawChoice(bool contChoice)yöntem argümanı contChoicebir değer türüdür. Düşündüğünüz gibi değiştiremezsiniz. Kullanıcı yazılan y veya n Hava bağımsız yöntemi ayrıldıktan sonra değeri cont1hala false. Yöntem imzasını bağımsız değişken içermeyecek şekilde değiştirmelisiniz, ancak bir bool.

if (cont1 == true)  

çünkü cont1zaten bir bool, onu bir bool ile karşılaştırmanıza gerek kalmayacak . Bunu basitçe koşul olarak kullanabilirsiniz if (cont1)ve eğer bir bool değişkeni falsekullanıp kullanmadığınızı kontrol etmeniz gerekirse if (!cont1).

3 rball Aug 19 2020 at 00:27

Burada ne kadar yardımcı olabileceğimden emin değilim, ancak IMHO, sizinle kod aracılığıyla konuşan biriyle tam teşekküllü bir kod incelemesi yapmanız gerekiyor. Burada bir grup "yanlış" var, ancak C # ile amacınızın ne olduğunu merak ettiğimi söyledim - sözdizimini öğrenmek için hızlıca bir şeyler mi yazıyorsunuz yoksa C # 'da bir şeyleri nasıl tasarlayacağınızı daha iyi anlamak mı istiyorsunuz?

Biri bana profesyonel bir ortamda bununla geldiyse, onlara söyleyeceğim ilk şey: "Bunu test edebilmelisin". Daha sonra TDD hakkında konuşur ve gerçekten bu kodun çok fazla şey yapmak için nasıl yapılandırıldığını göstermeye çalışırdım. Soyutlama yok ve her şey oldukça prosedürel. Her sınıf 1 şey yapmalı. Emin olduğum insanlar bu noktada benimle tartışacaklar. Her iki durumda da, sadece 1 sınıfa sahip olduğunuz gerçeği kötüdür.

Bunu geçtikten sonra, sadece genel "2 dakikalık hızlı C # ipuçları" için. Kartlar için numaralandırmayı kullanırdım, böylece 10, 10, 10 yerine 10, Vale, Kız, As olur. Bunun yerine var kullanın. if (cont1 == true)ile aynıdır if(cont1). Daha iyi adlandırılmış değişkenler kullanın: Sadece cont1'e bakarak bunun ne anlama geldiğine dair hiçbir fikrim yok.

JansthcirlU ayrıca koleksiyonları da gündeme getirdi. Bu koda baktığınızda, onları anlamışsınız gibi görünmüyor, bu yüzden ben de buraya odaklanırım.

Kodlamaya devam et :)