app/snake.rb
class Snake
attr_reader :bones, :lost, :direction
def initialize(direction = :right)
@bones = []
@lost = false
@direction = direction
end
def add_bone(bone)
head.unhead! if head
@bones.unshift bone
end
def direction=(dir)
@direction = dir if valid_direction?(dir)
end
def head
@bones.first
end
def move!
eaten = false
new_square = Board.find(head.new_coords)
if new_square.food
new_square.unfood!
eaten = true
Board.add_food!
end
pop_last unless eaten
if new_square.snake?
return lose!
end
Bone.new(self, new_square)
end
def lose!
@lost = true
check_if_record
end
def won?
@bones.size == Board::NUMBER_OF_CELLS
end
def check_if_record
result = @bones.length
if (r = LocalStorage['record'].to_i) && r < result
alert "#{result} points!\nNew record!"
LocalStorage['record'] = result
end
end
def serialize
{
bones: @bones.map(&:coords),
lost: @lost,
direction: @direction
}
end
def self.initialize_from_hash(hash)
inst = new
inst.instance_variable_set(:@lost, hash[:lost] == 'true')
inst.instance_variable_set(:@direction, hash[:direction].to_sym)
hash[:bones].reverse_each { |d| Bone.new(inst, Board.find(d)) }
inst
end
private
def pop_last
bone = @bones.pop
bone.square.unbone!
end
def valid_direction?(dir)
if dir == @direction
return false
end
if dir == Board::OPPOSITE_DIRECTION[@direction]
return false
end
true
end
end