Chơi một trò chơi hoàn hảo vào năm 2048


17

Công việc của bạn là mô phỏng một trò chơi hoàn hảo về mặt toán học vào năm 2048. Ý tưởng là tìm ra giới hạn trên lý thuyết về việc một trò chơi 2048 có thể đi được bao xa và tìm cách đến đó.

Để có được ý tưởng về cái này trông như thế nào, hãy chơi với bản sao 2x2 này và cố gắng ghi được 68 điểm. Nếu bạn làm như vậy, bạn sẽ kết thúc với một gạch 2, 4, 8 và 16. Không thể vượt qua điểm đó.

Nhiệm vụ của bạn được thực hiện dễ dàng hơn bởi vì bạn có thể chọn nơi gạch sinh sản và giá trị của chúng là gì, giống như bản sao này .

Bạn phải viết một chương trình hoặc chức năng chấp nhận một bảng 2048 làm đầu vào và xuất ra bảng với ô được sinh ra và bảng sau khi thu gọn các ô. Ví dụ:

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

Chương trình của bạn sẽ liên tục được cung cấp đầu ra của chính nó để mô phỏng toàn bộ trò chơi vào năm 2048. Đầu vào đầu tiên của chương trình sẽ là một bảng trống. Bạn phải sinh ra một ô trên nó, không giống như hai ô của trò chơi gốc. Ở bước cuối cùng của trò chơi, bạn sẽ không thể di chuyển, do đó hai bảng đầu ra của bạn có thể giống hệt nhau.

Tất nhiên bạn phải chỉ di chuyển hợp pháp đầu ra. Chỉ có thể sinh ra 2 hoặc 4, bạn phải di chuyển hoặc thu gọn ít nhất một ô khi di chuyển, v.v.

Tôi đã cố tình làm cho các yêu cầu đầu vào và đầu ra mơ hồ. Bạn có thể tự do chọn định dạng của đầu vào và đầu ra. Bạn có thể sử dụng ma trận, mảng, chuỗi hoặc bất cứ điều gì bạn muốn. Miễn là bạn có thể mô phỏng một trò chơi 2048 với họ, đầu vào và đầu ra của bạn đều ổn.

Người chiến thắng sẽ là người kết thúc trò chơi với tổng số ô cao nhất trên bảng, sau đó bằng số byte thấp nhất trong mã nguồn. Việc tính điểm từ trò chơi gốc sẽ không được tính đến. (Gợi ý: sử dụng 4)


@undergroundmonorail Điều này khác với câu hỏi đó. Câu hỏi này cho phép sinh ra những viên gạch của riêng bạn, và sắp sửa đi xa nhất có thể về mặt toán học, không chỉ đến năm 2048.
Kendall Frey

1
@TheDoctor 68 là tổng số sức mạnh của 2, và điểm số của bạn sẽ là bao nhiêu nếu bạn nhận được 2, 4, 8, 16.
user12205

2
Đây thực sự là một bản sao? Những gì nó sẽ làm cho nó khác nhau?
Kendall Frey

1
@Quincunx Điều đó thực sự sẽ tạo ra một trò chơi tối ưu.
Kendall Frey

4
Tôi thấy trung tâm của thử thách này là "Tìm một giải pháp tối ưu", là duy nhất, nhưng phải thừa nhận rằng đó là một lựa chọn tồi để đặt nó trong một "vỏ" trùng lặp. Người này hét lên, "Ôi nhìn kìa, một thử thách Golf Code 2048 khác." Với những phiếu bầu gần như quá chủ quan, bạn thực sự phải bán thử thách của mình cho đám đông. Đôi khi, điều đó có nghĩa là tạo ra sự lột xác khủng khiếp của riêng bạn vào năm 2048.
Rainbolt

Câu trả lời:


3

Ruby, vào góc, Điểm: 3340

Đây là một chiến lược rất đơn giản để khởi động điều này. Tôi có một ý tưởng cho một điểm số gần (hoàn hảo), nhưng tôi gặp khó khăn khi chính thức hóa nó, vì vậy đây là một điều đơn giản để mọi thứ diễn ra.

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

Các advancechức năng là một trong những yêu cầu của bạn. Nó lấy một bảng dưới dạng mảng 1d và trả về bảng sau khi gạch đã được sinh ra và sau khi di chuyển được thực hiện.

Bạn có thể kiểm tra nó với đoạn trích này

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

Chiến lược này rất đơn giản, và là chiến lược mà tôi thực sự đã sử dụng để bỏ qua tới 128 khi tôi đang chơi 2048: chỉ xen kẽ giữa lêntrái . Để làm cho công việc này càng lâu càng tốt, 4s mới được sinh ra ở góc dưới bên phải.

EDIT: Tôi đã thêm một công tắc được mã hóa cứng để thực hiện đúng một vài lần ở các bước cụ thể ngay trước khi kết thúc, điều này thực sự cho phép tôi đạt 1024. Mặc dù vậy, điều này đã vượt quá tầm kiểm soát, vì vậy tôi sẽ dừng việc này ngay bây giờ và nghĩ về một cách tiếp cận thường tốt hơn vào ngày mai. (Thành thật mà nói, việc tôi có thể tăng điểm của mình lên 4 lần bằng cách thêm các bản hack được điều chỉnh bằng tay chỉ cho tôi biết rằng chiến lược của tôi là tào lao.)

Đây là bảng bạn kết thúc với

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

Chỉ với nitpick, sinh ra 4 'sẽ không cho bạn điểm tối ưu vì bạn không đạt được 4 điểm mỗi khi một điểm được tạo ra trái ngược với việc được tạo bởi 2 2'.
BrunoJ

@BrunoJ Điểm cho thử thách này được tính đơn giản là tổng số tất cả các ô ở cuối, không phải là số điểm bạn có trong trò chơi thực tế. Nhưng nếu đó là trường hợp, tất nhiên bạn đúng. ;) ... Mặc dù tôi nghĩ với chiến lược của mình, nó sẽ không tạo ra sự khác biệt, bởi vì tôi chỉ đạt được 128 thay vì 256 sau đó.
Martin Ender

Ồ, không hiểu rằng việc ghi bàn không giống nhau, lời xin lỗi của tôi
BrunoJ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.