ルビー、コーナーへ、スコア: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