Mainkan game sempurna tahun 2048

18

Tugas Anda adalah mensimulasikan permainan yang sempurna secara matematis tahun 2048. Idenya adalah menemukan batas teoretis seberapa jauh permainan 2048 dapat berjalan, dan menemukan cara untuk sampai ke sana.

Untuk mendapatkan gambaran seperti apa ini, mainkan dengan klon 2x2 ini dan cobalah untuk mencetak 68 poin. Jika ya, Anda akan mendapatkan ubin 2, 4, 8, dan 16. Tidak mungkin untuk maju melewati titik itu.

Tugas Anda menjadi lebih mudah karena Anda dapat memilih tempat ubin bertelur dan apa nilainya, seperti klon ini .

Anda harus menulis sebuah program atau fungsi yang menerima papan 2048 sebagai input, dan mengeluarkan papan dengan ubin spawned dan papan setelah ubin runtuh. Sebagai contoh:

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

Program Anda akan berulang kali diberi output sendiri untuk mensimulasikan seluruh permainan tahun 2048. Input pertama dari program ini adalah papan kosong. Anda harus menelurkan satu ubin di atasnya, tidak seperti dua ubin game asli. Pada langkah terakhir permainan, Anda tidak akan bisa bergerak, sehingga dua papan keluaran Anda bisa identik.

Tentu saja Anda hanya harus mengeluarkan langkah hukum. Hanya 2 atau 4 yang dapat muncul, Anda harus memindahkan atau menciutkan setidaknya satu ubin saat bepergian, dll.

Saya sengaja membuat persyaratan input dan output tidak jelas. Anda bebas memilih format input dan output. Anda dapat menggunakan matriks, array, string, atau apa pun yang Anda inginkan. Selama Anda dapat mensimulasikan game 2048 dengan mereka, input dan output Anda baik-baik saja.

Pemenang akan menjadi orang yang mengakhiri permainan dengan jumlah ubin tertinggi di papan, kemudian dengan jumlah byte terendah dalam kode sumber. Skor dari game asli tidak akan diperhitungkan. (Petunjuk: gunakan 4-an)

Kendall Frey
sumber
@undergroundmonorail Ini berbeda dari pertanyaan itu. Pertanyaan ini memungkinkan memunculkan ubin Anda sendiri, dan tentang sejauh mungkin secara matematis, bukan hanya sampai 2048.
Kendall Frey
1
@TheDoctor 68 adalah jumlah kekuatan 2, dan berapa skor Anda jika Anda mendapat 2, 4, 8, 16.
user12205
2
Apakah ini benar-benar duplikat? Apa lagi yang diperlukan untuk membuatnya berbeda?
Kendall Frey
1
@ Quincunx Itu benar-benar akan menghasilkan game yang kurang optimal.
Kendall Frey
4
Saya menemukan inti dari tantangan ini, "Temukan solusi optimal", untuk menjadi unik, tetapi memang itu adalah pilihan yang buruk untuk melampirkannya dalam duplikat "shell". Yang ini berteriak, "Oh, lihat, tantangan Golf Code 2048 lainnya." Dengan suara dekat yang sangat subjektif, Anda benar-benar harus menjual tantangan Anda kepada orang banyak. Kadang-kadang itu berarti menghasilkan ripoff mengerikan Anda sendiri tahun 2048.
Rainbolt

Jawaban:

4

Ruby, Into the Corner, Nilai: 3340

Berikut adalah strategi yang sangat sederhana untuk memulai ini. Saya memang punya ide untuk skor sempurna (hampir), tapi saya kesulitan memformalkannya, jadi di sini ada sesuatu yang sederhana untuk menyelesaikannya.

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

The advanceFungsi adalah salah satu Anda minta. Dibutuhkan papan sebagai array 1d dan mengembalikan papan setelah ubin telah muncul dan setelah langkah dibuat.

Anda dapat mengujinya dengan cuplikan ini

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 :+}"

Strateginya sangat sederhana, dan ini adalah yang saya gunakan untuk melompat ke 128 ketika saya bermain 2048 sendiri: hanya bergantian antara atas dan kiri . Untuk membuat ini berfungsi selama mungkin, 4s baru muncul di sudut kanan bawah.

EDIT: Saya telah menambahkan sakelar kode keras untuk meluruskan beberapa kali pada langkah-langkah spesifik tepat sebelum akhir, yang sebenarnya membuat saya mencapai 1024. Namun, ini agak tidak terkendali, jadi saya akan berhenti dengan ini untuk saat ini dan pikirkan pendekatan yang umumnya lebih baik besok. (Jujur, fakta bahwa saya dapat meningkatkan skor saya dengan faktor 4 dengan menambahkan peretasan tweaked hanya memberitahu saya bahwa strategi saya adalah omong kosong.)

Papan inilah yang akhirnya Anda miliki

1024 512 256 128
 512 256 128  16
 256 128  64   8
   8  32   8   4
Martin Ender
sumber
Hanya untuk nitpick, pemijahan 4's tidak memberi Anda skor optimal karena Anda tidak mendapatkan 4 poin setiap kali satu diciptakan sebagai lawan yang dihasilkan oleh 2 2's.
BrunoJ
@BrunoJ Skor untuk tantangan ini hanya dihitung sebagai total semua ubin pada akhirnya, bukan skor yang Anda miliki di game sebenarnya. Tetapi jika itu masalahnya, tentu saja Anda benar. ;) ... Walaupun saya berpikir dengan strategi saya, itu tidak akan membuat perbedaan, karena saya hanya akan mendapatkan 128 daripada 256 saat itu.
Martin Ender
Oh, tidak menyadari bahwa skornya tidak sama, permintaan maaf saya
BrunoJ