Skip to content

Instantly share code, notes, and snippets.

@pachacamac
Created January 27, 2013 21:27
Show Gist options
  • Save pachacamac/4650630 to your computer and use it in GitHub Desktop.
Save pachacamac/4650630 to your computer and use it in GitHub Desktop.
a little logic game in fragments
MAX_CAPACITY = 3
def show(m)
puts "="*12,m.map{|l|' '<<l.map{|e|'*123456789'[e]}.join(' ')}.join("\n"),"="*12
end
def pop(map, x,y)
m = map.map(&:dup)
return m if x < 0 || y < 0 || x >= m[0].size || y >= m.size
if m[y][x] == MAX_CAPACITY
m[y][x] = 0
m = blast(m,x,y,-1, 0)
m = blast(m,x,y, 1, 0)
m = blast(m,x,y, 0,-1)
m = blast(m,x,y, 0, 1)
elsif m[y][x] > 0
m[y][x] += 1
end
m
end
def blast(map, x,y, dx,dy)
m = map.map(&:dup)
loop do
x += dx
y += dy
return m if x < 0 || y < 0 || x >= m[0].size || y >= m.size
if m[y][x] == MAX_CAPACITY
m = pop(m,x,y)
return m
elsif m[y][x] > 0
m[y][x] += 1
return m
end
end
end
def finished?(m)
!m.flatten.find{|e|e>0}
end
def element_positions(m)
ep = [].tap{|a| m.each_with_index{|r,y| r.each_with_index{|e,x| a<<[[x,y],e] if e > 0}}}
(rand(0..9) < 4 ? ep.shuffle : ep.sort{|a,b| b[1]<=>a[1]}).map(&:first)
end
def all_games(m, moves=[], games={})
return games if games.any? && moves.size > games.values.first #optimization
return games if games.size >= 250 #limit
ep = element_positions(m)
return games.merge!(moves => moves.size) if ep.empty?
ep.each do |p|
games.merge! all_games(pop(m,*p), moves+[p], games)
end
games
end
maps = [
[[0,0,0,0],
[0,3,3,0],
[0,1,2,0],
[0,0,0,0]],
[[3,1,2,2],
[2,2,2,2],
[2,1,3,2],
[2,2,2,2]],
[[1,1,3,1],
[2,3,2,3],
[1,1,3,1],
[1,1,2,1]],
[[1,1,3,2],
[1,1,2,1],
[2,2,3,3],
[1,2,1,2]],
[[0,2,3,0],
[3,0,0,3],
[2,0,0,2],
[2,2,3,2]],
[[2,2,2,0],
[2,2,1,2],
[2,1,2,3],
[0,2,3,0]],
#experimental
[[2,2,0,3],
[2,0,0,0],
[0,0,0,2],
[3,0,2,2]],
]
games = all_games(maps[6])
games.sort{|a,b|b[1]<=>a[1]}.each do |g|
puts "#{g[1]} moves: #{g[0].inspect}"
end
puts games.size
exit
maps.each do |m|
show m
i = 0
begin
x,y = gets.strip.split.map(&:to_i)
m = pop m, x, y
show m
i += 1
end until finished? m
puts "Level cleared in #{i} moves!\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment