D.ershane Çözümleri Ddili.org

Yapılar Çözümleri

  1. Aksine bir neden olmadığı için, en basit olarak iki tane karakter ile:
  2. struct OyunKağıdı
    {
        dchar renk;
        dchar değer;
    }
    
  3. Yine çok basit olarak, yapı nesnesinin üyelerini yan yana çıkışa göndermek yeterli olur:
  4. void oyunKağıdıYazdır(in OyunKağıdı kağıt)
    {
        write(kağıt.renk, kağıt.değer);
    }
    
  5. Eğer yeniSeri isminde başka bir işlevin yazılmış olduğunu kabul edersek, yeniDeste işlevini de onu her renk için dört kere çağırarak kolayca yazabiliriz:
  6. OyunKağıdı[] yeniDeste()
    out (sonuç)
    {
        assert(sonuç.length == 52);
    }
    body
    {
        OyunKağıdı[] deste;
    
        deste ~= yeniSeri('♠');
        deste ~= yeniSeri('♡');
        deste ~= yeniSeri('♢');
        deste ~= yeniSeri('♣');
    
        return deste;
    }
    

    Asıl iş, yararlandığımız yeniSeri tarafından halledilir. Bu işlev bütün değerleri içeren bir dizi tanımlıyor, ve verilen renk bilgisini onun elemanlarıyla sırayla birleştirerek bir seri oluşturuyor:

    OyunKağıdı[] yeniSeri(dchar renk)
    in
    {
        assert((renk == '♠') ||
               (renk == '♡') ||
               (renk == '♢') ||
               (renk == '♣'));
    }
    out (sonuç)
    {
        assert(sonuç.length == 13);
    }
    body
    {
        OyunKağıdı[] seri;
    
        dchar bütünDeğerler[] =
            [ '2', '3', '4', '5', '6', '7', '8', '9',
              '0', 'J', 'Q', 'K', 'A' ];
    
        foreach (değer; bütünDeğerler) {
            seri ~= OyunKağıdı(renk, değer);
        }
    
        return seri;
    }
    

    Program hatalarını önlemek için işlevlerin giriş ve çıkış koşullarını da yazdığıma dikkat edin.

  7. Rasgele seçilen iki elemanı değiş tokuş etmek, sonuçta destenin karışmasını da sağlar. Rastgele seçim sırasında, küçük de olsa aynı elemanı seçme olasılığı da vardır. Ama bu önemli bir sorun oluşturmaz, çünkü elemanı kendisiyle değiştirmenin etkisi yoktur.
  8. void karıştır(OyunKağıdı[] deste, in int değişTokuşAdedi)
    {
        /* Not: Daha etkin bir yöntem, desteyi başından sonuna
         *      kadar ilerlemek ve her elemanı destenin sonuna
         *      doğru rasgele bir elemanla değiştirmektir. */
    
        foreach (i; 0 .. değişTokuşAdedi) {
    
            // Rasgele iki tanesini seç
            const int birinci = uniform(0, deste.length);
            const int ikinci = uniform(0, deste.length);
    
            // Değiş tokuş et
            swap(deste[birinci], deste[ikinci]);
        }
    }
    

    O işlevde std.algorithm modülündeki swap işlevinden yararlandım. swap, kendisine verilen iki değeri değiş tokuş eder. Temelde şu işlev gibi çalışır:

    void değişTokuş(ref OyunKağıdı soldaki,
                    ref OyunKağıdı sağdaki)
    {
        auto geçici = soldaki;
        soldaki = sağdaki;
        sağdaki = geçici;
    }
    

Programın tamamı şöyle:

import std.stdio;
import std.random;
import std.algorithm;

struct OyunKağıdı
{
    dchar renk;
    dchar değer;
}

void oyunKağıdıYazdır(in OyunKağıdı kağıt)
{
    write(kağıt.renk, kağıt.değer);
}

OyunKağıdı[] yeniSeri(dchar renk)
in
{
    assert((renk == '♠') ||
           (renk == '♡') ||
           (renk == '♢') ||
           (renk == '♣'));
}
out (sonuç)
{
    assert(sonuç.length == 13);
}
body
{
    OyunKağıdı[] seri;

    dchar bütünDeğerler[] =
        [ '2', '3', '4', '5', '6', '7', '8', '9',
          '0', 'J', 'Q', 'K', 'A' ];

    foreach (değer; bütünDeğerler) {
        seri ~= OyunKağıdı(renk, değer);
    }

    return seri;
}

OyunKağıdı[] yeniDeste()
out (sonuç)
{
    assert(sonuç.length == 52);
}
body
{
    OyunKağıdı[] deste;

    deste ~= yeniSeri('♠');
    deste ~= yeniSeri('♡');
    deste ~= yeniSeri('♢');
    deste ~= yeniSeri('♣');

    return deste;
}

void karıştır(OyunKağıdı[] deste, in int değişTokuşAdedi)
{
    /* Not: Daha etkin bir yöntem, desteyi başından sonuna
     *      kadar ilerlemek ve her elemanı destenin sonuna
     *      doğru rasgele bir elemanla değiştirmektir. */

    foreach (i; 0 .. değişTokuşAdedi) {

        // Rasgele iki tanesini seç
        const int birinci = uniform(0, deste.length);
        const int ikinci = uniform(0, deste.length);

        // Değiş tokuş et
        swap(deste[birinci], deste[ikinci]);
    }
}

void main()
{
    OyunKağıdı[] deste = yeniDeste();
    karıştır(deste, 100);

    foreach (kağıt; deste) {
        oyunKağıdıYazdır(kağıt);
        write(' ');
    }

    writeln();
}