Skip to content

Instantly share code, notes, and snippets.

@cjavdev
Created December 19, 2022 17:51
Show Gist options
  • Save cjavdev/1b9d1f89629c400f1c10ba05e8433c26 to your computer and use it in GitHub Desktop.
Save cjavdev/1b9d1f89629c400f1c10ba05e8433c26 to your computer and use it in GitHub Desktop.
class Piece
attr_reader :shape, :kind
ORDER = [
:dash,
:plus,
:jay,
:line,
:square
]
def self.order
@order ||= ORDER.cycle
end
def self.generate(start)
send(order.next, start)
end
def self.line(start)
Piece.new([
[0, 0], [1, 0], [2, 0], [3, 0]
], start, :line)
end
def self.dash(start)
Piece.new([
[0, 0], [0, 1], [0, 2], [0, 3]
], start, :dash)
end
def self.square(start)
Piece.new([
[0, 0], [0, 1], [1, 0], [1, 1]
], start, :square)
end
def self.plus(start)
Piece.new([
[0, 1], [1, 0], [1, 1], [1, 2], [2, 1]
], start, :plus)
end
def self.jay(start)
Piece.new([
[0, 0], [0, 1], [0, 2], [1, 2], [2, 2]
], start, :jay)
end
def initialize(shape, start, kind)
@kind = kind
@shape = shape.map do |x, y|
[x + start[0], y + start[1]]
end
end
def move_left(positions)
return if @shape.any? {|_, y| y - 1 < 0}
return if @shape.any? do |x, y|
positions.include?([x, y - 1])
end
@shape = @shape.map do |x, y|
[x, y - 1]
end
end
def move_right(positions)
return if @shape.any? {|_, y| y + 1 > 6}
return if @shape.any? do |x, y|
positions.include?([x, y + 1])
end
@shape = @shape.map do |x, y|
[x, y + 1]
end
end
def move_down(positions)
return if @shape.any? {|x, _| x - 1 < 0}
return if @shape.any? do |x, y|
positions.include?([x - 1, y])
end
@shape = @shape.map do |x, y|
[x - 1, y]
end
end
end
class Tower
def initialize(instructions, piece_count)
@instructions = instructions.cycle
@falling = false
@grid = Array.new(10) { Array.new(7, 0) }
@pieces = []
@piece_count = piece_count
end
def height
if current_positions.any?
current_positions.map(&:first).max + 1
else
0
end
end
def current_positions
@pieces.flat_map(&:shape)
end
def spawn_piece
@piece_count -= 1
puts @piece_count
if @piece_count < 0
puts "Current height: #{height}"
throw :done
end
if @grid.length < height + 7
@grid += Array.new(7) { Array.new(7, 0) }
end
@current_piece = Piece.generate([
height + 3, 2
])
end
def lock_piece(piece)
@pieces << piece
piece.shape.each do |x, y|
@grid[x][y] = 1
end
end
def step
spawn_piece if !@current_piece
if @falling
if !@current_piece.move_down(current_positions)
lock_piece(@current_piece)
@current_piece = nil
end
@falling = !@falling
else
@current_piece.send(
@instructions.next,
current_positions
)
@falling = !@falling
end
end
def to_s
(@grid.length - 1).downto(0).map do |x|
(0..6).map do |y|
if current_positions.include?([x, y])
"#"
elsif @current_piece &&
@current_piece.shape.include?([x, y])
"@"
else
"."
end
end.join
end.join("\n")
end
end
pattern = ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>"
ins = pattern.chars.map do |c|
if c == '>'
:move_right
else
:move_left
end
end
tower = Tower.new(ins, 2022)
while true
tower.step
end
@cjavdev
Copy link
Author

cjavdev commented Dec 19, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment