Пограйте в ідеальну гру 2048 року


18

Ваше завдання - імітувати математично досконалу гру 2048 року. Ідея полягає в тому, щоб знайти теоретичну верхню межу того, як далеко може пройти гра 2048 року, і знайти, як дістатися.

Щоб зрозуміти, як це виглядає, пограйте з цим клоном 2х2 і спробуйте набрати 68 балів. Якщо ви зробите це, ви закінчите плиткою 2, 4, 8 і 16. Просунутись через цю точку неможливо.

Ваше завдання полегшується, тому що ви можете вибрати, де нерестовий плитка і які їх значення, як і цей клон .

Ви повинні написати програму або функцію, яка приймає дошку 2048 як вхідну інформацію та виводить дошку із породженою плиткою та дошкою після згортання плиток. Наприклад:

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

Ваша програма буде неодноразово подавати власний вихід, щоб імітувати всю гру 2048 року. Першим входом програми буде порожня дошка. Ви повинні покласти на неї одну плитку, на відміну від двох плиток оригінальної гри. На останньому кроці гри ви не зможете рухатися, тому дві ваші вихідні дошки можуть бути однаковими.

Звичайно, потрібно виводити лише юридичні кроки. Можна породити лише 2 або 4, ви повинні рухатись або згортати хоча б одну плитку на ходу тощо.

Я навмисно зробив вимоги до вводу та виходу розпливчастими. Ви можете вибрати формат введення та виводу. Ви можете використовувати матриці, масиви, рядки або що завгодно. Поки ви можете імітувати гру 2048 з ними, ваші входи та результати є нормальними.

Перемагає той, хто закінчить гру найвищою сумою плиток на дошці, потім найменшою кількістю байтів у вихідному коді. Рахунки з оригінальної гри не враховуються. (Підказка: використання 4-х)


@undergroundmonorail Це відрізняється від цього питання. Це питання дозволяє нерестувати власну плитку, і йдеться про те, наскільки це можливо математично, а не лише до 2048 року.
Кендалл Фрей,

1
@TheDoctor 68 - це сума повноважень 2, і те, яким буде ваш рахунок, якщо ви отримаєте 2, 4, 8, 16.
user12205

2
Це справді дублікат? Що більше потрібно для того, щоб це було інакше?
Кендалл Фрей

1
@Quincunx Це справді призведе до неоптимальної гри.
Кендалл Фрей

4
Я визнав, що серце цього виклику "Знайти оптимальне рішення" є унікальним, але, правда, це був поганий вибір, щоб укласти його у "дублі". Цей кричить: "О, дивіться, ще один виклик 2048 Code Golf". Коли голоси настільки суб'єктивні, ви справді повинні продати свій виклик натовпу. Іноді це означає генерувати власну страшну
зріст

Відповіді:


4

Рубі, в кут, Оцінка: 3340

Ось дуже проста стратегія, щоб розпочати це. У мене є ідея про (близький) ідеальний бал, але у мене виникають проблеми з його формалізацією, тому ось щось просте, щоб вийти з справи.

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

Ця advanceфункція потрібна вам. Дошка приймає як масив 1d і повертає дошку після породження плитки та після переміщення.

Ви можете перевірити його за допомогою цього фрагмента

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

Стратегія дуже проста, і це та, яку я насправді переходив до 128, коли я сам грав у 2048 році: просто чергуйте вгору та вліво . Щоб зробити цю роботу якомога довше, 4в правому нижньому куті з'являються нові s.

EDIT: Я додав жорсткий зашифрований перемикач, щоб перейти правильно декілька разів на конкретних кроках безпосередньо перед кінцем, що фактично дозволяє мені досягти 1024. Хоча це стає дещо поза рукою, тому я зупиняюсь на цьому зараз і подумайте про загально кращий підхід завтра. (Чесно кажучи, той факт, що я можу збільшити свою оцінку в 4 рази, додавши рукотворні хаки, лише говорить про те, що моя стратегія - це лайно.)

Це рада, на якій ви закінчите

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

Що стосується нітпіка, нерестування 4 не дає оптимального результату, оскільки ви не набираєте 4 бали кожного разу, коли створюється один, а не генерується 2 2.
BrunoJ

@BrunoJ Оцінка для цього виклику просто обчислюється як загальна кількість усіх плиток в кінці, а не оцінка, яку ви мали б у реальній грі. Але якщо це було так, ви, звичайно, праві. ;) ... Хоча я думаю, що зі своєю стратегією це не змінило б значення, тому що я отримав би лише 128, а не 256.
Мартін Ендер

Ой, не
зрозумів,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.