2048の完璧なゲームをプレイする


17

あなたの仕事は、数学的に完璧な2048のゲームをシミュレートすることです。アイデアは、2048のゲームがどこまで進むことができるかの理論的な上限を見つけ、そこに到達する方法を見つけることです。

これがどのように見えるかを知るには、この2x2クローンで遊んで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つのタイルとは異なり、その上に1つのタイルを生成する必要があります。ゲームの最後のステップでは、移動できなくなるため、2つの出力ボードは同一になります。

もちろん、合法的な動きのみを出力する必要があります。スポーンできるのは2つまたは4つだけです。移動中に少なくとも1つのタイルを移動または縮小する必要があります。

入力と出力の要件を意図的に曖昧にしました。入力と出力の形式を自由に選択できます。行列、配列、文​​字列など、何でも使用できます。それらで2048ゲームをシミュレートできる限り、入力と出力は問題ありません。

勝者は、ボード上のタイルの合計が最も多く、次にソースコードのバイト数が最も少ないゲームを終了した人になります。元のゲームからの得点は考慮されません。(ヒント:4を使用)


@undergroundmonorailこれはその質問とは異なります。この質問は、あなた自身のタイルを産卵ことができます、だけでなく、2048に、これまでのように数学的に可能な限り行くことについてです
ケンドール・フレイ

1
@TheDoctor 68は2の累乗の合計であり、2、4、8、16を取得した場合のスコアが何になるか
user12205

2
これは本当に重複していますか?それを変えるにはさらに何が必要でしょうか?
ケンドールフレイ

1
@Quincunxしかし、実際には次善のゲームが生成されます。
ケンドールフレイ

4
この課題の核心である「最適なソリューションを見つける」はユニークであることがわかりましたが、それを重複した「シェル」で囲むのは明らかに悪い選択でした。これは「ああ、もう一つの2048コードゴルフチャレンジ」と叫びます。近い票がとても主観的であることで、あなたは本当にする必要が売っ群衆にあなたの挑戦を。時には手段は、2048の独自のひどい盗作生成すること
Rainboltを

回答:


3

ルビー、コーナーへ、スコア: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この関数は、あなたが求めて1です。ボードを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 :+}"

戦略は非常に単純であり、私は自分自身を2048年に遊んでいたとき、私は実際には128にスキップするために使用さ1である:間だけ交互にアップして。この機能を可能な限り長くするため4に、右下隅に新しいが生成されます。

編集:ハードコーディングされたスイッチを追加して、最後の直前の特定のステップで数回右に移動します。これにより、実際に1024に到達します。明日は一般的に良いアプローチを考えてください。(正直なところ、手で微調整したハックを追加することでスコアを4倍に増やすことができるという事実は、私の戦略がくだらないことだけを教えてくれます。)

これが最終的にはボードです

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

簡単に言えば、2 2で生成されるのではなく、作成されるたびに4ポイントを獲得できないため、4を生成しても最適なスコアは得られません。
BrunoJ

@BrunoJこのチャレンジのスコアは、実際のゲームで得られるスコアではなく、単純に最後のすべてのタイルの合計として計算されます。しかし、もしそうなら、あなたはもちろん正しい。;)...私は自分の戦略では違いはないと思いますが、256ではなく128にしかならないからです。
マーティンエンダー14

ああ、得点が同じではないことを
理解
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.