Mükemmel bir 2048 oyunu oyna


18

İşiniz, 2048'in matematiksel olarak mükemmel bir oyununu simüle etmektir. Fikir, 2048 oyununun ne kadar ileri gidebileceğinin teorik üst sınırını bulmak ve oraya nasıl ulaşacağınızı bulmaktır.

Bunun nasıl göründüğüne dair bir fikir edinmek için bu 2x2 klonuyla oynayın ve 68 puan kazanmaya çalışın. Bunu yaparsanız, 2, 4, 8 ve 16 kiremit elde edersiniz. Bu noktayı geçmek imkansız.

Göreviniz daha kolay çünkü fayansların nerede doğacağını ve değerlerinin ne olduğunu seçebilirsiniz, tıpkı bu klon gibi .

2048 panosunu girdi olarak kabul eden ve fayansları daralttıktan sonra tahtaya spawned karo ve tahta ile çıktı veren bir program veya işlev yazmalısınız. Örneğin:

Input:
-------
0 0 0 0
0 0 0 0
0 0 0 0
0 0 8 8

Output:
-------
0 0 0 0
0 0 0 0
0 0 0 0
0 4 8 8

0 0 0 0
0 0 0 0
0 0 0 0
0 0 4 16

Tüm 2048 oyununu simüle etmek için programınız kendi çıktısını tekrar tekrar besleyecektir. Programın ilk girişi boş bir tahta olacaktır. Orijinal oyunun iki taşından farklı olarak, bir taş döşemelisiniz. Oyunun son adımında hareket edemezsiniz, böylece iki çıkış kartınız aynı olabilir.

Elbette sadece yasal hamleler yapmalısınız. Sadece 2 veya 4 üretilebilir, hareket halinde en az bir kutucuğu taşımanız veya daraltmanız gerekir.

Kasıtlı olarak girdi ve çıktı gereksinimlerini belirsizleştirdim. Giriş ve çıkışın biçimini seçmekte özgürsünüz. Matrisleri, dizileri, karakter dizilerini veya istediğinizi kullanabilirsiniz. Onlarla bir 2048 oyununu simüle edebildiğiniz sürece, girişleriniz ve çıkışlarınız iyi.

Kazanan, oyunu tahtadaki en yüksek fayans miktarıyla, daha sonra kaynak kodundaki en düşük bayt sayısıyla bitiren kişi olacaktır. Orijinal oyundan alınan puan dikkate alınmaz. (İpucu: 4'leri kullanın)


@undergroundmonorail Bu sorudan farklı. Bu soru kendi karolarınızın ortaya çıkmasına izin veriyor ve sadece 2048'e değil, matematiksel olarak mümkün olduğunca ileri gitmekle ilgili.
Kendall Frey

1
@TheDoctor 68, 2'nin toplam gücüdür ve 2, 4, 8, 16 alırsanız puanınız ne olur?
user12205

2
Bu gerçekten bir kopya mı? Farklı kılmak için daha ne gerekir?
Kendall Frey

1
@Quincunx Bu gerçekten yetersiz bir oyun üretecekti.
Kendall Frey

4
Bu zorluğun kalbini buldum, "En uygun çözümü bul", benzersiz olmakla birlikte, itiraf etmek gerekirse, bu kopyayı bir "kabuk" içine almak kötü bir seçimdi. Bu, "Oh bak, başka bir 2048 Code Golf mücadelesi" diye bağırıyor. Yakın oyların bu kadar öznel olmasıyla , meydan okumalarınızı gerçekten kalabalığa satmak zorundasınız. Bazen bu,
2048'de

Yanıtlar:


4

Ruby, Köşeye, Puan: 3340

İşte bunu başlatmak için çok basit bir strateji. Mükemmel bir puan için bir fikrim var, ama bunu resmileştirmekte sorun yaşıyorum, işte işlerin başlaması için basit bir şey var.

def slide board, dir
    case dir
    when 'U'
        i0 = 0
        i_stride = 1
        i_dist = 4
    when 'D'
        i0 = 15
        i_stride = -1
        i_dist = -4
    when 'L'
        i0 = 0
        i_stride = 4
        i_dist = 1
    when 'R'
        i0 = 15
        i_stride = -4
        i_dist = -1
    end

    4.times do |x|
        column = []
        top_merged = false
        4.times do |y|
            tile = board[i0 + x*i_stride + y*i_dist]
            next if tile == 0
            if top_merged || tile != column.last
                column.push tile
                top_merged = false
            else
                column[-1] *= 2
                top_merged = true
            end
        end

        4.times do |y|
            board[i0 + x*i_stride + y*i_dist] = column[y] || 0
        end
    end

    board
end

def advance board
    if board.reduce(:*) > 0
        return board, board
    end

    16.times do |i|
        if board[15-i] == 0
            board[15-i] = 4
            break
        end
    end

    spawned = board.clone

    # Attention, dirty dirty hand-tweaked edge cases to avoid
    # the inevitable for a bit longer. NSFS!
    if board[11] == 8 && (board[12..15] == [32, 16, 4, 4] ||
                          board[12..15] == [16, 16, 4, 4] && board[8..10] == [256,64,32]) || 
       board[11] == 16 && (board[12..15] == [32, 8, 4, 4] || 
                           board[12..15] == [4, 32, 8, 8] || 
                           board[12..15] == [4, 32, 0, 4])

        dir = 'R'
    elsif board[11] == 16 && board[12..15] == [4, 4, 32, 4] ||
          board[11] == 8 && board[12..15] == [0, 4, 32, 8]
        dir = 'U'
    else
        dir = (board.reduce(:+)/4).even? ? 'U' : 'L'
    end

    board = slide(board, dir)

    if board == spawned
        dir = dir == 'U' ? 'L' : 'U'
        board = slide(board, dir)
    end
    return spawned, board
end

Bu advancefonksiyon sizin istemenizdir. Bir kartı 1d dizisi olarak alır ve döşeme üretildikten ve hareket yapıldıktan sonra kartı döndürür.

Bu snippet ile test edebilirsiniz

board = [0]*16
loop do
    spawned, board = advance(board)
    board.each_slice(4) {|row| puts row*' '}
    puts
    break if board[15] > 0
end

puts "Score: #{board.reduce :+}"

Strateji çok basit ve aslında 2048'i oynadığımda 128'e atladığım stratejiydi: sadece yukarı ve sol arasında değişiyor . Bu işi olabildiğince uzun süre yapmak için, 4sağ alt köşede yeni s ortaya çıkar.

DÜZENLEME: Sonundan hemen önce belirli adımlarda birkaç kez sağa gitmek için sabit kodlu bir anahtar ekledim, bu da aslında 1024'e ulaşmamı sağlıyor. yarın genel olarak daha iyi bir yaklaşım düşünün. (Dürüst olmak gerekirse, elle ayarlanmış kesmek ekleyerek puanımı 4 kat artırabileceğim gerçeği bana sadece stratejimin bok olduğunu söylüyor.)

Sonunda kurulu olduğun tahta

1024 512 256 128
 512 256 128  16
 256 128  64   8
   8  32   8   4

Sadece nitpick'e göre, 4'leri yumurtlamak size en uygun puanı vermez, çünkü her biri 2 2'lerin ürettiğinden farklı olarak 4 puan kazanmazsınız.
BrunoJ

@BrunoJ Bu mücadelenin puanı, gerçek oyunda sahip olacağınız puan değil, sondaki tüm karoların toplamı olarak hesaplanır. Ancak durum buysa, haklısınız. ;) ... Her ne kadar stratejim ile bir fark yaratmazsa da, 256 yerine 128'e ulaşacağım.
Martin Ender

Oh, puanlamanın aynı olmadığını yakalamadım, özür dilerim
BrunoJ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.