Ruby,进入角落,得分: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
功能是您所要求的。它以棋盘为一维数组,并在生成瓦片并进行移动后返回棋盘。
您可以使用此代码段对其进行测试
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的策略:只是在上和左之间交替。为了使这项工作尽可能长的时间,4
在右下角会产生new 。
编辑:我已经添加了一个硬编码的开关,可以在结束之前的特定步骤执行几次,这实际上使我达到了1024。不过这有些失控了,所以我现在就停下来想一想明天总体上更好的方法。(老实说,我可以通过添加一些手动调整的技巧将得分提高4倍,这只能告诉我我的策略很糟糕。)
这是您最终获得的董事会
1024 512 256 128
512 256 128 16
256 128 64 8
8 32 8 4