shawn42/gamebox

View on GitHub
lib/gamebox/lib/linked_list.rb

Summary

Maintainability
A
0 mins
Test Coverage
class LinkedList
  include Enumerable

  ListElem = Struct.new(:obj, :prev, :next)
  attr_accessor :head, :tail

  def initialize(enum = nil)
    @head = @tail = ListElem.new
    @head.next = @head
    @head.prev = @head

    append enum unless enum.nil?
  end

  # pop off the first item
  def shift
    tmp = @head.next
    @head.next = tmp.next
    tmp.next.prev = @head
    #puts "SHIFTING [#{tmp.obj.x},#{tmp.obj.y}]"
#    puts to_s
    return tmp.obj
  end

  # pop off the last item
  def unshift
    tmp = @tail.prev
    @tail.prev = @tail.prev.prev
    @tail.next = @tail
    return tmp.obj
  end

  def place(new_obj, location, elem)
#    puts "placing #{new_obj[0][0]},#{new_obj[0][1]} #{location} #{elem.obj[0][0]},#{elem.obj[0][1]}"
    tmp = ListElem.new
    tmp.obj = new_obj
    case location
    when :before
      tmp.next = elem
      tmp.prev = elem.prev
      elem.prev.next = tmp
      elem.prev = tmp
    when :after
      tmp.prev = elem
      tmp.next = elem.next
      elem.next.prev = tmp
      elem.next = tmp
    end
#    puts to_s
    tmp
  end

  def append(e)
#    puts "appending #{e[0][0]},#{e[0][1]}"
    tmp = ListElem.new
    tmp.obj = e
    tmp.prev = @tail.prev
    tmp.next = @tail
    tmp.prev.next = tmp
    tmp.next.prev = tmp
#    puts to_s
    self
  end

  alias :<< :append
  def prepend(e)
    tmp = ListElem.new
    tmp.obj = e
    tmp.prev = @head
    tmp.next = @head.next
    tmp.prev.next = tmp
    tmp.next.prev = tmp
    self
  end
  alias :>> :prepend

  # only removed the first instance of e
  def remove(e)
    i = @head.next

    while @tail != i
      if i.obj == e
        # remove it
        i.prev.next = i.next
        i.next.prev = i.prev
        return i.obj
      end
      i = i.next
    end
    i
  end
  alias :- :remove

  def empty?()
    @tail.prev == @head
  end

  def each
    i = @head.next

    while @tail != i
      yield i.obj
      i = i.next
    end
  end

  def each_element
    i = @head.next

    while @tail != i
      yield i
      i = i.next
    end
  end

  def to_s
    str = "LinkedList #{self.object_id} ["
    i = @head.next

    while @tail != i
      str += "#{i.obj[0]}-#{i.obj[1]},"
      i = i.next
    end
    str  += "]"
    str
  end

  def size
    size = 0
    i = @head.next
    while @tail != i
      i = i.next
      size += 1
    end
    size
  end
end